refactor: move readwise files to it's own binary

This commit is contained in:
Alexander Navarro 2025-05-15 13:00:39 -04:00
parent b31502fb37
commit 2827193fd6
6 changed files with 105 additions and 73 deletions

View file

@ -0,0 +1,41 @@
use lib_sync_core::task_manager::TaskPayload;
use chrono::{DateTime, Local};
use serde::{de, Deserialize, Deserializer, Serialize};
use serde_json::Value;
use std::fmt::Display;
#[derive(Deserialize, Serialize, Debug)]
pub struct DocumentPayload {
title: String,
summary: Option<String>,
url: String,
#[serde(deserialize_with = "single_or_vec")]
tags: Vec<String>,
published_date: DateTime<Local>,
location: String,
}
impl Display for DocumentPayload {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
serde_json::to_string_pretty(self).map_err(|_| std::fmt::Error)?
)
}
}
impl TaskPayload for DocumentPayload {
fn get_key(&self) -> String {
self.url.clone()
}
}
fn single_or_vec<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<String>, D::Error> {
Ok(match Value::deserialize(deserializer)? {
Value::String(s) => vec![s.parse().map_err(de::Error::custom)?],
Value::Array(arr) => arr.into_iter().map(|a| a.to_string()).collect(),
Value::Null => Vec::new(),
_ => return Err(de::Error::custom("wrong type")),
})
}

76
cli/bin/readwise/main.rs Normal file
View file

@ -0,0 +1,76 @@
use clap::{CommandFactory, Parser};
use directories::ProjectDirs;
use figment::{
Figment,
providers::{Env, Serialized},
};
use lib_sync_core::task_manager::{TaskManager, TaskStatus};
use cli::config::{Command, Config};
use cli::{Error, Result};
use std::fs::File;
use tabled::Table;
use tracing_subscriber;
use crate::external_interface::DocumentPayload;
mod external_interface;
#[tokio::main]
async fn main() -> Result<()> {
let cli = Config::parse();
let args: Config = Figment::new()
.merge(Serialized::defaults(&cli))
.merge(Env::prefixed("APP_"))
.extract()?;
tracing_subscriber::fmt()
.with_max_level(args.log_level())
.init();
run(&cli.command).await?;
Ok(())
}
async fn run(command: &Command) -> Result<()> {
let project_dir = ProjectDirs::from("", "", "synchronizator_readwise").ok_or(
lib_sync_core::error::Error::Unhandled("Could not get standard directories"),
)?;
let task_manager = TaskManager::new(project_dir.data_dir()).await?;
match command {
Command::LoadTasks { path } => {
let file = File::open(path).map_err(|_| {
Error::Runtime(format!(
r#"The file "{}" could not be open"#,
path.display()
))
})?;
let documents: Vec<DocumentPayload> = serde_json::from_reader(file)?;
task_manager.load_tasks(documents).await?;
}
Command::Query => {
let tasks = task_manager
.get_tasks::<DocumentPayload>(None, Some(25))
.await?;
println!("{}", Table::new(tasks));
}
Command::Run => {
task_manager
.run_tasks::<DocumentPayload>(|task| {
println!("{}", task.get_key());
TaskStatus::Completed
})
.await?;
}
Command::None => {
Config::command().print_help()?;
}
}
Ok(())
}