1
0
mirror of https://github.com/arsenetar/dupeguru.git synced 2026-01-25 08:01:39 +00:00

Compare commits

..

23 Commits

Author SHA1 Message Date
Virgil Dupras
33ee220933 Updated cocoalib subrepo. 2011-04-16 15:15:59 +02:00
Virgil Dupras
23d36b58c8 UI tweaks for linux. 2011-04-16 04:06:08 -07:00
Virgil Dupras
39b895f01b UI tweaks for windows. 2011-04-16 11:46:24 +01:00
Virgil Dupras
5f4252cddc Updated a couple of remaning copyright years (in about boxes) from 2010 to 2011. 2011-04-16 03:27:10 -07:00
Virgil Dupras
fc54a1ea39 se v3.1.0 2011-04-16 12:20:46 +02:00
Virgil Dupras
285f338dce Added an option to register the contributor's OS on openhs when registering an app. 2011-04-15 14:42:14 +02:00
Virgil Dupras
379e420577 Fixed exclusion bug during folders scan. 2011-04-14 15:37:12 +02:00
Virgil Dupras
0b20b35ffb Fixed copying operations for folders which didn't work. 2011-04-14 12:55:50 +02:00
Virgil Dupras
d887cd118c Update cocoalib subrepo. 2011-04-14 11:51:29 +02:00
Virgil Dupras
54ffcfab79 [#149 state:fixed] Fixed crash on result saving. 2011-04-13 16:59:02 +02:00
Virgil Dupras
f28ffc680a [#140 state:fixed] Fixed a crash on dupe renaming. 2011-04-13 16:23:22 +02:00
Virgil Dupras
f33f30eabf Merged heads 2011-04-12 13:29:27 +02:00
Virgil Dupras
279d44b7f3 [#89 state:fixed] Added a Folders scan type in dgse.
--HG--
rename : core_se/tests/fs_test.py => core/tests/fs_test.py
2011-04-12 13:22:29 +02:00
Virgil Dupras
0fea59007c Updated copyright year to 2011. 2011-04-12 10:04:01 +02:00
Virgil Dupras
54720b15ca Added tkinter to cx_freeze explicit excludes because v4.2.3 started to falsely include it. 2011-03-20 11:28:53 +00:00
Virgil Dupras
39fc7a91d7 me v6.0.1 2011-03-18 09:11:11 +01:00
Virgil Dupras
7f9c322d48 Added tag se3.0.2 for changeset 77e169f75719 2011-03-16 15:30:07 +01:00
Virgil Dupras
b2ff02c773 Added missing entry in 3.0.2 changelog. 2011-03-16 14:38:17 +01:00
Virgil Dupras
2c242aedfd se v3.0.2 2011-03-16 14:36:46 +01:00
Virgil Dupras
70e4e6f5af Depend specifically on python 3.1 in deb packages instead of depending on python3 because PyQt modules are not binary compatiable with python 3.2 2011-03-16 04:07:22 -07:00
Virgil Dupras
ebeb068042 Removed an old workaround in the Qt version that doesn't seem to be needed with the current version of Qt. 2011-03-16 08:41:29 +00:00
Virgil Dupras
731e68f164 [#153 state:fixed] Fixed a refresh bug in directory panel. 2011-03-16 09:31:16 +01:00
Virgil Dupras
fa0c3aeb78 Added tag pe2.1.0 for changeset d274bcb98f2d 2011-03-07 15:59:13 +01:00
161 changed files with 567 additions and 330 deletions

View File

@@ -45,3 +45,5 @@ ca93352ce35184853ad9fcb881935a43a8b1e249 me5.10.3
f1d40b556c01f32c58f9ef9f9acac5b78e01ba7a pe2.0.0 f1d40b556c01f32c58f9ef9f9acac5b78e01ba7a pe2.0.0
2fd901a516f8cb6b4438491f63f2ebfd52a57c13 me6.0.0 2fd901a516f8cb6b4438491f63f2ebfd52a57c13 me6.0.0
ff43c6d9feb388f103b7857eaa6f7809185f78ec before-pluginbuilder ff43c6d9feb388f103b7857eaa6f7809185f78ec before-pluginbuilder
d274bcb98f2d02b86470a04cd62e718eff33b74f pe2.1.0
77e169f757195c11e9c1c5febeb2db8eb3589510 se3.0.2

View File

@@ -1,4 +1,4 @@
Copyright 2010 Hardcoded Software Inc. (http://www.hardcoded.net) Copyright 2011 Hardcoded Software Inc. (http://www.hardcoded.net)
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2009-12-30 # Created On: 2009-12-30
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -29,7 +29,7 @@
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
<string>NSApplication</string> <string>NSApplication</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>© Hardcoded Software, 2010</string> <string>© Hardcoded Software, 2011</string>
<key>SUFeedURL</key> <key>SUFeedURL</key>
<string>http://www.hardcoded.net/updates/dupeguru_me.appcast</string> <string>http://www.hardcoded.net/updates/dupeguru_me.appcast</string>
<key>SUPublicDSAKeyFile</key> <key>SUPublicDSAKeyFile</key>

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,4 +1,4 @@
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -29,7 +29,7 @@
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
<string>NSApplication</string> <string>NSApplication</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>© Hardcoded Software, 2010</string> <string>© Hardcoded Software, 2011</string>
<key>SUFeedURL</key> <key>SUFeedURL</key>
<string>http://www.hardcoded.net/updates/dupeguru_pe.appcast</string> <string>http://www.hardcoded.net/updates/dupeguru_pe.appcast</string>
<key>SUPublicDSAKeyFile</key> <key>SUPublicDSAKeyFile</key>

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,4 +1,4 @@
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at
@@ -42,7 +42,10 @@ http://www.hardcoded.net/licenses/bsd_license
- (id)init - (id)init
{ {
self = [super init]; self = [super init];
VTIsIntIn *vt = [[[VTIsIntIn alloc] initWithValues:[NSIndexSet indexSetWithIndex:1] reverse:YES] autorelease]; NSMutableIndexSet *contentsIndexes = [NSMutableIndexSet indexSet];
[contentsIndexes addIndex:1];
[contentsIndexes addIndex:2];
VTIsIntIn *vt = [[[VTIsIntIn alloc] initWithValues:contentsIndexes reverse:YES] autorelease];
[NSValueTransformer setValueTransformer:vt forName:@"vtScanTypeIsNotContent"]; [NSValueTransformer setValueTransformer:vt forName:@"vtScanTypeIsNotContent"];
_directoryPanel = nil; _directoryPanel = nil;
return self; return self;

View File

@@ -29,7 +29,7 @@
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
<string>NSApplication</string> <string>NSApplication</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>© Hardcoded Software, 2010</string> <string>© Hardcoded Software, 2011</string>
<key>SUFeedURL</key> <key>SUFeedURL</key>
<string>http://www.hardcoded.net/updates/dupeguru.appcast</string> <string>http://www.hardcoded.net/updates/dupeguru.appcast</string>
<key>SUPublicDSAKeyFile</key> <key>SUPublicDSAKeyFile</key>

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,4 +1,4 @@
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -29,6 +29,7 @@ class PyDupeGuru(PyDupeGuruBase):
self.py.scanner.scan_type = [ self.py.scanner.scan_type = [
ScanType.Filename, ScanType.Filename,
ScanType.Contents, ScanType.Contents,
ScanType.Folders,
][scan_type] ][scan_type]
except IndexError: except IndexError:
pass pass

View File

@@ -457,7 +457,6 @@
}; };
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "dupeguru" */;
compatibilityVersion = "Xcode 3.0"; compatibilityVersion = "Xcode 3.0";
developmentRegion = English;
hasScannedForEncodings = 1; hasScannedForEncodings = 1;
knownRegions = ( knownRegions = (
English, English,

View File

@@ -2,13 +2,13 @@
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10"> <archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data> <data>
<int key="IBDocument.SystemTarget">1050</int> <int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10J567</string> <string key="IBDocument.SystemVersion">10J869</string>
<string key="IBDocument.InterfaceBuilderVersion">823</string> <string key="IBDocument.InterfaceBuilderVersion">851</string>
<string key="IBDocument.AppKitVersion">1038.35</string> <string key="IBDocument.AppKitVersion">1038.35</string>
<string key="IBDocument.HIToolboxVersion">462.00</string> <string key="IBDocument.HIToolboxVersion">461.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions"> <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">823</string> <string key="NS.object.0">851</string>
</object> </object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
@@ -34,10 +34,6 @@
<string key="NSClassName">NSApplication</string> <string key="NSClassName">NSApplication</string>
</object> </object>
<object class="NSUserDefaultsController" id="75941798"> <object class="NSUserDefaultsController" id="75941798">
<object class="NSMutableArray" key="NSDeclaredKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>DebugMode</string>
</object>
<bool key="NSSharedInstance">YES</bool> <bool key="NSSharedInstance">YES</bool>
</object> </object>
<object class="NSWindowTemplate" id="489014306"> <object class="NSWindowTemplate" id="489014306">
@@ -273,6 +269,16 @@
<string key="NSAction">_popUpItemAction:</string> <string key="NSAction">_popUpItemAction:</string>
<reference key="NSTarget" ref="63752222"/> <reference key="NSTarget" ref="63752222"/>
</object> </object>
<object class="NSMenuItem" id="510059249">
<reference key="NSMenu" ref="38553798"/>
<string key="NSTitle">Folders</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="1002480020"/>
<reference key="NSMixedImage" ref="394002035"/>
<string key="NSAction">_popUpItemAction:</string>
<reference key="NSTarget" ref="63752222"/>
</object>
</object> </object>
</object> </object>
<int key="NSPreferredEdge">3</int> <int key="NSPreferredEdge">3</int>
@@ -1372,6 +1378,7 @@
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="101272617"/> <reference ref="101272617"/>
<reference ref="352817522"/> <reference ref="352817522"/>
<reference ref="510059249"/>
</object> </object>
<reference key="parent" ref="63752222"/> <reference key="parent" ref="63752222"/>
</object> </object>
@@ -1657,6 +1664,11 @@
<reference key="object" ref="236967908"/> <reference key="object" ref="236967908"/>
<reference key="parent" ref="727223254"/> <reference key="parent" ref="727223254"/>
</object> </object>
<object class="IBObjectRecord">
<int key="objectID">149</int>
<reference key="object" ref="510059249"/>
<reference key="parent" ref="38553798"/>
</object>
</object> </object>
</object> </object>
<object class="NSMutableDictionary" key="flattenedProperties"> <object class="NSMutableDictionary" key="flattenedProperties">
@@ -1688,6 +1700,7 @@
<string>145.IBViewBoundsToFrameTransform</string> <string>145.IBViewBoundsToFrameTransform</string>
<string>145.ImportedFromIB2</string> <string>145.ImportedFromIB2</string>
<string>146.IBPluginDependency</string> <string>146.IBPluginDependency</string>
<string>149.IBPluginDependency</string>
<string>51.IBPluginDependency</string> <string>51.IBPluginDependency</string>
<string>51.ImportedFromIB2</string> <string>51.ImportedFromIB2</string>
<string>52.IBEditorWindowLastContentRect</string> <string>52.IBEditorWindowLastContentRect</string>
@@ -1747,6 +1760,7 @@
<string>76.IBPluginDependency</string> <string>76.IBPluginDependency</string>
<string>77.IBPluginDependency</string> <string>77.IBPluginDependency</string>
<string>78.IBPluginDependency</string> <string>78.IBPluginDependency</string>
<string>79.IBEditorWindowLastContentRect</string>
<string>79.IBPluginDependency</string> <string>79.IBPluginDependency</string>
<string>79.ImportedFromIB2</string> <string>79.ImportedFromIB2</string>
<string>80.IBPluginDependency</string> <string>80.IBPluginDependency</string>
@@ -1815,6 +1829,7 @@
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>{{88, 520}, {389, 325}}</string> <string>{{88, 520}, {389, 325}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1887,6 +1902,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{216, 742}, {216, 63}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1936,7 +1952,7 @@
</object> </object>
</object> </object>
<nil key="sourceID"/> <nil key="sourceID"/>
<int key="maxID">148</int> <int key="maxID">149</int>
</object> </object>
<object class="IBClassDescriber" key="IBDocument.Classes"> <object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions"> <object class="NSMutableArray" key="referencedPartialClassDescriptions">

View File

@@ -72,4 +72,7 @@
"142.title" = "Ignorer doublons avec hardlink vers le même fichier"; "142.title" = "Ignorer doublons avec hardlink vers le même fichier";
/* Class = "NSButtonCell"; title = "Debug mode (restart required)"; ObjectID = "146"; */ /* Class = "NSButtonCell"; title = "Debug mode (restart required)"; ObjectID = "146"; */
"146.title" = "Mode de déboguage (redémarrage requis)"; "146.title" = "Mode de déboguage (redémarrage requis)";
/* Class = "NSMenuItem"; title = "Folders"; ObjectID = "149"; */
"149.title" = "Dossiers";

View File

@@ -2,13 +2,13 @@
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10"> <archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data> <data>
<int key="IBDocument.SystemTarget">1050</int> <int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">10J567</string> <string key="IBDocument.SystemVersion">10J869</string>
<string key="IBDocument.InterfaceBuilderVersion">823</string> <string key="IBDocument.InterfaceBuilderVersion">851</string>
<string key="IBDocument.AppKitVersion">1038.35</string> <string key="IBDocument.AppKitVersion">1038.35</string>
<string key="IBDocument.HIToolboxVersion">462.00</string> <string key="IBDocument.HIToolboxVersion">461.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions"> <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">823</string> <string key="NS.object.0">851</string>
</object> </object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
@@ -268,6 +268,16 @@
<string key="NSAction">_popUpItemAction:</string> <string key="NSAction">_popUpItemAction:</string>
<reference key="NSTarget" ref="63752222"/> <reference key="NSTarget" ref="63752222"/>
</object> </object>
<object class="NSMenuItem" id="510059249">
<reference key="NSMenu" ref="38553798"/>
<string key="NSTitle">Dossiers</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="1002480020"/>
<reference key="NSMixedImage" ref="394002035"/>
<string key="NSAction">_popUpItemAction:</string>
<reference key="NSTarget" ref="63752222"/>
</object>
</object> </object>
</object> </object>
<int key="NSPreferredEdge">3</int> <int key="NSPreferredEdge">3</int>
@@ -290,7 +300,7 @@
<reference key="NSControlView" ref="637819333"/> <reference key="NSControlView" ref="637819333"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<object class="NSCustomResource" key="NSNormalImage" id="587167894"> <object class="NSCustomResource" key="NSNormalImage" id="266862978">
<string key="NSClassName">NSImage</string> <string key="NSClassName">NSImage</string>
<string key="NSResourceName">NSSwitch</string> <string key="NSResourceName">NSSwitch</string>
</object> </object>
@@ -317,7 +327,7 @@
<reference key="NSControlView" ref="1067721243"/> <reference key="NSControlView" ref="1067721243"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="587167894"/> <reference key="NSNormalImage" ref="266862978"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>
@@ -339,7 +349,7 @@
<reference key="NSControlView" ref="290008886"/> <reference key="NSControlView" ref="290008886"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="587167894"/> <reference key="NSNormalImage" ref="266862978"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>
@@ -361,7 +371,7 @@
<reference key="NSControlView" ref="551239185"/> <reference key="NSControlView" ref="551239185"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="587167894"/> <reference key="NSNormalImage" ref="266862978"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>
@@ -383,7 +393,7 @@
<reference key="NSControlView" ref="208488736"/> <reference key="NSControlView" ref="208488736"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="587167894"/> <reference key="NSNormalImage" ref="266862978"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>
@@ -405,7 +415,7 @@
<reference key="NSControlView" ref="427690895"/> <reference key="NSControlView" ref="427690895"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="587167894"/> <reference key="NSNormalImage" ref="266862978"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>
@@ -621,7 +631,7 @@
<reference key="NSControlView" ref="724127338"/> <reference key="NSControlView" ref="724127338"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="587167894"/> <reference key="NSNormalImage" ref="266862978"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>
@@ -643,7 +653,7 @@
<reference key="NSControlView" ref="647216699"/> <reference key="NSControlView" ref="647216699"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="587167894"/> <reference key="NSNormalImage" ref="266862978"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>
@@ -665,7 +675,7 @@
<reference key="NSControlView" ref="727223254"/> <reference key="NSControlView" ref="727223254"/>
<int key="NSButtonFlags">1211912703</int> <int key="NSButtonFlags">1211912703</int>
<int key="NSButtonFlags2">2</int> <int key="NSButtonFlags2">2</int>
<reference key="NSNormalImage" ref="587167894"/> <reference key="NSNormalImage" ref="266862978"/>
<reference key="NSAlternateImage" ref="589920880"/> <reference key="NSAlternateImage" ref="589920880"/>
<string key="NSAlternateContents"/> <string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/> <string key="NSKeyEquivalent"/>
@@ -1378,6 +1388,7 @@
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="101272617"/> <reference ref="101272617"/>
<reference ref="352817522"/> <reference ref="352817522"/>
<reference ref="510059249"/>
</object> </object>
<reference key="parent" ref="63752222"/> <reference key="parent" ref="63752222"/>
</object> </object>
@@ -1663,6 +1674,11 @@
<reference key="object" ref="236967908"/> <reference key="object" ref="236967908"/>
<reference key="parent" ref="727223254"/> <reference key="parent" ref="727223254"/>
</object> </object>
<object class="IBObjectRecord">
<int key="objectID">149</int>
<reference key="object" ref="510059249"/>
<reference key="parent" ref="38553798"/>
</object>
</object> </object>
</object> </object>
<object class="NSMutableDictionary" key="flattenedProperties"> <object class="NSMutableDictionary" key="flattenedProperties">
@@ -1694,6 +1710,7 @@
<string>145.IBViewBoundsToFrameTransform</string> <string>145.IBViewBoundsToFrameTransform</string>
<string>145.ImportedFromIB2</string> <string>145.ImportedFromIB2</string>
<string>146.IBPluginDependency</string> <string>146.IBPluginDependency</string>
<string>149.IBPluginDependency</string>
<string>51.IBPluginDependency</string> <string>51.IBPluginDependency</string>
<string>51.ImportedFromIB2</string> <string>51.ImportedFromIB2</string>
<string>52.IBEditorWindowLastContentRect</string> <string>52.IBEditorWindowLastContentRect</string>
@@ -1754,6 +1771,7 @@
<string>76.IBPluginDependency</string> <string>76.IBPluginDependency</string>
<string>77.IBPluginDependency</string> <string>77.IBPluginDependency</string>
<string>78.IBPluginDependency</string> <string>78.IBPluginDependency</string>
<string>79.IBEditorWindowLastContentRect</string>
<string>79.IBPluginDependency</string> <string>79.IBPluginDependency</string>
<string>79.ImportedFromIB2</string> <string>79.ImportedFromIB2</string>
<string>80.IBPluginDependency</string> <string>80.IBPluginDependency</string>
@@ -1822,6 +1840,7 @@
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>{{88, 520}, {389, 325}}</string> <string>{{88, 520}, {389, 325}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1895,6 +1914,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{216, 742}, {216, 63}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/> <boolean value="YES"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -1944,7 +1964,7 @@
</object> </object>
</object> </object>
<nil key="sourceID"/> <nil key="sourceID"/>
<int key="maxID">148</int> <int key="maxID">149</int>
</object> </object>
<object class="IBClassDescriber" key="IBDocument.Classes"> <object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions"> <object class="NSMutableArray" key="referencedPartialClassDescriptions">

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2010 Hardcoded Software (http://www.hardcoded.net) Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2009-12-30 # Created On: 2009-12-30
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/11/11 # Created On: 2006/11/11
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -94,7 +94,8 @@ class DupeGuru(RegistrableApplication, Broadcaster):
def _get_file(self, str_path): def _get_file(self, str_path):
path = Path(str_path) path = Path(str_path)
f = fs.get_file(path, self.directories.fileclasses) # We add fs.Folder to fileclasses in case the file we're loading contains folder paths.
f = fs.get_file(path, self.directories.fileclasses + [fs.Folder])
if f is None: if f is None:
return None return None
try: try:
@@ -197,12 +198,7 @@ class DupeGuru(RegistrableApplication, Broadcaster):
while delete_if_empty(path, ['.DS_Store']): while delete_if_empty(path, ['.DS_Store']):
path = path[:-1] path = path[:-1]
def copy_or_move(self, dupe, copy, destination, dest_type): def copy_or_move(self, dupe, copy: bool, destination: str, dest_type: DestType):
"""
copy: True = Copy False = Move
destination: string.
dest_type: DestType constants
"""
source_path = dupe.path source_path = dupe.path
location_path = first(p for p in self.directories if dupe.path in p) location_path = first(p for p in self.directories if dupe.path in p)
dest_path = Path(destination) dest_path = Path(destination)
@@ -214,6 +210,9 @@ class DupeGuru(RegistrableApplication, Broadcaster):
dest_path = dest_path + source_base dest_path = dest_path + source_base
if not io.exists(dest_path): if not io.exists(dest_path):
io.makedirs(dest_path) io.makedirs(dest_path)
# Add filename to dest_path. For file move/copy, it's not required, but for folders, yes.
dest_path = dest_path + source_path[-1]
logging.debug("Copy/Move operation from '%s' to '%s'", source_path, dest_path)
# Raises an EnvironmentError if there's a problem # Raises an EnvironmentError if there's a problem
if copy: if copy:
smart_copy(source_path, dest_path) smart_copy(source_path, dest_path)
@@ -368,7 +367,10 @@ class DupeGuru(RegistrableApplication, Broadcaster):
def start_scanning(self): def start_scanning(self):
def do(j): def do(j):
j.set_progress(0, tr("Collecting files to scan")) j.set_progress(0, tr("Collecting files to scan"))
files = list(self.directories.get_files()) if self.scanner.scan_type == scanner.ScanType.Folders:
files = list(self.directories.get_folders())
else:
files = list(self.directories.get_files())
if self.options['ignore_hardlink_matches']: if self.options['ignore_hardlink_matches']:
files = self._remove_hardlink_dupes(files) files = self._remove_hardlink_dupes(files)
logging.info('Scanning %d files' % len(files)) logging.info('Scanning %d files' % len(files))

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/11/11 # Created On: 2006/11/11
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2010-02-02 # Created On: 2010-02-02
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/03/15 # Created On: 2006/03/15
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/02/27 # Created On: 2006/02/27
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -15,9 +15,10 @@ from hscommon.util import FileOrPath
from . import fs from . import fs
(STATE_NORMAL, class DirectoryState:
STATE_REFERENCE, Normal = 0
STATE_EXCLUDED) = range(3) Reference = 1
Excluded = 2
class AlreadyThereError(Exception): class AlreadyThereError(Exception):
"""The path being added is already in the directory list""" """The path being added is already in the directory list"""
@@ -51,11 +52,11 @@ class Directories:
def _default_state_for_path(self, path): def _default_state_for_path(self, path):
# Override this in subclasses to specify the state of some special folders. # Override this in subclasses to specify the state of some special folders.
if path[-1].startswith('.'): # hidden if path[-1].startswith('.'): # hidden
return STATE_EXCLUDED return DirectoryState.Excluded
def _get_files(self, from_path): def _get_files(self, from_path):
state = self.get_state(from_path) state = self.get_state(from_path)
if state == STATE_EXCLUDED: if state == DirectoryState.Excluded:
# Recursively get files from folders with lots of subfolder is expensive. However, there # Recursively get files from folders with lots of subfolder is expensive. However, there
# might be a subfolder in this path that is not excluded. What we want to do is to skim # might be a subfolder in this path that is not excluded. What we want to do is to skim
# through self.states and see if we must continue, or we can stop right here to save time # through self.states and see if we must continue, or we can stop right here to save time
@@ -63,11 +64,11 @@ class Directories:
return return
try: try:
filepaths = set() filepaths = set()
if state != STATE_EXCLUDED: if state != DirectoryState.Excluded:
found_files = fs.get_files(from_path, fileclasses=self.fileclasses) found_files = fs.get_files(from_path, fileclasses=self.fileclasses)
logging.debug("Collected {} files in folder {}".format(len(found_files), str(from_path))) logging.debug("Collected %d files in folder %s", len(found_files), str(from_path))
for file in found_files: for file in found_files:
file.is_ref = state == STATE_REFERENCE file.is_ref = state == DirectoryState.Reference
filepaths.add(file.path) filepaths.add(file.path)
yield file yield file
subpaths = [from_path + name for name in io.listdir(from_path)] subpaths = [from_path + name for name in io.listdir(from_path)]
@@ -79,6 +80,19 @@ class Directories:
except (EnvironmentError, fs.InvalidPath): except (EnvironmentError, fs.InvalidPath):
pass pass
def _get_folders(self, from_folder):
try:
for subfolder in from_folder.subfolders:
for folder in self._get_folders(subfolder):
yield folder
state = self.get_state(from_folder.path)
if state != DirectoryState.Excluded:
from_folder.is_ref = state == DirectoryState.Reference
logging.debug("Yielding Folder %r state: %d", from_folder, state)
yield from_folder
except (EnvironmentError, fs.InvalidPath):
pass
#---Public #---Public
def add_path(self, path): def add_path(self, path):
"""Adds 'path' to self, if not already there. """Adds 'path' to self, if not already there.
@@ -113,6 +127,16 @@ class Directories:
for file in self._get_files(path): for file in self._get_files(path):
yield file yield file
def get_folders(self):
"""Returns a list of all folders that are not excluded.
Returned folders also have their 'is_ref' attr set.
"""
for path in self._dirs:
from_folder = fs.Folder(path)
for folder in self._get_folders(from_folder):
yield folder
def get_state(self, path): def get_state(self, path):
"""Returns the state of 'path' (One of the STATE_* const.) """Returns the state of 'path' (One of the STATE_* const.)
""" """
@@ -125,7 +149,7 @@ class Directories:
if parent in self: if parent in self:
return self.get_state(parent) return self.get_state(parent)
else: else:
return STATE_NORMAL return DirectoryState.Normal
def has_any_file(self): def has_any_file(self):
try: try:

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/01/29 # Created On: 2006/01/29
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/09/16 # Created On: 2006/09/16
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2009-10-22 # Created On: 2009-10-22
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -63,6 +63,9 @@ class File:
self._md5partial_offset = 0x4000 #16Kb self._md5partial_offset = 0x4000 #16Kb
self._md5partial_size = 0x4000 #16Kb self._md5partial_size = 0x4000 #16Kb
def __repr__(self):
return "<{} {}>".format(self.__class__.__name__, str(self.path))
def __getattr__(self, attrname): def __getattr__(self, attrname):
# Only called when attr is not there # Only called when attr is not there
if attrname in self.INITIAL_INFO: if attrname in self.INITIAL_INFO:
@@ -147,6 +150,53 @@ class File:
return self.path[-1] return self.path[-1]
class Folder(File):
"""A wrapper around a folder path.
It has the size/md5 info of a File, but it's value are the sum of its subitems.
"""
def __init__(self, path):
File.__init__(self, path)
self._subfolders = None
def _all_items(self):
folders = self.subfolders
files = get_files(self.path)
return folders + files
def _read_info(self, field):
if field in {'size', 'mtime'}:
size = sum((f.size for f in self._all_items()), 0)
self.size = size
stats = io.stat(self.path)
self.mtime = nonone(stats.st_mtime, 0)
elif field in {'md5', 'md5partial'}:
# What's sensitive here is that we must make sure that subfiles'
# md5 are always added up in the same order, but we also want a
# different md5 if a file gets moved in a different subdirectory.
def get_dir_md5_concat():
items = self._all_items()
items.sort(key=lambda f:f.path)
md5s = [getattr(f, field) for f in items]
return b''.join(md5s)
md5 = hashlib.md5(get_dir_md5_concat())
digest = md5.digest()
setattr(self, field, digest)
@property
def subfolders(self):
if self._subfolders is None:
subpaths = [self.path + name for name in io.listdir(self.path)]
subfolders = [p for p in subpaths if not io.islink(p) and io.isdir(p)]
self._subfolders = [Folder(p) for p in subfolders]
return self._subfolders
@classmethod
def can_handle(cls, path):
return not io.islink(path) and io.isdir(path)
def get_file(path, fileclasses=[File]): def get_file(path, fileclasses=[File]):
for fileclass in fileclasses: for fileclass in fileclasses:
if fileclass.can_handle(path): if fileclass.can_handle(path):
@@ -172,12 +222,3 @@ def get_files(path, fileclasses=[File]):
return result return result
except EnvironmentError: except EnvironmentError:
raise InvalidPath(path) raise InvalidPath(path)
def get_all_files(path, fileclasses=[File]):
files = get_files(path, fileclasses=fileclasses)
filepaths = set(f.path for f in files)
subpaths = [path + name for name in io.listdir(path)]
# it's possible that a folder (bundle) gets into the file list. in that case, we don't want to recurse into it
subfolders = [p for p in subpaths if not io.islink(p) and io.isdir(p) and p not in filepaths]
subfiles = flatten(get_all_files(subpath, fileclasses=fileclasses) for subpath in subfolders)
return subfiles + files

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2010-02-06 # Created On: 2010-02-06
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2010-02-05 # Created On: 2010-02-05
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2010-02-06 # Created On: 2010-02-06
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -9,19 +8,19 @@
from hscommon.gui.tree import Tree, Node from hscommon.gui.tree import Tree, Node
from ..directories import STATE_NORMAL, STATE_REFERENCE, STATE_EXCLUDED from ..directories import DirectoryState
from .base import GUIObject from .base import GUIObject
STATE_ORDER = [STATE_NORMAL, STATE_REFERENCE, STATE_EXCLUDED] STATE_ORDER = [DirectoryState.Normal, DirectoryState.Reference, DirectoryState.Excluded]
# Lazily loads children # Lazily loads children
class DirectoryNode(Node): class DirectoryNode(Node):
def __init__(self, app, path, name): def __init__(self, tree, path, name):
Node.__init__(self, name) Node.__init__(self, name)
self._app = app self._tree = tree
self._directory_path = path self._directory_path = path
self._loaded = False self._loaded = False
self._state = STATE_ORDER.index(self._app.directories.get_state(path)) self._state = STATE_ORDER.index(self._tree.app.directories.get_state(path))
def __len__(self): def __len__(self):
if not self._loaded: if not self._loaded:
@@ -30,9 +29,9 @@ class DirectoryNode(Node):
def _load(self): def _load(self):
self.clear() self.clear()
subpaths = self._app.directories.get_subfolders(self._directory_path) subpaths = self._tree.app.directories.get_subfolders(self._directory_path)
for path in subpaths: for path in subpaths:
self.append(DirectoryNode(self._app, path, path[-1])) self.append(DirectoryNode(self._tree, path, path[-1]))
self._loaded = True self._loaded = True
# The state propery is an index to the combobox # The state propery is an index to the combobox
@@ -46,7 +45,9 @@ class DirectoryNode(Node):
return return
self._state = value self._state = value
state = STATE_ORDER[value] state = STATE_ORDER[value]
self._app.directories.set_state(self._directory_path, state) self._tree.app.directories.set_state(self._directory_path, state)
self._tree._refresh()
self._tree.view.refresh()
class DirectoryTree(GUIObject, Tree): class DirectoryTree(GUIObject, Tree):
@@ -62,7 +63,7 @@ class DirectoryTree(GUIObject, Tree):
def _refresh(self): def _refresh(self):
self.clear() self.clear()
for path in self.app.directories: for path in self.app.directories:
self.append(DirectoryNode(self.app, path, str(path))) self.append(DirectoryNode(self, path, str(path)))
def add_directory(self, path): def add_directory(self, path):
self.app.add_directory(path) self.app.add_directory(path)

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2010-04-12 # Created On: 2010-04-12
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2010-04-12 # Created On: 2010-04-12
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2010-02-11 # Created On: 2010-02-11
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -102,6 +102,10 @@ class ResultTable(GUIObject, GUITable):
def rename_selected(self, newname): def rename_selected(self, newname):
row = self.selected_row row = self.selected_row
if row is None:
# There's all kinds of way the current row can be swept off during rename. When it
# happens, selected_row will be None.
return False
row._data = None row._data = None
row._data_delta = None row._data_delta = None
return self.app.rename_selected(newname) return self.app.rename_selected(newname)

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2010-02-11 # Created On: 2010-02-11
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/05/02 # Created On: 2006/05/02
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/02/23 # Created On: 2006/02/23
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -8,10 +8,13 @@
import logging import logging
import re import re
import os
import os.path as op
from xml.etree import ElementTree as ET from xml.etree import ElementTree as ET
from . import engine from . import engine
from jobprogress.job import nulljob from jobprogress.job import nulljob
from hscommon.conflict import get_conflicted_name
from hscommon.markable import Markable from hscommon.markable import Markable
from hscommon.util import flatten, nonone, FileOrPath, format_size from hscommon.util import flatten, nonone, FileOrPath, format_size
from hscommon.trans import tr from hscommon.trans import tr
@@ -304,8 +307,22 @@ class Results(Markable):
match_elem.set('second', str(dupe2index[match.second])) match_elem.set('second', str(dupe2index[match.second]))
match_elem.set('percentage', str(int(match.percentage))) match_elem.set('percentage', str(int(match.percentage)))
tree = ET.ElementTree(root) tree = ET.ElementTree(root)
with FileOrPath(outfile, 'wb') as fp:
tree.write(fp, encoding='utf-8') def do_write(outfile):
with FileOrPath(outfile, 'wb') as fp:
tree.write(fp, encoding='utf-8')
try:
do_write(outfile)
except IOError as e:
if e.errno == 21: # outfile is a directory
p = str(outfile)
dirname, basename = op.split(p)
otherfiles = os.listdir(dirname)
newname = get_conflicted_name(otherfiles, basename)
do_write(op.join(dirname, newname))
else:
raise
self.is_modified = False self.is_modified = False
def sort_dupes(self, key, asc=True, delta=False): def sort_dupes(self, key, asc=True, delta=False):

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/03/03 # Created On: 2006/03/03
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -22,7 +22,7 @@ class ScanType:
Fields = 1 Fields = 1
FieldsNoOrder = 2 FieldsNoOrder = 2
Tag = 3 Tag = 3
# number 4 is obsolete Folders = 4
Contents = 5 Contents = 5
ContentsAudio = 6 ContentsAudio = 6
@@ -48,8 +48,8 @@ class Scanner:
for f in j.iter_with_progress(files, tr("Read size of %d/%d files")): for f in j.iter_with_progress(files, tr("Read size of %d/%d files")):
f.size # pre-read, makes a smoother progress if read here (especially for bundles) f.size # pre-read, makes a smoother progress if read here (especially for bundles)
files = [f for f in files if f.size >= self.size_threshold] files = [f for f in files if f.size >= self.size_threshold]
if self.scan_type in (ScanType.Contents, ScanType.ContentsAudio): if self.scan_type in {ScanType.Contents, ScanType.ContentsAudio, ScanType.Folders}:
sizeattr = 'size' if self.scan_type == ScanType.Contents else 'audiosize' sizeattr = 'audiosize' if self.scan_type == ScanType.ContentsAudio else 'size'
return engine.getmatches_by_contents(files, sizeattr, partial=self.scan_type==ScanType.ContentsAudio, j=j) return engine.getmatches_by_contents(files, sizeattr, partial=self.scan_type==ScanType.ContentsAudio, j=j)
else: else:
j = j.start_subjob([2, 8]) j = j.start_subjob([2, 8])
@@ -92,10 +92,22 @@ class Scanner:
j = j.start_subjob([8, 2]) j = j.start_subjob([8, 2])
for f in [f for f in files if not hasattr(f, 'is_ref')]: for f in [f for f in files if not hasattr(f, 'is_ref')]:
f.is_ref = False f.is_ref = False
logging.info('Getting matches') logging.info("Getting matches. Scan type: %d", self.scan_type)
matches = self._getmatches(files, j) matches = self._getmatches(files, j)
logging.info('Found %d matches' % len(matches)) logging.info('Found %d matches' % len(matches))
j.set_progress(100, tr("Removing false matches")) j.set_progress(100, tr("Removing false matches"))
if self.scan_type == ScanType.Folders and matches:
allpath = {m.first.path for m in matches}
allpath |= {m.second.path for m in matches}
sortedpaths = sorted(allpath)
toremove = set()
last_parent_path = sortedpaths[0]
for p in sortedpaths[1:]:
if p in last_parent_path:
toremove.add(p)
else:
last_parent_path = p
matches = [m for m in matches if m.first.path not in toremove or m.second.path not in toremove]
if not self.mix_file_kind: if not self.mix_file_kind:
matches = [m for m in matches if get_file_ext(m.first.name) == get_file_ext(m.second.name)] matches = [m for m in matches if get_file_ext(m.first.name) == get_file_ext(m.second.name)]
matches = [m for m in matches if io.exists(m.first.path) and io.exists(m.second.path)] matches = [m for m in matches if io.exists(m.first.path) and io.exists(m.second.path)]

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2007-06-23 # Created On: 2007-06-23
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -91,8 +91,8 @@ class TestCaseDupeGuru:
dgapp.copy_or_move(f, True, 'some_destination', 0) dgapp.copy_or_move(f, True, 'some_destination', 0)
eq_(1, len(hscommon.conflict.smart_copy.calls)) eq_(1, len(hscommon.conflict.smart_copy.calls))
call = hscommon.conflict.smart_copy.calls[0] call = hscommon.conflict.smart_copy.calls[0]
eq_('some_destination', call['dest_path']) eq_(call['dest_path'], op.join('some_destination', 'foo'))
eq_(f.path, call['source_path']) eq_(call['source_path'], f.path)
def test_copy_or_move_clean_empty_dirs(self, tmpdir, monkeypatch): def test_copy_or_move_clean_empty_dirs(self, tmpdir, monkeypatch):
tmppath = Path(str(tmpdir)) tmppath = Path(str(tmpdir))
@@ -136,6 +136,14 @@ class TestCaseDupeGuru:
app.start_scanning() app.start_scanning()
eq_(len(app.results.groups), 0) eq_(len(app.results.groups), 0)
def test_rename_when_nothing_is_selected(self):
# Issue #140
# It's possible that rename operation has its selected row swept off from under it, thus
# making the selected row None. Don't crash when it happens.
dgapp = DupeGuru()
rtable = ResultTable(CallLogger(), dgapp)
# selected_row is None because there's no result.
assert not rtable.rename_selected('foo') # no crash
class TestCaseDupeGuru_clean_empty_dirs: class TestCaseDupeGuru_clean_empty_dirs:
def pytest_funcarg__do_setup(self, request): def pytest_funcarg__do_setup(self, request):
@@ -462,3 +470,31 @@ class TestCaseDupeGuru_renameSelected:
assert 'foo bar 2' in names assert 'foo bar 2' in names
eq_(g.dupes[0].name, 'foo bar 2') eq_(g.dupes[0].name, 'foo bar 2')
class TestAppWithDirectoriesInTree:
def pytest_funcarg__do_setup(self, request):
tmpdir = request.getfuncargvalue('tmpdir')
p = Path(str(tmpdir))
io.mkdir(p + 'sub1')
io.mkdir(p + 'sub2')
io.mkdir(p + 'sub3')
self.app = DupeGuru()
self.dtree_gui = CallLogger()
self.dtree = DirectoryTree(self.dtree_gui, self.app)
self.dtree.connect()
self.dtree.add_directory(p)
self.dtree_gui.clear_calls()
def test_set_root_as_ref_makes_subfolders_ref_as_well(self, do_setup):
# Setting a node state to something also affect subnodes. These subnodes must be correctly
# refreshed.
node = self.dtree[0]
eq_(len(node), 3) # a len() call is required for subnodes to be loaded
subnode = node[0]
node.state = 1 # the state property is a state index
node = self.dtree[0]
eq_(len(node), 3)
subnode = node[0]
eq_(subnode.state, 1)
self.dtree_gui.check_gui_calls(['refresh'])

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2009-10-23 # Created On: 2009-10-23
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/02/27 # Created On: 2006/02/27
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -122,52 +122,52 @@ def test_states():
d = Directories() d = Directories()
p = testpath + 'onefile' p = testpath + 'onefile'
d.add_path(p) d.add_path(p)
eq_(STATE_NORMAL,d.get_state(p)) eq_(DirectoryState.Normal ,d.get_state(p))
d.set_state(p,STATE_REFERENCE) d.set_state(p, DirectoryState.Reference)
eq_(STATE_REFERENCE,d.get_state(p)) eq_(DirectoryState.Reference ,d.get_state(p))
eq_(STATE_REFERENCE,d.get_state(p + 'dir1')) eq_(DirectoryState.Reference ,d.get_state(p + 'dir1'))
eq_(1,len(d.states)) eq_(1,len(d.states))
eq_(p,list(d.states.keys())[0]) eq_(p,list(d.states.keys())[0])
eq_(STATE_REFERENCE,d.states[p]) eq_(DirectoryState.Reference ,d.states[p])
def test_get_state_with_path_not_there(): def test_get_state_with_path_not_there():
# When the path's not there, just return STATE_NORMAL # When the path's not there, just return DirectoryState.Normal
d = Directories() d = Directories()
d.add_path(testpath + 'onefile') d.add_path(testpath + 'onefile')
eq_(d.get_state(testpath), STATE_NORMAL) eq_(d.get_state(testpath), DirectoryState.Normal)
def test_states_remain_when_larger_directory_eat_smaller_ones(): def test_states_remain_when_larger_directory_eat_smaller_ones():
d = Directories() d = Directories()
p = testpath + 'onefile' p = testpath + 'onefile'
d.add_path(p) d.add_path(p)
d.set_state(p,STATE_EXCLUDED) d.set_state(p, DirectoryState.Excluded)
d.add_path(testpath) d.add_path(testpath)
d.set_state(testpath,STATE_REFERENCE) d.set_state(testpath, DirectoryState.Reference)
eq_(STATE_EXCLUDED,d.get_state(p)) eq_(DirectoryState.Excluded ,d.get_state(p))
eq_(STATE_EXCLUDED,d.get_state(p + 'dir1')) eq_(DirectoryState.Excluded ,d.get_state(p + 'dir1'))
eq_(STATE_REFERENCE,d.get_state(testpath)) eq_(DirectoryState.Reference ,d.get_state(testpath))
def test_set_state_keep_state_dict_size_to_minimum(): def test_set_state_keep_state_dict_size_to_minimum():
d = Directories() d = Directories()
p = testpath + 'fs' p = testpath + 'fs'
d.add_path(p) d.add_path(p)
d.set_state(p,STATE_REFERENCE) d.set_state(p, DirectoryState.Reference)
d.set_state(p + 'dir1',STATE_REFERENCE) d.set_state(p + 'dir1', DirectoryState.Reference)
eq_(1,len(d.states)) eq_(1,len(d.states))
eq_(STATE_REFERENCE,d.get_state(p + 'dir1')) eq_(DirectoryState.Reference ,d.get_state(p + 'dir1'))
d.set_state(p + 'dir1',STATE_NORMAL) d.set_state(p + 'dir1', DirectoryState.Normal)
eq_(2,len(d.states)) eq_(2,len(d.states))
eq_(STATE_NORMAL,d.get_state(p + 'dir1')) eq_(DirectoryState.Normal ,d.get_state(p + 'dir1'))
d.set_state(p + 'dir1',STATE_REFERENCE) d.set_state(p + 'dir1', DirectoryState.Reference)
eq_(1,len(d.states)) eq_(1,len(d.states))
eq_(STATE_REFERENCE,d.get_state(p + 'dir1')) eq_(DirectoryState.Reference ,d.get_state(p + 'dir1'))
def test_get_files(): def test_get_files():
d = Directories() d = Directories()
p = testpath + 'fs' p = testpath + 'fs'
d.add_path(p) d.add_path(p)
d.set_state(p + 'dir1',STATE_REFERENCE) d.set_state(p + 'dir1', DirectoryState.Reference)
d.set_state(p + 'dir2',STATE_EXCLUDED) d.set_state(p + 'dir2', DirectoryState.Excluded)
files = list(d.get_files()) files = list(d.get_files())
eq_(5, len(files)) eq_(5, len(files))
for f in files: for f in files:
@@ -176,11 +176,26 @@ def test_get_files():
else: else:
assert not f.is_ref assert not f.is_ref
def test_get_folders():
d = Directories()
p = testpath + 'fs'
d.add_path(p)
d.set_state(p + 'dir1', DirectoryState.Reference)
d.set_state(p + 'dir2', DirectoryState.Excluded)
folders = list(d.get_folders())
eq_(len(folders), 3)
ref = [f for f in folders if f.is_ref]
not_ref = [f for f in folders if not f.is_ref]
eq_(len(ref), 1)
eq_(ref[0].path, p + 'dir1')
eq_(len(not_ref), 2)
eq_(ref[0].size, 1)
def test_get_files_with_inherited_exclusion(): def test_get_files_with_inherited_exclusion():
d = Directories() d = Directories()
p = testpath + 'onefile' p = testpath + 'onefile'
d.add_path(p) d.add_path(p)
d.set_state(p,STATE_EXCLUDED) d.set_state(p, DirectoryState.Excluded)
eq_([], list(d.get_files())) eq_([], list(d.get_files()))
def test_save_and_load(tmpdir): def test_save_and_load(tmpdir):
@@ -192,14 +207,14 @@ def test_save_and_load(tmpdir):
io.mkdir(p2) io.mkdir(p2)
d1.add_path(p1) d1.add_path(p1)
d1.add_path(p2) d1.add_path(p2)
d1.set_state(p1, STATE_REFERENCE) d1.set_state(p1, DirectoryState.Reference)
d1.set_state(p1 + 'dir1',STATE_EXCLUDED) d1.set_state(p1 + 'dir1', DirectoryState.Excluded)
tmpxml = str(tmpdir.join('directories_testunit.xml')) tmpxml = str(tmpdir.join('directories_testunit.xml'))
d1.save_to_file(tmpxml) d1.save_to_file(tmpxml)
d2.load_from_file(tmpxml) d2.load_from_file(tmpxml)
eq_(2, len(d2)) eq_(2, len(d2))
eq_(STATE_REFERENCE,d2.get_state(p1)) eq_(DirectoryState.Reference ,d2.get_state(p1))
eq_(STATE_EXCLUDED,d2.get_state(p1 + 'dir1')) eq_(DirectoryState.Excluded ,d2.get_state(p1 + 'dir1'))
def test_invalid_path(): def test_invalid_path():
d = Directories() d = Directories()
@@ -211,7 +226,7 @@ def test_invalid_path():
def test_set_state_on_invalid_path(): def test_set_state_on_invalid_path():
d = Directories() d = Directories()
try: try:
d.set_state(Path('foobar',),STATE_NORMAL) d.set_state(Path('foobar',), DirectoryState.Normal)
except LookupError: except LookupError:
assert False assert False
@@ -237,7 +252,7 @@ def test_unicode_save(tmpdir):
io.mkdir(p1) io.mkdir(p1)
io.mkdir(p1 + 'foo\xe9') io.mkdir(p1 + 'foo\xe9')
d.add_path(p1) d.add_path(p1)
d.set_state(p1 + 'foo\xe9', STATE_EXCLUDED) d.set_state(p1 + 'foo\xe9', DirectoryState.Excluded)
tmpxml = str(tmpdir.join('directories_testunit.xml')) tmpxml = str(tmpdir.join('directories_testunit.xml'))
try: try:
d.save_to_file(tmpxml) d.save_to_file(tmpxml)
@@ -268,17 +283,17 @@ def test_get_state_returns_excluded_by_default_for_hidden_directories(tmpdir):
hidden_dir_path = p + '.foo' hidden_dir_path = p + '.foo'
io.mkdir(p + '.foo') io.mkdir(p + '.foo')
d.add_path(p) d.add_path(p)
eq_(d.get_state(hidden_dir_path), STATE_EXCLUDED) eq_(d.get_state(hidden_dir_path), DirectoryState.Excluded)
# But it can be overriden # But it can be overriden
d.set_state(hidden_dir_path, STATE_NORMAL) d.set_state(hidden_dir_path, DirectoryState.Normal)
eq_(d.get_state(hidden_dir_path), STATE_NORMAL) eq_(d.get_state(hidden_dir_path), DirectoryState.Normal)
def test_default_path_state_override(tmpdir): def test_default_path_state_override(tmpdir):
# It's possible for a subclass to override the default state of a path # It's possible for a subclass to override the default state of a path
class MyDirectories(Directories): class MyDirectories(Directories):
def _default_state_for_path(self, path): def _default_state_for_path(self, path):
if 'foobar' in path: if 'foobar' in path:
return STATE_EXCLUDED return DirectoryState.Excluded
d = MyDirectories() d = MyDirectories()
p1 = Path(str(tmpdir)) p1 = Path(str(tmpdir))
@@ -287,11 +302,11 @@ def test_default_path_state_override(tmpdir):
io.mkdir(p1 + 'foobaz') io.mkdir(p1 + 'foobaz')
io.open(p1 + 'foobaz/somefile', 'w').close() io.open(p1 + 'foobaz/somefile', 'w').close()
d.add_path(p1) d.add_path(p1)
eq_(d.get_state(p1 + 'foobaz'), STATE_NORMAL) eq_(d.get_state(p1 + 'foobaz'), DirectoryState.Normal)
eq_(d.get_state(p1 + 'foobar'), STATE_EXCLUDED) eq_(d.get_state(p1 + 'foobar'), DirectoryState.Excluded)
eq_(len(list(d.get_files())), 1) # only the 'foobaz' file is there eq_(len(list(d.get_files())), 1) # only the 'foobaz' file is there
# However, the default state can be changed # However, the default state can be changed
d.set_state(p1 + 'foobar', STATE_NORMAL) d.set_state(p1 + 'foobar', DirectoryState.Normal)
eq_(d.get_state(p1 + 'foobar'), STATE_NORMAL) eq_(d.get_state(p1 + 'foobar'), DirectoryState.Normal)
eq_(len(list(d.get_files())), 2) eq_(len(list(d.get_files())), 2)

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/01/29 # Created On: 2006/01/29
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2009-10-23 # Created On: 2009-10-23
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -11,14 +10,13 @@ import hashlib
from hscommon.path import Path from hscommon.path import Path
from hscommon.testutil import eq_ from hscommon.testutil import eq_
from core.fs import File
from core.tests.directories_test import create_fake_fs from core.tests.directories_test import create_fake_fs
from .. import fs from .. import fs
def test_size_aggregates_subfiles(tmpdir): def test_size_aggregates_subfiles(tmpdir):
p = create_fake_fs(Path(str(tmpdir))) p = create_fake_fs(Path(str(tmpdir)))
b = fs.Bundle(p) b = fs.Folder(p)
eq_(b.size, 12) eq_(b.size, 12)
def test_md5_aggregate_subfiles_sorted(tmpdir): def test_md5_aggregate_subfiles_sorted(tmpdir):
@@ -26,18 +24,22 @@ def test_md5_aggregate_subfiles_sorted(tmpdir):
#all files' md5 it contains, but it must make sure that it does so in the #all files' md5 it contains, but it must make sure that it does so in the
#same order everytime. #same order everytime.
p = create_fake_fs(Path(str(tmpdir))) p = create_fake_fs(Path(str(tmpdir)))
b = fs.Bundle(p) b = fs.Folder(p)
md5s = File(p + ('dir1', 'file1.test')).md5 md51 = fs.File(p + ('dir1', 'file1.test')).md5
md5s += File(p + ('dir2', 'file2.test')).md5 md52 = fs.File(p + ('dir2', 'file2.test')).md5
md5s += File(p + ('dir3', 'file3.test')).md5 md53 = fs.File(p + ('dir3', 'file3.test')).md5
md5s += File(p + 'file1.test').md5 md54 = fs.File(p + 'file1.test').md5
md5s += File(p + 'file2.test').md5 md55 = fs.File(p + 'file2.test').md5
md5s += File(p + 'file3.test').md5 md56 = fs.File(p + 'file3.test').md5
md5 = hashlib.md5(md5s) # The expected md5 is the md5 of md5s for folders and the direct md5 for files
folder_md51 = hashlib.md5(md51).digest()
folder_md52 = hashlib.md5(md52).digest()
folder_md53 = hashlib.md5(md53).digest()
md5 = hashlib.md5(folder_md51+folder_md52+folder_md53+md54+md55+md56)
eq_(b.md5, md5.digest()) eq_(b.md5, md5.digest())
def test_has_file_attrs(tmpdir): def test_has_file_attrs(tmpdir):
#a Bundle must behave like a file, so it must have mtime attributes #a Folder must behave like a file, so it must have mtime attributes
b = fs.Bundle(Path(str(tmpdir))) b = fs.Folder(Path(str(tmpdir)))
assert b.mtime > 0 assert b.mtime > 0
eq_(b.extension, '') eq_(b.extension, '')

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/05/02 # Created On: 2006/05/02
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,7 +1,7 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/02/23 # Created On: 2006/02/23
# $Id$ # $Id$
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -77,6 +77,18 @@ class TestCaseResultsEmpty:
self.results.groups = [] self.results.groups = []
assert not self.results.is_modified assert not self.results.is_modified
def test_save_to_same_name_as_folder(self, tmpdir):
# Issue #149
# When saving to a filename that already exists, the file is overwritten. However, when
# the name exists but that it's a folder, then there used to be a crash. The proper fix
# would have been some kind of feedback to the user, but the work involved for something
# that simply never happens (I never received a report of this crash, I experienced it
# while fooling around) is too much. Instead, use standard name conflict resolution.
folderpath = tmpdir.join('foo')
folderpath.mkdir()
self.results.save_to_xml(str(folderpath)) # no crash
assert tmpdir.join('[000] foo').check()
class TestCaseResultsWithSomeGroups: class TestCaseResultsWithSomeGroups:
def setup_method(self, method): def setup_method(self, method):

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/03/03 # Created On: 2006/03/03
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -471,3 +471,27 @@ def test_dont_group_files_that_dont_exist(tmpdir):
s._getmatches = getmatches s._getmatches = getmatches
assert not s.GetDupeGroups([file1, file2]) assert not s.GetDupeGroups([file1, file2])
def test_folder_scan_exclude_subfolder_matches(fake_fileexists):
# when doing a Folders scan type, don't include matches for folders whose parent folder already
# match.
s = Scanner()
s.scan_type = ScanType.Folders
topf1 = no("top folder 1", size=42)
topf1.md5 = topf1.md5partial = b"some_md5_1"
topf1.path = Path('/topf1')
topf2 = no("top folder 2", size=42)
topf2.md5 = topf2.md5partial = b"some_md5_1"
topf2.path = Path('/topf2')
subf1 = no("sub folder 1", size=41)
subf1.md5 = subf1.md5partial = b"some_md5_2"
subf1.path = Path('/topf1/sub')
subf2 = no("sub folder 2", size=41)
subf2.md5 = subf2.md5partial = b"some_md5_2"
subf2.path = Path('/topf2/sub')
eq_(len(s.GetDupeGroups([topf1, topf2, subf1, subf2])), 1) # only top folders
# however, if another folder matches a subfolder, keep in in the matches
otherf = no("other folder", size=41)
otherf.md5 = otherf.md5partial = b"some_md5_2"
otherf.path = Path('/otherfolder')
eq_(len(s.GetDupeGroups([topf1, topf2, subf1, subf2, otherf])), 2)

View File

@@ -1,2 +1,2 @@
__version__ = '6.0.0' __version__ = '6.0.1'
__appname__ = 'dupeGuru Music Edition' __appname__ = 'dupeGuru Music Edition'

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/11/16 # Created On: 2006/11/16
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/03/15 # Created On: 2006/03/15
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2009-10-23 # Created On: 2009-10-23
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/03/03 # Created On: 2006/03/03
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2009-10-23 # Created On: 2009-10-23
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/11/13 # Created On: 2006/11/13
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net) # Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -94,7 +94,7 @@ class Directories(directories.Directories):
directories.Directories.__init__(self, fileclasses=[Photo]) directories.Directories.__init__(self, fileclasses=[Photo])
try: try:
self.iphoto_libpath = get_iphoto_database_path() self.iphoto_libpath = get_iphoto_database_path()
self.set_state(self.iphoto_libpath[:-1], directories.STATE_EXCLUDED) self.set_state(self.iphoto_libpath[:-1], directories.DirectoryState.Excluded)
except directories.InvalidPathError: except directories.InvalidPathError:
self.iphoto_libpath = None self.iphoto_libpath = None
@@ -102,7 +102,7 @@ class Directories(directories.Directories):
if from_path == IPHOTO_PATH: if from_path == IPHOTO_PATH:
if self.iphoto_libpath is None: if self.iphoto_libpath is None:
return [] return []
is_ref = self.get_state(from_path) == directories.STATE_REFERENCE is_ref = self.get_state(from_path) == directories.DirectoryState.Reference
photos = get_iphoto_pictures(self.iphoto_libpath) photos = get_iphoto_pictures(self.iphoto_libpath)
for photo in photos: for photo in photos:
photo.is_ref = is_ref photo.is_ref = is_ref

Some files were not shown because too many files have changed in this diff Show More