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

@ -1,5 +1,4 @@
pub mod config;
pub mod readwise;
mod error;
pub use error::*;

View file

@ -1,15 +1,10 @@
use clap::{CommandFactory, Parser};
use clap::Parser;
use figment::{
providers::{Env, Serialized},
Figment,
};
use readwise_bulk_upload::config::{Command, Config};
use readwise_bulk_upload::readwise::DocumentPayload;
use lib_sync_core::task_manager::{TaskManager, TaskStatus};
use readwise_bulk_upload::{Error, Result};
use std::fs::File;
use directories::ProjectDirs;
use tabled::Table;
use cli::config::Config;
use cli::Result;
use tracing_subscriber;
#[tokio::main]
@ -24,47 +19,5 @@ async fn main() -> Result<()> {
.with_max_level(args.log_level())
.init();
run(&cli.command).await?;
Ok(())
}
async fn run(command: &Command) -> Result<()> {
let project_dir = ProjectDirs::from("", "", env!("CARGO_PKG_NAME"))
.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(())
}

View file

@ -1,41 +0,0 @@
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")),
})
}