1
- // RSS to sqlite database collector
2
-
3
1
mod modules {
4
2
pub mod sql;
3
+ pub mod config;
5
4
}
6
5
7
6
use modules:: sql:: create_db;
8
7
use modules:: sql:: insert_feed_items;
9
8
use modules:: sql:: last;
9
+ use modules:: config:: Config ;
10
10
11
+ use std:: error:: Error ;
12
+ use clap:: { Arg , Command } ;
11
13
use anyhow:: { Context , Result } ;
14
+ use env_logger;
12
15
use env_logger:: Builder ;
13
- use log:: { debug, info, warn, LevelFilter } ;
16
+ use log:: { debug, error , info, warn, LevelFilter } ;
14
17
use reqwest:: blocking;
15
18
use rss:: Channel ;
16
- use serde:: Deserialize ;
17
- // use std::error::Error;
18
- use std:: fs;
19
-
20
- #[ derive( Deserialize ) ]
21
- struct FeedConfig {
22
- dbfile : String ,
23
- feeds : Vec < String > ,
24
- }
25
-
26
- fn load_config ( ) -> Result < FeedConfig > {
27
- debug ! ( "Loading configuration" ) ;
28
- let config_data =
29
- fs:: read_to_string ( "config.json" ) . context ( "Failed to read configuration file" ) ?;
30
- debug ! ( "Parsing configuration" ) ;
31
- let config: FeedConfig =
32
- serde_json:: from_str ( & config_data) . context ( "Failed to parse configuration file" ) ?;
33
- Ok ( config)
34
- }
35
19
36
20
fn fetch_rss_feed ( url : & str ) -> Result < Channel > {
37
21
debug ! ( "Fetching RSS feed {}" , url) ;
@@ -40,22 +24,64 @@ fn fetch_rss_feed(url: &str) -> Result<Channel> {
40
24
Ok ( channel)
41
25
}
42
26
43
- fn main ( ) -> Result < ( ) > {
27
+ fn main ( ) -> Result < ( ) , Box < dyn Error > > {
28
+ // Setup logger
44
29
let mut builder = Builder :: from_default_env ( ) ;
45
30
builder. filter_level ( LevelFilter :: Info ) ;
46
31
builder. init ( ) ;
47
- // let's go
48
- info ! ( "RSS feed collector" ) ;
49
- warn ! ( "Work in progress" ) ;
50
- let config = load_config ( ) ?;
51
- let conn = create_db ( & config. dbfile ) ?;
52
- info ! ( "Processing {} feeds" , config. feeds. len( ) ) ;
53
- for feed in config. feeds . iter ( ) {
54
- let parsed_feed = fetch_rss_feed ( feed) . context ( "Failed to parse feed" ) ?;
55
- info ! ( "{} items from {}" , parsed_feed. items( ) . len( ) , feed) ;
56
- insert_feed_items ( & conn, & parsed_feed) . context ( "Failed to insert record" ) ?;
32
+
33
+ // Setup command arguments
34
+ let matches = Command :: new ( "RSS to SQLite" )
35
+ . version ( "0.2.0" )
36
+ . author ( "Geo Naumov <[email protected] >" )
37
+ . about ( "A collector for RSS feeds written in Rust. Uses the SQLite database." )
38
+ . subcommand ( Command :: new ( "update" ) . about ( "Update the feeds" ) )
39
+ . subcommand ( Command :: new ( "last" ) . about ( "Print last news items" ) )
40
+ . arg (
41
+ Arg :: new ( "debug" )
42
+ . help ( "Turn on debugging information" )
43
+ . short ( 'd' )
44
+ . long ( "debug" )
45
+ . action ( clap:: ArgAction :: SetTrue ) ,
46
+ )
47
+ . get_matches ( ) ;
48
+
49
+ // Debug flag
50
+ if matches. get_flag ( "debug" ) {
51
+ println ! ( "Debugging mode is on" ) ;
52
+ }
53
+
54
+ // Match subcommands
55
+ match matches. subcommand ( ) {
56
+ Some ( ( "update" , _) ) => {
57
+ info ! ( "Updating feeds..." ) ;
58
+ // Load configuration
59
+ debug ! ( "Loading configuration" ) ;
60
+ let config: Config = confy:: load ( "RSS2SQLite" , None ) ?;
61
+ let conn = create_db ( & config. dbfile ) ;
62
+ info ! ( "Processing {} feeds" , config. feeds. len( ) ) ;
63
+ for feed in config. feeds . iter ( ) {
64
+ let parsed_feed = fetch_rss_feed ( feed) . context ( "Failed to parse feed" ) ;
65
+ info ! ( "Feed: {}" , feed) ;
66
+ match & conn {
67
+ Ok ( ref conn) => {
68
+ insert_feed_items ( & conn, & parsed_feed. unwrap ( ) ) . context ( "Failed to insert record" ) ?;
69
+ } ,
70
+ Err ( ..) => {
71
+ // return Err(anyhow::anyhow!("Failed to open database: {}", e));
72
+ error ! ( "Database error!" ) ;
73
+ }
74
+ }
75
+ }
76
+ }
77
+ Some ( ( "last" , _) ) => {
78
+ info ! ( "Last news feeds..." ) ;
79
+ let config: Config = confy:: load ( "RSS2SQLite" , None ) ?;
80
+ let conn = create_db ( & config. dbfile ) ;
81
+ let _ = last ( & conn. unwrap ( ) ) . context ( "Failed to query the database" ) ?;
82
+ }
83
+ _ => warn ! ( "Subcommand is required" ) ,
57
84
}
58
- let _ = last ( & conn) . context ( "Failed to query the database" ) ?;
59
- info ! ( "Finished" ) ;
85
+ info ! ( "Finished!" ) ;
60
86
Ok ( ( ) )
61
87
}
0 commit comments