1
0
Fork 0
mirror of synced 2024-04-26 16:52:19 +12:00

Add some comments

This commit is contained in:
Rafał Mikrut 2020-09-01 22:48:20 +02:00
parent 9d4de08ece
commit 7eeff49426
4 changed files with 40 additions and 22 deletions

View file

@ -4,30 +4,37 @@ It is in very early development, so most of the functions aren't added and doesn
## Done
- Basic menu(need refactoring)
- Rich instruction with examples - CLI(`cargo run --bin czkawka_cli`)
- Duplicated file finding - CLI
- Including and excluding directories(absolute pathes)
- Option to remove files in different ways
- Fast(by size) or accurate(by hash) file checking
- Empty folders finding - CLI
- Advanced empty files finding(finds and remove folders which contains only empty folders)
- Option to remove all files
## TODO
- Comments - a lot of things should be described
- Tests
- Github CI
- Unit tests(if available)
- Duplicated file finding - CLI
- saving results to file
- support for * when excluding files and folders
- GUI(GTK)
- Removing empty folders
- Files with debug symbols
- Support for showing only duplicates with specific extension, name(Regex support needed)
- Maybe windows support, but this will need some refactoring in code
## Usage
For now only Linux(and probably also macOS) is supported
- Install requirements for GTK(minimum 3.16)
```
apt install -y libgtk-3-dev
```
- Download source
```
git clone github/czkawka // TODO
git clone https://github.com/qarmin/czkawka.git
cd czkawka
```
- Run GUI(Still WIP)
@ -35,8 +42,9 @@ cd czkawka
cargo run --bin czkawka_gui
```
- Run CLI
```
cargo run --bin czkawka_cli
```
## License
Czkawka is released under the terms of the GNU Lesser General Public License, version 2.1 or, at your option, any later version, as published by the Free Software Foundation.

View file

@ -151,7 +151,7 @@ impl DuplicateFinder {
println!("Include Directory ERROR: Path {} doesn't exists.", directory);
continue;
}
if !Path::new(&directory).exists() {
if !Path::new(&directory).is_dir() {
println!("Include Directory ERROR: {} isn't folder.", directory);
continue;
}
@ -210,7 +210,7 @@ impl DuplicateFinder {
println!("Exclude Directory ERROR: Path {} doesn't exists.", directory);
continue;
}
if !Path::new(&directory).exists() {
if !Path::new(&directory).is_dir() {
println!("Exclude Directory ERROR: {} isn't folder.", directory);
continue;
}

View file

@ -5,18 +5,22 @@ use std::path::Path;
use std::time::SystemTime;
use std::{fs, process};
/// Enum with values which show if folder is empty.
/// In function "optimize_folders" automatically "Maybe" is changed to "Yes", so it is not necessery to put it here
#[derive(Eq, PartialEq, Copy, Clone)]
enum FolderEmptiness {
No,
Maybe,
}
/// Struct assigned to each checked folder with parent path(used to ignore parent if children are not empty) and flag which shows if folder is empty
#[derive(Clone)]
struct FolderEntry {
parent_path: Option<String>,
is_empty: FolderEmptiness,
}
/// Struct to store most basics info about all folder
pub struct EmptyFolder {
number_of_checked_folders: usize,
number_of_empty_folders: usize,
@ -25,7 +29,9 @@ pub struct EmptyFolder {
included_directories: Vec<String>,
}
/// Method implementation for EmptyFolder
impl EmptyFolder {
/// New function providing basics values
pub fn new() -> EmptyFolder {
EmptyFolder {
number_of_checked_folders: 0,
@ -36,6 +42,7 @@ impl EmptyFolder {
}
}
/// Public function used by CLI to search for empty folders
pub fn find_empty_folders(mut self, delete_folders: bool) {
self.optimize_directories();
self.debug_print();
@ -68,7 +75,8 @@ impl EmptyFolder {
self.empty_folder_list = new_directory_folders;
}
/// Function to check if folder are empty, initial_checking is used to check again if folder is
/// Function to check if folder are empty.
/// Parameter initial_checking for second check before deleting to be sure that checked folder is still empty
fn check_for_empty_folders(&mut self, initial_checking: bool) {
let start_time: SystemTime = SystemTime::now();
let mut folders_to_check: Vec<String> = Vec::with_capacity(1024 * 2); // This should be small enough too not see to big difference and big enough to store most of paths without needing to resize vector
@ -87,7 +95,7 @@ impl EmptyFolder {
folders_to_check.push(id.clone());
}
} else {
// Add root folders for finding
// Add folders searched before
for id in &self.empty_folder_list {
folders_checked.insert(
id.0.clone(),
@ -104,7 +112,7 @@ impl EmptyFolder {
let mut next_folder: String;
while !folders_to_check.is_empty() {
current_folder = folders_to_check.pop().unwrap();
// Checked folder may be deleted so we assume that cannot removed folder be empty
let read_dir = match fs::read_dir(&current_folder) {
Ok(t) => t,
_ => {
@ -112,9 +120,11 @@ impl EmptyFolder {
continue;
}
};
for entry in read_dir {
let entry_data = entry.unwrap();
let metadata: Metadata = entry_data.metadata().unwrap();
// If child is dir, still folder may be considered as empty if all children are only directories.
if metadata.is_dir() {
let mut is_excluded_dir = false;
next_folder = "".to_owned() + &current_folder + &entry_data.file_name().into_string().unwrap() + "/";
@ -136,7 +146,7 @@ impl EmptyFolder {
);
}
} else {
// Not folder so it may be a file or symbolic link
// Not folder so it may be a file or symbolic link so it isn't empty
folders_checked.get_mut(&current_folder).unwrap().is_empty = FolderEmptiness::No;
let mut d = folders_checked.get_mut(&current_folder).unwrap();
let mut cf: String;
@ -153,13 +163,14 @@ impl EmptyFolder {
}
}
if initial_checking {
// We need to set empty folder list
for entry in folders_checked {
if entry.1.is_empty != FolderEmptiness::No {
self.empty_folder_list.insert(entry.0, entry.1);
}
}
} else {
// Sprawdzenie
// We need to check if parent of folder isn't also empty, because we wan't to delete only parent with two empty folders except this folders and at the end parent folder
let mut new_folders_list: HashMap<String, FolderEntry> = Default::default();
for entry in folders_checked {
if entry.1.is_empty != FolderEmptiness::No && self.empty_folder_list.contains_key(&entry.0) {
@ -172,9 +183,11 @@ impl EmptyFolder {
Common::print_time(start_time, SystemTime::now(), "check_for_empty_folder".to_string());
}
/// Deletes earlier finded empty folders
fn delete_empty_folders(&self) {
let start_time: SystemTime = SystemTime::now();
let mut errors: Vec<String> = Vec::new();
// Folders may be deleted or require too big privileges
for entry in &self.empty_folder_list {
match fs::remove_dir_all(entry.0) {
Ok(_) => (),
@ -192,6 +205,7 @@ impl EmptyFolder {
Common::print_time(start_time, SystemTime::now(), "delete_files".to_string());
}
/// Prints basic info about empty folders
fn print_empty_folders(&self) {
if !self.empty_folder_list.is_empty() {
println!("Found {} empty folders", self.empty_folder_list.len());
@ -201,6 +215,7 @@ impl EmptyFolder {
}
}
/// Debug print
fn debug_print(&self) {
if false {
println!("---------------DEBUG PRINT---------------");
@ -216,6 +231,7 @@ impl EmptyFolder {
}
// TODO maybe move this and one from duplicated finder to one common class to avoid duplicating code
/// Optimize include and exclude directories by removing duplicates etc.
fn optimize_directories(&mut self) {
let start_time: SystemTime = SystemTime::now();
@ -333,6 +349,8 @@ impl EmptyFolder {
self.included_directories.sort();
Common::print_time(start_time, SystemTime::now(), "optimize_directories".to_string());
}
/// Set include dir which needst to be relative, exists,
pub fn set_include_directory(&mut self, mut include_directory: String) {
// let start_time: SystemTime = SystemTime::now();
@ -369,7 +387,7 @@ impl EmptyFolder {
println!("Include Directory ERROR: Path {} doesn't exists.", directory);
continue;
}
if !Path::new(&directory).exists() {
if !Path::new(&directory).is_dir() {
println!("Include Directory ERROR: {} isn't folder.", directory);
continue;
}
@ -428,7 +446,7 @@ impl EmptyFolder {
println!("Exclude Directory ERROR: Path {} doesn't exists.", directory);
continue;
}
if !Path::new(&directory).exists() {
if !Path::new(&directory).is_dir() {
println!("Exclude Directory ERROR: {} isn't folder.", directory);
continue;
}

View file

@ -1,11 +1,3 @@
pub mod common;
pub mod duplicate;
pub mod empty_folder;
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}