Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sort button #894

Merged
merged 13 commits into from
Feb 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
369 changes: 204 additions & 165 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ panic = "unwind"
# LTO setting is disabled by default, because release mode is usually needed to develop app and compilation with LTO would take a lot of time
#lto = "fat"

# Optimize all dependencies except application/workspaces
# Optimize all dependencies except application/workspaces, even in debug builds
[profile.dev.package."*"]
opt-level = 3
14 changes: 14 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
## Version 5.1.0 - 19.02.2023r
- Added sort button - [#894](https://github.com/qarmin/czkawka/pull/894)
- Allow to set number of thread used to scan - [#839](https://github.com/qarmin/czkawka/pull/839)
- Faster similar images comparing with reference folders - [#826](https://github.com/qarmin/czkawka/pull/826)
- Update to clap 4 - [#878](https://github.com/qarmin/czkawka/pull/878)
- Use FileChooserNative instead FileChooserDialog - [#894](https://github.com/qarmin/czkawka/pull/894)
- Fix invalid music tags in music files when using reference folders - [#894](https://github.com/qarmin/czkawka/pull/894)
- Updated pdf dependency(a lot of less amount of broken pdf false positives) - [#894](https://github.com/qarmin/czkawka/pull/894)
- Changed strange PDF error message - "Try at" - [#894](https://github.com/qarmin/czkawka/pull/894)
- Treat extensions Mp4 and m4v as identical - [#834](https://github.com/qarmin/czkawka/pull/834)
- Improve thumbnail quality - [#895](https://github.com/qarmin/czkawka/pull/895)
- Verify if hardlinking works, and if not, disable button with proper message - [#881](https://github.com/qarmin/czkawka/pull/881)
- Apply some pydantic clippy lints on project - [#901](https://github.com/qarmin/czkawka/pull/901)

## Version 5.0.2 - 30.08.2022r
- Fixed problem with missing some similar images when using similarity > 0 - [#799](https://github.com/qarmin/czkawka/pull/799)
- Prebuilt Linux binaries are compiled without heif support - [24b](https://github.com/qarmin/czkawka/commit/24b64a32c65904c506b54270f0977ccbe5098cc8)
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Icons used inside GUI version
Reshot license
Reshot license - https://www.reshot.com/

czkawka_gui/icons/*

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
![com github qarmin czkawka](https://user-images.githubusercontent.com/41945903/102616149-66490400-4137-11eb-9cd6-813b2b070834.png)

**Czkawka** (_tch•kav•ka_ (IPA: [ʈ͡ʂkafka]), "hiccup" in Polish) is a simple, fast and free app to remove unnecessary files from your computer.
**Czkawka** (_tch•kav•ka_ (IPA: [ˈʧ̑kafka]), "hiccup" in Polish) is a simple, fast and free app to remove unnecessary files from your computer.

## Features
- Written in memory-safe Rust
Expand Down
10 changes: 5 additions & 5 deletions czkawka_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ hamming = "0.1.3"

# Needed by same music
bitflags = "1.3.2"
lofty = "0.10.0"
lofty = "0.11.0"

# Futures - needed by async progress sender
futures = "0.3.25"
futures = "0.3.26"

# Needed by broken files
zip = { version = "0.6.3", features = ["aes-crypto", "bzip2", "deflate", "time"], default-features = false }
zip = { version = "0.6.4", features = ["aes-crypto", "bzip2", "deflate", "time"], default-features = false }
audio_checker = "0.1.0"
pdf = "0.8.0"

Expand All @@ -56,7 +56,7 @@ serde_json = "1.0"
i18n-embed = { version = "0.13.8", features = ["fluent-system", "desktop-requester"] }
i18n-embed-fl = "0.6.5"
rust-embed = "6.4.2"
once_cell = "1.17.0"
once_cell = "1.17.1"

# Raw image files
rawloader = "0.37.1"
Expand All @@ -69,7 +69,7 @@ infer = "0.12.0"
num_cpus = "1.15.0"

# Heif/Heic
libheif-rs = { version = "0.15.1", optional = true }
libheif-rs = { version = "0.16.0", optional = true }
anyhow = { version = "1.0", optional = true }

state="0.5.3"
Expand Down
4 changes: 2 additions & 2 deletions czkawka_core/src/big_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub enum SearchMode {
SmallestFiles,
}

#[derive(Eq, PartialEq, Clone, Debug)]
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub enum DeleteMethod {
None,
Delete,
Expand Down Expand Up @@ -394,7 +394,7 @@ impl BigFile {
match self.delete_method {
DeleteMethod::Delete => {
for (_, file_entry) in &self.big_files {
if fs::remove_file(file_entry.path.clone()).is_err() {
if fs::remove_file(&file_entry.path).is_err() {
self.text_messages.warnings.push(file_entry.path.display().to_string());
}
}
Expand Down
62 changes: 31 additions & 31 deletions czkawka_core/src/broken_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
use std::{fs, mem, panic, thread};

use crossbeam_channel::Receiver;
use pdf::object::ParseOptions;
use pdf::PdfError;
use pdf::PdfError::Try;
use rayon::prelude::*;
Expand All @@ -33,7 +34,7 @@ pub struct ProgressData {
pub files_to_check: usize,
}

#[derive(Eq, PartialEq, Clone, Debug)]
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub enum DeleteMethod {
None,
Delete,
Expand Down Expand Up @@ -521,41 +522,40 @@ impl BrokenFiles {
Err(_inspected) => Some(None),
},

TypeOfFile::PDF => {
match fs::read(&file_entry.path) {
Ok(content) => {
// Will be available in pdf > 0.7.2
// let parser_options = ParseOptions {
// allow_error_in_option: true,
// allow_xref_error: true,
// allow_invalid_ops: true,
// allow_missing_endobj: true,
// };
// if let Err(e) = pdf::file::File::from_data_with_options(content, parser_options) {

let mut file_entry_clone = file_entry.clone();
let result = panic::catch_unwind(|| {
if let Err(e) = pdf::file::File::from_data(content) {
file_entry.error_string = e.to_string();
let error = unpack_pdf_error(e);
if let PdfError::InvalidPassword = error {
return Some(None);
TypeOfFile::PDF => match fs::read(&file_entry.path) {
Ok(content) => {
let parser_options = ParseOptions::tolerant(); // Only show as broken files with really big bugs

let mut file_entry_clone = file_entry.clone();
let result = panic::catch_unwind(|| {
if let Err(e) = pdf::file::File::from_data_with_options(content, parser_options) {
let mut error_string = e.to_string();
// Workaround for strange error message https://github.com/qarmin/czkawka/issues/898
if error_string.starts_with("Try at") {
if let Some(start_index) = error_string.find("/pdf-") {
error_string = format!("Decoding error in pdf-rs library - {}", &error_string[start_index..]);
}
}
Some(Some(file_entry))
});
if let Ok(pdf_result) = result {
pdf_result
} else {
let message = create_crash_message("PDF-rs", &file_entry_clone.path.to_string_lossy(), "https://github.com/pdf-rs/pdf");
println!("{message}");
file_entry_clone.error_string = message;
Some(Some(file_entry_clone))

file_entry.error_string = error_string;
let error = unpack_pdf_error(e);
if let PdfError::InvalidPassword = error {
return Some(None);
}
}
Some(Some(file_entry))
});
if let Ok(pdf_result) = result {
pdf_result
} else {
let message = create_crash_message("PDF-rs", &file_entry_clone.path.to_string_lossy(), "https://github.com/pdf-rs/pdf");
println!("{message}");
file_entry_clone.error_string = message;
Some(Some(file_entry_clone))
}
Err(_inspected) => Some(None),
}
}
Err(_inspected) => Some(None),
},

// This means that cache read invalid value because maybe cache comes from different czkawka version
TypeOfFile::Unknown => Some(None),
Expand Down
2 changes: 1 addition & 1 deletion czkawka_core/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ pub fn open_cache_folder(cache_file_name: &str, save_to_cache: bool, use_json: b
pub fn get_dynamic_image_from_heic(path: &str) -> Result<DynamicImage> {
let im = HeifContext::read_from_file(path)?;
let handle = im.primary_image_handle()?;
let image = handle.decode(ColorSpace::Rgb(RgbChroma::Rgb), false)?;
let image = handle.decode(ColorSpace::Rgb(RgbChroma::Rgb), None)?;
let width = image.width(Channel::Interleaved).map_err(|e| anyhow::anyhow!("{}", e))?;
let height = image.height(Channel::Interleaved).map_err(|e| anyhow::anyhow!("{}", e))?;
let planes = image.planes();
Expand Down
4 changes: 2 additions & 2 deletions czkawka_core/src/common_dir_traversal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub struct SymlinkInfo {
pub type_of_error: ErrorType,
}

#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, Copy)]
pub enum ErrorType {
InfiniteRecursion,
NonExistentFile,
Expand Down Expand Up @@ -87,7 +87,7 @@ pub enum Collect {
Files,
}

#[derive(Eq, PartialEq)]
#[derive(Eq, PartialEq, Copy, Clone)]
enum EntryType {
File,
Dir,
Expand Down
2 changes: 1 addition & 1 deletion czkawka_core/src/duplicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl HashType {
}
}

#[derive(Eq, PartialEq, Clone, Debug)]
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub enum DeleteMethod {
None,
AllExceptNewest,
Expand Down
2 changes: 1 addition & 1 deletion czkawka_core/src/invalid_symlinks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::common_items::ExcludedItems;
use crate::common_messages::Messages;
use crate::common_traits::*;

#[derive(Eq, PartialEq, Clone, Debug)]
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub enum DeleteMethod {
None,
Delete,
Expand Down
4 changes: 2 additions & 2 deletions czkawka_core/src/same_music.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::common_items::ExcludedItems;
use crate::common_messages::Messages;
use crate::common_traits::*;

#[derive(Eq, PartialEq, Clone, Debug)]
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub enum DeleteMethod {
None,
Delete,
Expand Down Expand Up @@ -666,7 +666,7 @@ impl SameMusic {
for file_entry in vec_file_entry {
let thing = file_entry.genre.trim().to_lowercase();
if !thing.is_empty() {
hash_map.entry(thing.clone()).or_insert_with(Vec::new).push(file_entry);
hash_map.entry(thing).or_insert_with(Vec::new).push(file_entry);
}
}
for (_title, vec_file_entry) in hash_map {
Expand Down
2 changes: 1 addition & 1 deletion czkawka_core/src/similar_images.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub struct FileEntry {
}

/// Used by CLI tool when we cannot use directly values
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Copy)]
pub enum SimilarityPreset {
Original,
VeryHigh,
Expand Down
7 changes: 4 additions & 3 deletions czkawka_core/src/similar_videos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ impl SimilarVideos {
if self.excluded_items.is_excluded(&current_file_name) {
continue 'dir;
}
let current_file_name_str = current_file_name.to_string_lossy().to_string();

let fe: FileEntry = FileEntry {
path: current_file_name.clone(),
Expand All @@ -401,15 +402,15 @@ impl SimilarVideos {
Err(_inspected) => {
warnings.push(flc!(
"core_file_modified_before_epoch",
generate_translation_hashmap(vec![("name", current_file_name.display().to_string())])
generate_translation_hashmap(vec![("name", current_file_name_str.clone())])
));
0
}
},
Err(e) => {
warnings.push(flc!(
"core_file_no_modification_date",
generate_translation_hashmap(vec![("name", current_file_name.display().to_string()), ("reason", e.to_string())])
generate_translation_hashmap(vec![("name", current_file_name_str.clone()), ("reason", e.to_string())])
));
0
}
Expand All @@ -418,7 +419,7 @@ impl SimilarVideos {
error: String::new(),
};

fe_result.push((current_file_name.to_string_lossy().to_string(), fe));
fe_result.push((current_file_name_str, fe));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion czkawka_core/src/temporary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub struct ProgressData {
pub files_checked: usize,
}

#[derive(Eq, PartialEq, Clone, Debug)]
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub enum DeleteMethod {
None,
Delete,
Expand Down
14 changes: 7 additions & 7 deletions czkawka_gui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ homepage = "https://github.com/qarmin/czkawka"
repository = "https://github.com/qarmin/czkawka"

[dependencies]
gdk4 = "0.5.5"
glib = "0.16.7"
gdk4 = "0.6.0"
glib = "0.17.1"

humansize = "2.1.3"
chrono = "0.4.23"
Expand All @@ -20,7 +20,7 @@ chrono = "0.4.23"
crossbeam-channel = "0.5.6"

# To get information about progress
futures = "0.3.25"
futures = "0.3.26"

# For saving/loading config files to specific directories
directories-next = "2.0.0"
Expand All @@ -38,22 +38,22 @@ regex = "1.7.1"
image_hasher = "1.1.2"

# Move files to trash
trash = "3.0.0"
trash = "3.0.1"

# For moving files(why std::fs doesn't have such features)
fs_extra = "1.2.0"
fs_extra = "1.3.0"

# Language
i18n-embed = { version = "0.13.8", features = ["fluent-system", "desktop-requester"] }
i18n-embed-fl = "0.6.5"
rust-embed = "6.4.2"
once_cell = "1.17.0"
once_cell = "1.17.1"

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.9", features = ["combaseapi", "objbase", "shobjidl_core", "windef", "winerror", "wtypesbase", "winuser"] }

[dependencies.gtk4]
version = "0.5.5"
version = "0.6.1"
default-features = false
features = ["v4_6"]

Expand Down
10 changes: 9 additions & 1 deletion czkawka_gui/i18n/en/czkawka_gui.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,11 @@ popover_custom_all_in_group_label = Don't select all records in group
popover_custom_mode_unselect = Unselect Custom
popover_custom_mode_select = Select Custom

popover_sort_file_name = File name
popover_sort_folder_name = Folder name
popover_sort_full_name = Full name
popover_sort_size = Size
popover_sort_selection = Selection

popover_invalid_regex = Regex is invalid
popover_valid_regex = Regex is valid
Expand All @@ -250,6 +255,7 @@ bottom_save_button = Save
bottom_symlink_button = Symlink
bottom_hardlink_button = Hardlink
bottom_move_button = Move
bottom_sort_button = Sort

bottom_search_button_tooltip = Start search
bottom_select_button_tooltip = Select records. Only selected files/folders can be later processed.
Expand All @@ -268,10 +274,12 @@ bottom_hardlink_button_not_available_tooltip =
Button is disabled, because hardlinks cannot be created.
Hardlinks only works with administrator privileges on Windows, so be sure to run app as administrator.
If app already works with such privileges check for similar issues on Github.
bottom_move_button_tooltip =
bottom_move_button_tooltip =
Moves files to chosen directory.
It copies all files to the directory without preserving the directory tree.
When trying to move two files with identical name to folder, second will fail and show error.
bottom_sort_button_tooltip =
Sorts files/folders according to selected method.

bottom_show_errors_tooltip = Show/Hide bottom text panel.
bottom_show_upper_notebook_tooltip = Show/Hide upper notebook panel.
Expand Down
Loading