Browse Source

Storage as Org Files

master
Julio Biason 4 years ago
parent
commit
058f57aa7a
  1. 3
      Cargo.lock
  2. 3
      Cargo.toml
  3. 13
      src/config/mod.rs
  4. 11
      src/main.rs
  5. 1
      src/storage/mod.rs
  6. 84
      src/storage/org.rs
  7. 6
      src/storage/storage.rs

3
Cargo.lock generated

@ -303,8 +303,9 @@ checksum = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97"
[[package]] [[package]]
name = "downfav" name = "downfav"
version = "0.3.2" version = "0.4.0"
dependencies = [ dependencies = [
"chrono",
"elefren", "elefren",
"env_logger", "env_logger",
"html2md", "html2md",

3
Cargo.toml

@ -1,6 +1,6 @@
[package] [package]
name = "downfav" name = "downfav"
version = "0.3.3" version = "0.4.0"
authors = ["Julio Biason <julio.biason@pm.me>"] authors = ["Julio Biason <julio.biason@pm.me>"]
edition = "2018" edition = "2018"
@ -13,3 +13,4 @@ serde_derive = "*"
toml = "0.5" toml = "0.5"
log = "0.4" log = "0.4"
env_logger = "0.8" env_logger = "0.8"
chrono = "0.4"

13
src/config/mod.rs

@ -32,6 +32,11 @@ pub struct JoplinConfig {
pub token: String, pub token: String,
} }
#[derive(Serialize, Deserialize, Debug)]
pub struct OrgConfig {
pub location: String,
}
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct Favourite { pub struct Favourite {
pub last: String, pub last: String,
@ -54,6 +59,7 @@ pub struct Config {
pub favourite: Favourite, pub favourite: Favourite,
pub mastodon: Data, pub mastodon: Data,
pub joplin: Option<JoplinConfig>, pub joplin: Option<JoplinConfig>,
pub org: Option<OrgConfig>,
} }
/// Errors while loading the configuration file /// Errors while loading the configuration file
@ -66,8 +72,9 @@ pub enum ConfigError {
} }
impl From<toml::de::Error> for ConfigError { impl From<toml::de::Error> for ConfigError {
fn from(_: toml::de::Error) -> Self { fn from(e: toml::de::Error) -> Self {
// Since we only have one single error so far... // Since we only have one single error so far...
log::debug!("Toml error: {:?}", e);
ConfigError::InvalidConfig ConfigError::InvalidConfig
} }
} }
@ -85,7 +92,6 @@ impl Config {
let mut fp = File::open("downfav.toml")?; let mut fp = File::open("downfav.toml")?;
let mut contents = String::new(); let mut contents = String::new();
fp.read_to_string(&mut contents).unwrap(); fp.read_to_string(&mut contents).unwrap();
Ok(toml::from_str(&contents)?) Ok(toml::from_str(&contents)?)
} }
@ -108,7 +114,8 @@ impl From<elefren::data::Data> for Config {
Config { Config {
favourite: Favourite::new(), favourite: Favourite::new(),
mastodon: data, mastodon: data,
joplin: None, // at least, not yet joplin: None,
org: None,
} }
} }
} }

11
src/main.rs

@ -24,6 +24,7 @@ use elefren::prelude::*;
use crate::storage::data::Data; use crate::storage::data::Data;
use crate::storage::filesystem::Filesystem; use crate::storage::filesystem::Filesystem;
use crate::storage::joplin::Joplin; use crate::storage::joplin::Joplin;
use crate::storage::org::Org;
use crate::storage::storage::Storage; use crate::storage::storage::Storage;
mod config; mod config;
@ -34,7 +35,8 @@ fn main() {
let config = match config::Config::get() { let config = match config::Config::get() {
Ok(config) => config, Ok(config) => config,
Err(_) => { Err(e) => {
log::debug!("Configuration error: {:?}", e);
let data = connect_to_mastodon(); let data = connect_to_mastodon();
config::Config::from(data) config::Config::from(data)
} }
@ -42,9 +44,10 @@ fn main() {
let top = config.favourite.last.to_string(); let top = config.favourite.last.to_string();
log::debug!("Last favourite seen: {}", top); log::debug!("Last favourite seen: {}", top);
let storage: Box<dyn Storage> = match &config.joplin { let storage: Box<dyn Storage> = match (&config.joplin, &config.org) {
Some(joplin) => Box::new(Joplin::new_from_config(&joplin)), (Some(joplin), _) => Box::new(Joplin::new_from_config(&joplin)),
None => Box::new(Filesystem::new()), (None, Some(org)) => Box::new(Org::new_from_config(&org)),
(None, None) => Box::new(Filesystem::new()),
}; };
let client = Mastodon::from(config.mastodon.clone()); let client = Mastodon::from(config.mastodon.clone());

1
src/storage/mod.rs

@ -20,4 +20,5 @@ pub mod attachment;
pub mod data; pub mod data;
pub mod filesystem; pub mod filesystem;
pub mod joplin; pub mod joplin;
pub mod org;
pub mod storage; pub mod storage;

84
src/storage/org.rs

@ -0,0 +1,84 @@
/*
DOWNFAV - Download Favourites
Copyright (C) 2020 Julio Biason
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use chrono::prelude::*;
use std::fs::OpenOptions;
use std::io::prelude::*;
use std::path::Path;
use std::path::PathBuf;
use crate::config::OrgConfig;
use crate::storage::data::Data;
use crate::storage::storage::Storage;
pub struct Org {
file: PathBuf,
date: String,
}
impl Org {
pub(crate) fn new_from_config(config: &OrgConfig) -> Org {
let now = Utc::now();
let filename = format!("{}{}{}.org", now.year(), now.month(), now.day());
let date = format!("{}-{}-{}", now.year(), now.month(), now.day());
let full_path = Path::new(&config.location).join(&filename);
log::debug!("Org file: {}", full_path.to_string_lossy());
Org {
file: full_path,
date,
}
}
}
impl Storage for Org {
fn save(&self, record: &Data) {
let mut fp = OpenOptions::new()
.write(true)
.append(true)
.open(&self.file)
.map_err(|_| {
// Let's assume here that the problem is that the file doesn't exist.
log::debug!(
"Creating {filename}",
filename = &self.file.to_string_lossy()
);
OpenOptions::new()
.write(true)
.create(true)
.open(&self.file)
.map(|mut fp| {
let text =
format!("#+title: Favourites from {date}\n\n", date = &self.date);
fp.write_all(text.as_bytes()).unwrap();
fp
})
})
.unwrap();
fp.write_all(
format!(
"* {user}/{id}\n {message}\n",
user = record.account,
id = record.id,
message = record.text,
)
.as_bytes(),
)
.unwrap();
}
}

6
src/storage/storage.rs

@ -20,6 +20,12 @@ use crate::storage::data::Data;
/// Trait for storing favorites on a storage. /// Trait for storing favorites on a storage.
pub trait Storage { pub trait Storage {
/// Storage initialization
fn init(&self) {}
/// Save the favourite in the storage. /// Save the favourite in the storage.
fn save(&self, record: &Data); fn save(&self, record: &Data);
/// Storage finalization
fn close(&self) {}
} }

Loading…
Cancel
Save