Compare commits

...

6 commits

Author SHA1 Message Date
Djkáťo
110e888b64
Update README.MD 2023-06-01 16:31:52 +02:00
Djkáťo
93e745a58b
Update README.MD 2023-04-25 12:03:54 +02:00
Djkáťo
5d34883e11
Create rust-clippy.yml 2023-04-25 12:00:51 +02:00
djkato
3a5b406598 readme, copy button 2023-04-24 19:06:20 +02:00
djkato
a00d2a710b change default window size 2023-04-24 16:47:37 +02:00
djkato
cdeb14a23a ui, add download options 2023-04-24 16:47:06 +02:00
5 changed files with 449 additions and 89 deletions

55
.github/workflows/rust-clippy.yml vendored Normal file
View file

@ -0,0 +1,55 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# rust-clippy is a tool that runs a bunch of lints to catch common
# mistakes in your Rust code and help improve your Rust code.
# More details at https://github.com/rust-lang/rust-clippy
# and https://rust-lang.github.io/rust-clippy/
name: rust-clippy analyze
on:
push:
branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '25 14 * * 2'
jobs:
rust-clippy-analyze:
name: Run rust-clippy analyzing
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Install Rust toolchain
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af #@v1
with:
profile: minimal
toolchain: stable
components: clippy
override: true
- name: Install required cargo
run: cargo install clippy-sarif sarif-fmt
- name: Run rust-clippy
run:
cargo clippy
--all-features
--message-format=json | clippy-sarif | tee rust-clippy-results.sarif | sarif-fmt
continue-on-error: true
- name: Upload analysis results to GitHub
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: rust-clippy-results.sarif
wait-for-processing: true

222
Cargo.lock generated
View file

@ -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",
]

View file

@ -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"

16
README.MD Normal file
View file

@ -0,0 +1,16 @@
# 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.
![image](https://github.com/djkato/m0nkrus-adobe-tracker/assets/25299243/d43d634a-7efe-4403-b8c8-e9478cee88d9)

View file

@ -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,33 +11,42 @@ use version_compare::Version;
use walkdir::WalkDir;
fn main() -> Result<(), eframe::Error> {
let mut installed_apps = list_installed_adobe_programs();
let online_apps = find_updates(&installed_apps);
compare_versions(&mut installed_apps, online_apps);
create_ui(installed_apps)
create_ui()
}
fn create_ui(installed_apps: Vec<LocalFoundApp>) -> Result<(), eframe::Error> {
fn create_ui() -> Result<(), eframe::Error> {
//egui
let options = NativeOptions {
initial_window_size: Some(egui::vec2(320.0, 240.0)),
initial_window_size: Some(egui::vec2(320.0, 480.0)),
..Default::default()
};
let app = Box::new(IsaApp {
app_list: installed_apps,
..Default::default()
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 {
app_list: Vec<LocalFoundApp>,
struct MonkrusApp {
local_app_list: Option<Vec<LocalFoundApp>>,
online_app_list: Option<Vec<OnlineFoundApp>>,
path: Option<PathBuf>,
}
impl App for IsaApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
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| {
for local_app in self.app_list.iter() {
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() {
@ -49,9 +59,20 @@ impl App for IsaApp {
),
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.style_mut().visuals.override_text_color =
Some(egui::Color32::GREEN);
ui.label(format!(
"Version Up to date! Current:{}",
&local_app.version
@ -60,21 +81,62 @@ impl App for IsaApp {
}
});
}
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());
}
} 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<LocalFoundApp>, online_apps: Vec<OnlineFoundApp>) {
fn compare_versions(
installed_apps: &mut Vec<LocalFoundApp>,
online_apps: &mut Vec<OnlineFoundApp>,
) {
for local_app in installed_apps.iter_mut() {
for online_app in online_apps.iter() {
if local_app.name == online_app.name {
if online_app.name.contains(&local_app.name) {
if local_app.newest_online.is_none() {
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)
} 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());
@ -83,15 +145,16 @@ fn compare_versions(installed_apps: &mut Vec<LocalFoundApp>, online_apps: Vec<On
}
}
}
}
/* SCAPER */
fn find_updates(app_list: &Vec<LocalFoundApp>) -> Vec<OnlineFoundApp> {
let version_regex = Regex::new(r"\(v.*?\)").unwrap();
fn find_online_programs(_app_list: &Vec<LocalFoundApp>) -> Vec<OnlineFoundApp> {
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#"<b>Adobe .*<wbr>"#).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(),
}
@ -106,21 +169,37 @@ fn find_updates(app_list: &Vec<LocalFoundApp>) -> Vec<OnlineFoundApp> {
//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() {
for app_name in app_list {
if web_line
.to_ascii_lowercase()
.contains(&app_name.name.to_ascii_lowercase())
{
if web_line.to_ascii_lowercase().contains("adobe") {
let mut version = "".to_owned();
if let Some(res) = version_regex.find(web_line) {
let mut name = "".to_owned();
if let Some(res) = name_regex.find(web_line) {
name = web_line
.get(res.start() + 3..res.end() - 5)
.unwrap()
.to_string();
}
if let Some(res) = version_brackets_regex.find(web_line) {
version = web_line
.get(res.start() + 2..res.end() - 1)
.unwrap()
.to_string();
if version.contains("<wbr>") {
version.pop();
version.pop();
version.pop();
version.pop();
version.pop();
}
} else if let Some(res) = version_bare_regex.find(web_line) {
version = web_line
.get(res.start() + 1..res.end() - 1)
.unwrap()
.to_string();
version = version.trim().to_string();
}
let mut magnet = "".to_string();
@ -135,16 +214,13 @@ fn find_updates(app_list: &Vec<LocalFoundApp>) -> Vec<OnlineFoundApp> {
}
}
}
println!(
"App: {}\nVersion: {}\nMagnet:{}\n",
&app_name.name, &version, magnet
);
online_apps.push(OnlineFoundApp {
name: app_name.name.clone(),
version,
println!("App: {}\nVersion: {}\nMagnet:{}\n", &name, &version, magnet);
let online_app = OnlineFoundApp {
name,
magnet,
});
}
version,
};
online_apps.push(online_app.clone());
}
}
};
@ -152,10 +228,10 @@ fn find_updates(app_list: &Vec<LocalFoundApp>) -> Vec<OnlineFoundApp> {
}
/* FILE BROWSER */
fn list_installed_adobe_programs() -> Vec<LocalFoundApp> {
fn find_local_programs(path: &PathBuf) -> Vec<LocalFoundApp> {
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();
@ -164,8 +240,8 @@ fn list_installed_adobe_programs() -> Vec<LocalFoundApp> {
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;
@ -188,7 +264,7 @@ fn list_installed_adobe_programs() -> Vec<LocalFoundApp> {
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);