mod cli;
use crate::cli::{Commands, DoArgs, LoginArgs, WPEpubCli};
use anyhow::Context;
use anyhow::Result;
use clap::Parser;
use reqwest::Client;
use tracing::info;
use tracing_subscriber::EnvFilter;
use wp_mini::WattpadClient;
use wp_mini_epub::{download_story_to_folder, login, logout, StoryField};
#[tokio::main]
async fn main() -> Result<()> {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("wp_epub_cli=info,warn"));
tracing_subscriber::fmt().with_env_filter(filter).init();
let reqwest_client = Client::builder()
.cookie_store(true)
.user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36")
.build()?;
let wattpad_client = WattpadClient::new();
let cli = WPEpubCli::parse();
info!("CLI arguments parsed successfully");
match cli.command {
Commands::Do(args) => handle_do_command(&wattpad_client, &reqwest_client, args)
.await
.context("Failed to process story")?,
Commands::Login(args) => handle_login_command(&wattpad_client, args)
.await
.context("Failed to login")?,
Commands::Logout => handle_logout_command(&wattpad_client)
.await
.context("Failed to logout")?,
}
Ok(())
}
async fn handle_do_command(
wattpad_client: &WattpadClient,
reqwest_client: &Client,
args: DoArgs,
) -> Result<()> {
info!(id = args.id, "Handling 'do' command");
let output_dir = args
.output_path
.unwrap_or_else(|| std::env::current_dir().expect("Failed to get current directory"));
let story_fields = vec![StoryField::Title];
let story_response = download_story_to_folder(
wattpad_client,
reqwest_client,
args.id,
args.include_images,
args.semaphore as usize,
&output_dir,
Some(&story_fields),
)
.await?;
let story_title = story_response
.metadata
.title
.unwrap_or("Unknown Title".to_string());
info!(title = %story_title, "Story processing completed successfully");
Ok(())
}
async fn handle_login_command(wattpad_client: &WattpadClient, args: LoginArgs) -> Result<()> {
info!(username = %args.username, "Handling 'login' command");
login(wattpad_client, &args.username, &args.password).await?;
info!("Login successful!");
Ok(())
}
async fn handle_logout_command(wattpad_client: &WattpadClient) -> Result<()> {
info!("Handling 'logout' command");
logout(wattpad_client).await?;
info!("Logout successful!");
Ok(())
}