implement debug output features

This commit is contained in:
yggverse 2025-02-11 20:29:14 +02:00
parent 196ec99361
commit 2ef0c8e7ff
4 changed files with 58 additions and 11 deletions

View file

@ -28,6 +28,9 @@ pulsarss --source https://path/to/feed.rss
* `source`, `s` - RSS feed source (required)
* `target`, `t` - Destination directory (`public` by default)
* `update`, `u` - Update timeout in seconds (`60` by default)
* `output`, `o` - Print output (`d` by default):
* `d` - debug
* `n` - disable
### Autostart

View file

@ -11,7 +11,11 @@ pub struct Argument {
#[arg(short, long, default_value_t = String::from("public"))]
pub target: String,
/// Update timeout in seconds (60 by default)
/// Update timeout in seconds (`60` by default)
#[arg(short, long, default_value_t = 60)]
pub update: u64,
/// Show output (`d` by default)
#[arg(short, long, default_value_t = String::from("d"))]
pub output: String,
}

View file

@ -1,5 +1,7 @@
mod argument;
mod output;
use output::Output;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
@ -8,16 +10,17 @@ fn main() -> Result<(), Box<dyn Error>> {
use std::{thread::sleep, time::Duration};
let argument = Argument::parse();
let output = Output::build(&argument.output);
let mut index: Vec<usize> = Vec::new();
output.debug("crawler started");
loop {
crawl(&mut index, &argument.source, &argument.target)?;
crawl(&argument.source, &argument.target, &output)?;
sleep(Duration::from_secs(argument.update));
}
}
fn crawl(index: &mut Vec<usize>, source: &str, target: &str) -> Result<(), Box<dyn Error>> {
fn crawl(source: &str, target: &str, output: &Output) -> Result<(), Box<dyn Error>> {
use reqwest::blocking::get;
use rss::Channel;
use std::{
@ -25,13 +28,18 @@ fn crawl(index: &mut Vec<usize>, source: &str, target: &str) -> Result<(), Box<d
io::Write,
};
for item in Channel::read_from(&get(source)?.bytes()?[..])?.items() {
let id = index.len() + 1;
output.debug("update begin");
let path = &path(id, target, item.pub_date().unwrap(), true)?;
let mut total = 0;
let mut exist = 0;
for item in Channel::read_from(&get(source)?.bytes()?[..])?.items() {
total += 1;
let path = &path(target, item.pub_date().unwrap(), true)?;
if metadata(path).is_ok() {
continue; // skip existing records
exist += 1;
continue;
}
let mut file = File::create(path)?;
@ -45,14 +53,17 @@ fn crawl(index: &mut Vec<usize>, source: &str, target: &str) -> Result<(), Box<d
)
.as_bytes(),
)?;
index.push(id);
}
output.debug(&format!(
"update completed (added: {} / exist: {exist} / total: {total})",
total - exist
));
Ok(())
}
fn path(_id: usize, base: &str, pub_date: &str, mkdir: bool) -> Result<String, Box<dyn Error>> {
fn path(base: &str, pub_date: &str, mkdir: bool) -> Result<String, Box<dyn Error>> {
use chrono::{DateTime, Datelike, Timelike};
use std::{fs::create_dir_all, path::MAIN_SEPARATOR};

29
src/output.rs Normal file
View file

@ -0,0 +1,29 @@
use chrono::{DateTime, Utc};
use std::time::SystemTime;
struct Level {
debug: bool,
}
pub struct Output(Level);
impl Output {
pub fn build(level: &str) -> Self {
Self(Level {
debug: level.contains("d"),
// @TODO other flags
})
}
pub fn debug(&self, message: &str) {
if self.0.debug {
eprintln!("[debug] [{}] {message}", time());
}
}
}
fn time() -> String {
let system_time = SystemTime::now();
let datetime: DateTime<Utc> = system_time.into();
datetime.to_rfc3339()
}