From 3eedfa8c4fdab2700a4dc4298e879a2ea3c58401 Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Fri, 11 Jun 2021 13:38:12 -0300 Subject: [PATCH] Basic multiple-account support --- Cargo.lock | 101 +++++++++++++++++++++++++++++++++++-------- Cargo.toml | 1 + src/config/config.rs | 86 +++++++++++++++++++++++++++++------- src/config/mod.rs | 2 + src/main.rs | 8 ++-- 5 files changed, 159 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9f8995c..6735087 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,7 +63,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "690a62be8920ccf773ee00ef0968649b0e724cda8bd5b12286302b4ae955fdf5" dependencies = [ "backtrace-sys", - "cfg-if", + "cfg-if 0.1.10", "libc", "rustc-demangle", ] @@ -167,6 +167,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "chrono" version = "0.4.9" @@ -267,7 +273,7 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] @@ -287,7 +293,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" dependencies = [ "arrayvec", - "cfg-if", + "cfg-if 0.1.10", "crossbeam-utils", "lazy_static", "memoffset", @@ -309,7 +315,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "lazy_static", ] @@ -319,6 +325,26 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" +[[package]] +name = "directories" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e69600ff1703123957937708eb27f7a564e48885c537782722ed0ba3189ce1d7" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +dependencies = [ + "libc", + "redox_users", + "winapi 0.3.8", +] + [[package]] name = "doc-comment" version = "0.3.1" @@ -331,6 +357,7 @@ version = "0.4.1" dependencies = [ "chrono", "clap", + "directories", "elefren", "env_logger", "html2md", @@ -386,7 +413,7 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87240518927716f79692c2ed85bfe6e98196d18c6401ec75355760233a7e12e9" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] @@ -520,9 +547,20 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", + "libc", + "wasi 0.7.0", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", "libc", - "wasi", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] @@ -792,9 +830,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.62" +version = "0.2.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" +checksum = "5600b4e6efc5421841a2138a6b082e07fe12f9aaa12783d50e5d13325b26b4fc" [[package]] name = "lock_api" @@ -812,7 +850,7 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] @@ -915,7 +953,7 @@ version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "fuchsia-zircon", "fuchsia-zircon-sys", "iovec", @@ -964,7 +1002,7 @@ version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "winapi 0.3.8", ] @@ -1016,7 +1054,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8152bb5a9b5b721538462336e3bef9a539f892715e5037fda0f984577311af15" dependencies = [ "bitflags", - "cfg-if", + "cfg-if 0.1.10", "foreign-types", "lazy_static", "libc", @@ -1276,7 +1314,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" dependencies = [ - "getrandom", + "getrandom 0.1.12", "libc", "rand_chacha 0.2.1", "rand_core 0.5.1", @@ -1325,7 +1363,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.12", ] [[package]] @@ -1423,6 +1461,25 @@ version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +[[package]] +name = "redox_syscall" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom 0.2.3", + "redox_syscall 0.2.8", +] + [[package]] name = "regex" version = "1.3.1" @@ -1810,10 +1867,10 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "rand 0.7.2", - "redox_syscall", + "redox_syscall 0.1.56", "remove_dir_all", "winapi 0.3.8", ] @@ -1863,7 +1920,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" dependencies = [ "libc", - "redox_syscall", + "redox_syscall 0.1.56", "winapi 0.3.8", ] @@ -2021,7 +2078,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] @@ -2167,6 +2224,12 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + [[package]] name = "winapi" version = "0.2.8" diff --git a/Cargo.toml b/Cargo.toml index 67179d3..94e3a29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ description = "Download Mastodon favourites" [dependencies] chrono = "0.4" clap = "2.33" +directories = "3.0" elefren = { version = "0.20", features = ["toml"] } env_logger = "0.8" html2md = "0.2" diff --git a/src/config/config.rs b/src/config/config.rs index 5244dca..806f78e 100644 --- a/src/config/config.rs +++ b/src/config/config.rs @@ -17,42 +17,96 @@ */ use std::collections::HashMap; +use std::fs::File; +use std::io::prelude::*; +use std::path::PathBuf; use directories::ProjectDirs; use elefren::Data; +use serde_derive::Deserialize; +use serde_derive::Serialize; /// The last seen favourite +#[derive(Serialize, Deserialize, Debug)] struct Favourite { last: String, } /// Account configuration +#[derive(Serialize, Deserialize, Debug)] struct AccountConfig { - favourite: Favourite, + favourite: Option, mastodon: Data, } -/// Errors from the configuration -pub enum ConfigError { - /// The system can't figure out the path for the configuration file - CantFigureConfigPath, -} - /// The main configuration -#[derive(serde_derive::Serialize, serde::derive::Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug)] pub struct Config(HashMap); impl Config { /// Figure out the filename for the configuration file. - fn filename() -> Result { - if let Some(proj_dirs) = - ProjectDirs::from("me", "JulioBiason", "downfav") - { - Ok(proj_dirs.config_dir()) - } else { - Error(ConfigError::CantFigureConfigPath) + fn filename() -> Result { + match ProjectDirs::from("me", "JulioBiason", "downfav.toml") { + Some(proj_dirs) => Ok(proj_dirs.config_dir().into()), + None => Err(ConfigError::CantFigureConfigPath), } } - pub fn new() -> Self {} + /// Open the configuration file; if it doesn't exist, returns an empty set. + pub fn open() -> Result { + let filename = Config::filename()?; + log::debug!("Trying to open file \"{:?}\"", filename); + match File::open(filename) { + Ok(mut fp) => { + let mut contents = String::new(); + fp.read_to_string(&mut contents)?; + let parsed = toml::from_str(&contents)?; + Ok(Self(parsed)) + } + Err(_) => Ok(Self(HashMap::new())), + } + } + + /// Add a new account to the configuration file + // TODO Result for account already exists? + pub fn add_account(&mut self, name: &str, configuration: Data) { + let account_data = AccountConfig { + favourite: None, + mastodon: configuration, + }; + self.0.insert(name.into(), account_data); + } + + /// Save the current configuration file. + // TODO Result for save result? + pub fn save(&self) { + let content = toml::to_string(&self.0).unwrap(); + let filename = Config::filename().unwrap(); + log::debug!("Saving configuration to file \"{:?}\"", filename); + let mut fp = File::create(filename).unwrap(); + fp.write_all(content.as_bytes()).unwrap(); + } +} + +/// Errors from the configuration +#[derive(Debug)] +pub enum ConfigError { + /// The system can't figure out the path for the configuration file + CantFigureConfigPath, + /// The configuration file has an error and can't be parsed + ConfigFileIsBroken, +} + +impl From for ConfigError { + fn from(e: toml::de::Error) -> Self { + log::debug!("Toml error: {:?}", e); + ConfigError::ConfigFileIsBroken + } +} + +impl From for ConfigError { + fn from(e: std::io::Error) -> Self { + log::debug!("I/O error: {:?}", e); + ConfigError::ConfigFileIsBroken + } } diff --git a/src/config/mod.rs b/src/config/mod.rs index 12ac44e..456b3ba 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -24,6 +24,8 @@ use elefren::Data; use serde_derive::Deserialize; use serde_derive::Serialize; +pub mod config; + #[derive(Serialize, Deserialize, Debug)] pub struct JoplinConfig { pub port: u32, diff --git a/src/main.rs b/src/main.rs index fb3f705..c92b4e4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,10 +43,10 @@ fn main() { /// Create a new account fn add_account(name: &str) { - log::debug!("Creating account {}", name); - println!("Enter information for account \"{}\":", name); - let data = connect_to_mastodon(); - config::Config::add_account(name, data) + let mut config = config::config::Config::open().unwrap(); + let connection_info = connect_to_mastodon(); + config.add_account(name, connection_info); + config.save(); } /// Retrieve favourites