mirror of
https://github.com/arsenetar/dupeguru.git
synced 2026-01-25 08:01:39 +00:00
Compare commits
75 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49839b8b8e | ||
|
|
500468ed1c | ||
|
|
de6f50ab12 | ||
|
|
2c6339f7a2 | ||
|
|
96c3d63557 | ||
|
|
e86b23259c | ||
|
|
89955aa96a | ||
|
|
39a601e393 | ||
|
|
3b9e11d14f | ||
|
|
81a7c4d6a6 | ||
|
|
35a162faf4 | ||
|
|
70e505ad92 | ||
|
|
aa3cf9700d | ||
|
|
e4b949abf6 | ||
|
|
2e23303d7e | ||
|
|
2fcaacd285 | ||
|
|
6627f0dbea | ||
|
|
a64b42de65 | ||
|
|
6dddcb1a47 | ||
|
|
4a8ce9b6c4 | ||
|
|
d4e6632e7e | ||
|
|
0ced3e39c8 | ||
|
|
26d923e175 | ||
|
|
592eba9eaa | ||
|
|
11450ae56a | ||
|
|
008bd1414e | ||
|
|
62f6cc3705 | ||
|
|
e16041c703 | ||
|
|
1103b58ec5 | ||
|
|
dc8b1b3b02 | ||
|
|
36b214443a | ||
|
|
d11e20f6ba | ||
|
|
477f73ffa4 | ||
|
|
0b5cd61540 | ||
|
|
17b5703885 | ||
|
|
7cac0b5d6e | ||
|
|
a4003b6072 | ||
|
|
fb26d7d077 | ||
|
|
f2cbb513d3 | ||
|
|
8c36218150 | ||
|
|
7637e493a6 | ||
|
|
62be8da6f9 | ||
|
|
b1c2941616 | ||
|
|
8efd3033a3 | ||
|
|
d417dbd2e3 | ||
|
|
3a717a86d8 | ||
|
|
e1f7260774 | ||
|
|
bfc1ee90ec | ||
|
|
93a5fd01b5 | ||
|
|
b028670250 | ||
|
|
dff141e800 | ||
|
|
f49c7dee96 | ||
|
|
5da793b029 | ||
|
|
a56258f8b3 | ||
|
|
ab6e0945a7 | ||
|
|
8ac035c8a9 | ||
|
|
1c15b0114b | ||
|
|
e78b14f9a2 | ||
|
|
573d088088 | ||
|
|
75b08125c0 | ||
|
|
20320f539f | ||
|
|
24771af955 | ||
|
|
2bfe9960f1 | ||
|
|
215bcb0d76 | ||
|
|
2dbf8b80ae | ||
|
|
470cd92030 | ||
|
|
111edc3ce5 | ||
|
|
df30a31782 | ||
|
|
91f3a59523 | ||
|
|
3441e51c0e | ||
|
|
a99c40b5d8 | ||
|
|
5b4de58c38 | ||
|
|
cd83b16dbd | ||
|
|
b67db988ab | ||
|
|
7ebea44cb0 |
13
.hgignore
13
.hgignore
@@ -8,26 +8,15 @@ run.py
|
|||||||
*.pyd
|
*.pyd
|
||||||
*.waf*
|
*.waf*
|
||||||
.lock-waf*
|
.lock-waf*
|
||||||
*.xcodeproj/xcuserdata
|
|
||||||
*.xcodeproj/project.xcworkspace/xcuserdata
|
|
||||||
conf.json
|
conf.json
|
||||||
build
|
build
|
||||||
dist
|
dist
|
||||||
install
|
install
|
||||||
installer_tmp-cache
|
installer_tmp-cache
|
||||||
|
env
|
||||||
cocoa/autogen
|
cocoa/autogen
|
||||||
cocoa/*/Info.plist
|
cocoa/*/Info.plist
|
||||||
cocoa/*/build
|
cocoa/*/build
|
||||||
cocoa/*/*.app
|
|
||||||
cs.lproj
|
|
||||||
de.lproj
|
|
||||||
fr.lproj
|
|
||||||
it.lproj
|
|
||||||
hy.lproj
|
|
||||||
ru.lproj
|
|
||||||
uk.lproj
|
|
||||||
zh_CN.lproj
|
|
||||||
pt_BR.lproj
|
|
||||||
qt/base/*_rc.py
|
qt/base/*_rc.py
|
||||||
help/*/conf.py
|
help/*/conf.py
|
||||||
help/*/changelog.rst
|
help/*/changelog.rst
|
||||||
7
.hgtags
7
.hgtags
@@ -78,3 +78,10 @@ c3d9f91dc9c9d60f370c72bc211f09be3e4fc18d se3.5.0
|
|||||||
e772f1de86744999ffbbe5845554417965b1dfba me6.4.1
|
e772f1de86744999ffbbe5845554417965b1dfba me6.4.1
|
||||||
c8a9a4d355927e509f514308c82306192bc71f92 pe2.6.0
|
c8a9a4d355927e509f514308c82306192bc71f92 pe2.6.0
|
||||||
a618e954f01e4bbdbe9a03e5667a67d62be995a7 me6.4.2
|
a618e954f01e4bbdbe9a03e5667a67d62be995a7 me6.4.2
|
||||||
|
0f18c4498a6c7529bf77207db70aed8a5ec96ee4 se3.6.0
|
||||||
|
8f478379ec62fd1329d527aafb1ab0f2410f3a79 me6.5.0
|
||||||
|
d773721e6c3260f8130f40b4ab10442edc9965ec pe2.7.0
|
||||||
|
6b42e0d5628b937aee8039ee34d4b329149718a5 se3.6.0-arch
|
||||||
|
df6e045b9e7679f2a1949a57060e5c1863904444 me6.5.0-arch
|
||||||
|
286ba6959cd0af059f245371a3afb52c1da91dee pe2.7.0-arch
|
||||||
|
810ab1e1324ed32dbd3b4db425e590dc0e344358 se3.6.1
|
||||||
|
|||||||
21
.tx/config
Normal file
21
.tx/config
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
[main]
|
||||||
|
host = https://www.transifex.net
|
||||||
|
|
||||||
|
[dupeguru.core]
|
||||||
|
file_filter = locale/<lang>/LC_MESSAGES/core.po
|
||||||
|
source_file = locale/core.pot
|
||||||
|
source_lang = en
|
||||||
|
type = PO
|
||||||
|
|
||||||
|
[dupeguru.columns]
|
||||||
|
file_filter = locale/<lang>/LC_MESSAGES/columns.po
|
||||||
|
source_file = locale/columns.pot
|
||||||
|
source_lang = en
|
||||||
|
type = PO
|
||||||
|
|
||||||
|
[dupeguru.ui]
|
||||||
|
file_filter = locale/<lang>/LC_MESSAGES/ui.po
|
||||||
|
source_file = locale/ui.pot
|
||||||
|
source_lang = en
|
||||||
|
type = PO
|
||||||
|
|
||||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
|||||||
Copyright 2012 Hardcoded Software Inc. (http://www.hardcoded.net)
|
Copyright 2013 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:
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
Contents
|
Contents
|
||||||
========
|
========
|
||||||
|
|
||||||
This package contains the source for dupeGuru. To learn how to build it, refer to the "Build dupeGuru" section. Below is the description of the various subfolders:
|
This package contains the source for dupeGuru. To learn how to build it, refer to the
|
||||||
|
"Build dupeGuru" section. Below is the description of the various subfolders:
|
||||||
|
|
||||||
- core: Contains the core logic code for dupeGuru. It's Python code written in TDD style.
|
- core: Contains the core logic code for dupeGuru. It's Python code.
|
||||||
- core_*: Edition-specific-cross-toolkit code written in Python.
|
- core_*: Edition-specific-cross-toolkit code written in Python.
|
||||||
- cocoa: UI code for the Cocoa toolkit. It's Objective-C code.
|
- cocoa: UI code for the Cocoa toolkit. It's Objective-C code.
|
||||||
- qt: UI code for the Qt toolkit. It's written in Python and uses PyQt.
|
- qt: UI code for the Qt toolkit. It's written in Python and uses PyQt.
|
||||||
- images: Images used by the different UI codebases.
|
- images: Images used by the different UI codebases.
|
||||||
- debian_*: Skeleton files required to create a .deb package
|
- debian: Skeleton files required to create a .deb package
|
||||||
- help: Help document, written for Sphinx.
|
- help: Help document, written for Sphinx.
|
||||||
|
|
||||||
There are also other sub-folder that comes from external repositories (automatically checked out
|
There are also other sub-folder that comes from external repositories (automatically checked out
|
||||||
with as mercurial subrepos):
|
as mercurial subrepos):
|
||||||
|
|
||||||
- hscommon: A collection of helpers used across HS applications.
|
- hscommon: A collection of helpers used across HS applications.
|
||||||
- cocoalib: A collection of helpers used across Cocoa UI codebases of HS applications.
|
- cocoalib: A collection of helpers used across Cocoa UI codebases of HS applications.
|
||||||
@@ -21,7 +22,8 @@ with as mercurial subrepos):
|
|||||||
dupeGuru Dependencies
|
dupeGuru Dependencies
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
Before being able to build dupeGuru, a few dependencies have to be installed:
|
Before being able to build dupeGuru, a few dependencies have to be installed. If you use pip, you
|
||||||
|
will not have to install them all manually (see "The easy way!" below):
|
||||||
|
|
||||||
General dependencies
|
General dependencies
|
||||||
--------------------
|
--------------------
|
||||||
@@ -39,7 +41,6 @@ OS X prerequisites
|
|||||||
|
|
||||||
- XCode's command line tools
|
- XCode's command line tools
|
||||||
- objp 1.1.0 (http://bitbucket.org/hsoft/objp)
|
- objp 1.1.0 (http://bitbucket.org/hsoft/objp)
|
||||||
- pluginbuilder 1.1.0 (http://bitbucket.org/hsoft/pluginbuilder)
|
|
||||||
- appscript 1.0.0 for ME and PE (http://appscript.sourceforge.net/)
|
- appscript 1.0.0 for ME and PE (http://appscript.sourceforge.net/)
|
||||||
- xibless 0.4.0 (https://bitbucket.org/hsoft/xibless)
|
- xibless 0.4.0 (https://bitbucket.org/hsoft/xibless)
|
||||||
|
|
||||||
@@ -47,14 +48,14 @@ Windows prerequisites
|
|||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
- Visual Studio 2008 (Express is enough) is needed to build C extensions. (http://www.microsoft.com/Express/)
|
- Visual Studio 2008 (Express is enough) is needed to build C extensions. (http://www.microsoft.com/Express/)
|
||||||
- PyQt 4.7.5 (http://www.riverbankcomputing.co.uk/news)
|
- PyQt 4.7+ (http://www.riverbankcomputing.co.uk/news)
|
||||||
- cx_Freeze, if you want to build a exe. You don't need it if you just want to run dupeGuru. (http://cx-freeze.sourceforge.net/)
|
- cx_Freeze, if you want to build a exe. You don't need it if you just want to run dupeGuru. (http://cx-freeze.sourceforge.net/)
|
||||||
- Advanced Installer, if you want to build the installer file. (http://www.advancedinstaller.com/)
|
- Advanced Installer, if you want to build the installer file. (http://www.advancedinstaller.com/)
|
||||||
|
|
||||||
Linux prerequisites
|
Linux prerequisites
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- PyQt 4.7.5 (http://www.riverbankcomputing.co.uk/news)
|
- PyQt 4.7+ (http://www.riverbankcomputing.co.uk/news)
|
||||||
|
|
||||||
The easy way!
|
The easy way!
|
||||||
-------------
|
-------------
|
||||||
@@ -64,12 +65,15 @@ There's an easy way to install the majority of the prerequisites above, and it's
|
|||||||
pip install -r requirements-[osx|win].txt
|
pip install -r requirements-[osx|win].txt
|
||||||
|
|
||||||
([osx|win] depends, of course, on your platform. On other platforms, just use requirements.txt).
|
([osx|win] depends, of course, on your platform. On other platforms, just use requirements.txt).
|
||||||
You might have to compile PyObjC manually (see gotchas below). Sparkle and
|
|
||||||
Advanced Installer, having nothing to do with Python, are also manual installs.
|
Advanced Installer, having nothing to do with Python, needs to be installed manually.
|
||||||
|
|
||||||
PyQt isn't in the requirements file either (there's no package uploaded on PyPI) and you also have
|
PyQt isn't in the requirements file either (there's no package uploaded on PyPI) and you also have
|
||||||
to install it manually.
|
to install it manually.
|
||||||
|
|
||||||
|
If you use a virtualenv (which you should), you have to enable the "site-packages" option because
|
||||||
|
dupeGuru will need the PyQt library which you'll have installed on your system.
|
||||||
|
|
||||||
Prerequisite gotchas
|
Prerequisite gotchas
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
@@ -93,17 +97,21 @@ pyqt4-dev-tools, mercurial and then python3-setuptools. Once you've done that, i
|
|||||||
Building dupeGuru
|
Building dupeGuru
|
||||||
=================
|
=================
|
||||||
|
|
||||||
First, make sure you meet the dependencies listed in the section above. Then you need to configure your build with:
|
First, make sure you meet the dependencies listed in the section above. Then you need to configure
|
||||||
|
your build with::
|
||||||
|
|
||||||
python configure.py
|
python configure.py
|
||||||
|
|
||||||
If you want, you can specify a UI to use with the `--ui` option. So, if you want to build dupeGuru with Qt on OS X, then you have to type `python configure.py --ui=qt`. You can also use the `--dev` flag to indicate a dev build (it will build `dg_cocoa.plugin` in alias mode and use the "dev" config in XCode).
|
If you want, you can specify a UI to use with the ``--ui`` option. So, if you want to build dupeGuru
|
||||||
|
with Qt on OS X, then you have to type ``python configure.py --ui=qt``. You can also use the
|
||||||
|
``--dev`` flag to indicate a dev build (mostly useful in OS X, where the python code in symlinked
|
||||||
|
so you don't have to repackage whenever you make a change in the python code).
|
||||||
|
|
||||||
Then, just build the thing and then run it with:
|
Then, just build the thing and then run it with::
|
||||||
|
|
||||||
python build.py
|
python build.py
|
||||||
python run.py
|
python run.py
|
||||||
|
|
||||||
If you want to create ready-to-upload package, run:
|
If you want to create ready-to-upload package, run::
|
||||||
|
|
||||||
python package.py
|
python package.py
|
||||||
102
build.py
102
build.py
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2009-12-30
|
# Created On: 2009-12-30
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
@@ -13,16 +13,18 @@ from optparse import OptionParser
|
|||||||
import shutil
|
import shutil
|
||||||
import json
|
import json
|
||||||
import importlib
|
import importlib
|
||||||
|
import compileall
|
||||||
|
|
||||||
from setuptools import setup, Extension
|
from setuptools import setup, Extension
|
||||||
|
|
||||||
from hscommon import sphinxgen
|
from hscommon import sphinxgen
|
||||||
from hscommon.build import (add_to_pythonpath, print_and_do, copy_packages, filereplace,
|
from hscommon.build import (add_to_pythonpath, print_and_do, copy_packages, filereplace,
|
||||||
get_module_version, move_all, copy_sysconfig_files_for_embed, copy_all, move, copy,
|
get_module_version, move_all, copy_sysconfig_files_for_embed, copy_all, OSXAppStructure,
|
||||||
OSXAppStructure, build_cocoalib_xibless, fix_qt_resource_file)
|
build_cocoalib_xibless, fix_qt_resource_file, build_cocoa_ext, copy_embeddable_python_dylib,
|
||||||
|
collect_stdlib_dependencies, copy)
|
||||||
from hscommon import loc
|
from hscommon import loc
|
||||||
from hscommon.plat import ISOSX
|
from hscommon.plat import ISOSX, ISLINUX
|
||||||
from hscommon.util import ensure_folder
|
from hscommon.util import ensure_folder, delete_files_with_pattern
|
||||||
|
|
||||||
def parse_args():
|
def parse_args():
|
||||||
usage = "usage: %prog [options]"
|
usage = "usage: %prog [options]"
|
||||||
@@ -95,27 +97,37 @@ def build_cocoa(edition, dev):
|
|||||||
build_cocoa_proxy_module()
|
build_cocoa_proxy_module()
|
||||||
build_cocoa_bridging_interfaces(edition)
|
build_cocoa_bridging_interfaces(edition)
|
||||||
print("Building the cocoa layer")
|
print("Building the cocoa layer")
|
||||||
from pluginbuilder import copy_embeddable_python_dylib, collect_dependencies
|
|
||||||
copy_embeddable_python_dylib('build')
|
copy_embeddable_python_dylib('build')
|
||||||
pydep_folder = op.join(app.resources, 'py')
|
pydep_folder = op.join(app.resources, 'py')
|
||||||
if not op.exists(pydep_folder):
|
if not op.exists(pydep_folder):
|
||||||
os.mkdir(pydep_folder)
|
os.mkdir(pydep_folder)
|
||||||
shutil.copy(op.join(cocoa_project_path, 'dg_cocoa.py'), 'build')
|
shutil.copy(op.join(cocoa_project_path, 'dg_cocoa.py'), 'build')
|
||||||
|
appscript_pkgs = ['appscript', 'aem', 'mactypes']
|
||||||
specific_packages = {
|
specific_packages = {
|
||||||
'se': ['core_se'],
|
'se': ['core_se'],
|
||||||
'me': ['core_me'],
|
'me': ['core_me'] + appscript_pkgs,
|
||||||
'pe': ['core_pe'],
|
'pe': ['core_pe'] + appscript_pkgs,
|
||||||
}[edition]
|
}[edition]
|
||||||
tocopy = ['core', 'hscommon', 'cocoa/inter', 'cocoalib/cocoa'] + specific_packages
|
tocopy = ['core', 'hscommon', 'cocoa/inter', 'cocoalib/cocoa', 'jobprogress', 'objp',
|
||||||
copy_packages(tocopy, 'build')
|
'send2trash'] + specific_packages
|
||||||
|
copy_packages(tocopy, pydep_folder, create_links=dev)
|
||||||
sys.path.insert(0, 'build')
|
sys.path.insert(0, 'build')
|
||||||
collect_dependencies('build/dg_cocoa.py', pydep_folder, excludes=['PyQt4'])
|
extra_deps = None
|
||||||
|
if edition == 'pe':
|
||||||
|
# ModuleFinder can't seem to correctly detect the multiprocessing dependency, so we have
|
||||||
|
# to manually specify it.
|
||||||
|
extra_deps=['multiprocessing']
|
||||||
|
collect_stdlib_dependencies('build/dg_cocoa.py', pydep_folder, extra_deps=extra_deps)
|
||||||
del sys.path[0]
|
del sys.path[0]
|
||||||
if dev:
|
|
||||||
copy_packages(tocopy, pydep_folder, create_links=True)
|
|
||||||
# Views are not referenced by python code, so they're not found by the collector.
|
# Views are not referenced by python code, so they're not found by the collector.
|
||||||
copy_all('build/inter/*.so', op.join(pydep_folder, 'inter'))
|
copy_all('build/inter/*.so', op.join(pydep_folder, 'inter'))
|
||||||
copy_sysconfig_files_for_embed(pydep_folder)
|
copy_sysconfig_files_for_embed(pydep_folder)
|
||||||
|
if not dev:
|
||||||
|
# Important: Don't ever run delete_files_with_pattern('*.py') on dev builds because you'll
|
||||||
|
# be deleting all py files in symlinked folders.
|
||||||
|
compileall.compile_dir(pydep_folder, force=True, legacy=True)
|
||||||
|
delete_files_with_pattern(pydep_folder, '*.py')
|
||||||
|
delete_files_with_pattern(pydep_folder, '__pycache__')
|
||||||
print("Compiling with WAF")
|
print("Compiling with WAF")
|
||||||
os.chdir('cocoa')
|
os.chdir('cocoa')
|
||||||
print_and_do(cocoa_compile_command(edition))
|
print_and_do(cocoa_compile_command(edition))
|
||||||
@@ -127,20 +139,18 @@ def build_cocoa(edition, dev):
|
|||||||
app.copy_resources(*resources, use_symlinks=dev)
|
app.copy_resources(*resources, use_symlinks=dev)
|
||||||
app.copy_frameworks('build/Python', 'cocoalib/Sparkle.framework')
|
app.copy_frameworks('build/Python', 'cocoalib/Sparkle.framework')
|
||||||
print("Creating the run.py file")
|
print("Creating the run.py file")
|
||||||
tmpl = open('run_template_cocoa.py', 'rt').read()
|
tmpl = open('cocoa/run_template.py', 'rt').read()
|
||||||
run_contents = tmpl.replace('{{app_path}}', app.dest)
|
run_contents = tmpl.replace('{{app_path}}', app.dest)
|
||||||
open('run.py', 'wt').write(run_contents)
|
open('run.py', 'wt').write(run_contents)
|
||||||
|
|
||||||
def build_qt(edition, dev):
|
def build_qt(edition, dev, conf):
|
||||||
print("Building localizations")
|
print("Building localizations")
|
||||||
build_localizations('qt', edition)
|
build_localizations('qt', edition)
|
||||||
print("Building Qt stuff")
|
print("Building Qt stuff")
|
||||||
print_and_do("pyrcc4 -py3 {0} > {1}".format(op.join('qt', 'base', 'dg.qrc'), op.join('qt', 'base', 'dg_rc.py')))
|
print_and_do("pyrcc4 -py3 {0} > {1}".format(op.join('qt', 'base', 'dg.qrc'), op.join('qt', 'base', 'dg_rc.py')))
|
||||||
fix_qt_resource_file(op.join('qt', 'base', 'dg_rc.py'))
|
fix_qt_resource_file(op.join('qt', 'base', 'dg_rc.py'))
|
||||||
print("Creating the run.py file")
|
print("Creating the run.py file")
|
||||||
tmpl = open('run_template_qt.py', 'rt').read()
|
filereplace(op.join('qt', 'run_template.py'), 'run.py', edition=edition)
|
||||||
run_contents = tmpl.replace('{{edition}}', edition)
|
|
||||||
open('run.py', 'wt').write(run_contents)
|
|
||||||
|
|
||||||
def build_help(edition):
|
def build_help(edition):
|
||||||
print("Generating Help")
|
print("Generating Help")
|
||||||
@@ -161,24 +171,6 @@ def build_base_localizations():
|
|||||||
loc.compile_all_po(op.join('hscommon', 'locale'))
|
loc.compile_all_po(op.join('hscommon', 'locale'))
|
||||||
loc.merge_locale_dir(op.join('hscommon', 'locale'), 'locale')
|
loc.merge_locale_dir(op.join('hscommon', 'locale'), 'locale')
|
||||||
|
|
||||||
def build_cocoa_localizations(edition):
|
|
||||||
print("Creating lproj folders based on .po files")
|
|
||||||
app = cocoa_app(edition)
|
|
||||||
en_stringsfile = op.join('cocoa', 'base', 'en.lproj', 'Localizable.strings')
|
|
||||||
en_cocoastringsfile = op.join('cocoalib', 'en.lproj', 'cocoalib.strings')
|
|
||||||
for lang in loc.get_langs('locale'):
|
|
||||||
pofile = op.join('locale', lang, 'LC_MESSAGES', 'ui.po')
|
|
||||||
dest_lproj = op.join(app.resources, lang + '.lproj')
|
|
||||||
ensure_folder(dest_lproj)
|
|
||||||
loc.po2strings(pofile, en_stringsfile, op.join(dest_lproj, 'Localizable.strings'))
|
|
||||||
pofile = op.join('cocoalib', 'locale', lang, 'LC_MESSAGES', 'cocoalib.po')
|
|
||||||
loc.po2strings(pofile, en_cocoastringsfile, op.join(dest_lproj, 'cocoalib.strings'))
|
|
||||||
# We also have to copy the "en.lproj" strings
|
|
||||||
en_lproj = op.join(app.resources, 'en.lproj')
|
|
||||||
ensure_folder(en_lproj)
|
|
||||||
copy(en_stringsfile, en_lproj)
|
|
||||||
copy(en_cocoastringsfile, en_lproj)
|
|
||||||
|
|
||||||
def build_qt_localizations():
|
def build_qt_localizations():
|
||||||
loc.compile_all_po(op.join('qtlib', 'locale'))
|
loc.compile_all_po(op.join('qtlib', 'locale'))
|
||||||
loc.merge_locale_dir(op.join('qtlib', 'locale'), 'locale')
|
loc.merge_locale_dir(op.join('qtlib', 'locale'), 'locale')
|
||||||
@@ -186,14 +178,24 @@ def build_qt_localizations():
|
|||||||
def build_localizations(ui, edition):
|
def build_localizations(ui, edition):
|
||||||
build_base_localizations()
|
build_base_localizations()
|
||||||
if ui == 'cocoa':
|
if ui == 'cocoa':
|
||||||
build_cocoa_localizations(edition)
|
app = cocoa_app(edition)
|
||||||
locale_dest = op.join(cocoa_app(edition).resources, 'locale')
|
loc.build_cocoa_localizations(app, en_stringsfile=op.join('cocoa', 'base', 'en.lproj', 'Localizable.strings'))
|
||||||
|
locale_dest = op.join(app.resources, 'locale')
|
||||||
elif ui == 'qt':
|
elif ui == 'qt':
|
||||||
build_qt_localizations()
|
build_qt_localizations()
|
||||||
locale_dest = op.join('build', 'locale')
|
locale_dest = op.join('build', 'locale')
|
||||||
if op.exists(locale_dest):
|
if op.exists(locale_dest):
|
||||||
shutil.rmtree(locale_dest)
|
shutil.rmtree(locale_dest)
|
||||||
shutil.copytree('locale', locale_dest, ignore=shutil.ignore_patterns('*.po', '*.pot'))
|
shutil.copytree('locale', locale_dest, ignore=shutil.ignore_patterns('*.po', '*.pot'))
|
||||||
|
if ui == 'qt' and not ISLINUX:
|
||||||
|
print("Copying qt_*.qm files into the 'locale' folder")
|
||||||
|
from PyQt4.QtCore import QLibraryInfo
|
||||||
|
trfolder = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
|
||||||
|
for lang in loc.get_langs('locale'):
|
||||||
|
qmname = 'qt_%s.qm' % lang
|
||||||
|
src = op.join(trfolder, qmname)
|
||||||
|
if op.exists(src):
|
||||||
|
copy(src, op.join('build', 'locale', qmname))
|
||||||
|
|
||||||
def build_updatepot():
|
def build_updatepot():
|
||||||
if ISOSX:
|
if ISOSX:
|
||||||
@@ -212,8 +214,10 @@ def build_updatepot():
|
|||||||
print("Building columns.pot")
|
print("Building columns.pot")
|
||||||
loc.generate_pot(all_cores, op.join('locale', 'columns.pot'), ['coltr'])
|
loc.generate_pot(all_cores, op.join('locale', 'columns.pot'), ['coltr'])
|
||||||
print("Building ui.pot")
|
print("Building ui.pot")
|
||||||
|
# When we're not under OS X, we don't want to overwrite ui.pot because it contains Cocoa locs
|
||||||
|
# We want to merge the generated pot with the old pot in the most preserving way possible.
|
||||||
ui_packages = ['qt', op.join('cocoa', 'inter')]
|
ui_packages = ['qt', op.join('cocoa', 'inter')]
|
||||||
loc.generate_pot(ui_packages, op.join('locale', 'ui.pot'), ['tr'])
|
loc.generate_pot(ui_packages, op.join('locale', 'ui.pot'), ['tr'], merge=(not ISOSX))
|
||||||
print("Building hscommon.pot")
|
print("Building hscommon.pot")
|
||||||
loc.generate_pot(['hscommon'], op.join('hscommon', 'locale', 'hscommon.pot'), ['tr'])
|
loc.generate_pot(['hscommon'], op.join('hscommon', 'locale', 'hscommon.pot'), ['tr'])
|
||||||
print("Building qtlib.pot")
|
print("Building qtlib.pot")
|
||||||
@@ -234,16 +238,6 @@ def build_mergepot():
|
|||||||
loc.merge_pots_into_pos(op.join('qtlib', 'locale'))
|
loc.merge_pots_into_pos(op.join('qtlib', 'locale'))
|
||||||
loc.merge_pots_into_pos(op.join('cocoalib', 'locale'))
|
loc.merge_pots_into_pos(op.join('cocoalib', 'locale'))
|
||||||
|
|
||||||
def build_cocoa_ext(extname, dest, source_files, extra_frameworks=(), extra_includes=()):
|
|
||||||
extra_link_args = ["-framework", "CoreFoundation", "-framework", "Foundation"]
|
|
||||||
for extra in extra_frameworks:
|
|
||||||
extra_link_args += ['-framework', extra]
|
|
||||||
ext = Extension(extname, source_files, extra_link_args=extra_link_args, include_dirs=extra_includes)
|
|
||||||
setup(script_args=['build_ext', '--inplace'], ext_modules=[ext])
|
|
||||||
fn = extname + '.so'
|
|
||||||
assert op.exists(fn)
|
|
||||||
move(fn, op.join(dest, fn))
|
|
||||||
|
|
||||||
def build_cocoa_proxy_module():
|
def build_cocoa_proxy_module():
|
||||||
print("Building Cocoa Proxy")
|
print("Building Cocoa Proxy")
|
||||||
import objp.p2o
|
import objp.p2o
|
||||||
@@ -261,7 +255,7 @@ def build_cocoa_bridging_interfaces(edition):
|
|||||||
add_to_pythonpath('cocoa')
|
add_to_pythonpath('cocoa')
|
||||||
add_to_pythonpath('cocoalib')
|
add_to_pythonpath('cocoalib')
|
||||||
from cocoa.inter import (PyGUIObject, GUIObjectView, PyColumns, ColumnsView, PyOutline,
|
from cocoa.inter import (PyGUIObject, GUIObjectView, PyColumns, ColumnsView, PyOutline,
|
||||||
OutlineView, PySelectableList, SelectableListView, PyTable, TableView, PyFairware)
|
OutlineView, PySelectableList, SelectableListView, PyTable, TableView, PyBaseApp, PyFairware)
|
||||||
from inter.deletion_options import PyDeletionOptions, DeletionOptionsView
|
from inter.deletion_options import PyDeletionOptions, DeletionOptionsView
|
||||||
from inter.details_panel import PyDetailsPanel, DetailsPanelView
|
from inter.details_panel import PyDetailsPanel, DetailsPanelView
|
||||||
from inter.directory_outline import PyDirectoryOutline, DirectoryOutlineView
|
from inter.directory_outline import PyDirectoryOutline, DirectoryOutlineView
|
||||||
@@ -273,7 +267,7 @@ def build_cocoa_bridging_interfaces(edition):
|
|||||||
from inter.stats_label import PyStatsLabel, StatsLabelView
|
from inter.stats_label import PyStatsLabel, StatsLabelView
|
||||||
from inter.app import PyDupeGuruBase, DupeGuruView
|
from inter.app import PyDupeGuruBase, DupeGuruView
|
||||||
appmod = importlib.import_module('inter.app_{}'.format(edition))
|
appmod = importlib.import_module('inter.app_{}'.format(edition))
|
||||||
allclasses = [PyGUIObject, PyColumns, PyOutline, PySelectableList, PyTable, PyFairware,
|
allclasses = [PyGUIObject, PyColumns, PyOutline, PySelectableList, PyTable, PyBaseApp, PyFairware,
|
||||||
PyDetailsPanel, PyDirectoryOutline, PyPrioritizeDialog, PyPrioritizeList, PyProblemDialog,
|
PyDetailsPanel, PyDirectoryOutline, PyPrioritizeDialog, PyPrioritizeList, PyProblemDialog,
|
||||||
PyIgnoreListDialog, PyDeletionOptions, PyResultTable, PyStatsLabel, PyDupeGuruBase,
|
PyIgnoreListDialog, PyDeletionOptions, PyResultTable, PyStatsLabel, PyDupeGuruBase,
|
||||||
appmod.PyDupeGuru]
|
appmod.PyDupeGuru]
|
||||||
@@ -310,7 +304,7 @@ def build_pe_modules(ui):
|
|||||||
move_all('_block*', 'core_pe')
|
move_all('_block*', 'core_pe')
|
||||||
move_all('_cache*', 'core_pe')
|
move_all('_cache*', 'core_pe')
|
||||||
|
|
||||||
def build_normal(edition, ui, dev):
|
def build_normal(edition, ui, dev, conf):
|
||||||
print("Building dupeGuru {0} with UI {1}".format(edition.upper(), ui))
|
print("Building dupeGuru {0} with UI {1}".format(edition.upper(), ui))
|
||||||
add_to_pythonpath('.')
|
add_to_pythonpath('.')
|
||||||
build_help(edition)
|
build_help(edition)
|
||||||
@@ -320,7 +314,7 @@ def build_normal(edition, ui, dev):
|
|||||||
if ui == 'cocoa':
|
if ui == 'cocoa':
|
||||||
build_cocoa(edition, dev)
|
build_cocoa(edition, dev)
|
||||||
elif ui == 'qt':
|
elif ui == 'qt':
|
||||||
build_qt(edition, dev)
|
build_qt(edition, dev, conf)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
options = parse_args()
|
options = parse_args()
|
||||||
@@ -355,7 +349,7 @@ def main():
|
|||||||
build_cocoalib_xibless()
|
build_cocoalib_xibless()
|
||||||
build_xibless(edition)
|
build_xibless(edition)
|
||||||
else:
|
else:
|
||||||
build_normal(edition, ui, dev)
|
build_normal(edition, ui, dev, conf)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
@@ -13,7 +13,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
#import "DetailsPanel.h"
|
#import "DetailsPanel.h"
|
||||||
#import "DirectoryPanel.h"
|
#import "DirectoryPanel.h"
|
||||||
#import "IgnoreListDialog.h"
|
#import "IgnoreListDialog.h"
|
||||||
#import "HSAboutBox.h"
|
#import "HSFairwareAboutBox.h"
|
||||||
#import "HSRecentFiles.h"
|
#import "HSRecentFiles.h"
|
||||||
|
|
||||||
@interface AppDelegateBase : NSObject
|
@interface AppDelegateBase : NSObject
|
||||||
@@ -28,7 +28,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
DetailsPanel *_detailsPanel;
|
DetailsPanel *_detailsPanel;
|
||||||
IgnoreListDialog *_ignoreListDialog;
|
IgnoreListDialog *_ignoreListDialog;
|
||||||
NSWindowController *_preferencesPanel;
|
NSWindowController *_preferencesPanel;
|
||||||
HSAboutBox *_aboutBox;
|
HSFairwareAboutBox *_aboutBox;
|
||||||
HSRecentFiles *_recentResults;
|
HSRecentFiles *_recentResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,6 +72,5 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
/* model --> view */
|
/* model --> view */
|
||||||
- (void)showMessage:(NSString *)msg;
|
- (void)showMessage:(NSString *)msg;
|
||||||
- (void)setupAsRegistered;
|
- (void)setupAsRegistered;
|
||||||
- (void)showFairwareNagWithPrompt:(NSString *)prompt;
|
|
||||||
- (void)showDemoNagWithPrompt:(NSString *)prompt;
|
- (void)showDemoNagWithPrompt:(NSString *)prompt;
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
@@ -160,7 +160,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
- (void)showAboutBox
|
- (void)showAboutBox
|
||||||
{
|
{
|
||||||
if (_aboutBox == nil) {
|
if (_aboutBox == nil) {
|
||||||
_aboutBox = [[HSAboutBox alloc] initWithApp:model];
|
_aboutBox = [[HSFairwareAboutBox alloc] initWithApp:model];
|
||||||
}
|
}
|
||||||
[[_aboutBox window] makeKeyAndOrderFront:nil];
|
[[_aboutBox window] makeKeyAndOrderFront:nil];
|
||||||
}
|
}
|
||||||
@@ -265,11 +265,6 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)showFairwareNagWithPrompt:(NSString *)prompt
|
|
||||||
{
|
|
||||||
[HSFairwareReminder showFairwareNagWithApp:[self model] prompt:prompt];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)showDemoNagWithPrompt:(NSString *)prompt
|
- (void)showDemoNagWithPrompt:(NSString *)prompt
|
||||||
{
|
{
|
||||||
[HSFairwareReminder showDemoNagWithApp:[self model] prompt:prompt];
|
[HSFairwareReminder showDemoNagWithApp:[self model] prompt:prompt];
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
http://www.hardcoded.net/licenses/bsd_license
|
http://www.hardcoded.net/licenses/bsd_license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "ResultWindow.h"
|
#import "ResultWindowBase.h"
|
||||||
#import "ResultWindow_UI.h"
|
#import "ResultWindow_UI.h"
|
||||||
#import "Dialogs.h"
|
#import "Dialogs.h"
|
||||||
#import "ProgressController.h"
|
#import "ProgressController.h"
|
||||||
@@ -29,7 +29,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
app = aApp;
|
app = aApp;
|
||||||
model = [app model];
|
model = [app model];
|
||||||
[self setWindow:createResultWindow_UI(self)];
|
[self setWindow:createResultWindow_UI(self)];
|
||||||
[[self window] setTitle:fmt(@"%@ Results", [model appName])];
|
[[self window] setTitle:fmt(NSLocalizedString(@"%@ Results", @""), [model appName])];
|
||||||
/* Put a cute iTunes-like bottom bar */
|
/* Put a cute iTunes-like bottom bar */
|
||||||
[[self window] setContentBorderThickness:28 forEdge:NSMinYEdge];
|
[[self window] setContentBorderThickness:28 forEdge:NSMinYEdge];
|
||||||
table = [[ResultTable alloc] initWithPyRef:[model resultTable] view:matches];
|
table = [[ResultTable alloc] initWithPyRef:[model resultTable] view:matches];
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
"%@ Results" = "%@ Results";
|
||||||
"A previous action is still hanging in there. You can't start a new one yet. Wait a few seconds, then try again." = "A previous action is still hanging in there. You can't start a new one yet. Wait a few seconds, then try again.";
|
"A previous action is still hanging in there. You can't start a new one yet. Wait a few seconds, then try again." = "A previous action is still hanging in there. You can't start a new one yet. Wait a few seconds, then try again.";
|
||||||
"About dupeGuru" = "About dupeGuru";
|
"About dupeGuru" = "About dupeGuru";
|
||||||
"Action" = "Action";
|
"Action" = "Action";
|
||||||
@@ -82,7 +83,7 @@
|
|||||||
"Load Recent Results" = "Load Recent Results";
|
"Load Recent Results" = "Load Recent Results";
|
||||||
"Load Results" = "Load Results";
|
"Load Results" = "Load Results";
|
||||||
"Load Results..." = "Load Results...";
|
"Load Results..." = "Load Results...";
|
||||||
"Make Selected Reference" = "Make Selected Reference";
|
"Make Selected into Reference" = "Make Selected into Reference";
|
||||||
"Mark All" = "Mark All";
|
"Mark All" = "Mark All";
|
||||||
"Mark None" = "Mark None";
|
"Mark None" = "Mark None";
|
||||||
"Mark Selected" = "Mark Selected";
|
"Mark Selected" = "Mark Selected";
|
||||||
@@ -104,7 +105,7 @@
|
|||||||
"Quick Look" = "Quick Look";
|
"Quick Look" = "Quick Look";
|
||||||
"Quit dupeGuru" = "Quit dupeGuru";
|
"Quit dupeGuru" = "Quit dupeGuru";
|
||||||
"Re-Prioritize duplicates" = "Re-Prioritize duplicates";
|
"Re-Prioritize duplicates" = "Re-Prioritize duplicates";
|
||||||
"Re-Prioritize Results" = "Re-Prioritize Results";
|
"Re-Prioritize Results..." = "Re-Prioritize Results...";
|
||||||
"Recreate absolute path" = "Recreate absolute path";
|
"Recreate absolute path" = "Recreate absolute path";
|
||||||
"Recreate relative path" = "Recreate relative path";
|
"Recreate relative path" = "Recreate relative path";
|
||||||
"Reference" = "Reference";
|
"Reference" = "Reference";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -52,11 +52,11 @@ actionMenu.addItem("Send Marked to Trash...", Action(None, 'trashMarked'), 'cmd+
|
|||||||
actionMenu.addItem("Move Marked to...", Action(None, 'moveMarked'), 'cmd+m')
|
actionMenu.addItem("Move Marked to...", Action(None, 'moveMarked'), 'cmd+m')
|
||||||
actionMenu.addItem("Copy Marked to...", Action(None, 'copyMarked'), 'cmd+alt+m')
|
actionMenu.addItem("Copy Marked to...", Action(None, 'copyMarked'), 'cmd+alt+m')
|
||||||
actionMenu.addItem("Remove Marked from Results", Action(None, 'removeMarked'), 'cmd+r')
|
actionMenu.addItem("Remove Marked from Results", Action(None, 'removeMarked'), 'cmd+r')
|
||||||
actionMenu.addItem("Re-Prioritize Results", Action(None, 'reprioritizeResults'))
|
actionMenu.addItem("Re-Prioritize Results...", Action(None, 'reprioritizeResults'))
|
||||||
actionMenu.addSeparator()
|
actionMenu.addSeparator()
|
||||||
actionMenu.addItem("Remove Selected from Results", Action(None, 'removeSelected'), 'cmd+backspace')
|
actionMenu.addItem("Remove Selected from Results", Action(None, 'removeSelected'), 'cmd+backspace')
|
||||||
actionMenu.addItem("Add Selected to Ignore List", Action(None, 'ignoreSelected'), 'cmd+g')
|
actionMenu.addItem("Add Selected to Ignore List", Action(None, 'ignoreSelected'), 'cmd+g')
|
||||||
actionMenu.addItem("Make Selected Reference", Action(None, 'switchSelected'), 'cmd+arrowup')
|
actionMenu.addItem("Make Selected into Reference", Action(None, 'switchSelected'), 'cmd+arrowup')
|
||||||
actionMenu.addSeparator()
|
actionMenu.addSeparator()
|
||||||
actionMenu.addItem("Open Selected with Default Application", Action(None, 'openSelected'), 'cmd+return')
|
actionMenu.addItem("Open Selected with Default Application", Action(None, 'openSelected'), 'cmd+return')
|
||||||
actionMenu.addItem("Reveal Selected in Finder", Action(None, 'revealSelected'), 'cmd+alt+return')
|
actionMenu.addItem("Reveal Selected in Finder", Action(None, 'revealSelected'), 'cmd+alt+return')
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
wnerclass = 'ResultWindow'
|
ownerclass = 'ResultWindowBase'
|
||||||
ownerimport = 'ResultWindow.h'
|
ownerimport = 'ResultWindowBase.h'
|
||||||
|
|
||||||
result = Window(557, 400, "dupeGuru Results")
|
result = Window(557, 400, "dupeGuru Results")
|
||||||
toolbar = result.createToolbar('ResultsToolbar')
|
toolbar = result.createToolbar('ResultsToolbar')
|
||||||
@@ -57,7 +57,7 @@ actionPopup.menu.addSeparator()
|
|||||||
for menu in (actionPopup.menu, contextMenu):
|
for menu in (actionPopup.menu, contextMenu):
|
||||||
menu.addItem("Remove Selected from Results", action=Action(owner, 'removeSelected'))
|
menu.addItem("Remove Selected from Results", action=Action(owner, 'removeSelected'))
|
||||||
menu.addItem("Add Selected to Ignore List", action=Action(owner, 'ignoreSelected'))
|
menu.addItem("Add Selected to Ignore List", action=Action(owner, 'ignoreSelected'))
|
||||||
menu.addItem("Make Selected Reference", action=Action(owner, 'switchSelected'))
|
menu.addItem("Make Selected into Reference", action=Action(owner, 'switchSelected'))
|
||||||
menu.addSeparator()
|
menu.addSeparator()
|
||||||
menu.addItem("Open Selected with Default Application", action=Action(owner, 'openSelected'))
|
menu.addItem("Open Selected with Default Application", action=Action(owner, 'openSelected'))
|
||||||
menu.addItem("Reveal Selected in Finder", action=Action(owner, 'revealSelected'))
|
menu.addItem("Reveal Selected in Finder", action=Action(owner, 'revealSelected'))
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/11/16
|
# Created On: 2006/11/16
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
@@ -14,7 +14,6 @@ from appscript import app, its, k, CommandError, ApplicationNotFoundError
|
|||||||
from . import tunes
|
from . import tunes
|
||||||
|
|
||||||
from cocoa import as_fetch, proxy
|
from cocoa import as_fetch, proxy
|
||||||
from hscommon import io
|
|
||||||
from hscommon.trans import trget
|
from hscommon.trans import trget
|
||||||
from hscommon.path import Path
|
from hscommon.path import Path
|
||||||
from hscommon.util import remove_invalid_xml
|
from hscommon.util import remove_invalid_xml
|
||||||
@@ -78,21 +77,21 @@ def get_itunes_database_path():
|
|||||||
return Path(plistpath)
|
return Path(plistpath)
|
||||||
|
|
||||||
def get_itunes_songs(plistpath):
|
def get_itunes_songs(plistpath):
|
||||||
if not io.exists(plistpath):
|
if not plistpath.exists():
|
||||||
return []
|
return []
|
||||||
s = io.open(plistpath, 'rt', encoding='utf-8').read()
|
s = plistpath.open('rt', encoding='utf-8').read()
|
||||||
# iTunes sometimes produces XML files with invalid characters in it.
|
# iTunes sometimes produces XML files with invalid characters in it.
|
||||||
s = remove_invalid_xml(s, replace_with='')
|
s = remove_invalid_xml(s, replace_with='')
|
||||||
plist = plistlib.readPlistFromBytes(s.encode('utf-8'))
|
plist = plistlib.readPlistFromBytes(s.encode('utf-8'))
|
||||||
result = []
|
result = []
|
||||||
for song_data in plist['Tracks'].values():
|
for song_data in plist['Tracks'].values():
|
||||||
if song_data['Track Type'] != 'File':
|
|
||||||
continue
|
|
||||||
try:
|
try:
|
||||||
|
if song_data['Track Type'] != 'File':
|
||||||
|
continue
|
||||||
song = ITunesSong(song_data)
|
song = ITunesSong(song_data)
|
||||||
except KeyError: # No "Location" or "Track ID" key in track
|
except KeyError: # No "Track Type", "Location" or "Track ID" key in track
|
||||||
continue
|
continue
|
||||||
if io.exists(song.path):
|
if song.path.exists():
|
||||||
result.append(song)
|
result.append(song)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/11/13
|
# Created On: 2006/11/13
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2009-05-24
|
# Created On: 2009-05-24
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Created On: 2012-05-30
|
# Created On: 2012-05-30
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string>NSApplication</string>
|
<string>NSApplication</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>© Hardcoded Software, 2012</string>
|
<string>© Hardcoded Software, 2013</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>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
@@ -7,7 +7,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "../base/ResultWindow.h"
|
#import "ResultWindowBase.h"
|
||||||
|
|
||||||
@interface ResultWindow : ResultWindowBase {}
|
@interface ResultWindow : ResultWindowBase {}
|
||||||
- (void)removeDeadTracks;
|
- (void)removeDeadTracks;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string>NSApplication</string>
|
<string>NSApplication</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>© Hardcoded Software, 2012</string>
|
<string>© Hardcoded Software, 2013</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>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
@@ -7,7 +7,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "../base/ResultWindow.h"
|
#import "ResultWindowBase.h"
|
||||||
|
|
||||||
@interface ResultWindow : ResultWindowBase {}
|
@interface ResultWindow : ResultWindowBase {}
|
||||||
- (void)clearPictureCache;
|
- (void)clearPictureCache;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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,6 +22,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
{@"size", 63, 16, 0, YES, nil},
|
{@"size", 63, 16, 0, YES, nil},
|
||||||
{@"extension", 40, 16, 0, YES, nil},
|
{@"extension", 40, 16, 0, YES, nil},
|
||||||
{@"dimensions", 73, 16, 0, YES, nil},
|
{@"dimensions", 73, 16, 0, YES, nil},
|
||||||
|
{@"exif_timestamp", 120, 16, 0, YES, nil},
|
||||||
{@"mtime", 120, 16, 0, YES, nil},
|
{@"mtime", 120, 16, 0, YES, nil},
|
||||||
{@"percentage", 58, 16, 0, YES, nil},
|
{@"percentage", 58, 16, 0, YES, nil},
|
||||||
{@"dupe_count", 80, 16, 0, YES, nil},
|
{@"dupe_count", 80, 16, 0, YES, nil},
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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,7 +29,7 @@
|
|||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string>NSApplication</string>
|
<string>NSApplication</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>© Hardcoded Software, 2012</string>
|
<string>© Hardcoded Software, 2013</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>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
@@ -7,7 +7,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "../base/ResultWindow.h"
|
#import "ResultWindowBase.h"
|
||||||
|
|
||||||
@interface ResultWindow : ResultWindowBase {}
|
@interface ResultWindow : ResultWindowBase {}
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2013 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
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import sys
|
||||||
import os
|
import os
|
||||||
import os.path as op
|
import os.path as op
|
||||||
|
|
||||||
@@ -25,8 +26,9 @@ def configure(conf):
|
|||||||
# I did a lot of fiddling-around, but I didn't find how to tell WAF the Python library name
|
# I did a lot of fiddling-around, but I didn't find how to tell WAF the Python library name
|
||||||
# to look for without making the whole compilation process fail, so I just create a symlink
|
# to look for without making the whole compilation process fail, so I just create a symlink
|
||||||
# with the name WAF is looking for.
|
# with the name WAF is looking for.
|
||||||
if not op.exists('../build/libpython3.2.dylib'):
|
versioned_dylib_path = '../build/libpython{}.dylib'.format(sys.version[:3])
|
||||||
os.symlink('../build/Python', '../build/libpython3.2.dylib')
|
if not op.exists(versioned_dylib_path):
|
||||||
|
os.symlink('../build/Python', versioned_dylib_path)
|
||||||
# The rest is standard WAF code that you can find the the python and macapp demos.
|
# The rest is standard WAF code that you can find the the python and macapp demos.
|
||||||
conf.load('compiler_c python')
|
conf.load('compiler_c python')
|
||||||
conf.check_python_version((3,2,0))
|
conf.check_python_version((3,2,0))
|
||||||
@@ -42,7 +44,7 @@ def build(ctx):
|
|||||||
cocoalib_node = ctx.srcnode.find_dir('..').find_dir('cocoalib')
|
cocoalib_node = ctx.srcnode.find_dir('..').find_dir('cocoalib')
|
||||||
cocoalib_folders = ['controllers', 'views']
|
cocoalib_folders = ['controllers', 'views']
|
||||||
cocoalib_includes = [cocoalib_node] + [cocoalib_node.find_dir(folder) for folder in cocoalib_folders]
|
cocoalib_includes = [cocoalib_node] + [cocoalib_node.find_dir(folder) for folder in cocoalib_folders]
|
||||||
cocoalib_uses = ['NSEventAdditions', 'Dialogs', 'HSAboutBox', 'HSFairwareReminder', 'Utils',
|
cocoalib_uses = ['NSEventAdditions', 'Dialogs', 'HSFairwareAboutBox', 'HSFairwareReminder', 'Utils',
|
||||||
'HSPyUtil', 'ProgressController', 'HSRecentFiles', 'HSQuicklook', 'ValueTransformers',
|
'HSPyUtil', 'ProgressController', 'HSRecentFiles', 'HSQuicklook', 'ValueTransformers',
|
||||||
'NSImageAdditions', 'NSNotificationAdditions',
|
'NSImageAdditions', 'NSNotificationAdditions',
|
||||||
'views/HSTableView', 'views/HSOutlineView', 'views/NSIndexPathAdditions',
|
'views/HSTableView', 'views/HSOutlineView', 'views/NSIndexPathAdditions',
|
||||||
|
|||||||
24
configure.py
24
configure.py
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2009-12-30
|
# Created On: 2009-12-30
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
@@ -12,17 +12,17 @@ import json
|
|||||||
|
|
||||||
from hscommon.plat import ISOSX
|
from hscommon.plat import ISOSX
|
||||||
|
|
||||||
def main(edition, ui, dev):
|
def main(options):
|
||||||
if edition not in {'se', 'me', 'pe'}:
|
if options.edition not in {'se', 'me', 'pe'}:
|
||||||
edition = 'se'
|
options.edition = 'se'
|
||||||
if ui not in {'cocoa', 'qt'}:
|
if options.ui not in {'cocoa', 'qt'}:
|
||||||
ui = 'cocoa' if ISOSX else 'qt'
|
options.ui = 'cocoa' if ISOSX else 'qt'
|
||||||
build_type = 'Dev' if dev else 'Release'
|
build_type = 'Dev' if options.dev else 'Release'
|
||||||
print("Configuring dupeGuru {0} for UI {1} ({2})".format(edition.upper(), ui, build_type))
|
print("Configuring dupeGuru {0} for UI {1} ({2})".format(options.edition.upper(), options.ui, build_type))
|
||||||
conf = {
|
conf = {
|
||||||
'edition': edition,
|
'edition': options.edition,
|
||||||
'ui': ui,
|
'ui': options.ui,
|
||||||
'dev': dev,
|
'dev': options.dev,
|
||||||
}
|
}
|
||||||
json.dump(conf, open('conf.json', 'w'))
|
json.dump(conf, open('conf.json', 'w'))
|
||||||
|
|
||||||
@@ -36,4 +36,4 @@ if __name__ == '__main__':
|
|||||||
parser.add_option('--dev', action='store_true', dest='dev', default=False,
|
parser.add_option('--dev', action='store_true', dest='dev', default=False,
|
||||||
help="If this flag is set, will configure for dev builds.")
|
help="If this flag is set, will configure for dev builds.")
|
||||||
(options, args) = parser.parse_args()
|
(options, args) = parser.parse_args()
|
||||||
main(options.edition, options.ui, options.dev)
|
main(options)
|
||||||
|
|||||||
48
core/app.py
48
core/app.py
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/11/11
|
# Created On: 2006/11/11
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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,7 +15,6 @@ import time
|
|||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
from send2trash import send2trash
|
from send2trash import send2trash
|
||||||
from hscommon import io
|
|
||||||
from hscommon.reg import RegistrableApplication
|
from hscommon.reg import RegistrableApplication
|
||||||
from hscommon.notify import Broadcaster
|
from hscommon.notify import Broadcaster
|
||||||
from hscommon.path import Path
|
from hscommon.path import Path
|
||||||
@@ -37,6 +36,8 @@ DEBUG_MODE_PREFERENCE = 'DebugMode'
|
|||||||
|
|
||||||
MSG_NO_MARKED_DUPES = tr("There are no marked duplicates. Nothing has been done.")
|
MSG_NO_MARKED_DUPES = tr("There are no marked duplicates. Nothing has been done.")
|
||||||
MSG_NO_SELECTED_DUPES = tr("There are no selected duplicates. Nothing has been done.")
|
MSG_NO_SELECTED_DUPES = tr("There are no selected duplicates. Nothing has been done.")
|
||||||
|
MSG_MANY_FILES_TO_OPEN = tr("You're about to open many files at once. Depending on what those "
|
||||||
|
"files are opened with, doing so can create quite a mess. Continue?")
|
||||||
|
|
||||||
class DestType:
|
class DestType:
|
||||||
Direct = 0
|
Direct = 0
|
||||||
@@ -168,7 +169,7 @@ class DupeGuru(RegistrableApplication, Broadcaster):
|
|||||||
self.results.perform_on_marked(op, True)
|
self.results.perform_on_marked(op, True)
|
||||||
|
|
||||||
def _do_delete_dupe(self, dupe, link_deleted, use_hardlinks, direct_deletion):
|
def _do_delete_dupe(self, dupe, link_deleted, use_hardlinks, direct_deletion):
|
||||||
if not io.exists(dupe.path):
|
if not dupe.path.exists():
|
||||||
return
|
return
|
||||||
logging.debug("Sending '%s' to trash", dupe.path)
|
logging.debug("Sending '%s' to trash", dupe.path)
|
||||||
str_path = str(dupe.path)
|
str_path = str(dupe.path)
|
||||||
@@ -241,9 +242,9 @@ class DupeGuru(RegistrableApplication, Broadcaster):
|
|||||||
self.view.show_problem_dialog()
|
self.view.show_problem_dialog()
|
||||||
else:
|
else:
|
||||||
msg = {
|
msg = {
|
||||||
JobType.Copy: tr("All marked files were copied sucessfully."),
|
JobType.Copy: tr("All marked files were copied successfully."),
|
||||||
JobType.Move: tr("All marked files were moved sucessfully."),
|
JobType.Move: tr("All marked files were moved successfully."),
|
||||||
JobType.Delete: tr("All marked files were sucessfully sent to Trash."),
|
JobType.Delete: tr("All marked files were successfully sent to Trash."),
|
||||||
}[jobid]
|
}[jobid]
|
||||||
self.view.show_message(msg)
|
self.view.show_message(msg)
|
||||||
|
|
||||||
@@ -253,7 +254,7 @@ class DupeGuru(RegistrableApplication, Broadcaster):
|
|||||||
result = []
|
result = []
|
||||||
for file in files:
|
for file in files:
|
||||||
try:
|
try:
|
||||||
inode = io.stat(file.path).st_ino
|
inode = file.path.stat().st_ino
|
||||||
except OSError:
|
except OSError:
|
||||||
# The file was probably deleted or something
|
# The file was probably deleted or something
|
||||||
continue
|
continue
|
||||||
@@ -324,8 +325,8 @@ class DupeGuru(RegistrableApplication, Broadcaster):
|
|||||||
if dest_type == DestType.Relative:
|
if dest_type == DestType.Relative:
|
||||||
source_base = source_base[location_path:]
|
source_base = source_base[location_path:]
|
||||||
dest_path = dest_path + source_base
|
dest_path = dest_path + source_base
|
||||||
if not io.exists(dest_path):
|
if not dest_path.exists():
|
||||||
io.makedirs(dest_path)
|
dest_path.makedirs()
|
||||||
# Add filename to dest_path. For file move/copy, it's not required, but for folders, yes.
|
# Add filename to dest_path. For file move/copy, it's not required, but for folders, yes.
|
||||||
dest_path = dest_path + source_path[-1]
|
dest_path = dest_path + source_path[-1]
|
||||||
logging.debug("Copy/Move operation from '%s' to '%s'", source_path, dest_path)
|
logging.debug("Copy/Move operation from '%s' to '%s'", source_path, dest_path)
|
||||||
@@ -441,9 +442,25 @@ class DupeGuru(RegistrableApplication, Broadcaster):
|
|||||||
for dupe in dupes:
|
for dupe in dupes:
|
||||||
g = self.results.get_group_of_duplicate(dupe)
|
g = self.results.get_group_of_duplicate(dupe)
|
||||||
if g not in changed_groups:
|
if g not in changed_groups:
|
||||||
self.results.make_ref(dupe)
|
if self.results.make_ref(dupe):
|
||||||
changed_groups.add(g)
|
changed_groups.add(g)
|
||||||
self.notify('results_changed_but_keep_selection')
|
# It's not always obvious to users what this action does, so to make it a bit clearer,
|
||||||
|
# we change our selection to the ref of all changed groups. However, we also want to keep
|
||||||
|
# the files that were ref before and weren't changed by the action. In effect, what this
|
||||||
|
# does is that we keep our old selection, but remove all non-ref dupes from it.
|
||||||
|
# If no group was changed, however, we don't touch the selection.
|
||||||
|
if not self.result_table.power_marker:
|
||||||
|
if changed_groups:
|
||||||
|
self.selected_dupes = [d for d in self.selected_dupes
|
||||||
|
if self.results.get_group_of_duplicate(d).ref is d]
|
||||||
|
self.notify('results_changed')
|
||||||
|
else:
|
||||||
|
# If we're in "Dupes Only" mode (previously called Power Marker), things are a bit
|
||||||
|
# different. The refs are not shown in the table, and if our operation is successful,
|
||||||
|
# this means that there's no way to follow our dupe selection. Then, the best thing to
|
||||||
|
# do is to keep our selection index-wise (different dupe selection, but same index
|
||||||
|
# selection).
|
||||||
|
self.notify('results_changed_but_keep_selection')
|
||||||
|
|
||||||
def mark_all(self):
|
def mark_all(self):
|
||||||
self.results.mark_all()
|
self.results.mark_all()
|
||||||
@@ -465,8 +482,11 @@ class DupeGuru(RegistrableApplication, Broadcaster):
|
|||||||
self.notify('marking_changed')
|
self.notify('marking_changed')
|
||||||
|
|
||||||
def open_selected(self):
|
def open_selected(self):
|
||||||
if self.selected_dupes:
|
if len(self.selected_dupes) > 10:
|
||||||
self.view.open_path(self.selected_dupes[0].path)
|
if not self.view.ask_yes_no(MSG_MANY_FILES_TO_OPEN):
|
||||||
|
return
|
||||||
|
for dupe in self.selected_dupes:
|
||||||
|
self.view.open_path(dupe.path)
|
||||||
|
|
||||||
def purge_ignore_list(self):
|
def purge_ignore_list(self):
|
||||||
self.scanner.ignore_list.Filter(lambda f,s:op.exists(f) and op.exists(s))
|
self.scanner.ignore_list.Filter(lambda f,s:op.exists(f) and op.exists(s))
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/02/27
|
# Created On: 2006/02/27
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
@@ -10,7 +10,6 @@ from xml.etree import ElementTree as ET
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from jobprogress import job
|
from jobprogress import job
|
||||||
from hscommon import io
|
|
||||||
from hscommon.path import Path
|
from hscommon.path import Path
|
||||||
from hscommon.util import FileOrPath
|
from hscommon.util import FileOrPath
|
||||||
|
|
||||||
@@ -73,9 +72,9 @@ class Directories:
|
|||||||
file.is_ref = state == DirectoryState.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 from_path.listdir()]
|
||||||
# it's possible that a folder (bundle) gets into the file list. in that case, we don't want to recurse into it
|
# 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]
|
subfolders = [p for p in subpaths if not p.islink() and p.isdir() and p not in filepaths]
|
||||||
for subfolder in subfolders:
|
for subfolder in subfolders:
|
||||||
for file in self._get_files(subfolder, j):
|
for file in self._get_files(subfolder, j):
|
||||||
yield file
|
yield file
|
||||||
@@ -106,7 +105,7 @@ class Directories:
|
|||||||
"""
|
"""
|
||||||
if path in self:
|
if path in self:
|
||||||
raise AlreadyThereError()
|
raise AlreadyThereError()
|
||||||
if not io.exists(path):
|
if not path.exists():
|
||||||
raise InvalidPathError()
|
raise InvalidPathError()
|
||||||
self._dirs = [p for p in self._dirs if p not in path]
|
self._dirs = [p for p in self._dirs if p not in path]
|
||||||
self._dirs.append(path)
|
self._dirs.append(path)
|
||||||
@@ -115,7 +114,7 @@ class Directories:
|
|||||||
def get_subfolders(path):
|
def get_subfolders(path):
|
||||||
"""returns a sorted list of paths corresponding to subfolders in `path`"""
|
"""returns a sorted list of paths corresponding to subfolders in `path`"""
|
||||||
try:
|
try:
|
||||||
names = [name for name in io.listdir(path) if io.isdir(path + name)]
|
names = [name for name in path.listdir() if (path + name).isdir()]
|
||||||
names.sort(key=lambda x:x.lower())
|
names.sort(key=lambda x:x.lower())
|
||||||
return [path + name for name in names]
|
return [path + name for name in names]
|
||||||
except EnvironmentError:
|
except EnvironmentError:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/01/29
|
# Created On: 2006/01/29
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
@@ -325,14 +325,15 @@ class Group:
|
|||||||
|
|
||||||
def switch_ref(self, with_dupe):
|
def switch_ref(self, with_dupe):
|
||||||
if self.ref.is_ref:
|
if self.ref.is_ref:
|
||||||
return
|
return False
|
||||||
try:
|
try:
|
||||||
self.ordered.remove(with_dupe)
|
self.ordered.remove(with_dupe)
|
||||||
self.ordered.insert(0, with_dupe)
|
self.ordered.insert(0, with_dupe)
|
||||||
self._percentage = None
|
self._percentage = None
|
||||||
self._matches_for_ref = None
|
self._matches_for_ref = None
|
||||||
|
return True
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
return False
|
||||||
|
|
||||||
dupes = property(lambda self: self[1:])
|
dupes = property(lambda self: self[1:])
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/09/16
|
# Created On: 2006/09/16
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
27
core/fs.py
27
core/fs.py
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2009-10-22
|
# Created On: 2009-10-22
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from hscommon import io
|
|
||||||
from hscommon.util import nonone, get_file_ext
|
from hscommon.util import nonone, get_file_ext
|
||||||
|
|
||||||
NOT_SET = object()
|
NOT_SET = object()
|
||||||
@@ -89,12 +88,12 @@ class File:
|
|||||||
|
|
||||||
def _read_info(self, field):
|
def _read_info(self, field):
|
||||||
if field in ('size', 'mtime'):
|
if field in ('size', 'mtime'):
|
||||||
stats = io.stat(self.path)
|
stats = self.path.stat()
|
||||||
self.size = nonone(stats.st_size, 0)
|
self.size = nonone(stats.st_size, 0)
|
||||||
self.mtime = nonone(stats.st_mtime, 0)
|
self.mtime = nonone(stats.st_mtime, 0)
|
||||||
elif field == 'md5partial':
|
elif field == 'md5partial':
|
||||||
try:
|
try:
|
||||||
fp = io.open(self.path, 'rb')
|
fp = self.path.open('rb')
|
||||||
offset, size = self._get_md5partial_offset_and_size()
|
offset, size = self._get_md5partial_offset_and_size()
|
||||||
fp.seek(offset)
|
fp.seek(offset)
|
||||||
partialdata = fp.read(size)
|
partialdata = fp.read(size)
|
||||||
@@ -105,7 +104,7 @@ class File:
|
|||||||
pass
|
pass
|
||||||
elif field == 'md5':
|
elif field == 'md5':
|
||||||
try:
|
try:
|
||||||
fp = io.open(self.path, 'rb')
|
fp = self.path.open('rb')
|
||||||
md5 = hashlib.md5()
|
md5 = hashlib.md5()
|
||||||
CHUNK_SIZE = 8192
|
CHUNK_SIZE = 8192
|
||||||
filedata = fp.read(CHUNK_SIZE)
|
filedata = fp.read(CHUNK_SIZE)
|
||||||
@@ -130,19 +129,19 @@ class File:
|
|||||||
#--- Public
|
#--- Public
|
||||||
@classmethod
|
@classmethod
|
||||||
def can_handle(cls, path):
|
def can_handle(cls, path):
|
||||||
return not io.islink(path) and io.isfile(path)
|
return not path.islink() and path.isfile()
|
||||||
|
|
||||||
def rename(self, newname):
|
def rename(self, newname):
|
||||||
if newname == self.name:
|
if newname == self.name:
|
||||||
return
|
return
|
||||||
destpath = self.path[:-1] + newname
|
destpath = self.path[:-1] + newname
|
||||||
if io.exists(destpath):
|
if destpath.exists():
|
||||||
raise AlreadyExistsError(newname, self.path[:-1])
|
raise AlreadyExistsError(newname, self.path[:-1])
|
||||||
try:
|
try:
|
||||||
io.rename(self.path, destpath)
|
self.path.rename(destpath)
|
||||||
except EnvironmentError:
|
except EnvironmentError:
|
||||||
raise OperationError(self)
|
raise OperationError(self)
|
||||||
if not io.exists(destpath):
|
if not destpath.exists():
|
||||||
raise OperationError(self)
|
raise OperationError(self)
|
||||||
self.path = destpath
|
self.path = destpath
|
||||||
|
|
||||||
@@ -180,7 +179,7 @@ class Folder(File):
|
|||||||
if field in {'size', 'mtime'}:
|
if field in {'size', 'mtime'}:
|
||||||
size = sum((f.size for f in self._all_items()), 0)
|
size = sum((f.size for f in self._all_items()), 0)
|
||||||
self.size = size
|
self.size = size
|
||||||
stats = io.stat(self.path)
|
stats = self.path.stat()
|
||||||
self.mtime = nonone(stats.st_mtime, 0)
|
self.mtime = nonone(stats.st_mtime, 0)
|
||||||
elif field in {'md5', 'md5partial'}:
|
elif field in {'md5', 'md5partial'}:
|
||||||
# What's sensitive here is that we must make sure that subfiles'
|
# What's sensitive here is that we must make sure that subfiles'
|
||||||
@@ -199,14 +198,14 @@ class Folder(File):
|
|||||||
@property
|
@property
|
||||||
def subfolders(self):
|
def subfolders(self):
|
||||||
if self._subfolders is None:
|
if self._subfolders is None:
|
||||||
subpaths = [self.path + name for name in io.listdir(self.path)]
|
subpaths = [self.path + name for name in self.path.listdir()]
|
||||||
subfolders = [p for p in subpaths if not io.islink(p) and io.isdir(p)]
|
subfolders = [p for p in subpaths if not p.islink() and p.isdir()]
|
||||||
self._subfolders = [Folder(p) for p in subfolders]
|
self._subfolders = [Folder(p) for p in subfolders]
|
||||||
return self._subfolders
|
return self._subfolders
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def can_handle(cls, path):
|
def can_handle(cls, path):
|
||||||
return not io.islink(path) and io.isdir(path)
|
return not path.islink() and path.isdir()
|
||||||
|
|
||||||
|
|
||||||
def get_file(path, fileclasses=[File]):
|
def get_file(path, fileclasses=[File]):
|
||||||
@@ -225,7 +224,7 @@ def get_files(path, fileclasses=[File]):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
try:
|
try:
|
||||||
paths = [combine_paths(path, name) for name in io.listdir(path)]
|
paths = [combine_paths(path, name) for name in path.listdir()]
|
||||||
result = []
|
result = []
|
||||||
for path in paths:
|
for path in paths:
|
||||||
file = get_file(path, fileclasses=fileclasses)
|
file = get_file(path, fileclasses=fileclasses)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2010-02-06
|
# Created On: 2010-02-06
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Created On: 2012-05-30
|
# Created On: 2012-05-30
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2010-02-05
|
# Created On: 2010-02-05
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2010-02-06
|
# Created On: 2010-02-06
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Created On: 2012/03/13
|
# Created On: 2012/03/13
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2012-03-13
|
# Created On: 2012-03-13
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2011-09-06
|
# Created On: 2011-09-06
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2010-04-12
|
# Created On: 2010-04-12
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2010-04-12
|
# Created On: 2010-04-12
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2010-02-11
|
# Created On: 2010-02-11
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2010-02-11
|
# Created On: 2010-02-11
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/05/02
|
# Created On: 2006/05/02
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/02/23
|
# Created On: 2006/02/23
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2011/09/07
|
# Created On: 2011/09/07
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/02/23
|
# Created On: 2006/02/23
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
@@ -244,8 +244,9 @@ class Results(Markable):
|
|||||||
def make_ref(self, dupe):
|
def make_ref(self, dupe):
|
||||||
g = self.get_group_of_duplicate(dupe)
|
g = self.get_group_of_duplicate(dupe)
|
||||||
r = g.ref
|
r = g.ref
|
||||||
|
if not g.switch_ref(dupe):
|
||||||
|
return False
|
||||||
self._remove_mark_flag(dupe)
|
self._remove_mark_flag(dupe)
|
||||||
g.switch_ref(dupe);
|
|
||||||
if not r.is_ref:
|
if not r.is_ref:
|
||||||
self.__total_count += 1
|
self.__total_count += 1
|
||||||
self.__total_size += r.size
|
self.__total_size += r.size
|
||||||
@@ -254,6 +255,7 @@ class Results(Markable):
|
|||||||
self.__total_size -= dupe.size
|
self.__total_size -= dupe.size
|
||||||
self.__dupes = None
|
self.__dupes = None
|
||||||
self.is_modified = True
|
self.is_modified = True
|
||||||
|
return True
|
||||||
|
|
||||||
def perform_on_marked(self, func, remove_from_results):
|
def perform_on_marked(self, func, remove_from_results):
|
||||||
# Performs `func` on all marked dupes. If an EnvironmentError is raised during the call,
|
# Performs `func` on all marked dupes. If an EnvironmentError is raised during the call,
|
||||||
@@ -265,7 +267,7 @@ class Results(Markable):
|
|||||||
try:
|
try:
|
||||||
func(dupe)
|
func(dupe)
|
||||||
to_remove.append(dupe)
|
to_remove.append(dupe)
|
||||||
except EnvironmentError as e:
|
except (EnvironmentError, UnicodeEncodeError) as e:
|
||||||
self.problems.append((dupe, str(e)))
|
self.problems.append((dupe, str(e)))
|
||||||
if remove_from_results:
|
if remove_from_results:
|
||||||
self.remove_duplicates(to_remove)
|
self.remove_duplicates(to_remove)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/03/03
|
# Created On: 2006/03/03
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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,7 +11,6 @@ import re
|
|||||||
import os.path as op
|
import os.path as op
|
||||||
|
|
||||||
from jobprogress import job
|
from jobprogress import job
|
||||||
from hscommon import io
|
|
||||||
from hscommon.util import dedupe, rem_file_ext, get_file_ext
|
from hscommon.util import dedupe, rem_file_ext, get_file_ext
|
||||||
from hscommon.trans import tr
|
from hscommon.trans import tr
|
||||||
|
|
||||||
@@ -129,6 +128,11 @@ class Scanner:
|
|||||||
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"))
|
||||||
|
# In removing what we call here "false matches", we first want to remove, if we scan by
|
||||||
|
# folders, we want to remove folder matches for which the parent is also in a match (they're
|
||||||
|
# "duplicated duplicates if you will). Then, we also don't want mixed file kinds if the
|
||||||
|
# option isn't enabled, we want matches for which both files exist and, lastly, we don't
|
||||||
|
# want matches with both files as ref.
|
||||||
if self.scan_type == ScanType.Folders and matches:
|
if self.scan_type == ScanType.Folders and matches:
|
||||||
allpath = {m.first.path for m in matches}
|
allpath = {m.first.path for m in matches}
|
||||||
allpath |= {m.second.path for m in matches}
|
allpath |= {m.second.path for m in matches}
|
||||||
@@ -143,7 +147,8 @@ class Scanner:
|
|||||||
matches = [m for m in matches if m.first.path not in toremove or m.second.path not in toremove]
|
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 m.first.path.exists() and m.second.path.exists()]
|
||||||
|
matches = [m for m in matches if not (m.first.is_ref and m.second.is_ref)]
|
||||||
if self.ignore_list:
|
if self.ignore_list:
|
||||||
j = j.start_subjob(2)
|
j = j.start_subjob(2)
|
||||||
iter_matches = j.iter_with_progress(matches, tr("Processed %d/%d matches against the ignore list"))
|
iter_matches = j.iter_with_progress(matches, tr("Processed %d/%d matches against the ignore list"))
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2007-06-23
|
# Created On: 2007-06-23
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
@@ -330,18 +330,22 @@ class TestCaseDupeGuruWithResults:
|
|||||||
app = self.app
|
app = self.app
|
||||||
# any other path that isn't a parent or child of the already added path
|
# any other path that isn't a parent or child of the already added path
|
||||||
otherpath = Path(op.dirname(__file__))
|
otherpath = Path(op.dirname(__file__))
|
||||||
eq_(app.add_directory(otherpath), 0)
|
app.add_directory(otherpath)
|
||||||
eq_(len(app.directories), 2)
|
eq_(len(app.directories), 2)
|
||||||
|
|
||||||
def test_addDirectory_already_there(self, do_setup):
|
def test_addDirectory_already_there(self, do_setup):
|
||||||
app = self.app
|
app = self.app
|
||||||
otherpath = Path(op.dirname(__file__))
|
otherpath = Path(op.dirname(__file__))
|
||||||
eq_(app.add_directory(otherpath), 0)
|
app.add_directory(otherpath)
|
||||||
eq_(app.add_directory(otherpath), 1)
|
app.add_directory(otherpath)
|
||||||
|
eq_(len(app.view.messages), 1)
|
||||||
|
assert "already" in app.view.messages[0]
|
||||||
|
|
||||||
def test_addDirectory_does_not_exist(self, do_setup):
|
def test_addDirectory_does_not_exist(self, do_setup):
|
||||||
app = self.app
|
app = self.app
|
||||||
eq_(2,app.add_directory('/does_not_exist'))
|
app.add_directory('/does_not_exist')
|
||||||
|
eq_(len(app.view.messages), 1)
|
||||||
|
assert "exist" in app.view.messages[0]
|
||||||
|
|
||||||
def test_ignore(self, do_setup):
|
def test_ignore(self, do_setup):
|
||||||
app = self.app
|
app = self.app
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2011/09/07
|
# Created On: 2011/09/07
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
@@ -24,6 +24,9 @@ from ..gui.prioritize_dialog import PrioritizeDialog
|
|||||||
class DupeGuruView:
|
class DupeGuruView:
|
||||||
JOB = nulljob
|
JOB = nulljob
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.messages = []
|
||||||
|
|
||||||
def start_job(self, jobid, func, args=()):
|
def start_job(self, jobid, func, args=()):
|
||||||
try:
|
try:
|
||||||
func(self.JOB, *args)
|
func(self.JOB, *args)
|
||||||
@@ -37,7 +40,7 @@ class DupeGuruView:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def show_message(self, msg):
|
def show_message(self, msg):
|
||||||
pass
|
self.messages.append(msg)
|
||||||
|
|
||||||
def ask_yes_no(self, prompt):
|
def ask_yes_no(self, prompt):
|
||||||
return True # always answer yes
|
return True # always answer yes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/02/27
|
# Created On: 2006/02/27
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/01/29
|
# Created On: 2006/01/29
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2009-10-23
|
# Created On: 2009-10-23
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/05/02
|
# Created On: 2006/05/02
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/02/23
|
# Created On: 2006/02/23
|
||||||
# Copyright 2012 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2013 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
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user