Skip to content

Commit 7574c71

Browse files
committed
Add command line interface and refactor config handling
Introduced command line interface using Clap to handle update and last subcommands. Refactored configuration loading to use Confy and separated configurations into a new module. Enhanced error handling and debugging capabilities.
1 parent 081ead2 commit 7574c71

File tree

1 file changed

+61
-35
lines changed

1 file changed

+61
-35
lines changed

src/main.rs

Lines changed: 61 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,21 @@
1-
// RSS to sqlite database collector
2-
31
mod modules {
42
pub mod sql;
3+
pub mod config;
54
}
65

76
use modules::sql::create_db;
87
use modules::sql::insert_feed_items;
98
use modules::sql::last;
9+
use modules::config::Config;
1010

11+
use std::error::Error;
12+
use clap::{Arg, Command};
1113
use anyhow::{Context, Result};
14+
use env_logger;
1215
use env_logger::Builder;
13-
use log::{debug, info, warn, LevelFilter};
16+
use log::{debug, error, info, warn, LevelFilter};
1417
use reqwest::blocking;
1518
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-
}
3519

3620
fn fetch_rss_feed(url: &str) -> Result<Channel> {
3721
debug!("Fetching RSS feed {}", url);
@@ -40,22 +24,64 @@ fn fetch_rss_feed(url: &str) -> Result<Channel> {
4024
Ok(channel)
4125
}
4226

43-
fn main() -> Result<()> {
27+
fn main() -> Result<(), Box<dyn Error>> {
28+
// Setup logger
4429
let mut builder = Builder::from_default_env();
4530
builder.filter_level(LevelFilter::Info);
4631
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"),
5784
}
58-
let _ = last(&conn).context("Failed to query the database")?;
59-
info!("Finished");
85+
info!("Finished!");
6086
Ok(())
6187
}

0 commit comments

Comments
 (0)