Skip to content

Commit 0c6015d

Browse files
committed
Include organize type root
Reduce redundancy and create a base dir for backup
1 parent b4987bc commit 0c6015d

File tree

4 files changed

+57
-48
lines changed

4 files changed

+57
-48
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ Cargo.lock
2020
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
2121
.idea/
2222

23+
.DS_Store
2324
ios
2425
extracted/

src/fileio.rs

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use crate::{constant, squire};
33
use plist::Value;
44
use rusqlite::{Connection, Result};
55
use std::fs::{create_dir_all, File};
6-
use std::io::copy;
76
use std::path::{Path, PathBuf};
87
use std::sync::mpsc::channel;
98
use std::sync::{Arc, Mutex};
@@ -86,7 +85,9 @@ pub fn parse_manifest_db(
8685
match file {
8786
Ok((file_id, relative_path)) => {
8887
let backup_cloned = backup.path.clone();
89-
let output_dir_cloned = arguments.output_dir.clone();
88+
let output_dir_cloned = arguments
89+
.output_dir
90+
.join(format!("{} - {}", backup.device_name, backup.serial_number));
9091
let sender_cloned = sender.clone();
9192
let organize_cloned = arguments.organize;
9293
let progress_bar = Arc::clone(&progress_bar_base);
@@ -95,7 +96,7 @@ pub fn parse_manifest_db(
9596
&backup_cloned,
9697
&output_dir_cloned,
9798
file_id,
98-
relative_path,
99+
&PathBuf::from(relative_path),
99100
organize_cloned,
100101
);
101102
sender_cloned.send(result).expect("Failed to send result");
@@ -126,7 +127,7 @@ pub fn parse_manifest_db(
126127
///
127128
/// * `backup_path` - The path to the backup directory
128129
/// * `output_path` - The path to the output directory
129-
/// * `file_id` - The file ID
130+
/// * `file_id` - The file ID to extract
130131
/// * `relative_path` - The relative path of the file
131132
///
132133
/// # Returns
@@ -137,38 +138,42 @@ fn extract_files(
137138
backup_path: &Path,
138139
output_path: &Path,
139140
file_id: String,
140-
relative_path: String,
141+
relative_path: &PathBuf,
141142
organize: parser::Organizer,
142143
) -> std::io::Result<()> {
143144
let src_path = backup_path.join(&file_id[..2]).join(file_id);
145+
if !src_path.exists() {
146+
let msg = format!("Path {} doesn't exist", src_path.display());
147+
log::debug!("{}", msg);
148+
return Err(std::io::Error::new(std::io::ErrorKind::NotFound, msg))
149+
}
150+
let filename = relative_path
151+
.file_name()
152+
.unwrap_or_default()
153+
.to_string_lossy()
154+
.to_string();
144155
let dest_path = match organize {
145-
parser::Organizer::Type => {
146-
output_path.join(squire::file_type(&PathBuf::from(relative_path)))
147-
}
148-
parser::Organizer::Size => output_path.join(squire::file_size(
149-
&PathBuf::from(&src_path),
150-
&PathBuf::from(relative_path),
151-
)),
152-
parser::Organizer::Auto => output_path.join(&relative_path),
156+
parser::Organizer::Type => output_path.join(squire::file_type(relative_path, &filename)),
157+
parser::Organizer::Size => output_path.join(squire::file_size(&src_path, &filename)),
158+
parser::Organizer::Root => output_path.join(filename).to_owned(),
159+
parser::Organizer::Auto => output_path.join(relative_path),
153160
};
154161
if let Some(parent) = dest_path.parent() {
155162
match create_dir_all(parent) {
156163
Ok(_) => (),
157164
Err(err) => return Err(err),
158165
}
159166
}
160-
if src_path.exists() {
161-
let mut src_file = File::open(&src_path)?;
162-
let mut dest_file = File::create(&dest_path)?;
163-
match copy(&mut src_file, &mut dest_file) {
164-
Ok(_) => (),
165-
Err(err) => return Err(err),
166-
}
167-
log::debug!(
168-
"Extracted: {} -> {}",
169-
src_path.display(),
170-
dest_path.display()
171-
);
167+
let mut src_file = File::open(&src_path)?;
168+
let mut dest_file = File::create(&dest_path)?;
169+
match std::io::copy(&mut src_file, &mut dest_file) {
170+
Ok(_) => (),
171+
Err(err) => return Err(err),
172172
}
173+
log::debug!(
174+
"Extracted: {} -> {}",
175+
src_path.display(),
176+
dest_path.display()
177+
);
173178
Ok(())
174179
}

src/parser.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::path::PathBuf;
66
pub enum Organizer {
77
Type,
88
Size,
9+
Root,
910
Auto,
1011
}
1112

@@ -127,9 +128,10 @@ pub fn arguments(metadata: &constant::MetaData) -> ArgConfig {
127128
match args[i].as_str() {
128129
"type" => organize = Organizer::Type,
129130
"size" => organize = Organizer::Size,
131+
"root" => organize = Organizer::Root,
130132
"auto" => organize = Organizer::Auto,
131133
_ => {
132-
println!("ERROR: '--organize' can only be 'type', 'size' or 'auto'");
134+
println!("ERROR: '--organize' can only be 'type', 'size', 'root' or 'auto' (default)");
133135
std::process::exit(1)
134136
}
135137
}
@@ -171,7 +173,10 @@ pub fn arguments(metadata: &constant::MetaData) -> ArgConfig {
171173
if tmp.exists() {
172174
tmp
173175
} else {
174-
println!("Backup directory '{}' does not exist!", tmp.display());
176+
println!(
177+
"ERROR: Backup directory '{}' does not exist!",
178+
tmp.display()
179+
);
175180
std::process::exit(1)
176181
}
177182
};

src/squire.rs

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,22 @@ pub fn size_converter(byte_size: u64) -> String {
126126
}
127127

128128
/// Returns the default number of worker threads (logical cores)
129-
/// If the number of logical cores cannot be determined, it defaults to 8
129+
/// If the number of logical cores cannot be determined, it defaults to 1
130130
///
131131
/// # Returns
132132
///
133133
/// A `usize` containing the number of worker threads
134134
pub fn default_workers() -> usize {
135135
let logical_cores = thread::available_parallelism();
136136
match logical_cores {
137-
Ok(cores) => cores.get(),
137+
Ok(cores) => {
138+
let workers = cores.get();
139+
if workers > 1 {
140+
workers / 2
141+
} else {
142+
workers
143+
}
144+
}
138145
Err(err) => {
139146
log::error!("{}", err);
140147
1
@@ -191,26 +198,22 @@ pub fn media_filter() -> String {
191198
/// # Arguments
192199
///
193200
/// * `relative_path` - The path to the file
201+
/// * `filename` - Name of the file
194202
///
195203
/// # Returns
196204
///
197-
/// A `String` with the file extension in upperacase
198-
pub fn file_type(relative_path: &PathBuf) -> PathBuf {
205+
/// A `String` with the file extension in uppercase
206+
pub fn file_type(relative_path: &PathBuf, filename: &String) -> PathBuf {
199207
// I basically want the file extension in upper case
200208
let file_extension = &relative_path
201209
.extension()
202210
.unwrap_or_default()
203211
.to_string_lossy()
204212
.to_uppercase();
205-
let file_name = &relative_path
206-
.file_name()
207-
.unwrap_or_default()
208-
.to_string_lossy()
209-
.to_string();
210213
if file_extension.is_empty() {
211214
return relative_path.to_owned();
212215
}
213-
PathBuf::from(&file_extension).join(file_name).to_owned()
216+
PathBuf::from(&file_extension).join(filename).to_owned()
214217
}
215218

216219
/// Classifies size into less than 1 MB, 10 MB, 100 MB, 1 GB, and the rest as unclassified.
@@ -238,23 +241,18 @@ fn classify_size(byte_size: usize) -> String {
238241
}
239242
}
240243

241-
/// Function to get the size of a file or directory
244+
/// Creates a file path categorized by its size
242245
///
243246
/// # Arguments
244247
///
245-
/// * `relative_path` - The path to the file or directory
248+
/// * `src_path` - The path to the file or directory
249+
/// * `filename` - Name of the file
246250
///
247251
/// # Returns
248252
///
249253
/// A `String` with human-readable format of the file/directory size
250-
pub fn file_size(src_path: &Path, relative_path: &Path) -> PathBuf {
251-
let raw_size = get_size(src_path);
252-
let file_name = &relative_path
253-
.file_name()
254-
.unwrap_or_default()
255-
.to_string_lossy()
256-
.to_string();
257-
PathBuf::from(&classify_size(raw_size as usize))
258-
.join(file_name)
254+
pub fn file_size(src_path: &Path, filename: &String) -> PathBuf {
255+
PathBuf::from(&classify_size(get_size(src_path) as usize))
256+
.join(filename)
259257
.to_owned()
260258
}

0 commit comments

Comments
 (0)