crier

RSS and Atom feed aggregator
Info | Log | Files | Refs | README

main.rs (3233B)


      1 use std::path::absolute;
      2 use std::path::PathBuf;
      3 use std::process;
      4 use std::io::stdout;
      5 use std::str::from_utf8;
      6 
      7 use uuid::Uuid;
      8 
      9 use clap::Arg;
     10 use clap::App;
     11 
     12 use log::debug;
     13 use log::info;
     14 use env_logger;
     15 
     16 use crier::Sequencer;
     17 use crier::io::FeedGet;
     18 use crier::mem::MemCache;
     19 use crier::io::fs::FsFeed;
     20 use crier::Error;
     21 
     22 struct Config {
     23     urls: Vec<String>,
     24     author: String,
     25     title: String,
     26     id: String,
     27 }
     28 
     29 impl Config {
     30     fn new(id: String, title: String, author: String, urls: Vec<String>) -> Config {
     31         Config {
     32             urls: urls,
     33             title: title,
     34             author: author,
     35             id: id,
     36         }
     37     }
     38 }
     39 
     40 fn parse() -> Config {
     41     let mut o = App::new("crier")
     42     .version(env!("CARGO_PKG_VERSION"))
     43     .author(env!("CARGO_PKG_AUTHORS"));
     44 
     45     o = o.arg(
     46         Arg::with_name("title")
     47             .long("title")
     48             .short("t")
     49             .value_name("Aggregated feed title")
     50             .takes_value(true)
     51             .required(true)
     52     );
     53 
     54     o = o.arg(
     55         Arg::with_name("author")
     56             .long("author")
     57             .short("a")
     58             .value_name("Aggregated feed author")
     59             .takes_value(true)
     60             .required(true)
     61     );
     62 
     63     // TODO: implement auto generate id when missing
     64     o = o.arg(
     65         Arg::with_name("id")
     66             .long("id")
     67             .short("i")
     68             .value_name("Aggregated feed id uuid value")
     69             .takes_value(true)
     70             .required(true)
     71     );
     72 
     73     o = o.arg(Arg::with_name("URLS")
     74         .multiple(true)
     75         .help("list of uris to merge"));
     76 
     77     let m = o.get_matches();
     78 
     79     Config::new(
     80         String::from(m.value_of("id").unwrap()),
     81         String::from(m.value_of("title").unwrap()),
     82         String::from(m.value_of("author").unwrap()),
     83         m.values_of("URLS").unwrap().map(|v| String::from(v)).collect())
     84 }
     85 
     86 fn add_feed(seq: &mut Sequencer, getter: impl FeedGet, uri: String) -> Result<i64, Error> {
     87     match getter.get(uri.as_str(), None) {
     88         Ok(v) => {
     89             let r = seq.add_from(v);
     90             info!("got {} results from {}", r, uri);
     91             return Ok(r);
     92         },
     93         Err(e) => {
     94             return Err(Error::ParseError);
     95         },
     96     };
     97 }
     98 
     99 fn process_entry(seq: &mut Sequencer, uri: String) -> Result<(), Error> {
    100     let v: PathBuf;
    101     let fp: String;
    102     let fs = FsFeed{};
    103 
    104     debug!("processing {}", uri);
    105     match absolute(uri) {
    106         Ok(r) => {
    107             fp = String::from(r.to_str().unwrap());
    108         },
    109         Err(e) => {
    110             return Err(Error::ParseError);
    111         }
    112     };
    113 
    114     match add_feed(seq, fs, fp) {
    115         Ok(r) => {
    116             return Ok(());
    117         },
    118         Err(e) => {
    119             return Err(e);
    120         },
    121     }
    122 }
    123 
    124 fn main() {
    125     let cfg = parse();
    126     let mut cache = MemCache::new();
    127 
    128     let id: Vec<u8> = cfg.id.into();
    129     let mut seq = Sequencer::new(id).with_cache(&mut cache);
    130 
    131     seq.set_title(cfg.title.as_str());
    132     seq.set_author(cfg.author.as_str());
    133 
    134     env_logger::init();
    135 
    136     debug!("config has {} uris", cfg.urls.len());
    137 
    138     for v in cfg.urls {
    139         process_entry(&mut seq, v).unwrap_or_else(|e| process::exit(1));
    140     }
    141 
    142     seq.write_to(stdout()).unwrap();
    143 }