From 3a5b40659834691c57f24eb93e93864e460d3ea9 Mon Sep 17 00:00:00 2001 From: djkato Date: Mon, 24 Apr 2023 19:06:20 +0200 Subject: [PATCH] readme, copy button --- Cargo.lock | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 1 + README.MD | 15 ++++ src/main.rs | 196 +++++++++++++++++++++++++--------------------- 4 files changed, 341 insertions(+), 93 deletions(-) create mode 100644 README.MD diff --git a/Cargo.lock b/Cargo.lock index 40be600..2ff4e5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,7 +75,7 @@ dependencies = [ "once_cell", "parking_lot", "paste", - "windows", + "windows 0.42.0", ] [[package]] @@ -106,6 +106,7 @@ dependencies = [ "eframe", "egui", "regex", + "rfd", "version-compare", "walkdir", ] @@ -276,6 +277,18 @@ dependencies = [ "syn", ] +[[package]] +name = "atk-sys" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ad703eb64dc058024f0e57ccfa069e15a413b98dbd50a1a950e743b7f11148" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + [[package]] name = "atomic_refcell" version = "0.1.9" @@ -404,6 +417,16 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +[[package]] +name = "cairo-sys-rs" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c48f4af05fabdcfa9658178e1326efa061853f040ce7d72e33af6885196f421" +dependencies = [ + "libc", + "system-deps", +] + [[package]] name = "calloop" version = "0.10.5" @@ -432,6 +455,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cfg-expr" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8790cf1286da485c72cf5fc7aeba308438800036ec67d89425924c4807268c9" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -965,6 +998,36 @@ dependencies = [ "slab", ] +[[package]] +name = "gdk-pixbuf-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3092cf797a5f1210479ea38070d9ae8a5b8e9f8f1be9f32f4643c529c7d70016" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk-sys" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76354f97a913e55b984759a997b693aa7dc71068c9e98bcce51aa167a0a5c5a" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + [[package]] name = "generic-array" version = "0.14.6" @@ -996,6 +1059,19 @@ dependencies = [ "wasi", ] +[[package]] +name = "gio-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9b693b8e39d042a95547fc258a7b07349b1f0b48f4b2fa3108ba3c51c0b5229" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + [[package]] name = "gl_generator" version = "0.14.0" @@ -1007,6 +1083,16 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "glib-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61a4f46316d06bfa33a7ac22df6f0524c8be58e3db2d9ca99ccb1f357b62a65" +dependencies = [ + "libc", + "system-deps", +] + [[package]] name = "glow" version = "0.12.1" @@ -1083,6 +1169,35 @@ dependencies = [ "gl_generator", ] +[[package]] +name = "gobject-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3520bb9c07ae2a12c7f2fbb24d4efc11231c8146a86956413fb1a79bb760a0f1" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gtk-sys" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b5f8946685d5fe44497007786600c2f368ff6b1e61a16251c89f72a97520a3" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps", +] + [[package]] name = "h2" version = "0.3.16" @@ -1108,6 +1223,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.2.6" @@ -1662,6 +1783,18 @@ dependencies = [ "ttf-parser", ] +[[package]] +name = "pango-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e134909a9a293e04d2cc31928aa95679c5e4df954d0b85483159bd20d8f047f" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + [[package]] name = "parking" version = "2.0.0" @@ -1903,6 +2036,31 @@ dependencies = [ "winreg", ] +[[package]] +name = "rfd" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cb2988ec50c9bcdb0c012b89643a6094a35a785a37897211ee62e1639342f7b" +dependencies = [ + "async-io", + "block", + "dispatch", + "futures-util", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "log", + "objc", + "objc-foundation", + "objc_id", + "raw-window-handle", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows 0.44.0", +] + [[package]] name = "rustix" version = "0.36.8" @@ -2043,6 +2201,15 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_spanned" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -2158,6 +2325,25 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "system-deps" +version = "6.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0fe581ad25d11420b873cf9aedaca0419c2b411487b134d4d21065f3d092055" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae9980cab1db3fceee2f6c6f643d5d8de2997c58ee8d25fb0cc8a9e9e7348e5" + [[package]] name = "tempfile" version = "3.4.0" @@ -2272,19 +2458,36 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + [[package]] name = "toml_datetime" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" -version = "0.19.4" +version = "0.19.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1eb0622d28f4b9c90adc4ea4b2b46b47663fde9ac5fafcb14a1369d5508825" +checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" dependencies = [ "indexmap", + "serde", + "serde_spanned", "toml_datetime", "winnow", ] @@ -2687,6 +2890,15 @@ dependencies = [ "windows_x86_64_msvc", ] +[[package]] +name = "windows" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-implement" version = "0.42.0" @@ -2816,9 +3028,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.3.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf09497b8f8b5ac5d3bb4d05c0a99be20f26fd3d5f2db7b0716e946d5103658" +checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index c0a45ef..3663a6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,5 +11,6 @@ downloader = "0.2.7" eframe = "0.21.3" egui = "0.21.0" regex = "1.7.1" +rfd = "0.11.3" version-compare = "0.1.1" walkdir = "2.3.2" diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..67d069e --- /dev/null +++ b/README.MD @@ -0,0 +1,15 @@ +#M0nkrus Adobe Tracker +a simple app that checks for updates for your locally installed (torrented) Adobe apps and provides M0nkrus magnets for downloads. + +Also provides a simple downloader for apps that are not installed. + +QnA: +> Do I need to be worried about this app being Malware? + +This programs Source code is free for you to read, and you can see yourself if there are any malicious lines of code. If there was, this github link would be down :) + +>How does it work? + +1. The app goes through your folder at `C:\Program Files\Adobe` and checks for installed apps. Tries to find the file `application.xml` and extract the program version information from there. +2. Downloads the following page to a `./temp/` folder next to the .exe file: [http://rutracker.ru/tracker.php?pid=1334502](http://rutracker.ru/tracker.php?pid=1334502), then extracts latest app downloads. +3. Compares the online version with local versions and provides a [magnet link](https://en.wikipedia.org/wiki/Magnet_URI_scheme) you can open with the torrent downloader app of your choise. \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 8bdfdc9..61b9133 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] use std::fs; +use std::path::PathBuf; // hide console window on Windows in release use downloader::Downloader; @@ -10,98 +11,119 @@ use version_compare::Version; use walkdir::WalkDir; fn main() -> Result<(), eframe::Error> { - let mut installed_apps = find_local_programs(); - /*let mut installed_apps: Vec = vec![ - LocalFoundApp { - name: "Adobe After Effects".to_owned(), - version: "1.0.0".to_owned(), - newest_online: None, - }, - LocalFoundApp { - name: "Adobe Premiere Pro".to_owned(), - version: "1.0.0".to_owned(), - newest_online: None, - }, - LocalFoundApp { - name: "Adobe Photoshop".to_owned(), - version: "1.0.0".to_owned(), - newest_online: None, - }, - ];*/ - let mut online_apps = find_online_programs(&installed_apps); - compare_versions(&mut installed_apps, &mut online_apps); - create_ui(installed_apps, online_apps) + create_ui() } -fn create_ui( - installed_apps: Vec, - online_apps: Vec, -) -> Result<(), eframe::Error> { +fn create_ui() -> Result<(), eframe::Error> { //egui let options = NativeOptions { initial_window_size: Some(egui::vec2(320.0, 480.0)), ..Default::default() }; - let app = Box::new(IsaApp { - local_app_list: installed_apps, - online_app_list: online_apps, + let app = Box::new(MonkrusApp { + local_app_list: None, + online_app_list: None, + path: None, }); run_native("Adobe checker", options, Box::new(|_cc| app)) } /* GUI */ #[derive(Default)] -struct IsaApp { - local_app_list: Vec, - online_app_list: Vec, +struct MonkrusApp { + local_app_list: Option>, + online_app_list: Option>, + path: Option, } -impl App for IsaApp { - fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - egui::CentralPanel::default().show(ctx, |ui| { - ui.heading("Updates"); - ui.separator(); - for local_app in self.local_app_list.iter() { - ui.horizontal(|ui| { - ui.label(format!("{}:", &local_app.name)); - if local_app.newest_online.is_some() { - ui.style_mut().visuals.hyperlink_color = egui::Color32::RED; - ui.hyperlink_to( - format!( - "Found newer version! Current: {}, Newest: {}", - local_app.version, - local_app.newest_online.as_ref().unwrap().version.clone() - ), - local_app.newest_online.as_ref().unwrap().magnet.clone(), - ); - ui.reset_style(); - } else { - ui.style_mut().visuals.override_text_color = Some(egui::Color32::GREEN); - ui.label(format!( - "Version Up to date! Current:{}", - &local_app.version - )); - ui.reset_style(); +impl App for MonkrusApp { + fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) { + if self.path.is_none() { + self.file_dialog_update(ctx, frame); + return; + } + let path = self.path.as_ref().unwrap(); + if let Some(local_app_list) = self.local_app_list.as_mut() { + if let Some(online_app_list) = self.online_app_list.as_mut() { + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("Updates"); + ui.separator(); + for local_app in local_app_list.iter() { + ui.horizontal(|ui| { + ui.label(format!("{}:", &local_app.name)); + if local_app.newest_online.is_some() { + ui.style_mut().visuals.hyperlink_color = egui::Color32::RED; + ui.hyperlink_to( + format!( + "Found newer version! Current: {}, Newest: {}", + local_app.version, + local_app.newest_online.as_ref().unwrap().version.clone() + ), + local_app.newest_online.as_ref().unwrap().magnet.clone(), + ); + if ui.button("Copy").on_hover_text("Click to copy").clicked() { + ui.output_mut(|w| { + w.copied_text = local_app + .newest_online + .as_ref() + .unwrap() + .magnet + .clone(); + }); + } + ui.reset_style(); + } else { + ui.style_mut().visuals.override_text_color = + Some(egui::Color32::GREEN); + ui.label(format!( + "Version Up to date! Current:{}", + &local_app.version + )); + ui.reset_style(); + } + }); } + ui.add_space(20.0); + ui.heading("Online found apps"); + ui.separator(); + egui::ScrollArea::vertical().show(ui, |ui| { + for online_app in online_app_list.iter() { + ui.horizontal(|ui| { + ui.label(format!( + "{}, version: {} ", + online_app.name, &online_app.version + )); + ui.hyperlink_to("download", &online_app.magnet); + if ui.button("Copy").on_hover_text("Click to copy").clicked() { + ui.output_mut(|w| { + w.copied_text = online_app.magnet.clone(); + }); + } + ui.add_space(ui.available_width()); + }); + } + }); }); + } else { + self.online_app_list = Some(find_online_programs(&local_app_list)); + compare_versions(local_app_list, self.online_app_list.as_mut().unwrap()); } - ui.add_space(20.0); - ui.heading("Online found apps"); - ui.separator(); - egui::ScrollArea::vertical().show(ui, |ui| { - for online_app in self.online_app_list.iter() { - ui.horizontal(|ui| { - ui.label(format!( - "{}, version: {} ", - online_app.name, &online_app.version - )); - ui.hyperlink_to("download", &online_app.magnet); - ui.add_space(ui.available_width()); - }); + } else { + self.local_app_list = Some(find_local_programs(path)); + } + } +} +impl MonkrusApp { + fn file_dialog_update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + egui::CentralPanel::default().show(ctx, |ui| { + ui.vertical_centered_justified(|ui| { + ui.heading("Adobe folder location"); + if ui.button("Select").clicked() { + let path = rfd::FileDialog::new().pick_folder(); + self.path = path; } }); }); } } - /* COMPARE VERS */ fn compare_versions( installed_apps: &mut Vec, @@ -114,12 +136,10 @@ fn compare_versions( if Version::from(&local_app.version) < Version::from(&online_app.version) { local_app.newest_online = Some(online_app.clone()); } - } else { - if Version::from(&local_app.newest_online.as_ref().unwrap().version) - < Version::from(&online_app.version) - { - local_app.newest_online = Some(online_app.clone()); - } + } else if Version::from(&local_app.newest_online.as_ref().unwrap().version) + < Version::from(&online_app.version) + { + local_app.newest_online = Some(online_app.clone()); } } } @@ -127,14 +147,14 @@ fn compare_versions( } /* SCAPER */ -fn find_online_programs(app_list: &Vec) -> Vec { +fn find_online_programs(_app_list: &Vec) -> Vec { let version_brackets_regex = Regex::new(r"\(v.*?\)").unwrap(); let version_bare_regex = Regex::new(r"v[.\d]* ").unwrap(); let magnet_regex = Regex::new(r#"href="magnet:\?xt.*?""#).unwrap(); let name_regex = Regex::new(r#"Adobe .*"#).unwrap(); //if temp is missing make it, delete previous tracker.php file if there is one match std::fs::read_dir("./temp") { - Ok(_) => std::fs::remove_file("./temp/tracker.php").unwrap_or_else(|_e| ()), + Ok(_) => std::fs::remove_file("./temp/tracker.php").unwrap_or(()), Err(_) => std::fs::create_dir("./temp").unwrap(), } @@ -149,8 +169,8 @@ fn find_online_programs(app_list: &Vec) -> Vec { //if downloaded, parse site let mut online_apps = Vec::new(); - if let Ok(_) = &result[0] { - println!(""); + if result[0].is_ok() { + println!(); let website_file = fs::read_to_string("./temp/tracker.php").unwrap(); for (web_line_i, web_line) in website_file.lines().enumerate() { if web_line.to_ascii_lowercase().contains("adobe") { @@ -174,7 +194,7 @@ fn find_online_programs(app_list: &Vec) -> Vec { version.pop(); version.pop(); } - } else if let Some(res) = version_bare_regex.find(&web_line) { + } else if let Some(res) = version_bare_regex.find(web_line) { version = web_line .get(res.start() + 1..res.end() - 1) .unwrap() @@ -195,7 +215,7 @@ fn find_online_programs(app_list: &Vec) -> Vec { } } println!("App: {}\nVersion: {}\nMagnet:{}\n", &name, &version, magnet); - let mut online_app = OnlineFoundApp { + let online_app = OnlineFoundApp { name, magnet, version, @@ -208,10 +228,10 @@ fn find_online_programs(app_list: &Vec) -> Vec { } /* FILE BROWSER */ -fn find_local_programs() -> Vec { +fn find_local_programs(path: &PathBuf) -> Vec { let version_regex = Regex::new(r#""\{\w*-\d*\.\d.*?-64-"#).unwrap(); let mut apps = Vec::new(); - for directory_res in WalkDir::new(r"C:\Program Files\Adobe").max_depth(1) { + for directory_res in WalkDir::new(path.as_path()).max_depth(1) { if let Ok(directory) = directory_res { let mut version = "".to_owned(); @@ -220,8 +240,8 @@ fn find_local_programs() -> Vec { if let Ok(files) = files_res { if files.path().ends_with("application.xml") { println!("{}", files.path().as_os_str().to_str().unwrap()); - let xml_file; - xml_file = std::fs::read_to_string(files.path()).unwrap(); + + let xml_file = std::fs::read_to_string(files.path()).unwrap(); for (i, line) in xml_file.lines().enumerate() { let xml_res_line: usize = i; @@ -244,7 +264,7 @@ fn find_local_programs() -> Vec { if let Some(app_name) = directory.path().file_name() { let mut app_name_str: String = app_name.to_str().unwrap().into(); - if let Some(adobe_app_name_usize) = app_name_str.find("2") { + if let Some(adobe_app_name_usize) = app_name_str.find('2') { app_name_str.truncate(adobe_app_name_usize); app_name_str = app_name_str.trim().to_string(); println!("App: {}, Version: {}", &app_name_str, &version);