From 315cf805bdc0d13604d63e02e13063396bcd974e Mon Sep 17 00:00:00 2001 From: xqtc Date: Mon, 14 Oct 2024 18:52:37 +0200 Subject: [PATCH] Server crate; Some refactoring; README --- Cargo.toml | 24 +------ README.md | 30 ++++++++- assets/img.png | Bin 0 -> 11793 bytes Cargo.lock => client/Cargo.lock | 85 +++++++++++++++++++++++++ client/Cargo.toml | 23 +++++++ {src => client/src}/config.rs | 0 {src => client/src}/ingestions.rs | 41 ++++++++++-- {src => client/src}/ingestions_util.rs | 64 ++++++++++--------- {src => client/src}/main.rs | 2 +- {src => client/src}/substance_util.rs | 0 {src => client/src}/substances.rs | 0 {src => client/src}/util.rs | 0 meowlog.proto | 30 +++++++++ 13 files changed, 238 insertions(+), 61 deletions(-) create mode 100644 assets/img.png rename Cargo.lock => client/Cargo.lock (93%) create mode 100644 client/Cargo.toml rename {src => client/src}/config.rs (100%) rename {src => client/src}/ingestions.rs (89%) rename {src => client/src}/ingestions_util.rs (68%) rename {src => client/src}/main.rs (97%) rename {src => client/src}/substance_util.rs (100%) rename {src => client/src}/substances.rs (100%) rename {src => client/src}/util.rs (100%) create mode 100644 meowlog.proto diff --git a/Cargo.toml b/Cargo.toml index 8f73be0..dc28830 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,21 +1,3 @@ -[package] -name = "meowlog" -version = "0.1.0" -edition = "2021" - -[dependencies] -bincode = "1.3.3" -chrono = { version = "0.4.38", features = ["serde"] } -clap = { version = "4.5.20", features = ["derive"] } -color-eyre = "0.6.3" -inquire = "0.7.5" -lazy_static = "1.5.0" -serde = { version = "1.0.210", features = ["derive"] } -serde_json = "1.0.128" -strum = { version = "0.26.3", features = ["derive"] } -strum_macros = "0.26.4" -toml = "0.8.19" -uuid = { version = "1.10.0", features = ["serde", "v4"] } - -[build-dependencies] -clap_complete = "4.5.33" +[workspace] +resolver = "2" +members = ["client", "server"] diff --git a/README.md b/README.md index 2141ff2..8feb2b9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,35 @@ +![img.png](assets/img.png) + # meowlog --- -## WIP NOT WORKING AND SUBJECT TO CHANGE + +## WIP SUBJECT TO CHANGE + +### ⚠️ IMPORTANT + +The client's core functionality (managing substances and ingestions) works. The codebase is a mess and will be heavily +refactired so use at your own risk. There will be no backwards compatibility until the first stable release. + +Planned features: + +- [x] Managing ingestions and substances +- [ ] Having a sensible set of default substances (taken from tripsit or psychonautwiki idk yet) +- [ ] Circular Concurrency Checking for binary files +- [ ] Server with syncing capabilities and maybe also a frontend with a similar featureset like the Psychonaut Wiki + Journal app +- [ ] Referring to harm reduction resources in the CLI + +Current problems: + +- [ ] Codebase is a mess +- [ ] No tests +- [ ] Poor error handling +- [ ] Unoptimized memory usage + --- + +### Client usage: + ``` Commands: add-ingestion Adds ingestion diff --git a/assets/img.png b/assets/img.png new file mode 100644 index 0000000000000000000000000000000000000000..5a379d58d493734214e86253a00dfb6dbc5815e6 GIT binary patch literal 11793 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 literal 0 HcmV?d00001 diff --git a/Cargo.lock b/client/Cargo.lock similarity index 93% rename from Cargo.lock rename to client/Cargo.lock index 4d28f98..1a6b205 100644 --- a/Cargo.lock +++ b/client/Cargo.lock @@ -17,6 +17,37 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aes" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" +dependencies = [ + "aes-soft", + "aesni", + "cipher", +] + +[[package]] +name = "aes-soft" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" +dependencies = [ + "cipher", + "opaque-debug", +] + +[[package]] +name = "aesni" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" +dependencies = [ + "cipher", + "opaque-debug", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -165,6 +196,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "cipher" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" +dependencies = [ + "generic-array", +] + [[package]] name = "clap" version = "4.5.20" @@ -253,6 +293,21 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crossterm" version = "0.25.0" @@ -318,6 +373,16 @@ dependencies = [ "byteorder", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -462,11 +527,13 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" name = "meowlog" version = "0.1.0" dependencies = [ + "aes", "bincode", "chrono", "clap", "clap_complete", "color-eyre", + "crc", "inquire", "lazy_static", "serde", @@ -531,6 +598,12 @@ version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "owo-colors" version = "3.5.0" @@ -833,6 +906,12 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicode-ident" version = "1.0.13" @@ -873,6 +952,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/client/Cargo.toml b/client/Cargo.toml new file mode 100644 index 0000000..fd8dbdf --- /dev/null +++ b/client/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "meowlog" +version = "0.1.0" +edition = "2021" + +[dependencies] +bincode = "1.3.3" +aes = "0.6.0" +crc = "3.2.1" +chrono = { version = "0.4.38", features = ["serde"] } +clap = { version = "4.5.20", features = ["derive"] } +color-eyre = "0.6.3" +inquire = "0.7.5" +lazy_static = "1.5.0" +serde = { version = "1.0.210", features = ["derive"] } +serde_json = "1.0.128" +strum = { version = "0.26.3", features = ["derive"] } +strum_macros = "0.26.4" +toml = "0.8.19" +uuid = { version = "1.10.0", features = ["serde", "v4"] } + +[build-dependencies] +clap_complete = "4.5.33" diff --git a/src/config.rs b/client/src/config.rs similarity index 100% rename from src/config.rs rename to client/src/config.rs diff --git a/src/ingestions.rs b/client/src/ingestions.rs similarity index 89% rename from src/ingestions.rs rename to client/src/ingestions.rs index d5371a0..b381e3c 100644 --- a/src/ingestions.rs +++ b/client/src/ingestions.rs @@ -25,7 +25,15 @@ pub struct Ingestion { impl std::fmt::Display for Ingestion { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{} {} {} {}{}", self.date, self.time.format("%H:%M"), self.substance.name, self.dose.value, self.dose.unit) + write!( + f, + "{} {} {} {}{}", + self.date, + self.time.format("%H:%M"), + self.substance.name, + self.dose.value, + self.dose.unit + ) } } @@ -113,7 +121,6 @@ pub fn list_ingestions() -> Result<(), std::io::Error> { Ok(()) } - pub fn edit_ingestion() -> Result<(), std::io::Error> { let ing_des = ensure_ingestion_files(); if ing_des.is_empty() { @@ -124,17 +131,36 @@ pub fn edit_ingestion() -> Result<(), std::io::Error> { let mut ingest_sel_vec_id: Vec = Vec::new(); let mut ingest_sel_vec_ing: Vec = Vec::new(); - for ingestion in ing_des.clone().into_iter() { ingest_sel_vec_id.push(ingestion.0); ingest_sel_vec_ing.push(ingestion.1); } - let ingest_select = inquire::Select::new("Which ingestion do you want to edit?", ingest_sel_vec_ing).prompt().unwrap(); - let ing_id = ing_des.iter() - .map(|(key, &ref val)| if val.substance.name == ingest_select.substance.name && val.substance.substance_class == ingest_select.substance.substance_class && val.date == ingest_select.date && val.time == ingest_select.time { key.clone() } else { unreachable!() }).collect::>(); + let ingest_select = + inquire::Select::new("Which ingestion do you want to edit?", ingest_sel_vec_ing) + .prompt() + .unwrap(); + let ing_id = ing_des + .iter() + .map(|(key, &ref val)| { + if val.substance.name == ingest_select.substance.name + && val.substance.substance_class == ingest_select.substance.substance_class + && val.date == ingest_select.date + && val.time == ingest_select.time + { + key.clone() + } else { + unreachable!() + } + }) + .collect::>(); - let edit_select = inquire::MultiSelect::new("What do you want to edit?", vec!["Substance", "Dose", "Ingestion Method", "Time", "Date"]).prompt().unwrap(); + let edit_select = inquire::MultiSelect::new( + "What do you want to edit?", + vec!["Substance", "Dose", "Ingestion Method", "Time", "Date"], + ) + .prompt() + .unwrap(); for edit in edit_select { match edit { @@ -249,3 +275,4 @@ pub fn create_ingestions_file() -> Result<(), std::io::Error> { let hash_ser = bincode::serialize(&hash).unwrap(); std::fs::write(INGESTIONS_FILE.to_string(), hash_ser) } + diff --git a/src/ingestions_util.rs b/client/src/ingestions_util.rs similarity index 68% rename from src/ingestions_util.rs rename to client/src/ingestions_util.rs index 4e5aa4e..1d89e6d 100644 --- a/src/ingestions_util.rs +++ b/client/src/ingestions_util.rs @@ -11,7 +11,8 @@ use uuid::Uuid; pub fn ensure_ingestion_files() -> HashMap { let ingesstions_bytes_loaded_des: HashMap; if path_exists(INGESTIONS_FILE.to_string()) { - let substances_bytes_loaded = std::fs::read(INGESTIONS_FILE.to_string()).expect("Could not read ingestions file"); + let substances_bytes_loaded = + std::fs::read(INGESTIONS_FILE.to_string()).expect("Could not read ingestions file"); ingesstions_bytes_loaded_des = bincode::deserialize(&substances_bytes_loaded).expect("Could not deserialize ingestions file. If you are tech-savvy try fixing it with a hex editor."); } else { std::fs::File::create(INGESTIONS_FILE.to_string()).unwrap(); @@ -24,37 +25,32 @@ pub fn ensure_ingestion_files() -> HashMap { } pub fn get_user_date(current: NaiveDateTime) -> chrono::NaiveDate { - let current_time = current.time(); let current_date = current.date(); - let date: chrono::NaiveDate = inquire::CustomType::::new( - "Enter the date (YYYY-MM-DD):", - ) - .with_placeholder("YYYY-MM-DD") - .with_default(current_date) - .with_parser(&|input| { - chrono::NaiveDate::parse_from_str(input, "%Y-%m-%d").map_err(|_| ()) - }) - .with_error_message("Please enter a valid date and time in the format YYYY-MM-DD") - .with_help_message("Use the format YYYY-MM-DD") - .prompt() - .unwrap(); + let date: chrono::NaiveDate = + inquire::CustomType::::new("Enter the date (YYYY-MM-DD):") + .with_placeholder("YYYY-MM-DD") + .with_default(current_date) + .with_parser(&|input| { + chrono::NaiveDate::parse_from_str(input, "%Y-%m-%d").map_err(|_| ()) + }) + .with_error_message("Please enter a valid date and time in the format YYYY-MM-DD") + .with_help_message("Use the format YYYY-MM-DD") + .prompt() + .unwrap(); date } pub fn get_user_time(current: NaiveDateTime) -> chrono::NaiveTime { let current_time = current.time(); - let time: chrono::NaiveTime = inquire::CustomType::::new( - "Enter the time (HH:MM):", - ) - .with_placeholder("HH:MM") - .with_default(current_time) - .with_parser(&|input| { - chrono::NaiveTime::parse_from_str(input, "%H:%M").map_err(|_| ()) - }) - .with_error_message("Please enter a valid time in the format HH:MM.") - .with_help_message("Use the format HH:MM") - .prompt() - .unwrap(); + let time: chrono::NaiveTime = + inquire::CustomType::::new("Enter the time (HH:MM):") + .with_placeholder("HH:MM") + .with_default(current_time) + .with_parser(&|input| chrono::NaiveTime::parse_from_str(input, "%H:%M").map_err(|_| ())) + .with_error_message("Please enter a valid time in the format HH:MM.") + .with_help_message("Use the format HH:MM") + .prompt() + .unwrap(); time } @@ -63,8 +59,8 @@ pub fn get_dose_unit() -> DoseUnit { "What unit should be used?", DoseUnit::iter().collect::>(), ) - .prompt() - .unwrap(); + .prompt() + .unwrap(); dose_unit } @@ -81,7 +77,13 @@ pub fn get_substance() -> Substance { let substance_file: HashMap = crate::substance_util::ensure_substance_file(); let substances: Vec = substance_file .into_iter() - .filter_map(|(_, s)| if s.name == substance_select { Some(s) } else { None }) + .filter_map(|(_, s)| { + if s.name == substance_select { + Some(s) + } else { + None + } + }) .collect(); if substances.len() != 1 { @@ -100,8 +102,8 @@ pub fn get_ingestion_method() -> IngestionMethod { "How did you ingest?", IngestionMethod::iter().collect::>(), ) - .prompt() - .unwrap(); + .prompt() + .unwrap(); ingestion_method } diff --git a/src/main.rs b/client/src/main.rs similarity index 97% rename from src/main.rs rename to client/src/main.rs index 388a12a..534ce72 100644 --- a/src/main.rs +++ b/client/src/main.rs @@ -55,7 +55,7 @@ fn main() { match &cli.command { Some(Commands::AddIngestion) => ingestions::add_ingestion(), - Some(Commands::EditIngestion) => {ingestions::edit_ingestion().unwrap()} + Some(Commands::EditIngestion) => ingestions::edit_ingestion().unwrap(), Some(Commands::ListIngestions) => ingestions::list_ingestions().unwrap(), Some(Commands::RemoveIngestion) => {} Some(Commands::AddSubstance) => substances::add_substance().unwrap(), diff --git a/src/substance_util.rs b/client/src/substance_util.rs similarity index 100% rename from src/substance_util.rs rename to client/src/substance_util.rs diff --git a/src/substances.rs b/client/src/substances.rs similarity index 100% rename from src/substances.rs rename to client/src/substances.rs diff --git a/src/util.rs b/client/src/util.rs similarity index 100% rename from src/util.rs rename to client/src/util.rs diff --git a/meowlog.proto b/meowlog.proto new file mode 100644 index 0000000..385c5b6 --- /dev/null +++ b/meowlog.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; +package meowlog; + +service MeowlogSync { + rpc GetLogs(GetLogsRequest) returns (GetLogsResponse) {} + rpc AddLog(AddLogRequest) returns (AddLogResponse) {} +} + +message GetLogsRequest { + string query = 1; +} + +message GetLogsResponse { + repeated Log logs = 1; +} + +message AddLogRequest { + Log log = 1; +} + +message AddLogResponse { + bool success = 1; +} + +message Log { + string id = 1; + string message = 2; + string level = 3; + string timestamp = 4; +} \ No newline at end of file