mirror of
https://github.com/arsenetar/dupeguru.git
synced 2026-01-25 08:01:39 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5f29d775c | ||
|
|
ebd7f1b4ce | ||
|
|
279b7ad10c | ||
|
|
878205fc49 | ||
|
|
b16df32150 | ||
|
|
04b06f7704 | ||
|
|
c6ea1c62d4 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,6 +5,7 @@
|
|||||||
*.pyd
|
*.pyd
|
||||||
*.waf*
|
*.waf*
|
||||||
.lock-waf*
|
.lock-waf*
|
||||||
|
.idea
|
||||||
|
|
||||||
build
|
build
|
||||||
dist
|
dist
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
[dupeGuru][dupeguru] is a cross-platform (Linux, OS X, Windows) GUI tool to find duplicate files in
|
[dupeGuru][dupeguru] is a cross-platform (Linux, OS X, Windows) GUI tool to find duplicate files in
|
||||||
a system. It's written mostly in Python 3 and has the peculiarity of using
|
a system. It's written mostly in Python 3 and has the peculiarity of using
|
||||||
[multiple GUI toolkits][cross-toolkit], all using the same core Python code. On OS X, the UI layer
|
[multiple GUI toolkits][cross-toolkit], all using the same core Python code. On OS X, the UI layer
|
||||||
is written in Objective-C and uses Cocoa. On Linux and Windows, it's written in Python and uses Qt4.
|
is written in Objective-C and uses Cocoa. On Linux and Windows, it's written in Python and uses Qt5.
|
||||||
|
|
||||||
dupeGuru comes in 3 editions (standard, music and picture) which are all buildable from this same
|
dupeGuru comes in 3 editions (standard, music and picture) which are all buildable from this same
|
||||||
source tree. You choose the edition you want to build in a ``configure.py`` flag.
|
source tree. You choose the edition you want to build in a ``configure.py`` flag.
|
||||||
@@ -47,7 +47,7 @@ Prerequisites are installed through `pip`. However, some of them are not "pip in
|
|||||||
to be installed manually.
|
to be installed manually.
|
||||||
|
|
||||||
* All systems: [Python 3.3+][python] and [setuptools][setuptools]
|
* All systems: [Python 3.3+][python] and [setuptools][setuptools]
|
||||||
* Mac OS X: The last XCode to have the 10.6 SDK included.
|
* Mac OS X: The last XCode to have the 10.7 SDK included. Python 3.4+.
|
||||||
* Windows: Visual Studio 2010, [PyQt 5.0+][pyqt], [cx_Freeze][cxfreeze] and
|
* Windows: Visual Studio 2010, [PyQt 5.0+][pyqt], [cx_Freeze][cxfreeze] and
|
||||||
[Advanced Installer][advinst] (you only need the last two if you want to create an installer)
|
[Advanced Installer][advinst] (you only need the last two if you want to create an installer)
|
||||||
|
|
||||||
|
|||||||
@@ -152,8 +152,8 @@ class DupeGuru(Broadcaster):
|
|||||||
# select_dest_folder(prompt: str) --> str
|
# select_dest_folder(prompt: str) --> str
|
||||||
# select_dest_file(prompt: str, ext: str) --> str
|
# select_dest_file(prompt: str, ext: str) --> str
|
||||||
|
|
||||||
# in fairware prompts, we don't mention the edition, it's too long.
|
|
||||||
PROMPT_NAME = "dupeGuru"
|
PROMPT_NAME = "dupeGuru"
|
||||||
|
SCANNER_CLASS = scanner.Scanner
|
||||||
|
|
||||||
def __init__(self, view):
|
def __init__(self, view):
|
||||||
if view.get_default(DEBUG_MODE_PREFERENCE):
|
if view.get_default(DEBUG_MODE_PREFERENCE):
|
||||||
@@ -166,7 +166,7 @@ class DupeGuru(Broadcaster):
|
|||||||
os.makedirs(self.appdata)
|
os.makedirs(self.appdata)
|
||||||
self.directories = directories.Directories()
|
self.directories = directories.Directories()
|
||||||
self.results = results.Results(self)
|
self.results = results.Results(self)
|
||||||
self.scanner = scanner.Scanner()
|
self.scanner = self.SCANNER_CLASS()
|
||||||
self.options = {
|
self.options = {
|
||||||
'escape_filter_regexp': True,
|
'escape_filter_regexp': True,
|
||||||
'clean_empty_dirs': False,
|
'clean_empty_dirs': False,
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
__version__ = '2.9.0'
|
__version__ = '2.10.0'
|
||||||
__appname__ = 'dupeGuru Picture Edition'
|
__appname__ = 'dupeGuru Picture Edition'
|
||||||
@@ -17,10 +17,10 @@ from .result_table import ResultTable
|
|||||||
class DupeGuru(DupeGuruBase):
|
class DupeGuru(DupeGuruBase):
|
||||||
NAME = __appname__
|
NAME = __appname__
|
||||||
METADATA_TO_READ = ['size', 'mtime', 'dimensions', 'exif_timestamp']
|
METADATA_TO_READ = ['size', 'mtime', 'dimensions', 'exif_timestamp']
|
||||||
|
SCANNER_CLASS = ScannerPE
|
||||||
|
|
||||||
def __init__(self, view):
|
def __init__(self, view):
|
||||||
DupeGuruBase.__init__(self, view)
|
DupeGuruBase.__init__(self, view)
|
||||||
self.scanner = ScannerPE()
|
|
||||||
self.scanner.cache_path = op.join(self.appdata, 'cached_pictures.db')
|
self.scanner.cache_path = op.join(self.appdata, 'cached_pictures.db')
|
||||||
|
|
||||||
def _get_dupe_sort_key(self, dupe, get_group, key, delta):
|
def _get_dupe_sort_key(self, dupe, get_group, key, delta):
|
||||||
|
|||||||
@@ -8,24 +8,24 @@
|
|||||||
|
|
||||||
import plistlib
|
import plistlib
|
||||||
|
|
||||||
class IPhotoPlistParser(plistlib.PlistParser):
|
class IPhotoPlistParser(plistlib._PlistParser):
|
||||||
"""A parser for iPhoto plists.
|
"""A parser for iPhoto plists.
|
||||||
|
|
||||||
iPhoto plists tend to be malformed, so we have to subclass the built-in parser to be a bit more
|
iPhoto plists tend to be malformed, so we have to subclass the built-in parser to be a bit more
|
||||||
lenient.
|
lenient.
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
plistlib.PlistParser.__init__(self)
|
plistlib._PlistParser.__init__(self, use_builtin_types=True, dict_type=dict)
|
||||||
# For debugging purposes, we remember the last bit of data to be analyzed so that we can
|
# For debugging purposes, we remember the last bit of data to be analyzed so that we can
|
||||||
# log it in case of an exception
|
# log it in case of an exception
|
||||||
self.lastdata = ''
|
self.lastdata = ''
|
||||||
|
|
||||||
def getData(self):
|
def get_data(self):
|
||||||
self.lastdata = plistlib.PlistParser.getData(self)
|
self.lastdata = plistlib._PlistParser.get_data(self)
|
||||||
return self.lastdata
|
return self.lastdata
|
||||||
|
|
||||||
def end_integer(self):
|
def end_integer(self):
|
||||||
try:
|
try:
|
||||||
self.addObject(int(self.getData()))
|
self.add_object(int(self.get_data()))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.addObject(0)
|
self.add_object(0)
|
||||||
|
|||||||
@@ -1,3 +1,17 @@
|
|||||||
|
=== 2.10.0 (2014-05-03)
|
||||||
|
|
||||||
|
* This is mostly a dependencies upgrade.
|
||||||
|
* Upgraded to Python 3.3.
|
||||||
|
* Upgraded to Qt 5.
|
||||||
|
* Minimum Windows version is now Windows 7 64bit.
|
||||||
|
* Minimum Ubuntu version is now 14.04.
|
||||||
|
* Minimum OS X version is now 10.7 (Lion).
|
||||||
|
* ... But with a couple of little improvements.
|
||||||
|
* Improved documentation.
|
||||||
|
* Overwrite subfolders' state when setting states in folder dialog (#248)
|
||||||
|
* Fix empty Ignore List dialog bug. (#253)
|
||||||
|
* The error report dialog now brings the user to Github issues.
|
||||||
|
|
||||||
=== 2.9.0 (2013-12-22)
|
=== 2.9.0 (2013-12-22)
|
||||||
|
|
||||||
* Read RAW pictures EXIF tags. [Mac] (#234)
|
* Read RAW pictures EXIF tags. [Mac] (#234)
|
||||||
|
|||||||
13
package.py
13
package.py
@@ -18,7 +18,7 @@ import glob
|
|||||||
from hscommon.plat import ISWINDOWS, ISLINUX
|
from hscommon.plat import ISWINDOWS, ISLINUX
|
||||||
from hscommon.build import (add_to_pythonpath, print_and_do, copy_packages, build_debian_changelog,
|
from hscommon.build import (add_to_pythonpath, print_and_do, copy_packages, build_debian_changelog,
|
||||||
copy_qt_plugins, get_module_version, filereplace, copy, setup_package_argparser,
|
copy_qt_plugins, get_module_version, filereplace, copy, setup_package_argparser,
|
||||||
package_cocoa_app_in_dmg, copy_all)
|
package_cocoa_app_in_dmg, copy_all, find_in_path)
|
||||||
|
|
||||||
def parse_args():
|
def parse_args():
|
||||||
parser = ArgumentParser()
|
parser = ArgumentParser()
|
||||||
@@ -38,6 +38,7 @@ def package_windows(edition, dev):
|
|||||||
print("Qt packaging only works under Windows.")
|
print("Qt packaging only works under Windows.")
|
||||||
return
|
return
|
||||||
from cx_Freeze import setup, Executable
|
from cx_Freeze import setup, Executable
|
||||||
|
from PyQt5.QtCore import QLibraryInfo
|
||||||
add_to_pythonpath('.')
|
add_to_pythonpath('.')
|
||||||
app_version = get_module_version('core_{}'.format(edition))
|
app_version = get_module_version('core_{}'.format(edition))
|
||||||
distdir = 'dist'
|
distdir = 'dist'
|
||||||
@@ -80,13 +81,15 @@ def package_windows(edition, dev):
|
|||||||
executables=executables
|
executables=executables
|
||||||
)
|
)
|
||||||
|
|
||||||
print("Removing useless DLLs")
|
print("Removing useless files")
|
||||||
# Huge useless dll that appeared with Qt5
|
|
||||||
for fn in glob.glob(op.join(distdir, 'icu*.dll')):
|
|
||||||
os.remove(fn)
|
|
||||||
# Debug info that cx_freeze brings in.
|
# Debug info that cx_freeze brings in.
|
||||||
for fn in glob.glob(op.join(distdir, '*', '*.pdb')):
|
for fn in glob.glob(op.join(distdir, '*', '*.pdb')):
|
||||||
os.remove(fn)
|
os.remove(fn)
|
||||||
|
print("Copying forgotten DLLs")
|
||||||
|
qtlibpath = QLibraryInfo.location(QLibraryInfo.LibrariesPath)
|
||||||
|
shutil.copy(op.join(qtlibpath, 'libEGL.dll'), distdir)
|
||||||
|
shutil.copy(find_in_path('msvcp110.dll'), distdir)
|
||||||
|
print("Copying the rest")
|
||||||
help_path = op.join('build', 'help')
|
help_path = op.join('build', 'help')
|
||||||
print("Copying {} to dist\\help".format(help_path))
|
print("Copying {} to dist\\help".format(help_path))
|
||||||
shutil.copytree(help_path, op.join(distdir, 'help'))
|
shutil.copytree(help_path, op.join(distdir, 'help'))
|
||||||
|
|||||||
@@ -71,7 +71,6 @@ class ResultWindow(QMainWindow):
|
|||||||
|
|
||||||
def _setupMenu(self):
|
def _setupMenu(self):
|
||||||
self.menubar = QMenuBar()
|
self.menubar = QMenuBar()
|
||||||
self.menubar.setNativeMenuBar(False)
|
|
||||||
self.menubar.setGeometry(QRect(0, 0, 630, 22))
|
self.menubar.setGeometry(QRect(0, 0, 630, 22))
|
||||||
self.menuFile = QMenu(self.menubar)
|
self.menuFile = QMenu(self.menubar)
|
||||||
self.menuFile.setTitle(tr("File"))
|
self.menuFile.setTitle(tr("File"))
|
||||||
|
|||||||
Reference in New Issue
Block a user