2021-02-06 09:59:03 +00:00
use std ::{ fs ::File , io ::Read } ;
2020-11-24 06:58:50 +00:00
use clap ::{ App , AppSettings , Arg } ;
2020-05-16 08:09:44 +01:00
2021-02-06 09:59:03 +00:00
pub fn cli_init ( ) -> AppConfig {
let app = App ::new ( " paperoni " )
2020-11-24 06:58:50 +00:00
. settings ( & [
AppSettings ::ArgRequiredElseHelp ,
AppSettings ::UnifiedHelpMessage ,
] )
2021-04-17 10:08:24 +01:00
. version ( clap ::crate_version! ( ) )
2020-11-24 06:58:50 +00:00
. about (
"
Paperoni is an article downloader .
It takes a url and downloads the article content from it and saves it to an epub .
" ,
)
. arg (
Arg ::with_name ( " urls " )
. help ( " Urls of web articles " )
. multiple ( true ) ,
)
2021-02-01 08:28:07 +00:00
. arg (
Arg ::with_name ( " file " )
. short ( " f " )
. long ( " file " )
. help ( " Input file containing links " )
. takes_value ( true ) ,
2021-02-11 10:51:21 +00:00
)
. arg (
Arg ::with_name ( " output_name " )
. long ( " merge " )
. help ( " Merge multiple articles into a single epub " )
. long_help ( " Merge multiple articles into a single epub that will be given the name provided " )
. takes_value ( true ) ,
2021-02-21 09:40:17 +00:00
) . arg (
Arg ::with_name ( " max_conn " )
. long ( " max_conn " )
. help ( " The maximum number of concurrent HTTP connections when downloading articles. Default is 8 " )
. long_help ( " The maximum number of concurrent HTTP connections when downloading articles. Default is 8. \n NOTE: It is advised to use as few connections as needed i.e between 1 and 50. Using more connections can end up overloading your network card with too many concurrent requests. " )
. takes_value ( true ) ) ;
2021-02-06 09:59:03 +00:00
let arg_matches = app . get_matches ( ) ;
let mut urls : Vec < String > = match arg_matches . value_of ( " file " ) {
Some ( file_name ) = > {
if let Ok ( mut file ) = File ::open ( file_name ) {
let mut content = String ::new ( ) ;
match file . read_to_string ( & mut content ) {
Ok ( _ ) = > content
. lines ( )
. filter ( | line | ! line . is_empty ( ) )
. map ( | line | line . to_owned ( ) )
. collect ( ) ,
Err ( _ ) = > vec! [ ] ,
}
} else {
println! ( " Unable to open file: {} " , file_name ) ;
vec! [ ]
}
}
None = > vec! [ ] ,
} ;
if let Some ( vals ) = arg_matches . values_of ( " urls " ) {
urls . extend (
vals . filter ( | val | ! val . is_empty ( ) )
. map ( | val | val . to_string ( ) ) ,
) ;
}
2021-02-21 09:40:17 +00:00
let max_conn = arg_matches
. value_of ( " max_conn " )
. map ( | conn_str | conn_str . parse ::< usize > ( ) . ok ( ) )
. flatten ( )
. map ( | max | if max > 0 { max } else { 1 } )
. unwrap_or ( 8 ) ;
let mut app_config = AppConfig ::new ( max_conn ) ;
2021-02-06 09:59:03 +00:00
app_config . set_urls ( urls ) ;
2021-02-11 10:51:21 +00:00
if let Some ( name ) = arg_matches . value_of ( " output_name " ) {
let file_name = if name . ends_with ( " .epub " ) & & name . len ( ) > 5 {
name . to_owned ( )
} else {
name . to_owned ( ) + " .epub "
} ;
app_config . set_merged ( file_name ) ;
}
2021-02-06 09:59:03 +00:00
app_config
}
pub struct AppConfig {
urls : Vec < String > ,
2021-02-06 14:03:02 +00:00
max_conn : usize ,
2021-02-11 10:51:21 +00:00
merged : Option < String > ,
2021-02-06 09:59:03 +00:00
}
impl AppConfig {
2021-02-21 09:40:17 +00:00
fn new ( max_conn : usize ) -> Self {
2021-02-06 14:03:02 +00:00
Self {
urls : vec ! [ ] ,
2021-02-21 09:40:17 +00:00
max_conn ,
2021-02-11 10:51:21 +00:00
merged : None ,
2021-02-06 14:03:02 +00:00
}
2021-02-06 09:59:03 +00:00
}
fn set_urls ( & mut self , urls : Vec < String > ) {
self . urls . extend ( urls ) ;
}
2021-02-11 10:51:21 +00:00
fn set_merged ( & mut self , name : String ) {
self . merged = Some ( name ) ;
}
2021-02-06 09:59:03 +00:00
pub fn urls ( & self ) -> & Vec < String > {
& self . urls
}
2021-02-06 14:03:02 +00:00
pub fn max_conn ( & self ) -> usize {
self . max_conn
}
2021-02-11 10:51:21 +00:00
pub fn merged ( & self ) -> Option < & String > {
self . merged . as_ref ( )
}
2020-05-16 08:09:44 +01:00
}