use crate::fetcher::Fetcher;
use eyre::WrapErr;
use structopt::StructOpt;
use tabular::{Row, Table};
use url::Url;
use crate::{config::Config, db::Database};
use std::path::PathBuf;
#[derive(StructOpt)]
pub struct Track {
#[structopt(short, long, env = "CYNDIKATOR_CONFIG")]
config: Option<PathBuf>,
feed: String,
#[structopt(long)]
ttl: Option<u32>,
}
impl Track {
pub async fn run(self) -> eyre::Result<()> {
let config = Config::load(self.config.as_deref())?;
let mut db = Database::open(config.database_path()?)?;
let url = Url::parse(&self.feed).wrap_err("invalid url")?;
let mut fetcher = Fetcher::new(&url);
let title = fetcher.title().await?;
db.track(&url, &title, self.ttl)?;
Ok(())
}
}
#[derive(StructOpt)]
pub struct Tracking {
#[structopt(short, long, env = "CYNDIKATOR_CONFIG")]
config: Option<PathBuf>,
}
impl Tracking {
pub async fn run(self) -> eyre::Result<()> {
let config = Config::load(self.config.as_deref())?;
let mut db = Database::open(config.database_path()?)?;
let feeds = db.tracking()?;
let mut table = Table::new("{:<} {:<} {:<} {:<}");
table.add_row(
Row::new()
.with_cell("title")
.with_cell("ttl")
.with_cell("last_fetch")
.with_cell("url"),
);
for feed in feeds {
table.add_row(
Row::new()
.with_cell(feed.title)
.with_cell(feed.ttl.unwrap_or(60))
.with_cell(
feed.last_fetch
.map_or_else(|| "never".to_string(), |d| d.to_rfc3339()),
)
.with_cell(feed.url),
);
}
println!("{}", table);
Ok(())
}
}
#[derive(StructOpt)]
pub struct Untrack {
#[structopt(short, long, env = "CYNDIKATOR_CONFIG")]
config: Option<PathBuf>,
feed: String,
}
impl Untrack {
pub async fn run(self) -> eyre::Result<()> {
let config = Config::load(self.config.as_deref())?;
let mut db = Database::open(config.database_path()?)?;
let existed = db.untrack(&self.feed)?;
if !existed {
std::process::exit(1);
}
Ok(())
}
}