From 6d1a82b27c476a1988d7fa6b99ba022ea34bbbca Mon Sep 17 00:00:00 2001 From: Dylan Sinnott Date: Mon, 24 Jul 2023 13:43:59 +0800 Subject: [PATCH 1/8] Add ability to trash files using the update api --- src/files.rs | 4 ++ src/files/trash.rs | 129 +++++++++++++++++++++++++++++++++++++ src/files/untrash.rs | 148 +++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 29 +++++++++ 4 files changed, 310 insertions(+) create mode 100644 src/files/trash.rs create mode 100644 src/files/untrash.rs diff --git a/src/files.rs b/src/files.rs index 89c968b..4eb80b1 100644 --- a/src/files.rs +++ b/src/files.rs @@ -1,5 +1,7 @@ pub mod copy; pub mod delete; +pub mod trash; +pub mod untrash; pub mod download; pub mod export; pub mod generate_ids; @@ -14,6 +16,8 @@ pub mod upload; pub use copy::copy; pub use delete::delete; +pub use trash::trash; +pub use untrash::untrash; pub use download::download; pub use export::export; pub use generate_ids::generate_ids; diff --git a/src/files/trash.rs b/src/files/trash.rs new file mode 100644 index 0000000..87b17d2 --- /dev/null +++ b/src/files/trash.rs @@ -0,0 +1,129 @@ +use crate::common::delegate::BackoffConfig; +use crate::common::delegate::ChunkSize; +use crate::common::delegate::UploadDelegate; +use crate::common::delegate::UploadDelegateConfig; +use crate::common::file_info; +use crate::common::file_info::FileInfo; +use crate::common::file_helper; +use crate::common::hub_helper; +use crate::files; +use crate::files::info; +use crate::files::info::DisplayConfig; +use crate::hub::Hub; +use mime::Mime; +use std::error; +use std::fmt::Display; +use std::fmt::Formatter; +use std::io; +use std::path::PathBuf; +use std::time::Duration; + +pub struct Config { + pub file_id: String +} + +pub async fn trash(config: Config) -> Result<(), Error> { + let hub = hub_helper::get_hub().await.map_err(Error::Hub)?; + + let exists = info::get_file(&hub, &config.file_id) + .await + .map_err(Error::GetFile)?; + + if exists.trashed.is_some_and(|trashed| trashed == true) { + println!("File is already trashed, exiting"); + return Ok(()); + } + + println!( + "Trashing {}", + config.file_id + ); + + trash_file(&hub, &config.file_id) + .await + .map_err(Error::Update)?; + + println!("File successfully updated"); + + Ok(()) +} + +pub async fn trash_file( + hub: &Hub, + file_id: &str +) -> Result<(), google_drive3::Error> +{ + let dst_file = google_drive3::api::File { + trashed: Some(true), + ..google_drive3::api::File::default() + }; + + let req = hub + .files() + .update(dst_file, &file_id) + .param("fields", "id,name,size,createdTime,modifiedTime,md5Checksum,mimeType,parents,shared,description,webContentLink,webViewLink") + .add_scope(google_drive3::api::Scope::Full) + .supports_all_drives(true); + + req.doit_without_upload().await?; + + Ok(()) +} + +#[derive(Debug)] +pub enum Error { + Hub(hub_helper::Error), + FileInfo(file_info::Error), + OpenFile(PathBuf, io::Error), + GetFile(google_drive3::Error), + Update(google_drive3::Error), +} + +impl error::Error for Error {} + +impl Display for Error { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Error::Hub(err) => write!(f, "{}", err), + Error::FileInfo(err) => write!(f, "{}", err), + Error::OpenFile(path, err) => { + write!(f, "Failed to open file '{}': {}", path.display(), err) + } + Error::GetFile(err) => write!(f, "Failed to get file: {}", err), + Error::Update(err) => write!(f, "Failed to update file: {}", err), + } + } +} + +#[derive(Debug, Clone)] +pub struct PatchFile { + id: String, + file: google_drive3::api::File, +} + +impl PatchFile { + pub fn new(id: String) -> Self { + Self { + id, + file: google_drive3::api::File::default(), + } + } + + pub fn with_name(&self, name: &str) -> Self { + Self { + file: google_drive3::api::File { + name: Some(name.to_string()), + ..self.file.clone() + }, + ..self.clone() + } + } + + pub fn id(&self) -> String { + self.id.clone() + } + + pub fn file(&self) -> google_drive3::api::File { + self.file.clone() + } +} diff --git a/src/files/untrash.rs b/src/files/untrash.rs new file mode 100644 index 0000000..f57809a --- /dev/null +++ b/src/files/untrash.rs @@ -0,0 +1,148 @@ +use crate::common::delegate::BackoffConfig; +use crate::common::delegate::ChunkSize; +use crate::common::delegate::UploadDelegate; +use crate::common::delegate::UploadDelegateConfig; +use crate::common::file_info; +use crate::common::file_info::FileInfo; +use crate::common::file_helper; +use crate::common::hub_helper; +use crate::files; +use crate::files::info; +use crate::files::info::DisplayConfig; +use crate::hub::Hub; +use mime::Mime; +use std::error; +use std::fmt::Display; +use std::fmt::Formatter; +use std::io; +use std::path::PathBuf; +use std::time::Duration; + +pub struct Config { + pub file_id: String, +} + +pub async fn untrash(config: Config) -> Result<(), Error> { + let hub = hub_helper::get_hub().await.map_err(Error::Hub)?; + + let exists = info::get_file(&hub, &config.file_id) + .await + .map_err(Error::GetFile)?; + + if exists.trashed.is_some_and(|trashed| trashed == false) || exists.trashed.is_none() { + println!("File is not trashed, exiting"); + return Ok(()); + } + + println!( + "Untrashing {}", + config.file_id + ); + + untrash_file(&hub, &config.file_id) + .await + .map_err(Error::Update)?; + + println!("File successfully updated"); + + Ok(()) +} + +pub async fn untrash_file( + hub: &Hub, + file_id: &str +) -> Result<(), google_drive3::Error> +{ + let dst_file = google_drive3::api::File { + trashed: Some(false), + ..google_drive3::api::File::default() + }; + + let req = hub + .files() + .update(dst_file, &file_id) + .param("fields", "id,name,size,createdTime,modifiedTime,md5Checksum,mimeType,parents,shared,description,webContentLink,webViewLink") + .add_scope(google_drive3::api::Scope::Full) + .supports_all_drives(true); + + req.doit_without_upload().await?; + + Ok(()) +} + +pub async fn update_metadata( + hub: &Hub, + delegate_config: UploadDelegateConfig, + patch_file: PatchFile, +) -> Result { + let mut delegate = UploadDelegate::new(delegate_config); + + let (_, file) = hub + .files() + .update(patch_file.file, &patch_file.id) + .param("fields", "id,name,size,createdTime,modifiedTime,md5Checksum,mimeType,parents,shared,description,webContentLink,webViewLink") + .add_scope(google_drive3::api::Scope::Full) + .delegate(&mut delegate) + .supports_all_drives(true) + .doit_without_upload().await?; + + Ok(file) +} + +#[derive(Debug)] +pub enum Error { + Hub(hub_helper::Error), + FileInfo(file_info::Error), + OpenFile(PathBuf, io::Error), + GetFile(google_drive3::Error), + Update(google_drive3::Error), +} + +impl error::Error for Error {} + +impl Display for Error { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Error::Hub(err) => write!(f, "{}", err), + Error::FileInfo(err) => write!(f, "{}", err), + Error::OpenFile(path, err) => { + write!(f, "Failed to open file '{}': {}", path.display(), err) + } + Error::GetFile(err) => write!(f, "Failed to get file: {}", err), + Error::Update(err) => write!(f, "Failed to update file: {}", err), + } + } +} + +#[derive(Debug, Clone)] +pub struct PatchFile { + id: String, + file: google_drive3::api::File, +} + +impl PatchFile { + pub fn new(id: String) -> Self { + Self { + id, + file: google_drive3::api::File::default(), + } + } + + pub fn with_name(&self, name: &str) -> Self { + Self { + file: google_drive3::api::File { + name: Some(name.to_string()), + ..self.file.clone() + }, + ..self.clone() + } + } + + pub fn id(&self) -> String { + self.id.clone() + } + + pub fn file(&self) -> google_drive3::api::File { + self.file.clone() + } +} diff --git a/src/main.rs b/src/main.rs index b309066..0f156d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -248,6 +248,18 @@ enum FileCommand { #[arg(long)] recursive: bool, }, + + /// Trash file + Trash { + /// File id + file_id: String, + }, + + /// Untrash file + Untrash { + /// File id + file_id: String, + }, /// Create directory Mkdir { @@ -579,6 +591,23 @@ async fn main() { .await .unwrap_or_else(handle_error) } + FileCommand::Trash { file_id } => { + // fmt + files::trash(files::trash::Config { + file_id + }) + .await + .unwrap_or_else(handle_error) + } + + FileCommand::Untrash { file_id } => { + // fmt + files::untrash(files::untrash::Config { + file_id + }) + .await + .unwrap_or_else(handle_error) + } FileCommand::Mkdir { name, From 122a647f07f4f6ecd98346d9489c3ee441798f23 Mon Sep 17 00:00:00 2001 From: Dylan Sinnott Date: Mon, 24 Jul 2023 13:49:32 +0800 Subject: [PATCH 2/8] Rustfmt and cargo fix --- src/common/file_helper.rs | 6 +++--- src/common/mod.rs | 2 +- src/files.rs | 8 ++++---- src/files/trash.rs | 27 +++++---------------------- src/files/untrash.rs | 21 +++------------------ src/main.rs | 22 +++++++++------------- 6 files changed, 25 insertions(+), 61 deletions(-) diff --git a/src/common/file_helper.rs b/src/common/file_helper.rs index 259283a..15d38df 100644 --- a/src/common/file_helper.rs +++ b/src/common/file_helper.rs @@ -1,7 +1,7 @@ -use std::io; +use mktemp::Temp; use std::fs::File; +use std::io; use std::path::PathBuf; -use mktemp::Temp; pub fn stdin_to_file() -> Result { let tmp_file = Temp::new_file()?; @@ -16,7 +16,7 @@ pub fn open_file(path: &Option) -> Result<(File, PathBuf), io::Error> { Some(path) => { let file = File::open(path)?; Ok((file, path.clone())) - }, + } None => { let tmp_file = stdin_to_file()?; let path = tmp_file.as_ref().to_path_buf(); diff --git a/src/common/mod.rs b/src/common/mod.rs index 41a8fc8..1fdb131 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -2,6 +2,7 @@ pub mod account_archive; pub mod delegate; pub mod drive_file; pub mod empty_file; +pub mod file_helper; pub mod file_info; pub mod file_tree; pub mod file_tree_drive; @@ -10,4 +11,3 @@ pub mod id_gen; pub mod md5_writer; pub mod permission; pub mod table; -pub mod file_helper; diff --git a/src/files.rs b/src/files.rs index 4eb80b1..230262a 100644 --- a/src/files.rs +++ b/src/files.rs @@ -1,7 +1,5 @@ pub mod copy; pub mod delete; -pub mod trash; -pub mod untrash; pub mod download; pub mod export; pub mod generate_ids; @@ -11,13 +9,13 @@ pub mod list; pub mod mkdir; pub mod mv; pub mod rename; +pub mod trash; +pub mod untrash; pub mod update; pub mod upload; pub use copy::copy; pub use delete::delete; -pub use trash::trash; -pub use untrash::untrash; pub use download::download; pub use export::export; pub use generate_ids::generate_ids; @@ -27,5 +25,7 @@ pub use list::list; pub use mkdir::mkdir; pub use mv::mv; pub use rename::rename; +pub use trash::trash; +pub use untrash::untrash; pub use update::update; pub use upload::upload; diff --git a/src/files/trash.rs b/src/files/trash.rs index 87b17d2..8889496 100644 --- a/src/files/trash.rs +++ b/src/files/trash.rs @@ -1,25 +1,15 @@ -use crate::common::delegate::BackoffConfig; -use crate::common::delegate::ChunkSize; -use crate::common::delegate::UploadDelegate; -use crate::common::delegate::UploadDelegateConfig; use crate::common::file_info; -use crate::common::file_info::FileInfo; -use crate::common::file_helper; use crate::common::hub_helper; -use crate::files; use crate::files::info; -use crate::files::info::DisplayConfig; use crate::hub::Hub; -use mime::Mime; use std::error; use std::fmt::Display; use std::fmt::Formatter; use std::io; use std::path::PathBuf; -use std::time::Duration; pub struct Config { - pub file_id: String + pub file_id: String, } pub async fn trash(config: Config) -> Result<(), Error> { @@ -33,11 +23,8 @@ pub async fn trash(config: Config) -> Result<(), Error> { println!("File is already trashed, exiting"); return Ok(()); } - - println!( - "Trashing {}", - config.file_id - ); + + println!("Trashing {}", config.file_id); trash_file(&hub, &config.file_id) .await @@ -48,11 +35,7 @@ pub async fn trash(config: Config) -> Result<(), Error> { Ok(()) } -pub async fn trash_file( - hub: &Hub, - file_id: &str -) -> Result<(), google_drive3::Error> -{ +pub async fn trash_file(hub: &Hub, file_id: &str) -> Result<(), google_drive3::Error> { let dst_file = google_drive3::api::File { trashed: Some(true), ..google_drive3::api::File::default() @@ -66,7 +49,7 @@ pub async fn trash_file( .supports_all_drives(true); req.doit_without_upload().await?; - + Ok(()) } diff --git a/src/files/untrash.rs b/src/files/untrash.rs index f57809a..fd16dac 100644 --- a/src/files/untrash.rs +++ b/src/files/untrash.rs @@ -1,22 +1,14 @@ -use crate::common::delegate::BackoffConfig; -use crate::common::delegate::ChunkSize; use crate::common::delegate::UploadDelegate; use crate::common::delegate::UploadDelegateConfig; use crate::common::file_info; -use crate::common::file_info::FileInfo; -use crate::common::file_helper; use crate::common::hub_helper; -use crate::files; use crate::files::info; -use crate::files::info::DisplayConfig; use crate::hub::Hub; -use mime::Mime; use std::error; use std::fmt::Display; use std::fmt::Formatter; use std::io; use std::path::PathBuf; -use std::time::Duration; pub struct Config { pub file_id: String, @@ -33,11 +25,8 @@ pub async fn untrash(config: Config) -> Result<(), Error> { println!("File is not trashed, exiting"); return Ok(()); } - - println!( - "Untrashing {}", - config.file_id - ); + + println!("Untrashing {}", config.file_id); untrash_file(&hub, &config.file_id) .await @@ -48,11 +37,7 @@ pub async fn untrash(config: Config) -> Result<(), Error> { Ok(()) } -pub async fn untrash_file( - hub: &Hub, - file_id: &str -) -> Result<(), google_drive3::Error> -{ +pub async fn untrash_file(hub: &Hub, file_id: &str) -> Result<(), google_drive3::Error> { let dst_file = google_drive3::api::File { trashed: Some(false), ..google_drive3::api::File::default() diff --git a/src/main.rs b/src/main.rs index 0f156d5..5cd81be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -248,13 +248,13 @@ enum FileCommand { #[arg(long)] recursive: bool, }, - + /// Trash file Trash { /// File id file_id: String, }, - + /// Untrash file Untrash { /// File id @@ -593,20 +593,16 @@ async fn main() { } FileCommand::Trash { file_id } => { // fmt - files::trash(files::trash::Config { - file_id - }) - .await - .unwrap_or_else(handle_error) + files::trash(files::trash::Config { file_id }) + .await + .unwrap_or_else(handle_error) } - + FileCommand::Untrash { file_id } => { // fmt - files::untrash(files::untrash::Config { - file_id - }) - .await - .unwrap_or_else(handle_error) + files::untrash(files::untrash::Config { file_id }) + .await + .unwrap_or_else(handle_error) } FileCommand::Mkdir { From 9aad96a831a15ded8efb0763d56e9e9bbf1d3c48 Mon Sep 17 00:00:00 2001 From: Dylan Sinnott Date: Mon, 24 Jul 2023 14:02:13 +0800 Subject: [PATCH 3/8] Add skip trashed option to files->list --- src/files/list.rs | 7 +++++++ src/main.rs | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/src/files/list.rs b/src/files/list.rs index aaa1c28..8646b68 100644 --- a/src/files/list.rs +++ b/src/files/list.rs @@ -22,6 +22,7 @@ pub struct Config { pub skip_header: bool, pub truncate_name: bool, pub field_separator: String, + pub skip_trashed: bool, } pub async fn list(config: Config) -> Result<(), Error> { @@ -42,6 +43,12 @@ pub async fn list(config: Config) -> Result<(), Error> { let file_type = simplified_file_type(&file); let file_name = format_file_name(&config, &file); + if config.skip_trashed{ + if file.trashed.is_some_and(|trashed| trashed == true){ + continue; + } + } + values.push([ file.id.unwrap_or_default(), file_name, diff --git a/src/main.rs b/src/main.rs index 5cd81be..28d8a84 100644 --- a/src/main.rs +++ b/src/main.rs @@ -152,6 +152,10 @@ enum FileCommand { /// Field separator #[arg(long, default_value_t = String::from("\t"))] field_separator: String, + + /// Skip trashed files + #[arg(long)] + skip_trashed: bool, }, /// Download file @@ -483,6 +487,7 @@ async fn main() { skip_header, full_name, field_separator, + skip_trashed, } => { let parent_query = parent.map(|folder_id| ListQuery::FilesInFolder { folder_id }); @@ -498,6 +503,7 @@ async fn main() { skip_header, truncate_name: !full_name, field_separator, + skip_trashed, }) .await .unwrap_or_else(handle_error) From 509cdec29eb8caeb3dcf8d25211fe0c19217c399 Mon Sep 17 00:00:00 2001 From: Dylan Sinnott Date: Mon, 24 Jul 2023 15:31:45 +0800 Subject: [PATCH 4/8] Remove unused Error states from trash and untrash, fix untrash functionality around checking state. --- src/files/info.rs | 2 +- src/files/trash.rs | 11 +---------- src/files/untrash.rs | 32 +------------------------------- 3 files changed, 3 insertions(+), 42 deletions(-) diff --git a/src/files/info.rs b/src/files/info.rs index 7be77a2..9ce8e64 100644 --- a/src/files/info.rs +++ b/src/files/info.rs @@ -39,7 +39,7 @@ pub async fn get_file( let (_, file) = hub .files() .get(file_id) - .param("fields", "id,name,size,createdTime,modifiedTime,md5Checksum,mimeType,parents,shared,description,webContentLink,webViewLink,shortcutDetails(targetId,targetMimeType)") + .param("fields", "id,name,size,createdTime,modifiedTime,md5Checksum,mimeType,parents,shared,description,webContentLink,webViewLink,shortcutDetails(targetId,targetMimeType),trashed,trashedTime") .supports_all_drives(true) .add_scope(google_drive3::api::Scope::Full) .doit() diff --git a/src/files/trash.rs b/src/files/trash.rs index 8889496..83f516c 100644 --- a/src/files/trash.rs +++ b/src/files/trash.rs @@ -1,12 +1,9 @@ -use crate::common::file_info; use crate::common::hub_helper; use crate::files::info; use crate::hub::Hub; use std::error; use std::fmt::Display; use std::fmt::Formatter; -use std::io; -use std::path::PathBuf; pub struct Config { pub file_id: String, @@ -56,8 +53,6 @@ pub async fn trash_file(hub: &Hub, file_id: &str) -> Result<(), google_drive3::E #[derive(Debug)] pub enum Error { Hub(hub_helper::Error), - FileInfo(file_info::Error), - OpenFile(PathBuf, io::Error), GetFile(google_drive3::Error), Update(google_drive3::Error), } @@ -68,12 +63,8 @@ impl Display for Error { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { Error::Hub(err) => write!(f, "{}", err), - Error::FileInfo(err) => write!(f, "{}", err), - Error::OpenFile(path, err) => { - write!(f, "Failed to open file '{}': {}", path.display(), err) - } Error::GetFile(err) => write!(f, "Failed to get file: {}", err), - Error::Update(err) => write!(f, "Failed to update file: {}", err), + Error::Update(err) => write!(f, "Failed to trash file: {}", err), } } } diff --git a/src/files/untrash.rs b/src/files/untrash.rs index fd16dac..95f774c 100644 --- a/src/files/untrash.rs +++ b/src/files/untrash.rs @@ -1,14 +1,9 @@ -use crate::common::delegate::UploadDelegate; -use crate::common::delegate::UploadDelegateConfig; -use crate::common::file_info; use crate::common::hub_helper; use crate::files::info; use crate::hub::Hub; use std::error; use std::fmt::Display; use std::fmt::Formatter; -use std::io; -use std::path::PathBuf; pub struct Config { pub file_id: String, @@ -21,7 +16,7 @@ pub async fn untrash(config: Config) -> Result<(), Error> { .await .map_err(Error::GetFile)?; - if exists.trashed.is_some_and(|trashed| trashed == false) || exists.trashed.is_none() { + if exists.trashed.is_some_and(|trashed| trashed == false) { println!("File is not trashed, exiting"); return Ok(()); } @@ -55,30 +50,9 @@ pub async fn untrash_file(hub: &Hub, file_id: &str) -> Result<(), google_drive3: Ok(()) } -pub async fn update_metadata( - hub: &Hub, - delegate_config: UploadDelegateConfig, - patch_file: PatchFile, -) -> Result { - let mut delegate = UploadDelegate::new(delegate_config); - - let (_, file) = hub - .files() - .update(patch_file.file, &patch_file.id) - .param("fields", "id,name,size,createdTime,modifiedTime,md5Checksum,mimeType,parents,shared,description,webContentLink,webViewLink") - .add_scope(google_drive3::api::Scope::Full) - .delegate(&mut delegate) - .supports_all_drives(true) - .doit_without_upload().await?; - - Ok(file) -} - #[derive(Debug)] pub enum Error { Hub(hub_helper::Error), - FileInfo(file_info::Error), - OpenFile(PathBuf, io::Error), GetFile(google_drive3::Error), Update(google_drive3::Error), } @@ -89,10 +63,6 @@ impl Display for Error { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { Error::Hub(err) => write!(f, "{}", err), - Error::FileInfo(err) => write!(f, "{}", err), - Error::OpenFile(path, err) => { - write!(f, "Failed to open file '{}': {}", path.display(), err) - } Error::GetFile(err) => write!(f, "Failed to get file: {}", err), Error::Update(err) => write!(f, "Failed to update file: {}", err), } From 56d81984c0f2dd519667c02f8539af0e7e8aef0d Mon Sep 17 00:00:00 2001 From: Dylan Sinnott Date: Mon, 24 Jul 2023 15:32:21 +0800 Subject: [PATCH 5/8] Display trashed info for files, but hide trashing info otherwise. --- src/files/info.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/files/info.rs b/src/files/info.rs index 9ce8e64..8bc5352 100644 --- a/src/files/info.rs +++ b/src/files/info.rs @@ -108,6 +108,18 @@ pub fn prepare_fields(file: &google_drive3::api::File, config: &DisplayConfig) - name: String::from("ViewUrl"), value: file.web_view_link.clone(), }, + Field { + name: String::from("Trashed"), + value: if file.trashed.is_some() && file.trashed.unwrap() {Some(format_bool(file.trashed.unwrap()))} else {None}, + }, + Field { + name: String::from("TrashedTime"), + value: file.trashed_time.map(format_date_time), + }, + Field { + name: String::from("TrashingUser"), + value: file.trashing_user.clone().map(|user| user.display_name.unwrap_or_default()), + }, ] } From b495f0e2c37d0ebaff88b7570b4a467dea286194 Mon Sep 17 00:00:00 2001 From: Dylan Sinnott Date: Tue, 25 Jul 2023 11:49:34 +0800 Subject: [PATCH 6/8] Restrict directory trashing/untrashing to happen on recurse only. --- src/files/trash.rs | 24 +++++++++++++++++++++++- src/files/untrash.rs | 24 +++++++++++++++++++++++- src/main.rs | 22 ++++++++++++++++++---- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/src/files/trash.rs b/src/files/trash.rs index 83f516c..69f168d 100644 --- a/src/files/trash.rs +++ b/src/files/trash.rs @@ -1,4 +1,4 @@ -use crate::common::hub_helper; +use crate::common::{drive_file, hub_helper}; use crate::files::info; use crate::hub::Hub; use std::error; @@ -7,6 +7,7 @@ use std::fmt::Formatter; pub struct Config { pub file_id: String, + pub trash_directories: bool, } pub async fn trash(config: Config) -> Result<(), Error> { @@ -16,6 +17,8 @@ pub async fn trash(config: Config) -> Result<(), Error> { .await .map_err(Error::GetFile)?; + err_if_directory(&exists, &config)?; + if exists.trashed.is_some_and(|trashed| trashed == true) { println!("File is already trashed, exiting"); return Ok(()); @@ -55,6 +58,7 @@ pub enum Error { Hub(hub_helper::Error), GetFile(google_drive3::Error), Update(google_drive3::Error), + IsDirectory(String), } impl error::Error for Error {} @@ -65,6 +69,11 @@ impl Display for Error { Error::Hub(err) => write!(f, "{}", err), Error::GetFile(err) => write!(f, "Failed to get file: {}", err), Error::Update(err) => write!(f, "Failed to trash file: {}", err), + Error::IsDirectory(f) => write!( + f, + "'{}' is a directory, use --recursive to trash directories", + name + ), } } } @@ -101,3 +110,16 @@ impl PatchFile { self.file.clone() } } + +fn err_if_directory(file: &google_drive3::api::File, config: &Config) -> Result<(), Error> { + if drive_file::is_directory(file) && !config.trash_directories { + let name = file + .name + .as_ref() + .map(|s| s.to_string()) + .unwrap_or_default(); + Err(Error::IsDirectory(name)) + } else { + Ok(()) + } +} \ No newline at end of file diff --git a/src/files/untrash.rs b/src/files/untrash.rs index 95f774c..f9f74e1 100644 --- a/src/files/untrash.rs +++ b/src/files/untrash.rs @@ -1,4 +1,4 @@ -use crate::common::hub_helper; +use crate::common::{drive_file, hub_helper}; use crate::files::info; use crate::hub::Hub; use std::error; @@ -7,6 +7,7 @@ use std::fmt::Formatter; pub struct Config { pub file_id: String, + pub untrash_directories: bool, } pub async fn untrash(config: Config) -> Result<(), Error> { @@ -16,6 +17,8 @@ pub async fn untrash(config: Config) -> Result<(), Error> { .await .map_err(Error::GetFile)?; + err_if_directory(&exists, &config)?; + if exists.trashed.is_some_and(|trashed| trashed == false) { println!("File is not trashed, exiting"); return Ok(()); @@ -55,6 +58,7 @@ pub enum Error { Hub(hub_helper::Error), GetFile(google_drive3::Error), Update(google_drive3::Error), + IsDirectory(String), } impl error::Error for Error {} @@ -65,6 +69,11 @@ impl Display for Error { Error::Hub(err) => write!(f, "{}", err), Error::GetFile(err) => write!(f, "Failed to get file: {}", err), Error::Update(err) => write!(f, "Failed to update file: {}", err), + Error::IsDirectory(f) => write!( + f, + "'{}' is a directory, use --recursive to trash directories", + name + ), } } } @@ -101,3 +110,16 @@ impl PatchFile { self.file.clone() } } + +fn err_if_directory(file: &google_drive3::api::File, config: &Config) -> Result<(), Error> { + if drive_file::is_directory(file) && !config.trash_directories { + let name = file + .name + .as_ref() + .map(|s| s.to_string()) + .unwrap_or_default(); + Err(Error::IsDirectory(name)) + } else { + Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs index 28d8a84..62e21e4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -257,12 +257,20 @@ enum FileCommand { Trash { /// File id file_id: String, + + /// Trash directory and all it's content + #[arg(long)] + recursive: bool, }, /// Untrash file Untrash { /// File id file_id: String, + + /// Untrash directory and all it's content + #[arg(long)] + recursive: bool, }, /// Create directory @@ -597,16 +605,22 @@ async fn main() { .await .unwrap_or_else(handle_error) } - FileCommand::Trash { file_id } => { + FileCommand::Trash { file_id, recursive } => { // fmt - files::trash(files::trash::Config { file_id }) + files::trash(files::trash::Config { + file_id, + trash_directories: recursive, + }) .await .unwrap_or_else(handle_error) } - FileCommand::Untrash { file_id } => { + FileCommand::Untrash { file_id, recursive } => { // fmt - files::untrash(files::untrash::Config { file_id }) + files::untrash(files::untrash::Config { + file_id, + untrash_directories: recursive + }) .await .unwrap_or_else(handle_error) } From 50e97ef9c5fc7a3b05bac360485f58b22abe9212 Mon Sep 17 00:00:00 2001 From: Dylan Sinnott Date: Wed, 26 Jul 2023 17:21:07 +0800 Subject: [PATCH 7/8] Fix obvious typos --- src/files/trash.rs | 2 +- src/files/untrash.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/files/trash.rs b/src/files/trash.rs index 69f168d..58a0f6d 100644 --- a/src/files/trash.rs +++ b/src/files/trash.rs @@ -69,7 +69,7 @@ impl Display for Error { Error::Hub(err) => write!(f, "{}", err), Error::GetFile(err) => write!(f, "Failed to get file: {}", err), Error::Update(err) => write!(f, "Failed to trash file: {}", err), - Error::IsDirectory(f) => write!( + Error::IsDirectory(name) => write!( f, "'{}' is a directory, use --recursive to trash directories", name diff --git a/src/files/untrash.rs b/src/files/untrash.rs index f9f74e1..427ab7e 100644 --- a/src/files/untrash.rs +++ b/src/files/untrash.rs @@ -69,7 +69,7 @@ impl Display for Error { Error::Hub(err) => write!(f, "{}", err), Error::GetFile(err) => write!(f, "Failed to get file: {}", err), Error::Update(err) => write!(f, "Failed to update file: {}", err), - Error::IsDirectory(f) => write!( + Error::IsDirectory(name) => write!( f, "'{}' is a directory, use --recursive to trash directories", name @@ -112,7 +112,7 @@ impl PatchFile { } fn err_if_directory(file: &google_drive3::api::File, config: &Config) -> Result<(), Error> { - if drive_file::is_directory(file) && !config.trash_directories { + if drive_file::is_directory(file) && !config.untrash_directories { let name = file .name .as_ref() From 556caf81e71375e61ccb6f4ea882e7b9012a9c6a Mon Sep 17 00:00:00 2001 From: Dylan Sinnott Date: Thu, 19 Sep 2024 11:03:47 +0800 Subject: [PATCH 8/8] Increase proc-macro2 version to one that works --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 730eae8..f69e4e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -971,9 +971,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ]