diff --git a/.drp_config b/.drp_config deleted file mode 100644 index c5ff67c..0000000 --- a/.drp_config +++ /dev/null @@ -1,15 +0,0 @@ -SHOULD_EXCLUDE_BE_ANONYMOUS:{ -n -} - -PORTFOLIO_LINK:{ -djkato.net -} - -EXCLUDE_CHARACTERS_LIST:{ -no_drp -} - -HIDE_PORTFOLIO_ROW:{ -no -} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 0116677..63d56ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -251,12 +251,14 @@ dependencies = [ [[package]] name = "drp_creative" -version = "1.0.2" +version = "1.0.3" dependencies = [ "discord-rich-presence", "lazy_static", "regex", "self_update", + "serde", + "toml 0.7.6", "tray-item", "win-msgbox", "windows", @@ -278,6 +280,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "equivalent" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" + [[package]] name = "errno" version = "0.3.1" @@ -641,7 +649,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -654,6 +662,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "heck" version = "0.4.0" @@ -763,7 +777,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", ] [[package]] @@ -1014,7 +1038,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.25", ] [[package]] @@ -1123,7 +1147,7 @@ checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" dependencies = [ "once_cell", "thiserror", - "toml", + "toml 0.5.9", ] [[package]] @@ -1152,9 +1176,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" dependencies = [ "unicode-ident", ] @@ -1170,9 +1194,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.27" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] @@ -1346,19 +1370,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.144" +version = "1.0.170" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" +checksum = "a56657f512baabca8f840542f9ca8152aecf182c473c26e46e58d6aab4f6e439" +dependencies = [ + "serde_derive", +] [[package]] name = "serde_derive" -version = "1.0.144" +version = "1.0.170" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" +checksum = "77d477848e6b23adba0db397777d5aad864555bc17fd9c89abb3b8009788b7b8" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.25", ] [[package]] @@ -1372,6 +1399,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1422,9 +1458,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.15" +version = "2.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" dependencies = [ "proc-macro2", "quote", @@ -1440,7 +1476,7 @@ dependencies = [ "cfg-expr", "heck", "pkg-config", - "toml", + "toml 0.5.9", "version-compare", ] @@ -1557,6 +1593,40 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" +dependencies = [ + "indexmap 2.0.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower-service" version = "0.3.2" @@ -2007,6 +2077,15 @@ dependencies = [ "find-winsdk", ] +[[package]] +name = "winnow" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index acaef88..7671b1d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "drp_creative" -version = "1.0.2" +version = "1.0.3" edition = "2021" author = "https://djkato.net" @@ -11,6 +11,8 @@ tray-item = "0.7.0" lazy_static = "1.4.0" self_update = { version = "0.36.0", features = ["archive-zip"] } win-msgbox = "0.1.2" +serde = { version = "1.0.170", features = ["derive"] } +toml = "0.7.6" [dependencies.windows] version = "0.39.0" diff --git a/README.md b/README.md index 097b2b3..b7c3397 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Examples: ![example1](https://i.imgur.com/yFzQh6O.png) ![example2](https://i.imgur.com/fziotzt.png) ![example3](https://i.imgur.com/9SEXuQr.png) - +![example4](https://i.imgur.com/ANAW6Ub.png) ## how to install: 1. Grab the latest version from the [Releases](https://github.com/djkato/DRP_Creative/releases) page, then make a folder in `C:/Program Files/` and call it whatever, for example `DRP Creative`. 3. Put the exe inside the folder you created and create a link to it. @@ -17,29 +17,21 @@ Examples: ## How to use: - App updates will be notified and suggested on startup via popup window. -- When it's running, you'll notice a new icon appear on your Taskbar. If you want to exclude the **currently open project** from showing up, click on the icon and click on `Don't show current project`. -![icon showcase](https://i.imgur.com/nADffGB.png) +- When it's running, you'll notice a new icon appear on your Taskbar. If you want to include/exclude the **currently open project** from showing up, click on the icon and click on `Remove project from include/exclude list`. +- There are two modes for the keywords list: + 1. Exclude(default): If the currently open project files name contains the keyword anywhere, it will show the default project name instead. + 2. Include: All projects will show default names, unless the the currently open project files name contains a keyword, then it will display the real name. This is a good alternative if you find yourself hiding more than showing what you're working on. +- If you don't want to see the default project names, and instead just not display anything, you can change that behavior by setting `show_default_when_excluded` to `false` in the config file. +- If you don't like the *"Portfolio: [your link]"* line on your status, you can disable it by setting `hide_portfolio_link` to `true` -- To change the portfolio website or remove excluded projects and words from the program, run the program at least once, and a `.drp_config` file will appear. You can open this with any text editor and rewrite the lines there. be gentle though, program expects a certain format for the file ^^' -- To disable the portfolio row, there's a "HIDE_PORTFOLIO_ROW" setting. +Example `drp_config.toml`: +```toml +keywords_list = ["WORK", "Untitled 681*"] +show_default_when_excluded = true # or false +portfolio_link = "djkato.net" +hide_portfolio_row = false +should_list_include_or_exclude = "Include" # Or "Exclude", capital sensitive -Example `.drp_config`: -```json -SHOULD_EXCLUDE_BE_ANONYMOUS:{ -n -} - -PORTFOLIO_LINK:{ -djkato.net -} - -EXCLUDE_CHARACTERS_LIST:{ -no_drp -} - -HIDE_PORTFOLIO_ROW:{ -no -} ``` ### Currently supported programs: **Full support:** diff --git a/drp_config.toml b/drp_config.toml new file mode 100644 index 0000000..e46e3a8 --- /dev/null +++ b/drp_config.toml @@ -0,0 +1,5 @@ +keywords_list = [] +show_default_when_excluded = true +portfolio_link = "djkato.net" +hide_portfolio_row = false +should_list_include_or_exclude = "Include" diff --git a/src/config.rs b/src/config.rs index 23a0ff2..bcc954c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,136 +1,91 @@ -use std::fs; +use serde::{Deserialize, Serialize}; +use std::{ + fs, + io::{Read, Write}, +}; -#[derive(Debug)] +#[derive(Debug, Serialize, Deserialize)] pub struct Config { - pub exclude_keywords_list: Vec, - pub should_exclude_be_invisible: bool, + pub keywords_list: Vec, + pub show_default_when_excluded: bool, pub portfolio_link: String, pub hide_portfolio_row: bool, + pub should_list_include_or_exclude: IncludeExclude, } -impl Config { - pub fn load() -> Config { - let default_config = use_default_config(); - - //if no config file, parse default config file and try save it, then use it - let config_file: Config = match fs::read_to_string(".drp_config") { - Result::Err(_err) => { - let def_config = parse_config_file(&default_config); - make_config_file(&def_config); - def_config - } - Result::Ok(val) => parse_config_file(&val), - }; - config_file +impl Default for Config { + fn default() -> Self { + Config { + keywords_list: Vec::new(), + should_list_include_or_exclude: IncludeExclude::Exclude, + portfolio_link: "djkato.net".to_owned(), + hide_portfolio_row: false, + show_default_when_excluded: true, + } } } + +#[derive(Debug, Serialize, Deserialize)] +pub enum IncludeExclude { + Include, + Exclude, +} + impl Config { - pub fn exclude_project(&mut self, project_name: &String) { - if self.exclude_keywords_list.contains(&project_name) { + pub fn add_project(&mut self, project_name: &String) { + if self.keywords_list.contains(&project_name) { return; } - self.exclude_keywords_list.push(project_name.clone()); - make_config_file(&self); + self.keywords_list.push(project_name.clone()); + self.write(); } -} -fn parse_config_file(config_file: &String) -> Config { - let mut exclude_keywords_list: Vec = Vec::new(); - let mut should_exclude_be_invisible = false; - let mut portfolio_link = String::new(); - let mut hide_portfolio_row = false; - for (i, line) in config_file.lines().enumerate() { - if line.contains("SHOULD_EXCLUDE_BE_ANONYMOUS:") { - match config_file - .lines() - .nth(i + 1) - .expect("index out of bounds") - .to_lowercase() - .as_str() - .trim() - { - "n" => should_exclude_be_invisible = false, - "no" => should_exclude_be_invisible = false, - "y" => should_exclude_be_invisible = true, - "yes" => should_exclude_be_invisible = true, - _ => should_exclude_be_invisible = false, - } - } - if line.contains("EXCLUDE_CHARACTERS_LIST:") { - for arg_line in config_file.lines().skip(i + 1) { - if arg_line.trim().contains("}") { - break; - } - exclude_keywords_list.push(arg_line.to_string()) - } - } - if line.contains("PORTFOLIO_LINK:") { - for arg_line in config_file.lines().skip(i) { - if arg_line.trim().contains("}") { - break; - } - portfolio_link = arg_line.to_string(); - } - } - if line.contains("HIDE_PORTFOLIO_ROW:") { - match config_file - .lines() - .nth(i + 1) - .expect("index out of bounds") - .to_lowercase() - .as_str() - .trim() - { - "n" => hide_portfolio_row = false, - "no" => hide_portfolio_row = false, - "y" => hide_portfolio_row = true, - "yes" => hide_portfolio_row = true, - _ => hide_portfolio_row = false, - } + + pub fn remove_project(&mut self, project_name: &String) { + if self.keywords_list.contains(&project_name) { + self.keywords_list.remove( + self.keywords_list + .iter() + .position(|proj| proj == project_name) + .unwrap(), + ); + self.write(); } } - Config { - exclude_keywords_list, - should_exclude_be_invisible, - portfolio_link, - hide_portfolio_row, + pub fn load_from_file(&mut self) { + if !std::path::Path::new("drp_config.toml").exists() { + self.write(); + } else { + let mut file = fs::File::options() + .read(true) + .open("drp_config.toml") + .expect( + "Config file exists but can't be acccessed. Check permissions for the file.", + ); + + let mut content = String::new(); + file.read_to_string(&mut content) + .expect("config file not valid"); + + if content.is_empty() { + self.write(); + } + + *self = toml::from_str::(content.as_str()) + .expect("Config file exists, but the format of it is wrong."); + } + } + + pub fn write(&self) { + let mut file = fs::File::options() + .write(true) + .create(true) + .truncate(true) + .open("drp_config.toml") + .expect("Couldn't write to file"); + let buff = + toml::ser::to_string_pretty(self).expect("Something is wrong with the default config"); + + file.write_all(buff.as_bytes()) + .expect("Failed to write files"); } } - -fn make_config_file(config: &Config) { - let mut config_file = String::from("SHOULD_EXCLUDE_BE_ANONYMOUS:{"); - config_file = config_file - + match config.should_exclude_be_invisible { - true => "\ny\n}\n", - false => "\nn\n}\n", - }; - - config_file = config_file + "\nPORTFOLIO_LINK:{\ndjkato.net\n}\n"; - - config_file = config_file + "\nEXCLUDE_CHARACTERS_LIST:{"; - for exclusive_word in &config.exclude_keywords_list { - config_file = config_file + format!("\n{}", exclusive_word).as_str(); - } - config_file = config_file + "\n}\n"; - - match fs::write(".drp_config", config_file) { - _ => (), - } -} - -fn use_default_config() -> String { - let str = String::from( - "SHOULD_EXCLUDE_BE_ANONYMOUS:{ -n -} - -PORTFOLIO_LINK:{ -djkato.net -} - -EXCLUDE_CHARACTERS_LIST:{ -no_drp -} -", - ); - str -} diff --git a/src/main.rs b/src/main.rs index af34810..b0b9737 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ pub mod config; pub mod program_status; pub mod self_updater; pub mod tray_icon; -use crate::config::Config; +use crate::config::{Config, IncludeExclude}; use crate::program_status::*; use crate::self_updater::try_update; use app::{App, Apps}; @@ -21,7 +21,9 @@ fn main() { Err(e) => println!("Failed to update! {e}"), } let apps = Apps::construct_apps(); - let mut config = Config::load(); + let mut config = Config::default(); + + config.load_from_file(); let timeout = time::Duration::from_millis(5000); @@ -33,15 +35,35 @@ fn main() { let mut drp_is_running = false; let mut discord_client: Option = None; let mut current_app_option: Option<&App> = None; - loop { + 'main: loop { if let Some(current_app) = current_app_option { if let Some(real_project_name) = is_program_still_running(¤t_app) { - //if project name includes filtered words, use default project name - for excluded_word in &config.exclude_keywords_list { - if real_project_name.contains(excluded_word.as_str()) { - project_name = current_app.default_project_name.clone(); - } else { - project_name = real_project_name.clone(); + project_name = match config.should_list_include_or_exclude { + IncludeExclude::Exclude => real_project_name.clone(), + IncludeExclude::Include => current_app.default_project_name.clone(), + }; + for listed_word in &config.keywords_list { + match &config.should_list_include_or_exclude { + &IncludeExclude::Exclude => { + if real_project_name.contains(listed_word.as_str()) { + if !&config.show_default_when_excluded { + continue 'main; + } + project_name = current_app.default_project_name.clone(); + } else { + project_name = real_project_name.clone(); + } + } + &IncludeExclude::Include => { + if real_project_name.contains(listed_word.as_str()) { + project_name = real_project_name.clone(); + } else { + if !&config.show_default_when_excluded { + continue 'main; + } + project_name = current_app.default_project_name.clone(); + } + } } } //If discord client isn't connected create and conenct it @@ -86,7 +108,10 @@ fn main() { //if discord client exists, update status if let Some(dc) = discord_client.as_mut() { match dc.set_activity(activity) { - _ => (), + Ok(_) => (), + Err(e) => { + dbg!(e); + } } } } @@ -99,20 +124,23 @@ fn main() { //respond to tray icon messages match tray_receiver.try_recv() { Ok(msg) => match msg { - tray_icon::Message::AnonymiseProject => { - //only exclude project name if it's not the default one - for app in apps.as_iter() { - if app.kind == current_app.kind { - if app.default_project_name != project_name { - config.exclude_project(&project_name); - } - } + tray_icon::Message::AddProjectToList => { + if let Some(real_project_name) = is_program_still_running(¤t_app) { + config.add_project(&real_project_name); + } + } + tray_icon::Message::RemoveProjectFromList => { + if let Some(real_project_name) = is_program_still_running(¤t_app) { + config.remove_project(&real_project_name); } } tray_icon::Message::Quit => { println!("qiuitting!"); exit(0) } + tray_icon::Message::OpenOptionsFile => { + let _ = std::process::Command::new("crp_config.toml").spawn(); + } }, Err(_err) => (), } @@ -120,8 +148,8 @@ fn main() { //respond to tray icon messages match tray_receiver.try_recv() { Ok(msg) => match msg { - tray_icon::Message::AnonymiseProject => {} tray_icon::Message::Quit => exit(0), + _ => (), }, Err(_err) => (), } diff --git a/src/tray_icon.rs b/src/tray_icon.rs index 2a8ba81..b6b4a48 100644 --- a/src/tray_icon.rs +++ b/src/tray_icon.rs @@ -4,23 +4,38 @@ use {std::sync::mpsc, tray_item::TrayItem}; pub enum Message { Quit, - AnonymiseProject, + AddProjectToList, + RemoveProjectFromList, + OpenOptionsFile, } pub fn create_tray() -> (Receiver, TrayItem) { let mut tray = TrayItem::new("DRP Creative", "drp-icon").unwrap(); let (tx, rx) = mpsc::channel(); let tx1 = tx.clone(); - tray.add_label("DRP Creative Options").unwrap(); + let tx2 = tx.clone(); + let tx3 = tx.clone(); + let tx4 = tx.clone(); + tray.add_menu_item("Open options file", move || { + tx4.send(Message::OpenOptionsFile).unwrap(); + }) + .unwrap(); - tray.add_menu_item("Don't show current project", move || { - tx.send(Message::AnonymiseProject).unwrap(); + tray.add_menu_item("Add project to include/exclude list", move || { + tx1.send(Message::AddProjectToList).unwrap(); + }) + .unwrap(); + + tray.add_menu_item("Remove project from include/exclude list", move || { + println!("REMOVE"); + tx3.send(Message::RemoveProjectFromList).unwrap(); }) .unwrap(); tray.add_menu_item("Quit", move || { - tx1.send(Message::Quit).unwrap(); + tx2.send(Message::Quit).unwrap(); }) .unwrap(); + return (rx, tray); }