mirror of
https://github.com/arsenetar/dupeguru.git
synced 2026-01-25 16:11:39 +00:00
Compare commits
114 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5f29d775c | ||
|
|
ebd7f1b4ce | ||
|
|
279b7ad10c | ||
|
|
878205fc49 | ||
|
|
b16df32150 | ||
|
|
04b06f7704 | ||
|
|
c6ea1c62d4 | ||
|
|
6ce0f66601 | ||
|
|
ac3a9e3ba8 | ||
|
|
903d2f9183 | ||
|
|
ca709a60cf | ||
|
|
a9b4ce5529 | ||
|
|
9b82ceca67 | ||
|
|
4c7c279dd2 | ||
|
|
79db31685e | ||
|
|
ba13b700b0 | ||
|
|
640561a534 | ||
|
|
e4f81cbf04 | ||
|
|
4be4825112 | ||
|
|
7d107d8efa | ||
|
|
10d1363334 | ||
|
|
b76820ebde | ||
|
|
72b3cfb364 | ||
|
|
8b83ed0e5c | ||
|
|
781f13ae1a | ||
|
|
8193bbae6e | ||
|
|
4cafeaff91 | ||
|
|
95c6a7d41f | ||
|
|
a29e007475 | ||
|
|
d924d7797a | ||
|
|
33c217ecc8 | ||
|
|
c9035046ae | ||
|
|
ad31016825 | ||
|
|
c809066a93 | ||
|
|
60ca27b5e1 | ||
|
|
1104e24408 | ||
|
|
f66db94ffd | ||
|
|
d98b5b22da | ||
|
|
937748e838 | ||
|
|
37ebf36cee | ||
|
|
1c84bdd198 | ||
|
|
4a2fa7cd2c | ||
|
|
7d4110f6d3 | ||
|
|
8497343d7f | ||
|
|
235a2c2904 | ||
|
|
25169cfc20 | ||
|
|
152f5f37ce | ||
|
|
3e42ad8469 | ||
|
|
7ba2e38cd6 | ||
|
|
c7c7a73384 | ||
|
|
46f8984bdc | ||
|
|
c7d306b7d5 | ||
|
|
47e636e949 | ||
|
|
0562729d8b | ||
|
|
4a36227a18 | ||
|
|
28b8b2e415 | ||
|
|
fd82464564 | ||
|
|
418acf6e5e | ||
|
|
d14d076989 | ||
|
|
cb8bb5a70e | ||
|
|
563c9aeff3 | ||
|
|
a0cc1f2e03 | ||
|
|
01403a3f92 | ||
|
|
7116674663 | ||
|
|
b6bc5de79c | ||
|
|
5a275db67d | ||
|
|
31395d8794 | ||
|
|
3734bd6f6c | ||
|
|
da06ef8cad | ||
|
|
0b00171655 | ||
|
|
c1cfa86ad1 | ||
|
|
c34c9562d3 | ||
|
|
0e542577b0 | ||
|
|
42be49da83 | ||
|
|
398ac9b7c6 | ||
|
|
508e9a5d94 | ||
|
|
cc5ea1dbc1 | ||
|
|
3b8d355b9e | ||
|
|
10dbfa9b38 | ||
|
|
e8c42740cf | ||
|
|
4b6c4f048d | ||
|
|
7594cccf8c | ||
|
|
1d9573cf6f | ||
|
|
76f45fb5a6 | ||
|
|
12cf9b800b | ||
|
|
ba7e6494c6 | ||
|
|
72d8160b28 | ||
|
|
6d53511cee | ||
|
|
64d3c211e6 | ||
|
|
fad112f554 | ||
|
|
a563327723 | ||
|
|
096e2bb78a | ||
|
|
5a8cb6f5e3 | ||
|
|
664d630b96 | ||
|
|
a4256d3d2b | ||
|
|
8e65f15e1a | ||
|
|
9ea9f60e92 | ||
|
|
8efefaf0bf | ||
|
|
33d9569427 | ||
|
|
2fdfacb34e | ||
|
|
97fcf1ffa8 | ||
|
|
350b2c64e0 | ||
|
|
dcc57a7afb | ||
|
|
8b510994ad | ||
|
|
4a4d1bbfcd | ||
|
|
78c3c8ec2d | ||
|
|
e99e2b18e0 | ||
|
|
ae1283f2e1 | ||
|
|
cc76f3ca87 | ||
|
|
be8efea081 | ||
|
|
7e8f9036d8 | ||
|
|
8a8ac027f5 | ||
|
|
1d9d09fdf7 | ||
|
|
5dc956870d |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,12 +5,14 @@
|
|||||||
*.pyd
|
*.pyd
|
||||||
*.waf*
|
*.waf*
|
||||||
.lock-waf*
|
.lock-waf*
|
||||||
|
.idea
|
||||||
|
|
||||||
build
|
build
|
||||||
dist
|
dist
|
||||||
install
|
install
|
||||||
installer_tmp-cache
|
installer_tmp-cache
|
||||||
env
|
env
|
||||||
|
/deps
|
||||||
cocoa/autogen
|
cocoa/autogen
|
||||||
|
|
||||||
/run.py
|
/run.py
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
|||||||
Copyright 2013 Hardcoded Software Inc. (http://www.hardcoded.net)
|
Copyright 2014 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:
|
||||||
|
|||||||
54
README.md
54
README.md
@@ -1,14 +1,24 @@
|
|||||||
# dupeGuru
|
# dupeGuru
|
||||||
|
|
||||||
This package contains the source for dupeGuru. Its documentation is
|
[dupeGuru][dupeguru] is a cross-platform (Linux, OS X, Windows) GUI tool to find duplicate files in
|
||||||
[available online][documentation]. Here's how this source tree is organised:
|
a system. It's written mostly in Python 3 and has the peculiarity of using
|
||||||
|
[multiple GUI toolkits][cross-toolkit], all using the same core Python code. On OS X, the UI layer
|
||||||
|
is written in Objective-C and uses Cocoa. On Linux and Windows, it's written in Python and uses Qt5.
|
||||||
|
|
||||||
|
dupeGuru comes in 3 editions (standard, music and picture) which are all buildable from this same
|
||||||
|
source tree. You choose the edition you want to build in a ``configure.py`` flag.
|
||||||
|
|
||||||
|
# Contents of this folder
|
||||||
|
|
||||||
|
This folder contains the source for dupeGuru. Its documentation is in ``help``, but is also
|
||||||
|
[available online][documentation] in its built form. Here's how this source tree is organised:
|
||||||
|
|
||||||
* core: Contains the core logic code for dupeGuru. It's Python code.
|
* 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
|
* pkg: Skeleton files required to create different packages
|
||||||
* help: Help document, written for Sphinx.
|
* help: Help document, written for Sphinx.
|
||||||
* locale: .po files for localisation.
|
* locale: .po files for localisation.
|
||||||
|
|
||||||
@@ -36,26 +46,29 @@ and follow instructions from the script. You can then ignore the rest of the bui
|
|||||||
Prerequisites are installed through `pip`. However, some of them are not "pip installable" and have
|
Prerequisites are installed through `pip`. However, some of them are not "pip installable" and have
|
||||||
to be installed manually.
|
to be installed manually.
|
||||||
|
|
||||||
* All systems: [Python 3.2+][python] and [setuptools][setuptools]
|
* All systems: [Python 3.3+][python] and [setuptools][setuptools]
|
||||||
* Mac OS X: The last XCode to have the 10.6 SDK included.
|
* Mac OS X: The last XCode to have the 10.7 SDK included. Python 3.4+.
|
||||||
* Windows: Visual Studio 2008, [PyQt 4.7+][pyqt], [cx_Freeze][cxfreeze] and
|
* Windows: Visual Studio 2010, [PyQt 5.0+][pyqt], [cx_Freeze][cxfreeze] and
|
||||||
[Advanced Installer][advinst] (you only need the last two if you want to create an installer)
|
[Advanced Installer][advinst] (you only need the last two if you want to create an installer)
|
||||||
|
|
||||||
On Ubuntu, the apt-get command to install all pre-requisites is:
|
On Ubuntu (14.04+), the apt-get command to install all pre-requisites is:
|
||||||
|
|
||||||
$ apt-get install python3-dev python3-pyqt4 pyqt4-dev-tools python3-setuptools
|
$ apt-get install python3-dev python3-pyqt5 pyqt5-dev-tools
|
||||||
|
|
||||||
## Virtualenv setup
|
On Arch, it's:
|
||||||
|
|
||||||
First, you need `pip` and `virtualenv` in your system Python install:
|
$ pacman -S python-pyqt5
|
||||||
|
|
||||||
$ sudo easy_install pip
|
## Setting up the virtual environment
|
||||||
$ sudo pip install virtualenv
|
|
||||||
|
|
||||||
Then, in dupeGuru's source folder, create a virtual environment and activate it:
|
Use Python's built-in `pyvenv` to create a virtual environment in which we're going to install our.
|
||||||
|
Python-related dependencies. `pyvenv` is built-in Python but, unlike its `virtualenv` predecessor,
|
||||||
|
it doesn't install setuptools and pip, so it has to be installed manually:
|
||||||
|
|
||||||
$ virtualenv --system-site-packages env
|
$ pyvenv --system-site-packages env
|
||||||
$ source env/bin/activate
|
$ source env/bin/activate
|
||||||
|
$ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python
|
||||||
|
$ easy_install pip
|
||||||
|
|
||||||
Then, you can install pip requirements in your virtualenv:
|
Then, you can install pip requirements in your virtualenv:
|
||||||
|
|
||||||
@@ -63,17 +76,6 @@ Then, you can install pip requirements in your virtualenv:
|
|||||||
|
|
||||||
([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).
|
||||||
|
|
||||||
## Alternative: pyvenv
|
|
||||||
|
|
||||||
If you're on Python 3.3+, you can use the built-in `pyvenv` instead of `virtualenv`. `pyvenv` is
|
|
||||||
pretty much the same thing as `virtualenv`, except that it doesn't install setuptools and pip, so it
|
|
||||||
has to be installed manually:
|
|
||||||
|
|
||||||
$ pyvenv --system-site-packages env
|
|
||||||
$ source env/bin/activate
|
|
||||||
$ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python
|
|
||||||
$ easy_install pip
|
|
||||||
|
|
||||||
## Actual building and running
|
## Actual building and running
|
||||||
|
|
||||||
With your virtualenv activated, you can build and run dupeGuru with these commands:
|
With your virtualenv activated, you can build and run dupeGuru with these commands:
|
||||||
@@ -86,6 +88,8 @@ You can also package dupeGuru into an installable package with:
|
|||||||
|
|
||||||
$ python package.py
|
$ python package.py
|
||||||
|
|
||||||
|
[dupeguru]: http://www.hardcoded.net/dupeguru/
|
||||||
|
[cross-toolkit]: http://www.hardcoded.net/articles/cross-toolkit-software
|
||||||
[documentation]: http://www.hardcoded.net/dupeguru/help/en/
|
[documentation]: http://www.hardcoded.net/dupeguru/help/en/
|
||||||
[python]: http://www.python.org/
|
[python]: http://www.python.org/
|
||||||
[setuptools]: https://pypi.python.org/pypi/setuptools
|
[setuptools]: https://pypi.python.org/pypi/setuptools
|
||||||
|
|||||||
35
bootstrap.sh
35
bootstrap.sh
@@ -2,24 +2,39 @@
|
|||||||
|
|
||||||
command -v python3 -m venv >/dev/null 2>&1 || { echo >&2 "Python 3.3 required. Install it and try again. Aborting"; exit 1; }
|
command -v python3 -m venv >/dev/null 2>&1 || { echo >&2 "Python 3.3 required. Install it and try again. Aborting"; exit 1; }
|
||||||
|
|
||||||
|
if [ -d "deps" ]; then
|
||||||
|
# We have a collection of dependencies in our source package. We might as well use it instead
|
||||||
|
# of downloading it from PyPI.
|
||||||
|
PIPARGS="--no-index --find-links=deps"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -d "env" ]; then
|
if [ ! -d "env" ]; then
|
||||||
echo "No virtualenv. Creating one"
|
echo "No virtualenv. Creating one"
|
||||||
command -v curl >/dev/null 2>&1 || { echo >&2 "curl required. Install it and try again. Aborting"; exit 1; }
|
# We need a "system-site-packages" env to have PyQt, but we also need to ensure a local pip
|
||||||
python3 -m venv --system-site-packages env
|
# install. To achieve our latter goal, we start with a normal venv, which we later upgrade to
|
||||||
source env/bin/activate
|
# a system-site-packages once pip is installed.
|
||||||
curl https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py | python
|
python3 -m venv env
|
||||||
easy_install pip
|
|
||||||
else
|
|
||||||
echo "There's already an env. Activating it"
|
|
||||||
source env/bin/activate
|
source env/bin/activate
|
||||||
|
if python -m ensurepip; then
|
||||||
|
echo "We're under Python 3.4+, no need to try to install pip!"
|
||||||
|
else
|
||||||
|
python get-pip.py $PIPARGS --force-reinstall
|
||||||
|
fi
|
||||||
|
deactivate
|
||||||
|
if [ "$(uname)" != "Darwin" ]; then
|
||||||
|
# We only need system site packages for PyQt, so under OS X, we don't enable it
|
||||||
|
python3 -m venv env --upgrade --system-site-packages
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
source env/bin/activate
|
||||||
|
|
||||||
echo "Installing pip requirements"
|
echo "Installing pip requirements"
|
||||||
if [ "$(uname)" == "Darwin" ]; then
|
if [ "$(uname)" == "Darwin" ]; then
|
||||||
pip install -r requirements-osx.txt
|
pip install $PIPARGS -r requirements-osx.txt
|
||||||
else
|
else
|
||||||
python3 -c "import PyQt4" >/dev/null 2>&1 || { echo >&2 "PyQt 4.8+ required. Install it and try again. Aborting"; exit 1; }
|
python3 -c "import PyQt5" >/dev/null 2>&1 || { echo >&2 "PyQt 5.1+ required. Install it and try again. Aborting"; exit 1; }
|
||||||
pip install -r requirements.txt
|
pip install $PIPARGS -r requirements.txt
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Bootstrapping complete! You can now configure, build and run dupeGuru with:"
|
echo "Bootstrapping complete! You can now configure, build and run dupeGuru with:"
|
||||||
|
|||||||
34
build.py
34
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 2013 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2014 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
|
||||||
@@ -19,7 +19,7 @@ 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, OSXAppStructure,
|
get_module_version, move_all, copy_all, OSXAppStructure,
|
||||||
build_cocoalib_xibless, fix_qt_resource_file, build_cocoa_ext, copy_embeddable_python_dylib,
|
build_cocoalib_xibless, fix_qt_resource_file, build_cocoa_ext, copy_embeddable_python_dylib,
|
||||||
collect_stdlib_dependencies, copy)
|
collect_stdlib_dependencies, copy)
|
||||||
from hscommon import loc
|
from hscommon import loc
|
||||||
@@ -104,7 +104,7 @@ def build_cocoa(edition, dev):
|
|||||||
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']
|
appscript_pkgs = ['appscript', 'aem', 'mactypes', 'osax']
|
||||||
specific_packages = {
|
specific_packages = {
|
||||||
'se': ['core_se'],
|
'se': ['core_se'],
|
||||||
'me': ['core_me'] + appscript_pkgs + ['hsaudiotag'],
|
'me': ['core_me'] + appscript_pkgs + ['hsaudiotag'],
|
||||||
@@ -123,7 +123,6 @@ def build_cocoa(edition, dev):
|
|||||||
del sys.path[0]
|
del sys.path[0]
|
||||||
# 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)
|
|
||||||
if not dev:
|
if not dev:
|
||||||
# Important: Don't ever run delete_files_with_pattern('*.py') on dev builds because you'll
|
# Important: Don't ever run delete_files_with_pattern('*.py') on dev builds because you'll
|
||||||
# be deleting all py files in symlinked folders.
|
# be deleting all py files in symlinked folders.
|
||||||
@@ -135,6 +134,7 @@ def build_cocoa(edition, dev):
|
|||||||
print_and_do(cocoa_compile_command(edition))
|
print_and_do(cocoa_compile_command(edition))
|
||||||
os.chdir('..')
|
os.chdir('..')
|
||||||
app.copy_executable('cocoa/build/dupeGuru')
|
app.copy_executable('cocoa/build/dupeGuru')
|
||||||
|
build_help(edition)
|
||||||
print("Copying resources and frameworks")
|
print("Copying resources and frameworks")
|
||||||
image_path = ed('cocoa/{}/dupeguru.icns')
|
image_path = ed('cocoa/{}/dupeguru.icns')
|
||||||
resources = [image_path, 'cocoa/base/dsa_pub.pem', 'build/dg_cocoa.py', 'build/help']
|
resources = [image_path, 'cocoa/base/dsa_pub.pem', 'build/dg_cocoa.py', 'build/help']
|
||||||
@@ -149,8 +149,9 @@ 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("pyrcc5 {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'))
|
||||||
|
build_help(edition)
|
||||||
print("Creating the run.py file")
|
print("Creating the run.py file")
|
||||||
filereplace(op.join('qt', 'run_template.py'), 'run.py', edition=edition)
|
filereplace(op.join('qt', 'run_template.py'), 'run.py', edition=edition)
|
||||||
|
|
||||||
@@ -168,17 +169,12 @@ def build_help(edition):
|
|||||||
conftmpl = op.join(current_path, 'help', 'conf.tmpl')
|
conftmpl = op.join(current_path, 'help', 'conf.tmpl')
|
||||||
sphinxgen.gen(help_basepath, help_destpath, changelog_path, tixurl, confrepl, conftmpl, changelogtmpl)
|
sphinxgen.gen(help_basepath, help_destpath, changelog_path, tixurl, confrepl, conftmpl, changelogtmpl)
|
||||||
|
|
||||||
def build_base_localizations():
|
|
||||||
loc.compile_all_po('locale')
|
|
||||||
loc.compile_all_po(op.join('hscommon', 'locale'))
|
|
||||||
loc.merge_locale_dir(op.join('hscommon', 'locale'), 'locale')
|
|
||||||
|
|
||||||
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')
|
||||||
|
|
||||||
def build_localizations(ui, edition):
|
def build_localizations(ui, edition):
|
||||||
build_base_localizations()
|
loc.compile_all_po('locale')
|
||||||
if ui == 'cocoa':
|
if ui == 'cocoa':
|
||||||
app = cocoa_app(edition)
|
app = cocoa_app(edition)
|
||||||
loc.build_cocoa_localizations(app, en_stringsfile=op.join('cocoa', 'base', 'en.lproj', 'Localizable.strings'))
|
loc.build_cocoa_localizations(app, en_stringsfile=op.join('cocoa', 'base', 'en.lproj', 'Localizable.strings'))
|
||||||
@@ -191,7 +187,7 @@ def build_localizations(ui, edition):
|
|||||||
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:
|
if ui == 'qt' and not ISLINUX:
|
||||||
print("Copying qt_*.qm files into the 'locale' folder")
|
print("Copying qt_*.qm files into the 'locale' folder")
|
||||||
from PyQt4.QtCore import QLibraryInfo
|
from PyQt5.QtCore import QLibraryInfo
|
||||||
trfolder = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
|
trfolder = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
|
||||||
for lang in loc.get_langs('locale'):
|
for lang in loc.get_langs('locale'):
|
||||||
qmname = 'qt_%s.qm' % lang
|
qmname = 'qt_%s.qm' % lang
|
||||||
@@ -220,8 +216,6 @@ def build_updatepot():
|
|||||||
# We want to merge the generated pot with the old pot in the most preserving way possible.
|
# 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'], merge=(not ISOSX))
|
loc.generate_pot(ui_packages, op.join('locale', 'ui.pot'), ['tr'], merge=(not ISOSX))
|
||||||
print("Building hscommon.pot")
|
|
||||||
loc.generate_pot(['hscommon'], op.join('hscommon', 'locale', 'hscommon.pot'), ['tr'])
|
|
||||||
print("Building qtlib.pot")
|
print("Building qtlib.pot")
|
||||||
loc.generate_pot(['qtlib'], op.join('qtlib', 'locale', 'qtlib.pot'), ['tr'])
|
loc.generate_pot(['qtlib'], op.join('qtlib', 'locale', 'qtlib.pot'), ['tr'])
|
||||||
if ISOSX:
|
if ISOSX:
|
||||||
@@ -236,13 +230,11 @@ def build_updatepot():
|
|||||||
def build_mergepot():
|
def build_mergepot():
|
||||||
print("Updating .po files using .pot files")
|
print("Updating .po files using .pot files")
|
||||||
loc.merge_pots_into_pos('locale')
|
loc.merge_pots_into_pos('locale')
|
||||||
loc.merge_pots_into_pos(op.join('hscommon', 'locale'))
|
|
||||||
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_normpo():
|
def build_normpo():
|
||||||
loc.normalize_all_pos('locale')
|
loc.normalize_all_pos('locale')
|
||||||
loc.normalize_all_pos(op.join('hscommon', 'locale'))
|
|
||||||
loc.normalize_all_pos(op.join('qtlib', 'locale'))
|
loc.normalize_all_pos(op.join('qtlib', 'locale'))
|
||||||
loc.normalize_all_pos(op.join('cocoalib', 'locale'))
|
loc.normalize_all_pos(op.join('cocoalib', 'locale'))
|
||||||
|
|
||||||
@@ -264,7 +256,7 @@ def build_cocoa_bridging_interfaces(edition):
|
|||||||
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, PyBaseApp,
|
OutlineView, PySelectableList, SelectableListView, PyTable, TableView, PyBaseApp,
|
||||||
PyFairware, PyTextField, ProgressWindowView, PyProgressWindow)
|
PyTextField, ProgressWindowView, PyProgressWindow)
|
||||||
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
|
||||||
@@ -276,7 +268,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, PyBaseApp, PyFairware,
|
allclasses = [PyGUIObject, PyColumns, PyOutline, PySelectableList, PyTable, PyBaseApp,
|
||||||
PyDetailsPanel, PyDirectoryOutline, PyPrioritizeDialog, PyPrioritizeList, PyProblemDialog,
|
PyDetailsPanel, PyDirectoryOutline, PyPrioritizeDialog, PyPrioritizeList, PyProblemDialog,
|
||||||
PyIgnoreListDialog, PyDeletionOptions, PyResultTable, PyStatsLabel, PyDupeGuruBase,
|
PyIgnoreListDialog, PyDeletionOptions, PyResultTable, PyStatsLabel, PyDupeGuruBase,
|
||||||
PyTextField, PyProgressWindow, appmod.PyDupeGuru]
|
PyTextField, PyProgressWindow, appmod.PyDupeGuru]
|
||||||
@@ -317,7 +309,6 @@ def build_pe_modules(ui):
|
|||||||
def build_normal(edition, ui, dev, conf):
|
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)
|
|
||||||
print("Building dupeGuru")
|
print("Building dupeGuru")
|
||||||
if edition == 'pe':
|
if edition == 'pe':
|
||||||
build_pe_modules(ui)
|
build_pe_modules(ui)
|
||||||
@@ -335,8 +326,9 @@ def main():
|
|||||||
if dev:
|
if dev:
|
||||||
print("Building in Dev mode")
|
print("Building in Dev mode")
|
||||||
if options.clean:
|
if options.clean:
|
||||||
if op.exists('build'):
|
for path in ['build', op.join('cocoa', 'build'), op.join('cocoa', 'autogen')]:
|
||||||
shutil.rmtree('build')
|
if op.exists(path):
|
||||||
|
shutil.rmtree(path)
|
||||||
if not op.exists('build'):
|
if not op.exists('build'):
|
||||||
os.mkdir('build')
|
os.mkdir('build')
|
||||||
if options.doc:
|
if options.doc:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 "HSFairwareAboutBox.h"
|
#import "HSAboutBox.h"
|
||||||
#import "HSRecentFiles.h"
|
#import "HSRecentFiles.h"
|
||||||
#import "HSProgressWindow.h"
|
#import "HSProgressWindow.h"
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
IgnoreListDialog *_ignoreListDialog;
|
IgnoreListDialog *_ignoreListDialog;
|
||||||
HSProgressWindow *_progressWindow;
|
HSProgressWindow *_progressWindow;
|
||||||
NSWindowController *_preferencesPanel;
|
NSWindowController *_preferencesPanel;
|
||||||
HSFairwareAboutBox *_aboutBox;
|
HSAboutBox *_aboutBox;
|
||||||
HSRecentFiles *_recentResults;
|
HSRecentFiles *_recentResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,6 +73,4 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
|
|
||||||
/* model --> view */
|
/* model --> view */
|
||||||
- (void)showMessage:(NSString *)msg;
|
- (void)showMessage:(NSString *)msg;
|
||||||
- (void)setupAsRegistered;
|
|
||||||
- (void)showDemoNagWithPrompt:(NSString *)prompt;
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
||||||
which should be included with this package. The terms are also available at
|
which should be included with this package. The terms are also available at
|
||||||
@@ -8,7 +8,6 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
|
|
||||||
#import "AppDelegateBase.h"
|
#import "AppDelegateBase.h"
|
||||||
#import "ProgressController.h"
|
#import "ProgressController.h"
|
||||||
#import "HSFairwareReminder.h"
|
|
||||||
#import "HSPyUtil.h"
|
#import "HSPyUtil.h"
|
||||||
#import "Consts.h"
|
#import "Consts.h"
|
||||||
#import "Dialogs.h"
|
#import "Dialogs.h"
|
||||||
@@ -140,7 +139,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
[op setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]];
|
[op setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]];
|
||||||
[op setTitle:NSLocalizedString(@"Select a results file to load", @"")];
|
[op setTitle:NSLocalizedString(@"Select a results file to load", @"")];
|
||||||
if ([op runModal] == NSOKButton) {
|
if ([op runModal] == NSOKButton) {
|
||||||
NSString *filename = [[op filenames] objectAtIndex:0];
|
NSString *filename = [[[op URLs] objectAtIndex:0] path];
|
||||||
[model loadResultsFrom:filename];
|
[model loadResultsFrom:filename];
|
||||||
[[self recentResults] addFile:filename];
|
[[self recentResults] addFile:filename];
|
||||||
}
|
}
|
||||||
@@ -162,7 +161,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
- (void)showAboutBox
|
- (void)showAboutBox
|
||||||
{
|
{
|
||||||
if (_aboutBox == nil) {
|
if (_aboutBox == nil) {
|
||||||
_aboutBox = [[HSFairwareAboutBox alloc] initWithApp:model];
|
_aboutBox = [[HSAboutBox alloc] initWithApp:model];
|
||||||
}
|
}
|
||||||
[[_aboutBox window] makeKeyAndOrderFront:nil];
|
[[_aboutBox window] makeKeyAndOrderFront:nil];
|
||||||
}
|
}
|
||||||
@@ -199,7 +198,6 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
/* Delegate */
|
/* Delegate */
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
[model initialRegistrationSetup];
|
|
||||||
[model loadSession];
|
[model loadSession];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,16 +259,6 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
[[self resultWindow] showProblemDialog];
|
[[self resultWindow] showProblemDialog];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setupAsRegistered
|
|
||||||
{
|
|
||||||
// Nothing to do.
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)showDemoNagWithPrompt:(NSString *)prompt
|
|
||||||
{
|
|
||||||
[HSFairwareReminder showDemoNagWithApp:[self model] prompt:prompt];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)selectDestFolderWithPrompt:(NSString *)prompt
|
- (NSString *)selectDestFolderWithPrompt:(NSString *)prompt
|
||||||
{
|
{
|
||||||
NSOpenPanel *op = [NSOpenPanel openPanel];
|
NSOpenPanel *op = [NSOpenPanel openPanel];
|
||||||
@@ -280,7 +268,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
[op setAllowsMultipleSelection:NO];
|
[op setAllowsMultipleSelection:NO];
|
||||||
[op setTitle:prompt];
|
[op setTitle:prompt];
|
||||||
if ([op runModal] == NSOKButton) {
|
if ([op runModal] == NSOKButton) {
|
||||||
return [[op filenames] objectAtIndex:0];
|
return [[[op URLs] objectAtIndex:0] path];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil;
|
return nil;
|
||||||
@@ -294,7 +282,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
[sp setAllowedFileTypes:[NSArray arrayWithObject:extension]];
|
[sp setAllowedFileTypes:[NSArray arrayWithObject:extension]];
|
||||||
[sp setTitle:prompt];
|
[sp setTitle:prompt];
|
||||||
if ([sp runModal] == NSOKButton) {
|
if ([sp runModal] == NSOKButton) {
|
||||||
return [sp filename];
|
return [[sp URL] path];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil;
|
return nil;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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
|
||||||
@@ -64,4 +64,9 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
[[self window] close];
|
[[self window] close];
|
||||||
return r == NSOKButton;
|
return r == NSOKButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setHardlinkOptionEnabled:(BOOL)enabled
|
||||||
|
{
|
||||||
|
[linkTypeRadio setEnabled:enabled];
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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
|
||||||
@@ -16,4 +16,6 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
@interface DirectoryOutline : HSOutline {}
|
@interface DirectoryOutline : HSOutline {}
|
||||||
- (id)initWithPyRef:(PyObject *)aPyRef outlineView:(HSOutlineView *)aOutlineView;
|
- (id)initWithPyRef:(PyObject *)aPyRef outlineView:(HSOutlineView *)aOutlineView;
|
||||||
- (PyDirectoryOutline *)model;
|
- (PyDirectoryOutline *)model;
|
||||||
|
|
||||||
|
- (void)selectAll;
|
||||||
@end;
|
@end;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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,12 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
return (PyDirectoryOutline *)model;
|
return (PyDirectoryOutline *)model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Public */
|
||||||
|
- (void)selectAll
|
||||||
|
{
|
||||||
|
[[self model] selectAll];
|
||||||
|
}
|
||||||
|
|
||||||
/* Delegate */
|
/* Delegate */
|
||||||
- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id < NSDraggingInfo >)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
|
- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id < NSDraggingInfo >)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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
|
||||||
@@ -46,4 +46,6 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
|
|
||||||
- (void)addDirectory:(NSString *)directory;
|
- (void)addDirectory:(NSString *)directory;
|
||||||
- (void)refreshRemoveButtonText;
|
- (void)refreshRemoveButtonText;
|
||||||
|
- (void)markAll;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
||||||
which should be included with this package. The terms are also available at
|
which should be included with this package. The terms are also available at
|
||||||
@@ -91,8 +91,8 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
[op setTitle:NSLocalizedString(@"Select a folder to add to the scanning list", @"")];
|
[op setTitle:NSLocalizedString(@"Select a folder to add to the scanning list", @"")];
|
||||||
[op setDelegate:self];
|
[op setDelegate:self];
|
||||||
if ([op runModal] == NSOKButton) {
|
if ([op runModal] == NSOKButton) {
|
||||||
for (NSString *directory in [op filenames]) {
|
for (NSURL *directoryURL in [op URLs]) {
|
||||||
[self addDirectory:directory];
|
[self addDirectory:[directoryURL path]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,6 +158,14 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)markAll
|
||||||
|
{
|
||||||
|
/* markAll isn't very descriptive of what we do, but since we re-use the Mark All button from
|
||||||
|
the result window, we don't have much choice.
|
||||||
|
*/
|
||||||
|
[outline selectAll];
|
||||||
|
}
|
||||||
|
|
||||||
/* Delegate */
|
/* Delegate */
|
||||||
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)path
|
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)path
|
||||||
{
|
{
|
||||||
@@ -171,6 +179,14 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
[self addDirectory:path];
|
[self addDirectory:path];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
||||||
|
{
|
||||||
|
if ([item action] == @selector(markAll)) {
|
||||||
|
[item setTitle:NSLocalizedString(@"Select All", @"")];
|
||||||
|
}
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
/* Notifications */
|
/* Notifications */
|
||||||
|
|
||||||
- (void)directorySelectionChanged:(NSNotification *)aNotification
|
- (void)directorySelectionChanged:(NSNotification *)aNotification
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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
|
||||||
@@ -258,8 +258,8 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
[sp setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]];
|
[sp setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]];
|
||||||
[sp setTitle:NSLocalizedString(@"Select a file to save your results to", @"")];
|
[sp setTitle:NSLocalizedString(@"Select a file to save your results to", @"")];
|
||||||
if ([sp runModal] == NSOKButton) {
|
if ([sp runModal] == NSOKButton) {
|
||||||
[model saveResultsAs:[sp filename]];
|
[model saveResultsAs:[[sp URL] path]];
|
||||||
[[app recentResults] addFile:[sp filename]];
|
[[app recentResults] addFile:[[sp URL] path]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,6 +344,9 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
|
|
||||||
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
||||||
{
|
{
|
||||||
|
if ([item action] == @selector(markAll)) {
|
||||||
|
[item setTitle:NSLocalizedString(@"Mark All", @"")];
|
||||||
|
}
|
||||||
return ![[ProgressController mainProgressController] isShown];
|
return ![[ProgressController mainProgressController] isShown];
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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,5 @@
|
|||||||
|
|
||||||
"%@ Results" = "%@ Results";
|
"%@ 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.";
|
|
||||||
"About dupeGuru" = "About dupeGuru";
|
"About dupeGuru" = "About dupeGuru";
|
||||||
"Action" = "Action";
|
"Action" = "Action";
|
||||||
"Actions" = "Actions";
|
"Actions" = "Actions";
|
||||||
@@ -127,6 +126,7 @@
|
|||||||
"Select a file to save your results to" = "Select a file to save your results to";
|
"Select a file to save your results to" = "Select a file to save your results to";
|
||||||
"Select a folder to add to the scanning list" = "Select a folder to add to the scanning list";
|
"Select a folder to add to the scanning list" = "Select a folder to add to the scanning list";
|
||||||
"Select a results file to load" = "Select a results file to load";
|
"Select a results file to load" = "Select a results file to load";
|
||||||
|
"Select All" = "Select All";
|
||||||
"Select folders to scan and press \"Scan\"." = "Select folders to scan and press \"Scan\".";
|
"Select folders to scan and press \"Scan\"." = "Select folders to scan and press \"Scan\".";
|
||||||
"Selected" = "Selected";
|
"Selected" = "Selected";
|
||||||
"Send Marked to Trash..." = "Send Marked to Trash...";
|
"Send Marked to Trash..." = "Send Marked to Trash...";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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,24 +1,23 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from objp.util import pyref, dontwrap
|
from objp.util import pyref, dontwrap
|
||||||
from cocoa import install_exception_hook, install_cocoa_logger, patch_threaded_job_performer, proxy
|
from cocoa import install_exception_hook, install_cocoa_logger, patch_threaded_job_performer
|
||||||
from cocoa.inter import PyFairware, FairwareView
|
from cocoa.inter import PyBaseApp, BaseAppView
|
||||||
|
|
||||||
class DupeGuruView(FairwareView):
|
class DupeGuruView(BaseAppView):
|
||||||
def askYesNoWithPrompt_(self, prompt: str) -> bool: pass
|
def askYesNoWithPrompt_(self, prompt: str) -> bool: pass
|
||||||
def showProblemDialog(self): pass
|
def showProblemDialog(self): pass
|
||||||
def selectDestFolderWithPrompt_(self, prompt: str) -> str: pass
|
def selectDestFolderWithPrompt_(self, prompt: str) -> str: pass
|
||||||
def selectDestFileWithPrompt_extension_(self, prompt: str, extension: str) -> str: pass
|
def selectDestFileWithPrompt_extension_(self, prompt: str, extension: str) -> str: pass
|
||||||
|
|
||||||
class PyDupeGuruBase(PyFairware):
|
class PyDupeGuruBase(PyBaseApp):
|
||||||
@dontwrap
|
@dontwrap
|
||||||
def _init(self, modelclass):
|
def _init(self, modelclass):
|
||||||
logging.basicConfig(level=logging.WARNING, format='%(levelname)s %(message)s')
|
logging.basicConfig(level=logging.WARNING, format='%(levelname)s %(message)s')
|
||||||
install_exception_hook()
|
install_exception_hook('https://github.com/hsoft/dupeguru/issues')
|
||||||
install_cocoa_logger()
|
install_cocoa_logger()
|
||||||
patch_threaded_job_performer()
|
patch_threaded_job_performer()
|
||||||
appdata = proxy.getAppdataPath()
|
self.model = modelclass(self)
|
||||||
self.model = modelclass(self, appdata)
|
|
||||||
|
|
||||||
#---Sub-proxies
|
#---Sub-proxies
|
||||||
def detailsPanel(self) -> pyref:
|
def detailsPanel(self) -> pyref:
|
||||||
@@ -144,14 +143,6 @@ class PyDupeGuruBase(PyFairware):
|
|||||||
self.model.options['copymove_dest_type'] = copymove_dest_type
|
self.model.options['copymove_dest_type'] = copymove_dest_type
|
||||||
|
|
||||||
#--- model --> view
|
#--- model --> view
|
||||||
@dontwrap
|
|
||||||
def open_path(self, path):
|
|
||||||
proxy.openPath_(str(path))
|
|
||||||
|
|
||||||
@dontwrap
|
|
||||||
def reveal_path(self, path):
|
|
||||||
proxy.revealPath_(str(path))
|
|
||||||
|
|
||||||
@dontwrap
|
@dontwrap
|
||||||
def ask_yes_no(self, prompt):
|
def ask_yes_no(self, prompt):
|
||||||
return self.callback.askYesNoWithPrompt_(prompt)
|
return self.callback.askYesNoWithPrompt_(prompt)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/11/16
|
# Created On: 2006/11/16
|
||||||
# Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2014 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
|
||||||
@@ -19,11 +19,11 @@ from hscommon.path import Path
|
|||||||
from hscommon.util import remove_invalid_xml
|
from hscommon.util import remove_invalid_xml
|
||||||
|
|
||||||
from core import directories
|
from core import directories
|
||||||
from core.app import JobType
|
from core.app import JobType, JOBID2TITLE
|
||||||
from core.scanner import ScanType
|
from core.scanner import ScanType
|
||||||
from core_me.app import DupeGuru as DupeGuruBase
|
from core_me.app import DupeGuru as DupeGuruBase
|
||||||
from core_me import fs
|
from core_me import fs
|
||||||
from .app import JOBID2TITLE, PyDupeGuruBase
|
from .app import PyDupeGuruBase
|
||||||
|
|
||||||
tr = trget('ui')
|
tr = trget('ui')
|
||||||
|
|
||||||
@@ -143,16 +143,13 @@ class Directories(directories.Directories):
|
|||||||
|
|
||||||
|
|
||||||
class DupeGuruME(DupeGuruBase):
|
class DupeGuruME(DupeGuruBase):
|
||||||
def __init__(self, view, appdata):
|
def __init__(self, view):
|
||||||
appdata = op.join(appdata, 'dupeGuru Music Edition')
|
DupeGuruBase.__init__(self, view)
|
||||||
DupeGuruBase.__init__(self, view, appdata)
|
|
||||||
# Use fileclasses set in DupeGuruBase.__init__()
|
# Use fileclasses set in DupeGuruBase.__init__()
|
||||||
self.directories = Directories(fileclasses=self.directories.fileclasses)
|
self.directories = Directories(fileclasses=self.directories.fileclasses)
|
||||||
self.dead_tracks = []
|
self.dead_tracks = []
|
||||||
|
|
||||||
def _do_delete(self, j, *args):
|
def _do_delete(self, j, *args):
|
||||||
# XXX If I read correctly, Python 3.3 will allow us to go fetch inner function easily, so
|
|
||||||
# we'll be able to replace "op" below with DupeGuruBase._do_delete.op.
|
|
||||||
def op(dupe):
|
def op(dupe):
|
||||||
j.add_progress()
|
j.add_progress()
|
||||||
return self._do_delete_dupe(dupe, *args)
|
return self._do_delete_dupe(dupe, *args)
|
||||||
@@ -174,7 +171,7 @@ class DupeGuruME(DupeGuruBase):
|
|||||||
DupeGuruBase._do_delete_dupe(self, dupe, *args)
|
DupeGuruBase._do_delete_dupe(self, dupe, *args)
|
||||||
|
|
||||||
def _create_file(self, path):
|
def _create_file(self, path):
|
||||||
if (self.directories.itunes_libpath is not None) and (path in self.directories.itunes_libpath[:-1]):
|
if (self.directories.itunes_libpath is not None) and (path in self.directories.itunes_libpath.parent()):
|
||||||
if not hasattr(self, 'itunes_songs'):
|
if not hasattr(self, 'itunes_songs'):
|
||||||
songs = get_itunes_songs(self.directories.itunes_libpath)
|
songs = get_itunes_songs(self.directories.itunes_libpath)
|
||||||
self.itunes_songs = {song.path: song for song in songs}
|
self.itunes_songs = {song.path: song for song in songs}
|
||||||
@@ -184,11 +181,14 @@ class DupeGuruME(DupeGuruBase):
|
|||||||
pass # We'll return the default file type, as per the last line of this method
|
pass # We'll return the default file type, as per the last line of this method
|
||||||
return DupeGuruBase._create_file(self, path)
|
return DupeGuruBase._create_file(self, path)
|
||||||
|
|
||||||
def _job_completed(self, jobid, exc):
|
def _job_completed(self, jobid):
|
||||||
if (jobid in {JobType.RemoveDeadTracks, JobType.ScanDeadTracks}) and (exc is not None):
|
# XXX Just before release, I'm realizing that this piece of code below is why I was passing
|
||||||
msg = tr("There were communication problems with iTunes. The operation couldn't be completed.")
|
# job exception as an argument to _job_completed(). I have to comment it for now. It's not
|
||||||
self.view.show_message(msg)
|
# the end of the world, but I should find an elegant solution to this at some point.
|
||||||
return True
|
# if (jobid in {JobType.RemoveDeadTracks, JobType.ScanDeadTracks}) and (exc is not None):
|
||||||
|
# msg = tr("There were communication problems with iTunes. The operation couldn't be completed.")
|
||||||
|
# self.view.show_message(msg)
|
||||||
|
# return True
|
||||||
if jobid == JobType.ScanDeadTracks:
|
if jobid == JobType.ScanDeadTracks:
|
||||||
dead_tracks_count = len(self.dead_tracks)
|
dead_tracks_count = len(self.dead_tracks)
|
||||||
if dead_tracks_count > 0:
|
if dead_tracks_count > 0:
|
||||||
@@ -202,7 +202,7 @@ class DupeGuruME(DupeGuruBase):
|
|||||||
if hasattr(self, 'itunes_songs'):
|
if hasattr(self, 'itunes_songs'):
|
||||||
# If we load another file, we want a refresh song list
|
# If we load another file, we want a refresh song list
|
||||||
del self.itunes_songs
|
del self.itunes_songs
|
||||||
DupeGuruBase._job_completed(self, jobid, exc)
|
DupeGuruBase._job_completed(self, jobid)
|
||||||
|
|
||||||
def copy_or_move(self, dupe, copy, destination, dest_type):
|
def copy_or_move(self, dupe, copy, destination, dest_type):
|
||||||
if isinstance(dupe, ITunesSong):
|
if isinstance(dupe, ITunesSong):
|
||||||
@@ -230,7 +230,7 @@ class DupeGuruME(DupeGuruBase):
|
|||||||
except CommandError as e:
|
except CommandError as e:
|
||||||
logging.warning('Error while trying to remove a track from iTunes: %s' % str(e))
|
logging.warning('Error while trying to remove a track from iTunes: %s' % str(e))
|
||||||
|
|
||||||
self.view.start_job(JobType.RemoveDeadTracks, do)
|
self._start_job(JobType.RemoveDeadTracks, do)
|
||||||
|
|
||||||
def scan_dead_tracks(self):
|
def scan_dead_tracks(self):
|
||||||
def do(j):
|
def do(j):
|
||||||
@@ -248,7 +248,7 @@ class DupeGuruME(DupeGuruBase):
|
|||||||
self.dead_tracks.append(track)
|
self.dead_tracks.append(track)
|
||||||
logging.info('Found %d dead tracks' % len(self.dead_tracks))
|
logging.info('Found %d dead tracks' % len(self.dead_tracks))
|
||||||
|
|
||||||
self.view.start_job(JobType.ScanDeadTracks, do)
|
self._start_job(JobType.ScanDeadTracks, do)
|
||||||
|
|
||||||
class PyDupeGuru(PyDupeGuruBase):
|
class PyDupeGuru(PyDupeGuruBase):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|||||||
@@ -1,21 +1,19 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2006/11/13
|
# Created On: 2006/11/13
|
||||||
# Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2014 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 os.path as op
|
|
||||||
import plistlib
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
import io
|
||||||
|
|
||||||
from appscript import app, its, k, CommandError, ApplicationNotFoundError
|
from appscript import app, its, k, CommandError, ApplicationNotFoundError
|
||||||
|
|
||||||
from hscommon import io
|
|
||||||
from hscommon.util import remove_invalid_xml, first
|
from hscommon.util import remove_invalid_xml, first
|
||||||
from hscommon.path import Path
|
from hscommon.path import Path, pathify
|
||||||
from hscommon.trans import trget
|
from hscommon.trans import trget
|
||||||
from cocoa import proxy
|
from cocoa import proxy
|
||||||
|
|
||||||
@@ -25,6 +23,7 @@ from core.app import JobType
|
|||||||
from core_pe import _block_osx
|
from core_pe import _block_osx
|
||||||
from core_pe.photo import Photo as PhotoBase
|
from core_pe.photo import Photo as PhotoBase
|
||||||
from core_pe.app import DupeGuru as DupeGuruBase
|
from core_pe.app import DupeGuru as DupeGuruBase
|
||||||
|
from core_pe.iphoto_plist import IPhotoPlistParser
|
||||||
from .app import PyDupeGuruBase
|
from .app import PyDupeGuruBase
|
||||||
|
|
||||||
tr = trget('ui')
|
tr = trget('ui')
|
||||||
@@ -48,6 +47,16 @@ class Photo(PhotoBase):
|
|||||||
raise IOError('The picture %s could not be read' % str(self.path))
|
raise IOError('The picture %s could not be read' % str(self.path))
|
||||||
return blocks
|
return blocks
|
||||||
|
|
||||||
|
def _get_exif_timestamp(self):
|
||||||
|
exifdata = proxy.readExifData_(str(self.path))
|
||||||
|
if exifdata:
|
||||||
|
try:
|
||||||
|
return exifdata['{Exif}']['DateTimeOriginal']
|
||||||
|
except KeyError:
|
||||||
|
return ''
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
class IPhoto(Photo):
|
class IPhoto(Photo):
|
||||||
def __init__(self, path, db_id):
|
def __init__(self, path, db_id):
|
||||||
@@ -67,11 +76,12 @@ class AperturePhoto(Photo):
|
|||||||
def display_folder_path(self):
|
def display_folder_path(self):
|
||||||
return APERTURE_PATH
|
return APERTURE_PATH
|
||||||
|
|
||||||
def get_iphoto_or_aperture_pictures(plistpath, photo_class):
|
@pathify
|
||||||
|
def get_iphoto_or_aperture_pictures(plistpath: Path, photo_class):
|
||||||
# The structure of iPhoto and Aperture libraries for the base photo list are excactly the same.
|
# The structure of iPhoto and Aperture libraries for the base photo list are excactly the same.
|
||||||
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()
|
||||||
# There was a case where a guy had 0x10 chars in his plist, causing expat errors on loading
|
# There was a case where a guy had 0x10 chars in his plist, causing expat errors on loading
|
||||||
s = remove_invalid_xml(s, replace_with='')
|
s = remove_invalid_xml(s, replace_with='')
|
||||||
# It seems that iPhoto sometimes doesn't properly escape & chars. The regexp below is to find
|
# It seems that iPhoto sometimes doesn't properly escape & chars. The regexp below is to find
|
||||||
@@ -80,7 +90,12 @@ def get_iphoto_or_aperture_pictures(plistpath, photo_class):
|
|||||||
s, count = re.subn(r'&(?![a-zA-Z0-9_-]+|#[0-9]+|#x[0-9a-fA-F]+;)', '', s)
|
s, count = re.subn(r'&(?![a-zA-Z0-9_-]+|#[0-9]+|#x[0-9a-fA-F]+;)', '', s)
|
||||||
if count:
|
if count:
|
||||||
logging.warning("%d invalid XML entities replacement made", count)
|
logging.warning("%d invalid XML entities replacement made", count)
|
||||||
plist = plistlib.readPlistFromBytes(s.encode('utf-8'))
|
parser = IPhotoPlistParser()
|
||||||
|
try:
|
||||||
|
plist = parser.parse(io.BytesIO(s.encode('utf-8')))
|
||||||
|
except Exception:
|
||||||
|
logging.warning("iPhoto plist parsing choked on data: %r", parser.lastdata)
|
||||||
|
raise
|
||||||
result = []
|
result = []
|
||||||
for key, photo_data in plist['Master Image List'].items():
|
for key, photo_data in plist['Master Image List'].items():
|
||||||
if photo_data['MediaType'] != 'Image':
|
if photo_data['MediaType'] != 'Image':
|
||||||
@@ -114,12 +129,12 @@ class Directories(directories.Directories):
|
|||||||
directories.Directories.__init__(self, fileclasses=[Photo])
|
directories.Directories.__init__(self, fileclasses=[Photo])
|
||||||
try:
|
try:
|
||||||
self.iphoto_libpath = get_iphoto_database_path()
|
self.iphoto_libpath = get_iphoto_database_path()
|
||||||
self.set_state(self.iphoto_libpath[:-1], directories.DirectoryState.Excluded)
|
self.set_state(self.iphoto_libpath.parent(), directories.DirectoryState.Excluded)
|
||||||
except directories.InvalidPathError:
|
except directories.InvalidPathError:
|
||||||
self.iphoto_libpath = None
|
self.iphoto_libpath = None
|
||||||
try:
|
try:
|
||||||
self.aperture_libpath = get_aperture_database_path()
|
self.aperture_libpath = get_aperture_database_path()
|
||||||
self.set_state(self.aperture_libpath[:-1], directories.DirectoryState.Excluded)
|
self.set_state(self.aperture_libpath.parent(), directories.DirectoryState.Excluded)
|
||||||
except directories.InvalidPathError:
|
except directories.InvalidPathError:
|
||||||
self.aperture_libpath = None
|
self.aperture_libpath = None
|
||||||
|
|
||||||
@@ -171,9 +186,8 @@ class Directories(directories.Directories):
|
|||||||
|
|
||||||
|
|
||||||
class DupeGuruPE(DupeGuruBase):
|
class DupeGuruPE(DupeGuruBase):
|
||||||
def __init__(self, view, appdata):
|
def __init__(self, view):
|
||||||
appdata = op.join(appdata, 'dupeGuru Picture Edition')
|
DupeGuruBase.__init__(self, view)
|
||||||
DupeGuruBase.__init__(self, view, appdata)
|
|
||||||
self.directories = Directories()
|
self.directories = Directories()
|
||||||
|
|
||||||
def _do_delete(self, j, *args):
|
def _do_delete(self, j, *args):
|
||||||
@@ -247,20 +261,20 @@ class DupeGuruPE(DupeGuruBase):
|
|||||||
DupeGuruBase._do_delete_dupe(self, dupe, *args)
|
DupeGuruBase._do_delete_dupe(self, dupe, *args)
|
||||||
|
|
||||||
def _create_file(self, path):
|
def _create_file(self, path):
|
||||||
if (self.directories.iphoto_libpath is not None) and (path in self.directories.iphoto_libpath[:-1]):
|
if (self.directories.iphoto_libpath is not None) and (path in self.directories.iphoto_libpath.parent()):
|
||||||
if not hasattr(self, 'path2iphoto'):
|
if not hasattr(self, 'path2iphoto'):
|
||||||
photos = get_iphoto_pictures(self.directories.iphoto_libpath)
|
photos = get_iphoto_pictures(self.directories.iphoto_libpath)
|
||||||
self.path2iphoto = {p.path: p for p in photos}
|
self.path2iphoto = {p.path: p for p in photos}
|
||||||
return self.path2iphoto.get(path)
|
return self.path2iphoto.get(path)
|
||||||
if (self.directories.aperture_libpath is not None) and (path in self.directories.aperture_libpath[:-1]):
|
if (self.directories.aperture_libpath is not None) and (path in self.directories.aperture_libpath.parent()):
|
||||||
if not hasattr(self, 'path2aperture'):
|
if not hasattr(self, 'path2aperture'):
|
||||||
photos = get_aperture_pictures(self.directories.aperture_libpath)
|
photos = get_aperture_pictures(self.directories.aperture_libpath)
|
||||||
self.path2aperture = {p.path: p for p in photos}
|
self.path2aperture = {p.path: p for p in photos}
|
||||||
return self.path2aperture.get(path)
|
return self.path2aperture.get(path)
|
||||||
return DupeGuruBase._create_file(self, path)
|
return DupeGuruBase._create_file(self, path)
|
||||||
|
|
||||||
def _job_completed(self, jobid, exc):
|
def _job_completed(self, jobid):
|
||||||
DupeGuruBase._job_completed(self, jobid, exc)
|
DupeGuruBase._job_completed(self, jobid)
|
||||||
if jobid == JobType.Load:
|
if jobid == JobType.Load:
|
||||||
if hasattr(self, 'path2iphoto'):
|
if hasattr(self, 'path2iphoto'):
|
||||||
del self.path2iphoto
|
del self.path2iphoto
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2009-05-24
|
# Created On: 2009-05-24
|
||||||
# Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
|
||||||
#
|
#
|
||||||
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
||||||
# which should be included with this package. The terms are also available at
|
# which should be included with this package. The terms are also available at
|
||||||
@@ -9,15 +9,13 @@
|
|||||||
import logging
|
import logging
|
||||||
import os.path as op
|
import os.path as op
|
||||||
|
|
||||||
from hscommon import io
|
from hscommon.path import Path, pathify
|
||||||
from hscommon.path import Path
|
|
||||||
from cocoa import proxy
|
from cocoa import proxy
|
||||||
|
|
||||||
from core.scanner import ScanType
|
from core.scanner import ScanType
|
||||||
from core import fs
|
|
||||||
from core.directories import Directories as DirectoriesBase, DirectoryState
|
from core.directories import Directories as DirectoriesBase, DirectoryState
|
||||||
from core_se.app import DupeGuru as DupeGuruBase
|
from core_se.app import DupeGuru as DupeGuruBase
|
||||||
from core_se.fs import File
|
from core_se import fs
|
||||||
from .app import PyDupeGuruBase
|
from .app import PyDupeGuruBase
|
||||||
|
|
||||||
def is_bundle(str_path):
|
def is_bundle(str_path):
|
||||||
@@ -28,15 +26,17 @@ def is_bundle(str_path):
|
|||||||
|
|
||||||
class Bundle(fs.Folder):
|
class Bundle(fs.Folder):
|
||||||
@classmethod
|
@classmethod
|
||||||
def can_handle(cls, path):
|
@pathify
|
||||||
return not io.islink(path) and io.isdir(path) and is_bundle(str(path))
|
def can_handle(cls, path: Path):
|
||||||
|
return not path.islink() and path.isdir() and is_bundle(str(path))
|
||||||
|
|
||||||
|
|
||||||
class Directories(DirectoriesBase):
|
class Directories(DirectoriesBase):
|
||||||
ROOT_PATH_TO_EXCLUDE = list(map(Path, ['/Library', '/Volumes', '/System', '/bin', '/sbin', '/opt', '/private', '/dev']))
|
ROOT_PATH_TO_EXCLUDE = list(map(Path, ['/Library', '/Volumes', '/System', '/bin', '/sbin', '/opt', '/private', '/dev']))
|
||||||
HOME_PATH_TO_EXCLUDE = [Path('Library')]
|
HOME_PATH_TO_EXCLUDE = [Path('Library')]
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
DirectoriesBase.__init__(self, fileclasses=[Bundle, File])
|
DirectoriesBase.__init__(self, fileclasses=[Bundle, fs.File])
|
||||||
|
self.folderclass = fs.Folder
|
||||||
|
|
||||||
def _default_state_for_path(self, path):
|
def _default_state_for_path(self, path):
|
||||||
result = DirectoriesBase._default_state_for_path(self, path)
|
result = DirectoriesBase._default_state_for_path(self, path)
|
||||||
@@ -68,9 +68,10 @@ class Directories(DirectoriesBase):
|
|||||||
|
|
||||||
|
|
||||||
class DupeGuru(DupeGuruBase):
|
class DupeGuru(DupeGuruBase):
|
||||||
def __init__(self, view, appdata):
|
def __init__(self, view):
|
||||||
appdata = op.join(appdata, 'dupeGuru')
|
# appdata = op.join(appdata, 'dupeGuru')
|
||||||
DupeGuruBase.__init__(self, view, appdata)
|
# print(repr(appdata))
|
||||||
|
DupeGuruBase.__init__(self, view)
|
||||||
self.directories = Directories()
|
self.directories = Directories()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Created On: 2012-05-30
|
# Created On: 2012-05-30
|
||||||
# Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2014 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,6 +11,7 @@ from cocoa.inter import PyGUIObject, GUIObjectView
|
|||||||
class DeletionOptionsView(GUIObjectView):
|
class DeletionOptionsView(GUIObjectView):
|
||||||
def updateMsg_(self, msg: str): pass
|
def updateMsg_(self, msg: str): pass
|
||||||
def show(self) -> bool: pass
|
def show(self) -> bool: pass
|
||||||
|
def setHardlinkOptionEnabled_(self, enabled: bool): pass
|
||||||
|
|
||||||
class PyDeletionOptions(PyGUIObject):
|
class PyDeletionOptions(PyGUIObject):
|
||||||
def setLinkDeleted_(self, link_deleted: bool):
|
def setLinkDeleted_(self, link_deleted: bool):
|
||||||
@@ -31,3 +32,6 @@ class PyDeletionOptions(PyGUIObject):
|
|||||||
def show(self):
|
def show(self):
|
||||||
return self.callback.show()
|
return self.callback.show()
|
||||||
|
|
||||||
|
@dontwrap
|
||||||
|
def set_hardlink_option_enabled(self, enabled):
|
||||||
|
self.callback.setHardlinkOptionEnabled_(enabled)
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ class PyDirectoryOutline(PyOutline):
|
|||||||
def removeSelectedDirectory(self):
|
def removeSelectedDirectory(self):
|
||||||
self.model.remove_selected()
|
self.model.remove_selected()
|
||||||
|
|
||||||
|
def selectAll(self):
|
||||||
|
self.model.select_all()
|
||||||
|
|
||||||
# python --> cocoa
|
# python --> cocoa
|
||||||
@dontwrap
|
@dontwrap
|
||||||
def refresh_states(self):
|
def refresh_states(self):
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2014 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 @@ def configure(conf):
|
|||||||
os.symlink('../build/Python', 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,3,0))
|
||||||
conf.check_python_headers()
|
conf.check_python_headers()
|
||||||
conf.env.FRAMEWORK_COCOA = 'Cocoa'
|
conf.env.FRAMEWORK_COCOA = 'Cocoa'
|
||||||
conf.env.ARCH_COCOA = ['x86_64']
|
conf.env.ARCH_COCOA = ['x86_64']
|
||||||
@@ -44,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', 'HSFairwareAboutBox', 'HSFairwareReminder', 'Utils',
|
cocoalib_uses = ['NSEventAdditions', 'Dialogs', 'HSAboutBox', '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',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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,8 +14,6 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
NSTextField *titleTextField;
|
NSTextField *titleTextField;
|
||||||
NSTextField *versionTextField;
|
NSTextField *versionTextField;
|
||||||
NSTextField *copyrightTextField;
|
NSTextField *copyrightTextField;
|
||||||
NSTextField *registeredTextField;
|
|
||||||
NSButton *registerButton;
|
|
||||||
|
|
||||||
PyBaseApp *app;
|
PyBaseApp *app;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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,13 +11,16 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
@interface HSErrorReportWindow : NSWindowController
|
@interface HSErrorReportWindow : NSWindowController
|
||||||
{
|
{
|
||||||
NSTextView *contentTextView;
|
NSTextView *contentTextView;
|
||||||
|
NSString *githubUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property (readwrite, retain) NSTextView *contentTextView;
|
@property (readwrite, retain) NSTextView *contentTextView;
|
||||||
|
@property (readwrite, retain) NSString *githubUrl;
|
||||||
|
|
||||||
+ (void)showErrorReportWithContent:(NSString *)content;
|
// True if the user wants to send the report
|
||||||
- (id)initWithContent:(NSString *)content;
|
+ (void)showErrorReportWithContent:(NSString *)content githubUrl:(NSString *)githubUrl;
|
||||||
|
- (id)initWithContent:(NSString *)content githubUrl:(NSString *)githubUrl;
|
||||||
|
|
||||||
- (void)send;
|
- (void)goToGithub;
|
||||||
- (void)dontSend;
|
- (void)close;
|
||||||
@end
|
@end
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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,37 +12,33 @@ http://www.hardcoded.net/licenses/bsd_license
|
|||||||
@implementation HSErrorReportWindow
|
@implementation HSErrorReportWindow
|
||||||
|
|
||||||
@synthesize contentTextView;
|
@synthesize contentTextView;
|
||||||
|
@synthesize githubUrl;
|
||||||
|
|
||||||
+ (void)showErrorReportWithContent:(NSString *)content
|
+ (void)showErrorReportWithContent:(NSString *)content githubUrl:(NSString *)githubUrl
|
||||||
{
|
{
|
||||||
HSErrorReportWindow *report = [[HSErrorReportWindow alloc] initWithContent:content];
|
HSErrorReportWindow *report = [[HSErrorReportWindow alloc] initWithContent:content githubUrl:githubUrl];
|
||||||
[NSApp runModalForWindow:[report window]];
|
[NSApp runModalForWindow:[report window]];
|
||||||
[report release];
|
[report release];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithContent:(NSString *)content
|
- (id)initWithContent:(NSString *)content githubUrl:(NSString *)aGithubUrl
|
||||||
{
|
{
|
||||||
self = [super initWithWindow:nil];
|
self = [super initWithWindow:nil];
|
||||||
[self setWindow:createHSErrorReportWindow_UI(self)];
|
[self setWindow:createHSErrorReportWindow_UI(self)];
|
||||||
[contentTextView alignLeft:nil];
|
[contentTextView alignLeft:nil];
|
||||||
[[[contentTextView textStorage] mutableString] setString:content];
|
[[[contentTextView textStorage] mutableString] setString:content];
|
||||||
|
self.githubUrl = aGithubUrl;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)send
|
- (void)goToGithub
|
||||||
{
|
{
|
||||||
NSString *text = [[contentTextView textStorage] string];
|
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:self.githubUrl]];
|
||||||
NSString *URL = [NSString stringWithFormat:@"mailto:support@hardcoded.net?SUBJECT=Error Report&BODY=%@",text];
|
}
|
||||||
NSString *encodedURL = [URL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
|
||||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:encodedURL]];
|
|
||||||
|
|
||||||
|
- (void)close
|
||||||
|
{
|
||||||
[[self window] orderOut:self];
|
[[self window] orderOut:self];
|
||||||
[NSApp stopModalWithCode:NSOKButton];
|
[NSApp stopModalWithCode:NSOKButton];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dontSend
|
|
||||||
{
|
|
||||||
[[self window] orderOut:self];
|
|
||||||
[NSApp stopModalWithCode:NSCancelButton];
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
|
||||||
|
|
||||||
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
|
|
||||||
http://www.hardcoded.net/licenses/bsd_license
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
#import "HSFairwareProtocol.h"
|
|
||||||
|
|
||||||
@interface HSFairware : NSObject <HSFairwareProtocol>
|
|
||||||
{
|
|
||||||
NSInteger appId;
|
|
||||||
NSString *name;
|
|
||||||
BOOL registered;
|
|
||||||
}
|
|
||||||
- (id)initWithAppId:(NSInteger)aAppId name:(NSString *)aName;
|
|
||||||
@end
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
|
||||||
|
|
||||||
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
|
|
||||||
http://www.hardcoded.net/licenses/bsd_license
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import "HSFairware.h"
|
|
||||||
#import <CommonCrypto/CommonDigest.h>
|
|
||||||
#import "HSFairwareReminder.h"
|
|
||||||
#import "Dialogs.h"
|
|
||||||
#import "Utils.h"
|
|
||||||
|
|
||||||
NSString* md5str(NSString *source)
|
|
||||||
{
|
|
||||||
const char *cSource = [source UTF8String];
|
|
||||||
unsigned char result[16];
|
|
||||||
CC_MD5(cSource, strlen(cSource), result);
|
|
||||||
return fmt(@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
|
||||||
result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7],
|
|
||||||
result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL validateCode(NSString *code, NSString *email, NSInteger appId)
|
|
||||||
{
|
|
||||||
if ([code length] != 32) {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
NSInteger i;
|
|
||||||
for (i=0; i<=100; i++) {
|
|
||||||
NSString *blob = fmt(@"%i%@%iaybabtu", appId, email, i);
|
|
||||||
if ([md5str(blob) isEqualTo:code]) {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString* normalizeString(NSString *str)
|
|
||||||
{
|
|
||||||
return [[str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] lowercaseString];
|
|
||||||
}
|
|
||||||
|
|
||||||
@implementation HSFairware
|
|
||||||
- (id)initWithAppId:(NSInteger)aAppId name:(NSString *)aName;
|
|
||||||
{
|
|
||||||
self = [super init];
|
|
||||||
appId = aAppId;
|
|
||||||
name = [aName retain];
|
|
||||||
registered = NO;
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dealloc
|
|
||||||
{
|
|
||||||
[name release];
|
|
||||||
[super dealloc];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Private */
|
|
||||||
- (void)setRegistrationCode:(NSString *)aCode email:(NSString *)aEmail
|
|
||||||
{
|
|
||||||
registered = validateCode(aCode, aEmail, appId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Public */
|
|
||||||
- (void)initialRegistrationSetup
|
|
||||||
{
|
|
||||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
|
||||||
NSString *code = [ud stringForKey:@"RegistrationCode"];
|
|
||||||
NSString *email = [ud stringForKey:@"RegistrationEmail"];
|
|
||||||
if (code && email) {
|
|
||||||
[self setRegistrationCode:code email:email];
|
|
||||||
}
|
|
||||||
if (!registered) {
|
|
||||||
BOOL fairwareMode = [ud boolForKey:@"FairwareMode"];
|
|
||||||
if (!fairwareMode) {
|
|
||||||
NSString *prompt = @"%@ is fairware, which means \"open source software developed "
|
|
||||||
"with expectation of fair contributions from users\". It's a very interesting "
|
|
||||||
"concept, but one year of fairware has shown that most people just want to know "
|
|
||||||
"how much it costs and not be bothered with theories about intellectual property."
|
|
||||||
"\n\n"
|
|
||||||
"So I won't bother you and will be very straightforward: You can try %@ for "
|
|
||||||
"free but you have to buy it in order to use it without limitations. In demo mode, "
|
|
||||||
"%@ will show this dialog on startup."
|
|
||||||
"\n\n"
|
|
||||||
"So it's as simple as this. If you're curious about fairware, however, I encourage "
|
|
||||||
"you to read more about it by clicking on the \"Fairware?\" button.";
|
|
||||||
[HSFairwareReminder showDemoNagWithApp:self prompt:fmt(prompt, name, name, name)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)appName
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)appLongName
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isRegistered
|
|
||||||
{
|
|
||||||
return registered;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)setRegisteredCode:(NSString *)code andEmail:(NSString *)email
|
|
||||||
{
|
|
||||||
code = normalizeString(code);
|
|
||||||
email = normalizeString(email);
|
|
||||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
|
||||||
if (([code isEqualTo:@"fairware"]) || ([email isEqualTo:@"fairware"])) {
|
|
||||||
[ud setBool:YES forKey:@"FairwareMode"];
|
|
||||||
[Dialogs showMessage:@"Fairware mode enabled."];
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
[self setRegistrationCode:code email:email];
|
|
||||||
if (registered) {
|
|
||||||
[ud setObject:code forKey:@"RegistrationCode"];
|
|
||||||
[ud setObject:email forKey:@"RegistrationEmail"];
|
|
||||||
[Dialogs showMessage:@"Your code is valid, thanks!"];
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
[Dialogs showMessage:@"Your code is invalid. Make sure that you wrote the good code. Also "
|
|
||||||
"make sure that the e-mail you gave is the same as the e-mail you used for your purchase."];
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)contribute
|
|
||||||
{
|
|
||||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://open.hardcoded.net/contribute/"]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)buy
|
|
||||||
{
|
|
||||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.hardcoded.net/purchase.htm"]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)aboutFairware
|
|
||||||
{
|
|
||||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://open.hardcoded.net/about/"]];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
|
||||||
|
|
||||||
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
|
|
||||||
http://www.hardcoded.net/licenses/bsd_license
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
#import "PyFairware.h"
|
|
||||||
|
|
||||||
@interface HSFairwareAboutBox : NSWindowController
|
|
||||||
{
|
|
||||||
NSTextField *titleTextField;
|
|
||||||
NSTextField *versionTextField;
|
|
||||||
NSTextField *copyrightTextField;
|
|
||||||
NSTextField *registeredTextField;
|
|
||||||
NSButton *registerButton;
|
|
||||||
|
|
||||||
PyFairware *app;
|
|
||||||
}
|
|
||||||
|
|
||||||
@property (readwrite, retain) NSTextField *titleTextField;
|
|
||||||
@property (readwrite, retain) NSTextField *versionTextField;
|
|
||||||
@property (readwrite, retain) NSTextField *copyrightTextField;
|
|
||||||
@property (readwrite, retain) NSTextField *registeredTextField;
|
|
||||||
@property (readwrite, retain) NSButton *registerButton;
|
|
||||||
|
|
||||||
- (id)initWithApp:(PyFairware *)app;
|
|
||||||
- (void)updateFields;
|
|
||||||
|
|
||||||
- (void)showRegisterDialog;
|
|
||||||
@end
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
|
||||||
|
|
||||||
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
|
|
||||||
http://www.hardcoded.net/licenses/bsd_license
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import "HSFairwareAboutBox.h"
|
|
||||||
#import "HSFairwareAboutBox_UI.h"
|
|
||||||
#import "HSFairwareReminder.h"
|
|
||||||
|
|
||||||
@implementation HSFairwareAboutBox
|
|
||||||
|
|
||||||
@synthesize titleTextField;
|
|
||||||
@synthesize versionTextField;
|
|
||||||
@synthesize copyrightTextField;
|
|
||||||
@synthesize registeredTextField;
|
|
||||||
@synthesize registerButton;
|
|
||||||
|
|
||||||
- (id)initWithApp:(PyFairware *)aApp
|
|
||||||
{
|
|
||||||
self = [super initWithWindow:nil];
|
|
||||||
[self setWindow:createHSFairwareAboutBox_UI(self)];
|
|
||||||
app = [aApp retain];
|
|
||||||
[self updateFields];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dealloc
|
|
||||||
{
|
|
||||||
[app release];
|
|
||||||
[super dealloc];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)updateFields
|
|
||||||
{
|
|
||||||
[titleTextField setStringValue:[app appLongName]];
|
|
||||||
NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
|
|
||||||
[versionTextField setStringValue:[NSString stringWithFormat:@"Version: %@",version]];
|
|
||||||
NSString *copyright = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSHumanReadableCopyright"];
|
|
||||||
[copyrightTextField setStringValue:copyright];
|
|
||||||
if ([app isRegistered]) {
|
|
||||||
[registeredTextField setHidden:NO];
|
|
||||||
[registerButton setHidden:YES];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
[registeredTextField setHidden:YES];
|
|
||||||
[registerButton setHidden:NO];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)showRegisterDialog
|
|
||||||
{
|
|
||||||
HSFairwareReminder *fr = [[HSFairwareReminder alloc] initWithApp:app];
|
|
||||||
[fr enterCode];
|
|
||||||
[fr release];
|
|
||||||
[self updateFields];
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
|
||||||
|
|
||||||
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
|
|
||||||
http://www.hardcoded.net/licenses/bsd_license
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
|
|
||||||
@protocol HSFairwareProtocol
|
|
||||||
- (void)initialRegistrationSetup;
|
|
||||||
- (NSString *)appName;
|
|
||||||
- (NSString *)appLongName;
|
|
||||||
- (BOOL)isRegistered;
|
|
||||||
- (BOOL)setRegisteredCode:(NSString *)code andEmail:(NSString *)email;
|
|
||||||
- (void)contribute;
|
|
||||||
- (void)buy;
|
|
||||||
- (void)aboutFairware;
|
|
||||||
@end
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
|
||||||
|
|
||||||
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
|
|
||||||
http://www.hardcoded.net/licenses/bsd_license
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
#import "HSFairwareProtocol.h"
|
|
||||||
|
|
||||||
@interface HSFairwareReminder : NSObject
|
|
||||||
{
|
|
||||||
NSWindow *codePanel;
|
|
||||||
NSTextField *codePromptTextField;
|
|
||||||
NSTextField *codeTextField;
|
|
||||||
NSTextField *emailTextField;
|
|
||||||
NSWindow *demoNagPanel;
|
|
||||||
NSTextField *demoPromptTextField;
|
|
||||||
|
|
||||||
id <HSFairwareProtocol> app;
|
|
||||||
}
|
|
||||||
|
|
||||||
@property (readwrite, retain) NSWindow *codePanel;
|
|
||||||
@property (readwrite, retain) NSTextField *codePromptTextField;
|
|
||||||
@property (readwrite, retain) NSTextField *codeTextField;
|
|
||||||
@property (readwrite, retain) NSTextField *emailTextField;
|
|
||||||
@property (readwrite, retain) NSWindow *demoNagPanel;
|
|
||||||
@property (readwrite, retain) NSTextField *demoPromptTextField;
|
|
||||||
|
|
||||||
//Show nag only if needed
|
|
||||||
+ (BOOL)showDemoNagWithApp:(id <HSFairwareProtocol>)app prompt:(NSString *)prompt;
|
|
||||||
- (id)initWithApp:(id <HSFairwareProtocol>)app;
|
|
||||||
|
|
||||||
- (void)contribute;
|
|
||||||
- (void)buy;
|
|
||||||
- (void)moreInfo;
|
|
||||||
- (void)cancelCode;
|
|
||||||
- (void)showEnterCode;
|
|
||||||
- (void)submitCode;
|
|
||||||
- (void)closeDialog;
|
|
||||||
|
|
||||||
- (BOOL)showNagPanel:(NSWindow *)panel; //YES: The code has been sucessfully submitted NO: The use wan't to try the demo.
|
|
||||||
- (BOOL)showDemoNagPanelWithPrompt:(NSString *)prompt;
|
|
||||||
- (NSInteger)enterCode; //returns the modal code.
|
|
||||||
@end
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
|
||||||
|
|
||||||
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
|
|
||||||
http://www.hardcoded.net/licenses/bsd_license
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import "HSFairwareReminder.h"
|
|
||||||
#import "HSDemoReminder_UI.h"
|
|
||||||
#import "HSEnterCode_UI.h"
|
|
||||||
#import "Dialogs.h"
|
|
||||||
#import "Utils.h"
|
|
||||||
|
|
||||||
@implementation HSFairwareReminder
|
|
||||||
|
|
||||||
@synthesize codePanel;
|
|
||||||
@synthesize codePromptTextField;
|
|
||||||
@synthesize codeTextField;
|
|
||||||
@synthesize emailTextField;
|
|
||||||
@synthesize demoNagPanel;
|
|
||||||
@synthesize demoPromptTextField;
|
|
||||||
|
|
||||||
+ (BOOL)showDemoNagWithApp:(id <HSFairwareProtocol>)app prompt:(NSString *)prompt
|
|
||||||
{
|
|
||||||
HSFairwareReminder *fr = [[HSFairwareReminder alloc] initWithApp:app];
|
|
||||||
BOOL r = [fr showDemoNagPanelWithPrompt:prompt];
|
|
||||||
[fr release];
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)initWithApp:(id <HSFairwareProtocol>)aApp
|
|
||||||
{
|
|
||||||
self = [super init];
|
|
||||||
app = aApp;
|
|
||||||
[self setDemoNagPanel:createHSDemoReminder_UI(self)];
|
|
||||||
[self setCodePanel:createHSEnterCode_UI(self)];
|
|
||||||
[codePanel update];
|
|
||||||
[codePromptTextField setStringValue:fmt([codePromptTextField stringValue],[app appName])];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)contribute
|
|
||||||
{
|
|
||||||
[app contribute];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)buy
|
|
||||||
{
|
|
||||||
[app buy];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)moreInfo
|
|
||||||
{
|
|
||||||
[app aboutFairware];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)cancelCode
|
|
||||||
{
|
|
||||||
[codePanel close];
|
|
||||||
[NSApp stopModalWithCode:NSCancelButton];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)showEnterCode
|
|
||||||
{
|
|
||||||
[demoNagPanel close];
|
|
||||||
[NSApp stopModalWithCode:NSOKButton];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)submitCode
|
|
||||||
{
|
|
||||||
NSString *code = [codeTextField stringValue];
|
|
||||||
NSString *email = [emailTextField stringValue];
|
|
||||||
if ([app setRegisteredCode:code andEmail:email]) {
|
|
||||||
[codePanel close];
|
|
||||||
[NSApp stopModalWithCode:NSOKButton];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)closeDialog
|
|
||||||
{
|
|
||||||
[demoNagPanel close];
|
|
||||||
[NSApp stopModalWithCode:NSCancelButton];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)showNagPanel:(NSWindow *)panel;
|
|
||||||
{
|
|
||||||
NSInteger r;
|
|
||||||
while (YES) {
|
|
||||||
r = [NSApp runModalForWindow:panel];
|
|
||||||
if (r == NSOKButton) {
|
|
||||||
r = [self enterCode];
|
|
||||||
if (r == NSOKButton) {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)showDemoNagPanelWithPrompt:(NSString *)prompt
|
|
||||||
{
|
|
||||||
[demoNagPanel setTitle:fmt([demoNagPanel title],[app appName])];
|
|
||||||
[demoPromptTextField setStringValue:prompt];
|
|
||||||
return [self showNagPanel:demoNagPanel];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSInteger)enterCode
|
|
||||||
{
|
|
||||||
return [NSApp runModalForWindow:codePanel];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013, Hardcoded Software Inc., http://www.hardcoded.net
|
Copyright 2014, 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,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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 2013 Hardcoded Software (http://www.hardcoded.net)
|
Copyright 2014 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
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
- (NSString *)bundleIdentifier;
|
- (NSString *)bundleIdentifier;
|
||||||
- (NSString *)appVersion;
|
- (NSString *)appVersion;
|
||||||
- (NSString *)osxVersion;
|
- (NSString *)osxVersion;
|
||||||
|
- (NSString *)bundleInfo:(NSString *)key;
|
||||||
- (void)postNotification:(NSString *)name userInfo:(NSDictionary *)userInfo;
|
- (void)postNotification:(NSString *)name userInfo:(NSDictionary *)userInfo;
|
||||||
- (id)prefValue:(NSString *)prefname;
|
- (id)prefValue:(NSString *)prefname;
|
||||||
- (void)setPrefValue:(NSString *)prefname value:(id)value;
|
- (void)setPrefValue:(NSString *)prefname value:(id)value;
|
||||||
@@ -27,6 +28,7 @@
|
|||||||
- (NSString *)url2path:(NSString *)url;
|
- (NSString *)url2path:(NSString *)url;
|
||||||
- (void)createPool;
|
- (void)createPool;
|
||||||
- (void)destroyPool;
|
- (void)destroyPool;
|
||||||
- (void)reportCrash:(NSString *)crashReport;
|
- (void)reportCrash:(NSString *)crashReport withGithubUrl:(NSString *)githubUrl;
|
||||||
- (void)log:(NSString *)s;
|
- (void)log:(NSString *)s;
|
||||||
|
- (NSDictionary *)readExifData:(NSString *)imagePath;
|
||||||
@end
|
@end
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
#import "CocoaProxy.h"
|
#import "CocoaProxy.h"
|
||||||
#import <CoreServices/CoreServices.h>
|
|
||||||
#import "HSErrorReportWindow.h"
|
#import "HSErrorReportWindow.h"
|
||||||
|
|
||||||
@implementation CocoaProxy
|
@implementation CocoaProxy
|
||||||
@@ -92,13 +91,14 @@
|
|||||||
return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
|
return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString *)bundleInfo:(NSString *)key
|
||||||
|
{
|
||||||
|
return [[NSBundle mainBundle] objectForInfoDictionaryKey:key];
|
||||||
|
}
|
||||||
|
|
||||||
- (NSString *)osxVersion
|
- (NSString *)osxVersion
|
||||||
{
|
{
|
||||||
SInt32 major, minor, bugfix;
|
return [[NSProcessInfo processInfo] operatingSystemVersionString];
|
||||||
Gestalt(gestaltSystemVersionMajor, &major);
|
|
||||||
Gestalt(gestaltSystemVersionMinor, &minor);
|
|
||||||
Gestalt(gestaltSystemVersionBugFix, &bugfix);
|
|
||||||
return [NSString stringWithFormat:@"%d.%d.%d", major, minor, bugfix];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)postNotification:(NSString *)name userInfo:(NSDictionary *)userInfo
|
- (void)postNotification:(NSString *)name userInfo:(NSDictionary *)userInfo
|
||||||
@@ -143,13 +143,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)reportCrash:(NSString *)crashReport
|
- (void)reportCrash:(NSString *)crashReport withGithubUrl:(NSString *)githubUrl
|
||||||
{
|
{
|
||||||
[HSErrorReportWindow showErrorReportWithContent:crashReport];
|
return [HSErrorReportWindow showErrorReportWithContent:crashReport githubUrl:githubUrl];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)log:(NSString *)s
|
- (void)log:(NSString *)s
|
||||||
{
|
{
|
||||||
NSLog(@"%@", s);
|
NSLog(@"%@", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSDictionary *)readExifData:(NSString *)imagePath
|
||||||
|
{
|
||||||
|
NSDictionary *result = nil;
|
||||||
|
NSURL* url = [NSURL fileURLWithPath:imagePath];
|
||||||
|
CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url, nil);
|
||||||
|
if (source != nil) {
|
||||||
|
CFDictionaryRef metadataRef = CGImageSourceCopyPropertiesAtIndex (source, 0, nil);
|
||||||
|
if (metadataRef != nil) {
|
||||||
|
result = [NSDictionary dictionaryWithDictionary:(NSDictionary *)metadataRef];
|
||||||
|
CFRelease(metadataRef);
|
||||||
|
}
|
||||||
|
CFRelease(source);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Created By: Virgil Dupras
|
# Created By: Virgil Dupras
|
||||||
# Created On: 2007-10-06
|
# Created On: 2007-10-06
|
||||||
# Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
# Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
|
||||||
|
|
||||||
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
||||||
# which should be included with this package. The terms are also available at
|
# which should be included with this package. The terms are also available at
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .CocoaProxy import CocoaProxy
|
from .CocoaProxy import CocoaProxy
|
||||||
@@ -81,30 +80,31 @@ def safe_format_exception(type, value, tb):
|
|||||||
result.extend(traceback.format_exception_only(type, value))
|
result.extend(traceback.format_exception_only(type, value))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def report_crash(type, value, tb):
|
def install_exception_hook(github_url):
|
||||||
app_identifier = proxy.bundleIdentifier()
|
def report_crash(type, value, tb):
|
||||||
app_version = proxy.appVersion()
|
app_identifier = proxy.bundleIdentifier()
|
||||||
osx_version = proxy.osxVersion()
|
app_version = proxy.appVersion()
|
||||||
s = "Application Identifier: {}\n".format(app_identifier)
|
osx_version = proxy.osxVersion()
|
||||||
s += "Application Version: {}\n".format(app_version)
|
s = "Application Identifier: {}\n".format(app_identifier)
|
||||||
s += "Mac OS X Version: {}\n\n".format(osx_version)
|
s += "Application Version: {}\n".format(app_version)
|
||||||
s += ''.join(safe_format_exception(type, value, tb))
|
s += "Mac OS X Version: {}\n\n".format(osx_version)
|
||||||
if app_identifier:
|
s += ''.join(safe_format_exception(type, value, tb))
|
||||||
s += '\nRelevant Console logs:\n\n'
|
if LOG_BUFFER:
|
||||||
p = subprocess.Popen(['grep', app_identifier, '/var/log/system.log'], stdout=subprocess.PIPE)
|
s += '\nRelevant Console logs:\n\n'
|
||||||
try:
|
s += '\n'.join(LOG_BUFFER)
|
||||||
s += str(p.communicate()[0], encoding='utf-8')
|
proxy.reportCrash_withGithubUrl_(s, github_url)
|
||||||
except IndexError:
|
|
||||||
# This can happen if something went wrong with the grep (permission errors?)
|
|
||||||
pass
|
|
||||||
proxy.reportCrash_(s)
|
|
||||||
|
|
||||||
def install_exception_hook():
|
|
||||||
sys.excepthook = report_crash
|
sys.excepthook = report_crash
|
||||||
|
|
||||||
|
# A global log buffer to use for error reports
|
||||||
|
LOG_BUFFER = []
|
||||||
|
|
||||||
class CocoaHandler(logging.Handler):
|
class CocoaHandler(logging.Handler):
|
||||||
def emit(self, record):
|
def emit(self, record):
|
||||||
proxy.log_(record.getMessage())
|
msg = record.getMessage()
|
||||||
|
proxy.log_(msg)
|
||||||
|
LOG_BUFFER.append(msg)
|
||||||
|
del LOG_BUFFER[:-20]
|
||||||
|
|
||||||
def install_cocoa_logger():
|
def install_cocoa_logger():
|
||||||
logging.getLogger().addHandler(CocoaHandler())
|
logging.getLogger().addHandler(CocoaHandler())
|
||||||
|
|||||||
@@ -294,45 +294,7 @@ class PyBaseApp(PyGUIObject):
|
|||||||
def set_default(self, key_name, value):
|
def set_default(self, key_name, value):
|
||||||
proxy.setPrefValue_value_(key_name, value)
|
proxy.setPrefValue_value_(key_name, value)
|
||||||
|
|
||||||
@dontwrap
|
|
||||||
def open_url(self, url):
|
|
||||||
proxy.openURL_(url)
|
|
||||||
|
|
||||||
@dontwrap
|
@dontwrap
|
||||||
def show_message(self, msg):
|
def show_message(self, msg):
|
||||||
self.callback.showMessage_(msg)
|
self.callback.showMessage_(msg)
|
||||||
|
|
||||||
class FairwareView(BaseAppView):
|
|
||||||
def setupAsRegistered(self): pass
|
|
||||||
def showDemoNagWithPrompt_(self, prompt: str): pass
|
|
||||||
|
|
||||||
class PyFairware(PyBaseApp):
|
|
||||||
FOLLOW_PROTOCOLS = ['HSFairwareProtocol']
|
|
||||||
|
|
||||||
def initialRegistrationSetup(self):
|
|
||||||
self.model.initial_registration_setup()
|
|
||||||
|
|
||||||
def isRegistered(self) -> bool:
|
|
||||||
return self.model.registered
|
|
||||||
|
|
||||||
def setRegisteredCode_andEmail_(self, code: str, email: str) -> bool:
|
|
||||||
return self.model.set_registration(code, email, False)
|
|
||||||
|
|
||||||
def contribute(self):
|
|
||||||
self.model.contribute()
|
|
||||||
|
|
||||||
def buy(self):
|
|
||||||
self.model.buy()
|
|
||||||
|
|
||||||
def aboutFairware(self):
|
|
||||||
self.model.about_fairware()
|
|
||||||
|
|
||||||
#--- Python --> Cocoa
|
|
||||||
@dontwrap
|
|
||||||
def setup_as_registered(self):
|
|
||||||
self.callback.setupAsRegistered()
|
|
||||||
|
|
||||||
@dontwrap
|
|
||||||
def show_demo_nag(self, prompt):
|
|
||||||
self.callback.showDemoNagWithPrompt_(prompt)
|
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user