Browse Source

Inverted the dependency between data and storage

master
Julio Biason 5 years ago
parent
commit
9dc05f0d4a
  1. 7
      Cargo.lock
  2. 2
      Cargo.toml
  3. 13
      src/main.rs
  4. 60
      src/storage/data.rs
  5. 76
      src/storage/filesystem.rs
  6. 2
      src/storage/mod.rs
  7. 11
      src/storage/storage.rs

7
Cargo.lock generated

@ -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"

2
Cargo.toml

@ -5,7 +5,7 @@ authors = ["Julio Biason <julio.biason@pm.me>"]
edition = "2018"
[dependencies]
elefren = { version = "0.19", features = ["toml"] }
elefren = { version = "0.20", features = ["toml"] }
html2md = "0.2.9"
reqwest = "0.9.17"
serde = "*"

13
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, {

60
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<Attachment>,
}
/// 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<T: Storage>(&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
}

76
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<Attachment>,
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(),
}
}
}

2
src/storage/mod.rs

@ -1,4 +1,4 @@
pub mod attachment;
pub mod filesystem;
pub mod joplin;
pub mod storage;
pub mod data;

11
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);
}

Loading…
Cancel
Save