From 9dc05f0d4aa9ce1bf3c58a5ee9256c5f3fe82cdc Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Tue, 14 Apr 2020 13:09:11 -0300 Subject: [PATCH] Inverted the dependency between data and storage --- Cargo.lock | 7 ++-- Cargo.toml | 2 +- src/main.rs | 13 +++---- src/storage/data.rs | 60 +++++++++++++++++++++++++++++++ src/storage/filesystem.rs | 76 ++++++++++++--------------------------- src/storage/mod.rs | 2 +- src/storage/storage.rs | 11 ++---- 7 files changed, 99 insertions(+), 72 deletions(-) create mode 100644 src/storage/data.rs diff --git a/Cargo.lock b/Cargo.lock index a7b36c9..3c9aa20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -262,7 +262,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "downfav" version = "0.3.0" dependencies = [ - "elefren 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)", + "elefren 0.20.1 (registry+https://github.com/rust-lang/crates.io-index)", "html2md 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -282,13 +282,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "elefren" -version = "0.19.4" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-old-types 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "isolang 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1833,7 +1834,7 @@ dependencies = [ "checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97" "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" -"checksum elefren 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)" = "34f49632a0d50544fe2874ac59c0c36c79871269e58b491ed73c94ffe71d0568" +"checksum elefren 0.20.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dfca8d8d0147086081224e22183a37a7b98e3230b945a717f1b5a0eed5fb07af" "checksum encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)" = "87240518927716f79692c2ed85bfe6e98196d18c6401ec75355760233a7e12e9" "checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" diff --git a/Cargo.toml b/Cargo.toml index 224f91f..23e8896 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Julio Biason "] edition = "2018" [dependencies] -elefren = { version = "0.19", features = ["toml"] } +elefren = { version = "0.20", features = ["toml"] } html2md = "0.2.9" reqwest = "0.9.17" serde = "*" diff --git a/src/main.rs b/src/main.rs index 5c8f2c7..e65978e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ use std::io; -use crate::storage::storage::Storage; +use crate::storage::data::Data; +use crate::storage::filesystem::Filesystem; use elefren::helpers::cli; use elefren::helpers::toml as elefren_toml; use elefren::prelude::*; @@ -12,17 +13,17 @@ fn main() { let config = dbg!(config::Config::get()); let client = dbg!(get_mastodon_connection()); let top = dbg!(config.last_favorite.to_string()); - let _joplin = crate::storage::joplin::validate(&config); + // let _joplin = crate::storage::joplin::validate(&config); + let save_to = Filesystem::new(); let most_recent_favourite = client .favourites() .unwrap() .items_iter() - .take_while(|record| record.id != top) + .take_while(|record| dbg!(record).id != top) .map(|record| { - let storage = dbg!(storage::filesystem::Filesystem::from(dbg!(&record))); - storage.open(); - storage.save(); + let conversion = dbg!(Data::from(dbg!(&record))); + conversion.save(&save_to); record }) .fold(None, { diff --git a/src/storage/data.rs b/src/storage/data.rs new file mode 100644 index 0000000..6f5e964 --- /dev/null +++ b/src/storage/data.rs @@ -0,0 +1,60 @@ +use elefren::entities::status::Status; +use html2md; +use std::convert::From; + +use crate::storage::attachment::Attachment; +use crate::storage::storage::Storage; + +/// Our data content. +#[derive(Debug)] +pub struct Data { + pub id: String, + pub account: String, + pub text: String, + pub attachments: Vec, +} + +/// Convert the incoming Status from Elefren to ours. +impl From<&Status> for Data { + fn from(origin: &Status) -> Self { + println!("Downloading ID: {}", origin.id); + + Self { + id: origin.id.to_string(), + account: origin.account.acct.to_string(), + text: build_text(origin), + attachments: origin + .media_attachments + .iter() + .map(|attachment| Attachment::from(attachment)) + .collect(), + } + } +} + +impl Data { + pub fn save(&self, storage: &T) { + storage.save(self); + } +} + +fn build_text(status: &Status) -> String { + let base_content = html2md::parse_html(&status.content); + let source = &status.url; + let title = &status.spoiler_text; + + let mut result = String::new(); + if title.len() > 0 { + result.push_str(title); + result.push_str("\n"); + } + + result.push_str(&html2md::parse_html(&base_content)); + + if let Some(url) = source { + result.push_str("\n"); + result.push_str(&url); + } + + result +} diff --git a/src/storage/filesystem.rs b/src/storage/filesystem.rs index e351354..e20cc2d 100644 --- a/src/storage/filesystem.rs +++ b/src/storage/filesystem.rs @@ -1,79 +1,49 @@ -use elefren::entities::status::Status; -use html2md; -use std::convert::From; use std::fs::File; use std::io::Write; use std::path::Path; use std::path::PathBuf; -use crate::storage::attachment::Attachment; +use crate::storage::data::Data; use crate::storage::storage::Storage; -#[derive(Debug)] -pub struct Filesystem { - id: String, - account: String, - text: String, - attachments: Vec, +pub struct Filesystem {} + +impl Storage for Filesystem { + fn save(&self, data: &Data) { + self.create_dirs(data); + self.save_content(data); + self.save_attachments(data); + } } impl Filesystem { + pub fn new() -> Self { + Self {} + } + /// The directory in which the data from this toot will be saved. - fn dir(&self) -> PathBuf { - Path::new("data").join(&self.account).join(&self.id) + fn dir(&self, data: &Data) -> PathBuf { + Path::new("data").join(&data.account).join(&data.id) } /// Make sure the path structure exists for saving the data. - fn create_dirs(&self) { - std::fs::create_dir_all(self.dir()).expect("Failed to create storage directory"); + fn create_dirs(&self, data: &Data) { + std::fs::create_dir_all(self.dir(data)).expect("Failed to create storage directory"); } /// Save the content in the directory. - fn save_content(&self) { - let filename = self.dir().join("toot.md"); + fn save_content(&self, data: &Data) { + let filename = self.dir(data).join("toot.md"); let mut fp = File::create(filename).expect("Failed to create file"); - fp.write_all(self.text.as_bytes()) + fp.write_all(data.text.as_bytes()) .expect("Failed to save content"); } /// Save the attachments. - fn save_attachments(&self) { - self.attachments.iter().for_each(|attachment| { - let filename = self.dir().join(attachment.get_filename()); + fn save_attachments(&self, data: &Data) { + data.attachments.iter().for_each(|attachment| { + let filename = self.dir(data).join(attachment.get_filename()); attachment.download(filename.as_path()); }) } } - -impl Storage for Filesystem { - fn open(&self) { - dbg!(self.create_dirs()); - } - - fn get_id(&self) -> &String { - &self.id - } - - fn save(&self) { - self.save_content(); - self.save_attachments(); - } -} - -impl From<&Status> for Filesystem { - fn from(origin: &Status) -> Self { - println!("Downloading ID: {}", origin.id); - - Self { - id: origin.id.to_string(), - account: origin.account.acct.to_string(), - text: html2md::parse_html(&origin.content), - // on save, we download those URLs - attachments: origin - .media_attachments - .iter() - .map(|attachment| Attachment::from(attachment)) - .collect(), - } - } -} diff --git a/src/storage/mod.rs b/src/storage/mod.rs index b5f4ae0..64620c1 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -1,4 +1,4 @@ pub mod attachment; pub mod filesystem; -pub mod joplin; pub mod storage; +pub mod data; diff --git a/src/storage/storage.rs b/src/storage/storage.rs index bc3773c..a848b4a 100644 --- a/src/storage/storage.rs +++ b/src/storage/storage.rs @@ -1,12 +1,7 @@ +use crate::storage::data::Data; + /// Trait for storing favorites on a storage. pub trait Storage { - /// Initization. Any required pre-storage functions must be added here. - fn open(&self); - /// Save the favourite in the storage. - fn save(&self); - - /// Return the original favourite identification. - fn get_id(&self) -> &String; + fn save(&self, record: &Data); } -