Skip to content

Commit 414297b

Browse files
committed
TST
1 parent 4c612a8 commit 414297b

3 files changed

Lines changed: 91 additions & 24 deletions

File tree

czkawka_core/src/common/directories.rs

Lines changed: 80 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ impl Directories {
2929
self.reference_files = Vec::new();
3030
self.reference_directories = Vec::new();
3131
let paths = if cfg!(target_family = "windows") {
32-
reference_paths.into_iter().map(|p| normalize_windows_path(p)).collect()
32+
reference_paths.into_iter().map(normalize_windows_path).collect()
3333
} else {
3434
reference_paths
3535
};
@@ -40,7 +40,7 @@ impl Directories {
4040
self.included_files = Vec::new();
4141
self.included_directories = Vec::new();
4242
let paths = if cfg!(target_family = "windows") {
43-
included_paths.into_iter().map(|p| normalize_windows_path(p)).collect()
43+
included_paths.into_iter().map(normalize_windows_path).collect()
4444
} else {
4545
included_paths
4646
};
@@ -51,7 +51,7 @@ impl Directories {
5151
self.excluded_files = Vec::new();
5252
self.excluded_directories = Vec::new();
5353
let paths = if cfg!(target_family = "windows") {
54-
excluded_paths.into_iter().map(|p| normalize_windows_path(p)).collect()
54+
excluded_paths.into_iter().map(normalize_windows_path).collect()
5555
} else {
5656
excluded_paths
5757
};
@@ -134,13 +134,11 @@ impl Directories {
134134
pub(crate) fn optimize_directories(&mut self, recursive_search: bool, skip_exist_check: bool) -> Result<Messages, Messages> {
135135
let mut messages: Messages = Messages::new();
136136

137-
dbg!("1", &self);
138137
if self.included_directories.is_empty() && self.included_files.is_empty() {
139138
messages.critical = Some(flc!("core_missing_no_chosen_included_path"));
140139
return Err(messages);
141140
}
142141

143-
dbg!("2", &self);
144142
// Remove duplicated entries like: "/", "/"
145143
for items in &mut [
146144
&mut self.included_directories,
@@ -153,7 +151,6 @@ impl Directories {
153151
items.sort_unstable();
154152
items.dedup();
155153
}
156-
dbg!("3", &self);
157154

158155
// Optimize for duplicated included directories - "/", "/home". "/home/Pulpit" to "/"
159156
// Do not use when not using recursive search
@@ -163,21 +160,18 @@ impl Directories {
163160
kk.retain(|item| !cloned.iter().any(|other_item| item != other_item && item.starts_with(other_item)));
164161
}
165162
}
166-
dbg!("4", &self);
167163

168164
// Remove included directories which are inside any excluded directory
169165
// Same with included files
170166
for kk in [&mut self.included_directories, &mut self.included_files] {
171167
kk.retain(|id| !self.excluded_directories.iter().any(|ed| id.starts_with(ed)));
172168
}
173-
dbg!("5", &self);
174169

175170
// Also check if files are not excluded directly
176171
{
177172
let kk = &mut self.included_files;
178173
kk.retain(|id| !self.excluded_directories.iter().any(|ed| id == ed));
179174
}
180-
dbg!("6", &self);
181175

182176
// Remove non existed directories and files
183177
if !skip_exist_check {
@@ -190,22 +184,19 @@ impl Directories {
190184
kk.retain(|path| path.exists());
191185
}
192186
}
193-
dbg!("7", &self);
194187

195188
// Excluded paths must are inside included path, because otherwise they are pointless
196189
// So first, removing included files, that are inside excluded directories
197190
// So this will allow to remove excluded directories outside included directories
198191
self.included_files.retain(|ifile| !self.excluded_directories.iter().any(|ed| ifile.starts_with(ed)));
199192
self.excluded_directories.retain(|ed| self.included_directories.iter().any(|id| ed.starts_with(id)));
200193

201-
dbg!("8", &self);
202194
// Selecting Reference folders
203195
{
204196
self.reference_directories.retain(|folder| self.included_directories.iter().any(|e| folder.starts_with(e)));
205197
self.reference_files
206198
.retain(|file| self.included_directories.iter().any(|e| file.starts_with(e)) || self.included_files.iter().any(|f| file == f));
207199
}
208-
dbg!("9", &self);
209200

210201
// Not needed, but better is to have sorted everything
211202
for items in &mut [
@@ -218,7 +209,6 @@ impl Directories {
218209
] {
219210
items.sort_unstable();
220211
}
221-
dbg!("10", &self);
222212

223213
// Get device IDs for included directories, probably ther better solution would be to get one id per directory, but this is faster, but a little less precise
224214
#[cfg(target_family = "unix")]
@@ -230,19 +220,16 @@ impl Directories {
230220
}
231221
}
232222
}
233-
dbg!("11", &self);
234223

235224
if self.included_directories.is_empty() && self.included_files.is_empty() {
236225
messages.critical = Some(flc!("core_missing_no_chosen_included_path"));
237226
return Err(messages);
238227
}
239-
dbg!("12", &self);
240228

241229
if self.reference_directories == self.included_directories && self.included_files == self.reference_files {
242230
messages.critical = Some(flc!("core_reference_included_paths_same"));
243231
return Err(messages);
244232
}
245-
dbg!("13", &self);
246233

247234
Ok(messages)
248235
}
@@ -300,9 +287,10 @@ impl Directories {
300287

301288
#[cfg(test)]
302289
mod tests {
303-
use super::*;
304290
use std::path::PathBuf;
305291

292+
use super::*;
293+
306294
#[test]
307295
fn test_no_included_paths_errors() {
308296
let mut d = Directories::new();
@@ -316,20 +304,89 @@ mod tests {
316304
let mut d = Directories::new();
317305
d.included_directories.push(p.clone());
318306
d.included_directories.push(p.clone());
319-
let msgs = d.optimize_directories(true, true).unwrap();
320-
assert_eq!(d.included_directories, vec![
321-
p.clone(),
322-
]);
307+
let _msgs = d.optimize_directories(true, true).unwrap();
308+
assert_eq!(d.included_directories, vec![p]);
323309
}
324310

325311
#[test]
326312
fn test_excluded_removes_included_inside() {
327313
let base = PathBuf::from("/this/base/does/not/exist");
328314
let sub = base.join("sub");
329315
let mut d = Directories::new();
330-
d.included_directories.push(sub.clone());
331-
d.excluded_directories.push(base.clone());
316+
d.included_directories.push(sub);
317+
d.excluded_directories.push(base);
332318
let _msgs = d.optimize_directories(true, true).unwrap_err();
333319
assert_eq!(d.included_directories, Vec::<PathBuf>::new());
334320
}
321+
322+
#[test]
323+
fn test_optimize_nested_included_directories_dedup() {
324+
let mut d = Directories::new();
325+
d.included_directories.push(PathBuf::from("/"));
326+
d.included_directories.push(PathBuf::from("/home"));
327+
d.included_directories.push(PathBuf::from("/home/Pulpit"));
328+
329+
// use recursive_search = true and skip_exist_check = true as requested
330+
let msgs = d.optimize_directories(true, true).unwrap();
331+
// only root should remain after dedup
332+
assert_eq!(d.included_directories, vec![PathBuf::from("/")]);
333+
assert!(msgs.critical.is_none());
334+
}
335+
336+
#[test]
337+
fn test_excluded_directories_pruned_to_inside_included() {
338+
let mut d = Directories::new();
339+
d.included_directories.push(PathBuf::from("/this/include"));
340+
d.excluded_directories.push(PathBuf::from("/this/include/sub"));
341+
d.excluded_directories.push(PathBuf::from("/other/place"));
342+
343+
let _msgs = d.optimize_directories(true, true).unwrap();
344+
assert_eq!(d.excluded_directories, vec![PathBuf::from("/this/include/sub")]);
345+
}
346+
347+
#[test]
348+
fn test_reference_dirs_and_files_retained_correctly() {
349+
let mut d = Directories::new();
350+
d.included_directories.push(PathBuf::from("/a"));
351+
d.included_files.push(PathBuf::from("/a/included_file.txt"));
352+
353+
d.reference_directories.push(PathBuf::from("/a/sub"));
354+
d.reference_directories.push(PathBuf::from("/other"));
355+
356+
d.reference_files.push(PathBuf::from("/a/included_file.txt"));
357+
d.reference_files.push(PathBuf::from("/other/file2.txt"));
358+
359+
let _msgs = d.optimize_directories(true, true).unwrap();
360+
361+
assert_eq!(d.reference_directories, vec![PathBuf::from("/a/sub")]);
362+
assert_eq!(d.reference_files, vec![PathBuf::from("/a/included_file.txt")]);
363+
}
364+
365+
#[test]
366+
fn test_reference_equals_included_error() {
367+
let mut d = Directories::new();
368+
d.included_directories.push(PathBuf::from("/same"));
369+
d.reference_directories.push(PathBuf::from("/same"));
370+
d.included_files = Vec::new();
371+
d.reference_files = Vec::new();
372+
373+
let msgs = d.optimize_directories(true, true).unwrap_err();
374+
assert!(msgs.critical.is_some());
375+
}
376+
377+
#[test]
378+
fn test_included_files_removed_when_equal_to_excluded_directory() {
379+
let mut d = Directories::new();
380+
d.included_directories.push(PathBuf::from("/base"));
381+
d.included_files.push(PathBuf::from("/base/file"));
382+
383+
// excluded directory equals included file path
384+
d.excluded_directories.push(PathBuf::from("/base/file"));
385+
386+
let _msgs = d.optimize_directories(true, true).unwrap();
387+
// included_files should be removed because it equals an excluded directory
388+
assert!(d.included_files.is_empty());
389+
// excluded_directories should be retained as it's inside included_directories
390+
assert_eq!(d.excluded_directories, vec![PathBuf::from("/base/file")]);
391+
}
335392
}

czkawka_core/src/common/image.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use libraw::Processor;
1515
use log::{error, trace};
1616
use nom_exif::{ExifIter, ExifTag, MediaParser, MediaSource};
1717
use rawler::decoders::RawDecodeParams;
18+
use rawler::decoders::WellKnownIFD::Exif;
1819
use rawler::imgop::develop::RawDevelop;
1920
use rawler::rawsource::RawSource;
2021

@@ -213,6 +214,12 @@ pub enum ExifOrientation {
213214
}
214215

215216
pub(crate) fn get_rotation_from_exif(path: &str) -> Result<Option<ExifOrientation>, nom_exif::Error> {
217+
if let Some(extension) = Path::new(path).extension()
218+
&& HEIC_EXTENSIONS.contains(&extension.to_string_lossy().to_lowercase().as_str())
219+
{
220+
return Ok(None); // libheif already applies orientation
221+
}
222+
216223
let res = panic::catch_unwind(|| {
217224
let mut parser = MediaParser::new();
218225
let ms = MediaSource::file_path(path)?;

czkawka_core/src/helpers/messages.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,13 @@ impl Messages {
116116

117117
/// Extends this `Messages` struct with another, appending all messages, warnings, and errors.
118118
pub fn extend_with_another_messages(&mut self, messages: Self) {
119-
let (messages, warnings, errors) = (messages.messages, messages.warnings, messages.errors);
119+
let (messages, warnings, errors, critical) = (messages.messages, messages.warnings, messages.errors, messages.critical);
120120
self.messages.extend(messages);
121121
self.warnings.extend(warnings);
122122
self.errors.extend(errors);
123+
if critical.is_some() {
124+
self.critical = critical;
125+
}
123126
}
124127
}
125128

0 commit comments

Comments
 (0)