From 4664b638628d7eff53cfc5550ad0a80e3c5322fe Mon Sep 17 00:00:00 2001 From: Alexis Delhaie Date: Thu, 24 Sep 2020 10:47:06 +0200 Subject: [PATCH] update/downgrade v1 to V2 --- .gitignore | 1 + Cargo.lock | 323 +++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 20 +++ build.rs | 9 ++ icon.ico | Bin 0 -> 121149 bytes src/main.rs | 155 ++++++++++++++++++++ src/model_version_1.rs | 27 ++++ src/model_version_2.rs | 151 +++++++++++++++++++ 8 files changed, 686 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 build.rs create mode 100644 icon.ico create mode 100644 src/main.rs create mode 100644 src/model_version_1.rs create mode 100644 src/model_version_2.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..8f164f5 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,323 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "blake2b_simd" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "chrono" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b" +dependencies = [ + "num-integer", + "num-traits", + "time", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if", + "lazy_static", +] + +[[package]] +name = "dirs" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" +dependencies = [ + "cfg-if", + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "getrandom" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "itoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" + +[[package]] +name = "num-integer" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" +dependencies = [ + "autocfg", +] + +[[package]] +name = "platform-dirs" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e6f10c0c97e3d27b298374c2c67a057216c98e0a86c44df6bcd1f02bacbe38" +dependencies = [ + "dirs", +] + +[[package]] +name = "proc-macro2" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_users" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +dependencies = [ + "getrandom", + "redox_syscall", + "rust-argon2", +] + +[[package]] +name = "rust-argon2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19" +dependencies = [ + "base64", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "save-updater-src" +version = "0.1.0" +dependencies = [ + "chrono", + "platform-dirs", + "serde", + "serde_json", + "winres", +] + +[[package]] +name = "serde" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "time" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "toml" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "winres" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4fb510bbfe5b8992ff15f77a2e6fe6cf062878f0eda00c0f44963a807ca5dc" +dependencies = [ + "toml", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..4b6686f --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "save-updater-src" +version = "0.1.0" +authors = ["Alexis Delhaie "] +edition = "2018" +build = "build.rs" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +platform-dirs = "0.2.0" +serde_json = "1.0" +serde = { version = "1.0", features = ["derive"] } +chrono = "0.4.15" + +[build-dependencies] +winres = "0.1" + +[profile.release] +opt-level = 3 diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..d6d4a09 --- /dev/null +++ b/build.rs @@ -0,0 +1,9 @@ +extern crate winres; + +fn main() { + if cfg!(target_os = "windows") { + let mut res = winres::WindowsResource::new(); + res.set_icon("icon.ico"); + res.compile().unwrap(); + } +} \ No newline at end of file diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..736ffc4e16568040e8cdafa796a7781f40ab6399 GIT binary patch literal 121149 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 z z>=;QpKOA_3(>j)ae%Q}H$BKRmeUE%l>g&;?y0M`e8J#;vlK&A7JZ@1APM0m&z58yQSg)V%|J7GfsI#a9rg7vu+yakl*gEI)&viZ~<%ZBbj~`FgewV&a z{F9HT(Nk-HV;%6AMt!|?%eb#Z-(#EP(^l}=F4e>}mKjqGnf1%NXY0yFIKziS$@3R-aTL = env::args().collect(); + if args.len() >= 2 { + let verb = &args[1]; + + match verb.as_ref() { + "update" => update_cmd(), + "help" => help_cmd(false, ""), + "downgrade" => { + if args.len() >= 3 { + let allow_downgrade = confirm( + "Do you really want to downgrade your save? \ + You may experience data lost", + ) + .unwrap(); + if allow_downgrade { + let version: u64 = args[2] + .parse::() + .expect("ERROR: Cannot get version number"); + downgrade_cmd(version); + } else { + println!("Operation aborted"); + } + } else { + help_cmd(true, "ERROR: The version number is missing") + } + } + _ => help_cmd(true, "ERROR: This verb is not allowed"), + } + } else { + help_cmd(true, "ERROR: The verb arg is missing"); + } +} + +fn help_cmd(has_error: bool, err: &str) { + if has_error { + eprintln!("{}", err); + println!(""); + } + println!("Usage: save-updater.exe [args]\n"); + println!("List of verbs:"); + println!(" update Update the Chronos file save"); + println!(" downgrade Downgrade to a version"); + println!(" help Show this screen"); +} + +fn downgrade_cmd(version: u64) { + let json_file = open_save_file().expect("ERROR: Cannot open save file"); + let v: Value = serde_json::from_str(&json_file).expect("ERROR: Cannot parse save file"); + let current_version: u64 = v["version"] + .as_u64() + .expect("ERROR: Error while parsing save version"); + if version == (current_version - 1) && version > 0 { + add_to_backup(&json_file).expect("ERROR: Failed to create backup"); + match version { + 1 => { + let s: SaveVersion2 = + serde_json::from_str(&json_file).expect("ERROR: Cannot parse save file"); + let new_save = downgrade_to_v1(s); + let json = + serde_json::to_string(&new_save).expect("ERROR: Fail to build new save file"); + save_to_file(&json, "data.json").expect("ERROR: Fail to save updated file"); + println!("INFO: Save file has been downgraded"); + } + _ => eprintln!("ERROR: Version not supported"), + } + } else { + eprintln!("ERROR: Only downgrading to the previous version is allowed"); + } +} + +fn update_cmd() { + let json_file = open_save_file().expect("ERROR: Cannot open save file"); + let v: Value = serde_json::from_str(&json_file).expect("ERROR: Cannot parse save file"); + if v["version"] == 1 { + add_to_backup(&json_file).expect("ERROR: Failed to create backup"); + let s: SaveVersion1 = + serde_json::from_str(&json_file).expect("ERROR: Cannot parse save file"); + let new_save = start_upgrade_from_v1(s); + let json = serde_json::to_string(&new_save).expect("ERROR: Fail to build new save file"); + save_to_file(&json, "data.json").expect("ERROR: Fail to save updated file"); + println!("INFO: Save file is up-to-date"); + } else { + println!("Save already up-to-date"); + } +} + +fn open_save_file() -> std::result::Result { + let app_dirs = AppDirs::new(Some("Chronos"), AppUI::CommandLine) + .expect("ERROR: Cannot get application data folder"); + let path = app_dirs.config_dir.join("data").join("data.json"); + if path.exists() { + let file = File::open(path).expect("ERROR: cannot open file"); + let mut buf_reader = BufReader::new(file); + let mut contents = String::new(); + buf_reader + .read_to_string(&mut contents) + .expect("cannot read file"); + Ok(contents) + } else { + Err("Save file not found") + } +} + +fn save_to_file(content: &String, filename: &str) -> std::io::Result<()> { + let app_dirs = AppDirs::new(Some("Chronos"), AppUI::CommandLine) + .expect("ERROR: Cannot get application data folder"); + let path = app_dirs.config_dir.join("data").join(filename); + let mut file = File::create(path)?; + file.write_all(content.as_bytes())?; + Ok(()) +} + +fn confirm(msg: &str) -> std::io::Result { + println!("{}\nType 'yes', other input will be ignore", msg); + let mut buffer = String::new(); + io::stdin().read_line(&mut buffer)?; + Ok(buffer.trim() == "yes") +} + +fn add_to_backup(content: &String) -> std::io::Result<()> { + let app_dirs = AppDirs::new(Some("Chronos"), AppUI::CommandLine) + .expect("ERROR: Cannot get application data folder"); + let path = app_dirs.config_dir.join("data").join("backup"); + create_dir_all(&path)?; + let timestamp = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .expect("ERROR: Failed to get timestamp") + .as_secs(); + let path = path.join(format!("{}.data.json", timestamp)); + let mut file = File::create(path)?; + file.write_all(content.as_bytes())?; + Ok(()) +} + +fn start_upgrade_from_v1(save: SaveVersion1) -> SaveVersion2 { + println!("INFO: Starting upgrading from version 1 to version 2"); + let save = upgrade_to_v2(save); + save +} diff --git a/src/model_version_1.rs b/src/model_version_1.rs new file mode 100644 index 0000000..a86e6dd --- /dev/null +++ b/src/model_version_1.rs @@ -0,0 +1,27 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +pub struct SaveVersion1 { + pub template: WeekVersion1, + pub version: u32, + pub weeks: Vec, +} + +#[derive(Serialize, Deserialize)] +pub struct WeekVersion1 { + pub monday: DayVersion1, + pub tuesday: DayVersion1, + pub wednesday: DayVersion1, + pub thurday: DayVersion1, + pub friday: DayVersion1, + #[serde(alias = "weekNumber", rename(serialize = "weekNumber"))] + pub week_number: u32, +} + +#[derive(Serialize, Deserialize)] +pub struct DayVersion1 { + #[serde(alias = "break", rename(serialize = "break"))] + pub break_time: u32, + pub end: String, + pub start: String, +} diff --git a/src/model_version_2.rs b/src/model_version_2.rs new file mode 100644 index 0000000..3d19af8 --- /dev/null +++ b/src/model_version_2.rs @@ -0,0 +1,151 @@ +pub use crate::model_version_1::DayVersion1; +pub use crate::model_version_1::SaveVersion1; +pub use crate::model_version_1::WeekVersion1; +use chrono::prelude::*; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +pub struct SaveVersion2 { + pub template: WeekVersion2, + pub version: u32, + pub weeks: Vec, +} + +#[derive(Serialize, Deserialize)] +pub struct WeekVersion2 { + pub monday: DayVersion2, + pub tuesday: DayVersion2, + pub wednesday: DayVersion2, + pub thurday: DayVersion2, + pub friday: DayVersion2, + #[serde(alias = "weekNumber", rename(serialize = "weekNumber"))] + pub week_number: u32, +} + +#[derive(Serialize, Deserialize)] +pub struct DayVersion2 { + #[serde(alias = "break", rename(serialize = "break"))] + pub break_time: u32, + pub end: String, + pub start: String, + pub validate: bool, +} + +// Upgrade + +pub fn upgrade_to_v2(s: SaveVersion1) -> SaveVersion2 { + let save = SaveVersion2 { + version: 2, + template: upgrade_template(s.template), + weeks: upgrade_weeks(s.weeks), + }; + save +} + +fn upgrade_template(w: WeekVersion1) -> WeekVersion2 { + println!("INFO: Upgrading template"); + let week = WeekVersion2 { + monday: upgrade_day(w.monday, false), + tuesday: upgrade_day(w.tuesday, false), + wednesday: upgrade_day(w.wednesday, false), + thurday: upgrade_day(w.thurday, false), + friday: upgrade_day(w.friday, false), + week_number: w.week_number, + }; + week +} + +fn upgrade_weeks(ws: Vec) -> Vec { + println!("INFO: Upgrading weeks"); + let mut v: Vec = Vec::new(); + let naive_date_time = Utc::now().naive_utc(); + let week_number = naive_date_time.iso_week().week(); + let dow = naive_date_time.weekday(); + for w in ws { + if w.week_number < week_number { + let week = WeekVersion2 { + monday: upgrade_day(w.monday, true), + tuesday: upgrade_day(w.tuesday, true), + wednesday: upgrade_day(w.wednesday, true), + thurday: upgrade_day(w.thurday, true), + friday: upgrade_day(w.friday, true), + week_number: w.week_number, + }; + v.push(week); + } else if w.week_number == week_number { + let week = WeekVersion2 { + monday: upgrade_day(w.monday, dow.num_days_from_monday() > 0), + tuesday: upgrade_day(w.tuesday, dow.num_days_from_monday() > 1), + wednesday: upgrade_day(w.wednesday, dow.num_days_from_monday() > 2), + thurday: upgrade_day(w.thurday, dow.num_days_from_monday() > 3), + friday: upgrade_day(w.friday, dow.num_days_from_monday() > 4), + week_number: w.week_number, + }; + v.push(week); + } else { + let week = WeekVersion2 { + monday: upgrade_day(w.monday, false), + tuesday: upgrade_day(w.tuesday, false), + wednesday: upgrade_day(w.wednesday, false), + thurday: upgrade_day(w.thurday, false), + friday: upgrade_day(w.friday, false), + week_number: w.week_number, + }; + v.push(week); + } + } + v +} + +fn upgrade_day(d: DayVersion1, new_validate: bool) -> DayVersion2 { + println!("INFO: Upgrading day"); + let day = DayVersion2 { + break_time: d.break_time, + end: d.end, + start: d.start, + validate: new_validate, + }; + day +} + +// Downgrade + +pub fn downgrade_to_v1(s: SaveVersion2) -> SaveVersion1 { + let save = SaveVersion1 { + version: 1, + template: downgrade_week(s.template), + weeks: downgrade_weeks(s.weeks), + }; + save +} + +fn downgrade_week(w: WeekVersion2) -> WeekVersion1 { + let week = WeekVersion1 { + monday: downgrade_day(w.monday), + tuesday: downgrade_day(w.tuesday), + wednesday: downgrade_day(w.wednesday), + thurday: downgrade_day(w.thurday), + friday: downgrade_day(w.friday), + week_number: w.week_number, + }; + week +} + +fn downgrade_weeks(ws: Vec) -> Vec { + println!("INFO: Downgrading weeks"); + let mut v: Vec = Vec::new(); + for w in ws { + v.push(downgrade_week(w)); + } + v +} + +fn downgrade_day(d: DayVersion2) -> DayVersion1 { + println!("INFO: Downgrading day"); + let day = DayVersion1 { + break_time: d.break_time, + end: d.end, + start: d.start, + }; + day +}