From 72101ca296bbbdd70a46aa9f0b05e6272b1088dd Mon Sep 17 00:00:00 2001 From: Francesco Pio Gaglione Date: Sat, 28 Sep 2024 17:08:08 +0200 Subject: [PATCH 1/4] run AppImage files from cosmic-files --- src/app.rs | 65 ++++++++++++++++++++++++++++++++++--------------- src/mime_app.rs | 1 + 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/src/app.rs b/src/app.rs index e47c5fd..795b1da 100644 --- a/src/app.rs +++ b/src/app.rs @@ -41,15 +41,7 @@ use notify_debouncer_full::{ }; use slotmap::Key as SlotMapKey; use std::{ - any::TypeId, - collections::{BTreeMap, HashMap, HashSet, VecDeque}, - env, fmt, fs, - future::pending, - num::NonZeroU16, - path::PathBuf, - process, - sync::{Arc, Mutex}, - time::{self, Instant}, + any::TypeId, collections::{BTreeMap, HashMap, HashSet, VecDeque}, env, ffi::OsStr, fmt, fs, future::pending, io::{BufRead, BufReader}, num::NonZeroU16, os::unix::fs::PermissionsExt, path::PathBuf, process, sync::{Arc, Mutex}, time::{self, Instant} }; use tokio::sync::mpsc; use trash::TrashItem; @@ -2350,18 +2342,51 @@ impl Application for App { }; } if !found_desktop_exec { - match open::that_detached(&path) { - Ok(()) => { - let _ = recently_used_xbel::update_recently_used( - &path, - App::APP_ID.to_string(), - "cosmic-files".to_string(), - None, - ); - } - Err(err) => { - log::warn!("failed to open {:?}: {}", path, err); + let file_extension = path.extension(); + match file_extension { + Some(ext) if ext == OsStr::new("AppImage") => { + // Set the executable permission to the file + let mut perms = fs::metadata(&path) + .expect("Failed to get metadata") + .permissions(); + // Set the executable permission to the file + perms.set_mode(0o755); + fs::set_permissions(&path, perms).expect("Failed to set permissions"); + + log::info!("running app: {:?}", ext); + let cmd = std::process::Command::new(path).spawn(); + match cmd { + Ok(mut res) => { + if let Some(stderr) = res.stderr.take() { + let reader = BufReader::new(stderr); + for line in reader.lines() { + if let Ok(line) = line { + log::error!( + "running app error: {}", + line + ); + } + } + } + } + Err(error) => { + log::error!("error: {:?}", error); + } + } } + _ => match open::that_detached(&path) { + Ok(()) => { + let _ = recently_used_xbel::update_recently_used( + &path, + App::APP_ID.to_string(), + "cosmic-files".to_string(), + None, + ); + } + Err(err) => { + log::warn!("failed to open {:?}: {}", path, err); + } + }, } } } diff --git a/src/mime_app.rs b/src/mime_app.rs index 268152f..b604658 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -31,6 +31,7 @@ pub fn exec_to_command(exec: &str, path_opt: Option) -> Option Date: Sat, 28 Sep 2024 17:10:39 +0200 Subject: [PATCH 2/4] removed log --- src/mime_app.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mime_app.rs b/src/mime_app.rs index b604658..268152f 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -31,7 +31,6 @@ pub fn exec_to_command(exec: &str, path_opt: Option) -> Option Date: Sat, 28 Sep 2024 22:32:25 +0200 Subject: [PATCH 3/4] removed std err pipe --- src/app.rs | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/app.rs b/src/app.rs index 795b1da..5bf7daa 100644 --- a/src/app.rs +++ b/src/app.rs @@ -41,7 +41,19 @@ use notify_debouncer_full::{ }; use slotmap::Key as SlotMapKey; use std::{ - any::TypeId, collections::{BTreeMap, HashMap, HashSet, VecDeque}, env, ffi::OsStr, fmt, fs, future::pending, io::{BufRead, BufReader}, num::NonZeroU16, os::unix::fs::PermissionsExt, path::PathBuf, process, sync::{Arc, Mutex}, time::{self, Instant} + any::TypeId, + collections::{BTreeMap, HashMap, HashSet, VecDeque}, + env, + ffi::OsStr, + fmt, fs, + future::pending, + io::{BufRead, BufReader}, + num::NonZeroU16, + os::unix::fs::PermissionsExt, + path::PathBuf, + process, + sync::{Arc, Mutex}, + time::{self, Instant}, }; use tokio::sync::mpsc; use trash::TrashItem; @@ -2351,28 +2363,11 @@ impl Application for App { .permissions(); // Set the executable permission to the file perms.set_mode(0o755); - fs::set_permissions(&path, perms).expect("Failed to set permissions"); + fs::set_permissions(&path, perms) + .expect("Failed to set permissions"); log::info!("running app: {:?}", ext); - let cmd = std::process::Command::new(path).spawn(); - match cmd { - Ok(mut res) => { - if let Some(stderr) = res.stderr.take() { - let reader = BufReader::new(stderr); - for line in reader.lines() { - if let Ok(line) = line { - log::error!( - "running app error: {}", - line - ); - } - } - } - } - Err(error) => { - log::error!("error: {:?}", error); - } - } + let _ = std::process::Command::new(path).spawn(); } _ => match open::that_detached(&path) { Ok(()) => { From 54e9be645961ea9838f809aaf3d8cef533c5d5ee Mon Sep 17 00:00:00 2001 From: Francesco Pio Gaglione Date: Thu, 3 Oct 2024 18:23:50 +0200 Subject: [PATCH 4/4] permission dialog --- i18n/en/cosmic_files.ftl | 5 ++++ src/app.rs | 55 +++++++++++++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index e7579d1..e0f403b 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -66,6 +66,11 @@ apply-to-all = Apply to all keep-both = Keep both skip = Skip +## Execution permission Dialog +add-permission-title = Add execution permission +add-permission-control = Add execution permission to {$path} +add-permission = Add permission + ## Metadata Dialog owner = Owner group = Group diff --git a/src/app.rs b/src/app.rs index 5bf7daa..45b42c8 100644 --- a/src/app.rs +++ b/src/app.rs @@ -256,6 +256,7 @@ impl MenuAction for NavMenuAction { pub enum Message { AddToSidebar(Option), AppTheme(AppTheme), + AddExecutablePermission(PathBuf), CloseToast(widget::ToastId), Compress(Option), Config(Config), @@ -416,6 +417,10 @@ pub enum DialogPage { name: String, dir: bool, }, + AddExecutablePermission { + file_path: PathBuf, + run: bool, + }, Replace { from: tab::Item, to: tab::Item, @@ -1546,12 +1551,31 @@ impl Application for App { let to = parent.join(name); self.operation(Operation::Rename { from, to }); } + DialogPage::AddExecutablePermission { file_path, run } => { + let mut perms = fs::metadata(&file_path) + .expect("Failed to get metadata") + .permissions(); + + let current_mode = perms.mode(); + let new_mode = current_mode | 0o100; + perms.set_mode(new_mode); + fs::set_permissions(&file_path, perms) + .expect("Failed to set permissions"); + + if run { + log::info!("running app: {:?}", file_path); + let _ = std::process::Command::new(file_path).spawn(); + } + } DialogPage::Replace { .. } => { log::warn!("replace dialog should be completed with replace result"); } } } } + Message::AddExecutablePermission(file_path) => { + return Command::batch([self.update(Message::AddExecutablePermission(file_path))]); + } Message::DialogPush(dialog_page) => { self.dialog_pages.push_back(dialog_page); } @@ -2357,17 +2381,16 @@ impl Application for App { let file_extension = path.extension(); match file_extension { Some(ext) if ext == OsStr::new("AppImage") => { - // Set the executable permission to the file let mut perms = fs::metadata(&path) .expect("Failed to get metadata") .permissions(); - // Set the executable permission to the file - perms.set_mode(0o755); - fs::set_permissions(&path, perms) - .expect("Failed to set permissions"); - log::info!("running app: {:?}", ext); - let _ = std::process::Command::new(path).spawn(); + self.dialog_pages.push_back( + DialogPage::AddExecutablePermission { + file_path: path.clone(), + run: true, + }, + ); } _ => match open::that_detached(&path) { Ok(()) => { @@ -3109,6 +3132,24 @@ impl Application for App { .spacing(space_xxs), ) } + DialogPage::AddExecutablePermission { file_path, run } => { + let mut dialog = widget::dialog(fl!("add-permission-title")) + .primary_action( + widget::button::text(fl!("add-permission")) + .style(theme::Button::Suggested) + .on_press(Message::DialogComplete), + ) + .secondary_action( + widget::button::text("cancell") + .style(theme::Button::Destructive) + .on_press(Message::DialogCancel), + ) + .control(widget::column().push(widget::text::text(fl!( + "add-permission-control", + path = file_path.as_os_str().to_str() + )))); + dialog + } DialogPage::RenameItem { from, parent,