mirror of
https://github.com/arsenetar/dupeguru.git
synced 2026-01-25 08:01: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
|
||||
*.waf*
|
||||
.lock-waf*
|
||||
.idea
|
||||
|
||||
build
|
||||
dist
|
||||
install
|
||||
installer_tmp-cache
|
||||
env
|
||||
/deps
|
||||
cocoa/autogen
|
||||
|
||||
/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.
|
||||
|
||||
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
|
||||
|
||||
This package contains the source for dupeGuru. Its documentation is
|
||||
[available online][documentation]. Here's how this source tree is organised:
|
||||
[dupeGuru][dupeguru] is a cross-platform (Linux, OS X, Windows) GUI tool to find duplicate files in
|
||||
a system. It's written mostly in Python 3 and has the peculiarity of using
|
||||
[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_*: Edition-specific-cross-toolkit code written in Python.
|
||||
* 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.
|
||||
* 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.
|
||||
* 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
|
||||
to be installed manually.
|
||||
|
||||
* All systems: [Python 3.2+][python] and [setuptools][setuptools]
|
||||
* Mac OS X: The last XCode to have the 10.6 SDK included.
|
||||
* Windows: Visual Studio 2008, [PyQt 4.7+][pyqt], [cx_Freeze][cxfreeze] and
|
||||
* All systems: [Python 3.3+][python] and [setuptools][setuptools]
|
||||
* Mac OS X: The last XCode to have the 10.7 SDK included. Python 3.4+.
|
||||
* Windows: Visual Studio 2010, [PyQt 5.0+][pyqt], [cx_Freeze][cxfreeze] and
|
||||
[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
|
||||
$ sudo pip install virtualenv
|
||||
## Setting up the virtual environment
|
||||
|
||||
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
|
||||
$ 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:
|
||||
|
||||
@@ -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).
|
||||
|
||||
## 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
|
||||
|
||||
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
|
||||
|
||||
[dupeguru]: http://www.hardcoded.net/dupeguru/
|
||||
[cross-toolkit]: http://www.hardcoded.net/articles/cross-toolkit-software
|
||||
[documentation]: http://www.hardcoded.net/dupeguru/help/en/
|
||||
[python]: http://www.python.org/
|
||||
[setuptools]: https://pypi.python.org/pypi/setuptools
|
||||
|
||||
33
bootstrap.sh
33
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; }
|
||||
|
||||
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
|
||||
echo "No virtualenv. Creating one"
|
||||
command -v curl >/dev/null 2>&1 || { echo >&2 "curl required. Install it and try again. Aborting"; exit 1; }
|
||||
python3 -m venv --system-site-packages env
|
||||
# We need a "system-site-packages" env to have PyQt, but we also need to ensure a local pip
|
||||
# install. To achieve our latter goal, we start with a normal venv, which we later upgrade to
|
||||
# a system-site-packages once pip is installed.
|
||||
python3 -m venv env
|
||||
source env/bin/activate
|
||||
curl https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py | python
|
||||
easy_install pip
|
||||
if python -m ensurepip; then
|
||||
echo "We're under Python 3.4+, no need to try to install pip!"
|
||||
else
|
||||
echo "There's already an env. Activating it"
|
||||
source env/bin/activate
|
||||
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
|
||||
|
||||
source env/bin/activate
|
||||
|
||||
echo "Installing pip requirements"
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
pip install -r requirements-osx.txt
|
||||
pip install $PIPARGS -r requirements-osx.txt
|
||||
else
|
||||
python3 -c "import PyQt4" >/dev/null 2>&1 || { echo >&2 "PyQt 4.8+ required. Install it and try again. Aborting"; exit 1; }
|
||||
pip install -r requirements.txt
|
||||
python3 -c "import PyQt5" >/dev/null 2>&1 || { echo >&2 "PyQt 5.1+ required. Install it and try again. Aborting"; exit 1; }
|
||||
pip install $PIPARGS -r requirements.txt
|
||||
fi
|
||||
|
||||
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 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,
|
||||
# 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.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,
|
||||
collect_stdlib_dependencies, copy)
|
||||
from hscommon import loc
|
||||
@@ -104,7 +104,7 @@ def build_cocoa(edition, dev):
|
||||
if not op.exists(pydep_folder):
|
||||
os.mkdir(pydep_folder)
|
||||
shutil.copy(op.join(cocoa_project_path, 'dg_cocoa.py'), 'build')
|
||||
appscript_pkgs = ['appscript', 'aem', 'mactypes']
|
||||
appscript_pkgs = ['appscript', 'aem', 'mactypes', 'osax']
|
||||
specific_packages = {
|
||||
'se': ['core_se'],
|
||||
'me': ['core_me'] + appscript_pkgs + ['hsaudiotag'],
|
||||
@@ -123,7 +123,6 @@ def build_cocoa(edition, dev):
|
||||
del sys.path[0]
|
||||
# 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_sysconfig_files_for_embed(pydep_folder)
|
||||
if not dev:
|
||||
# Important: Don't ever run delete_files_with_pattern('*.py') on dev builds because you'll
|
||||
# be deleting all py files in symlinked folders.
|
||||
@@ -135,6 +134,7 @@ def build_cocoa(edition, dev):
|
||||
print_and_do(cocoa_compile_command(edition))
|
||||
os.chdir('..')
|
||||
app.copy_executable('cocoa/build/dupeGuru')
|
||||
build_help(edition)
|
||||
print("Copying resources and frameworks")
|
||||
image_path = ed('cocoa/{}/dupeguru.icns')
|
||||
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")
|
||||
build_localizations('qt', edition)
|
||||
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'))
|
||||
build_help(edition)
|
||||
print("Creating the run.py file")
|
||||
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')
|
||||
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():
|
||||
loc.compile_all_po(op.join('qtlib', 'locale'))
|
||||
loc.merge_locale_dir(op.join('qtlib', 'locale'), 'locale')
|
||||
|
||||
def build_localizations(ui, edition):
|
||||
build_base_localizations()
|
||||
loc.compile_all_po('locale')
|
||||
if ui == 'cocoa':
|
||||
app = cocoa_app(edition)
|
||||
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'))
|
||||
if ui == 'qt' and not ISLINUX:
|
||||
print("Copying qt_*.qm files into the 'locale' folder")
|
||||
from PyQt4.QtCore import QLibraryInfo
|
||||
from PyQt5.QtCore import QLibraryInfo
|
||||
trfolder = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
|
||||
for lang in loc.get_langs('locale'):
|
||||
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.
|
||||
ui_packages = ['qt', op.join('cocoa', 'inter')]
|
||||
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")
|
||||
loc.generate_pot(['qtlib'], op.join('qtlib', 'locale', 'qtlib.pot'), ['tr'])
|
||||
if ISOSX:
|
||||
@@ -236,13 +230,11 @@ def build_updatepot():
|
||||
def build_mergepot():
|
||||
print("Updating .po files using .pot files")
|
||||
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('cocoalib', 'locale'))
|
||||
|
||||
def build_normpo():
|
||||
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('cocoalib', 'locale'))
|
||||
|
||||
@@ -264,7 +256,7 @@ def build_cocoa_bridging_interfaces(edition):
|
||||
add_to_pythonpath('cocoalib')
|
||||
from cocoa.inter import (PyGUIObject, GUIObjectView, PyColumns, ColumnsView, PyOutline,
|
||||
OutlineView, PySelectableList, SelectableListView, PyTable, TableView, PyBaseApp,
|
||||
PyFairware, PyTextField, ProgressWindowView, PyProgressWindow)
|
||||
PyTextField, ProgressWindowView, PyProgressWindow)
|
||||
from inter.deletion_options import PyDeletionOptions, DeletionOptionsView
|
||||
from inter.details_panel import PyDetailsPanel, DetailsPanelView
|
||||
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.app import PyDupeGuruBase, DupeGuruView
|
||||
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,
|
||||
PyIgnoreListDialog, PyDeletionOptions, PyResultTable, PyStatsLabel, PyDupeGuruBase,
|
||||
PyTextField, PyProgressWindow, appmod.PyDupeGuru]
|
||||
@@ -317,7 +309,6 @@ def build_pe_modules(ui):
|
||||
def build_normal(edition, ui, dev, conf):
|
||||
print("Building dupeGuru {0} with UI {1}".format(edition.upper(), ui))
|
||||
add_to_pythonpath('.')
|
||||
build_help(edition)
|
||||
print("Building dupeGuru")
|
||||
if edition == 'pe':
|
||||
build_pe_modules(ui)
|
||||
@@ -335,8 +326,9 @@ def main():
|
||||
if dev:
|
||||
print("Building in Dev mode")
|
||||
if options.clean:
|
||||
if op.exists('build'):
|
||||
shutil.rmtree('build')
|
||||
for path in ['build', op.join('cocoa', 'build'), op.join('cocoa', 'autogen')]:
|
||||
if op.exists(path):
|
||||
shutil.rmtree(path)
|
||||
if not op.exists('build'):
|
||||
os.mkdir('build')
|
||||
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,
|
||||
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 "DirectoryPanel.h"
|
||||
#import "IgnoreListDialog.h"
|
||||
#import "HSFairwareAboutBox.h"
|
||||
#import "HSAboutBox.h"
|
||||
#import "HSRecentFiles.h"
|
||||
#import "HSProgressWindow.h"
|
||||
|
||||
@@ -30,7 +30,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
||||
IgnoreListDialog *_ignoreListDialog;
|
||||
HSProgressWindow *_progressWindow;
|
||||
NSWindowController *_preferencesPanel;
|
||||
HSFairwareAboutBox *_aboutBox;
|
||||
HSAboutBox *_aboutBox;
|
||||
HSRecentFiles *_recentResults;
|
||||
}
|
||||
|
||||
@@ -73,6 +73,4 @@ http://www.hardcoded.net/licenses/bsd_license
|
||||
|
||||
/* model --> view */
|
||||
- (void)showMessage:(NSString *)msg;
|
||||
- (void)setupAsRegistered;
|
||||
- (void)showDemoNagWithPrompt:(NSString *)prompt;
|
||||
@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,
|
||||
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 "ProgressController.h"
|
||||
#import "HSFairwareReminder.h"
|
||||
#import "HSPyUtil.h"
|
||||
#import "Consts.h"
|
||||
#import "Dialogs.h"
|
||||
@@ -140,7 +139,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
||||
[op setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]];
|
||||
[op setTitle:NSLocalizedString(@"Select a results file to load", @"")];
|
||||
if ([op runModal] == NSOKButton) {
|
||||
NSString *filename = [[op filenames] objectAtIndex:0];
|
||||
NSString *filename = [[[op URLs] objectAtIndex:0] path];
|
||||
[model loadResultsFrom:filename];
|
||||
[[self recentResults] addFile:filename];
|
||||
}
|
||||
@@ -162,7 +161,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
||||
- (void)showAboutBox
|
||||
{
|
||||
if (_aboutBox == nil) {
|
||||
_aboutBox = [[HSFairwareAboutBox alloc] initWithApp:model];
|
||||
_aboutBox = [[HSAboutBox alloc] initWithApp:model];
|
||||
}
|
||||
[[_aboutBox window] makeKeyAndOrderFront:nil];
|
||||
}
|
||||
@@ -199,7 +198,6 @@ http://www.hardcoded.net/licenses/bsd_license
|
||||
/* Delegate */
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
[model initialRegistrationSetup];
|
||||
[model loadSession];
|
||||
}
|
||||
|
||||
@@ -261,16 +259,6 @@ http://www.hardcoded.net/licenses/bsd_license
|
||||
[[self resultWindow] showProblemDialog];
|
||||
}
|
||||
|
||||
- (void)setupAsRegistered
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
- (void)showDemoNagWithPrompt:(NSString *)prompt
|
||||
{
|
||||
[HSFairwareReminder showDemoNagWithApp:[self model] prompt:prompt];
|
||||
}
|
||||
|
||||
- (NSString *)selectDestFolderWithPrompt:(NSString *)prompt
|
||||
{
|
||||
NSOpenPanel *op = [NSOpenPanel openPanel];
|
||||
@@ -280,7 +268,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
||||
[op setAllowsMultipleSelection:NO];
|
||||
[op setTitle:prompt];
|
||||
if ([op runModal] == NSOKButton) {
|
||||
return [[op filenames] objectAtIndex:0];
|
||||
return [[[op URLs] objectAtIndex:0] path];
|
||||
}
|
||||
else {
|
||||
return nil;
|
||||
@@ -294,7 +282,7 @@ http://www.hardcoded.net/licenses/bsd_license
|
||||
[sp setAllowedFileTypes:[NSArray arrayWithObject:extension]];
|
||||
[sp setTitle:prompt];
|
||||
if ([sp runModal] == NSOKButton) {
|
||||
return [sp filename];
|
||||
return [[sp URL] path];
|
||||
}
|
||||
else {
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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];
|
||||
return r == NSOKButton;
|
||||
}
|
||||
|
||||
- (void)setHardlinkOptionEnabled:(BOOL)enabled
|
||||
{
|
||||
[linkTypeRadio setEnabled:enabled];
|
||||
}
|
||||
@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,
|
||||
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,
|
||||
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,
|
||||
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 {}
|
||||
- (id)initWithPyRef:(PyObject *)aPyRef outlineView:(HSOutlineView *)aOutlineView;
|
||||
- (PyDirectoryOutline *)model;
|
||||
|
||||
- (void)selectAll;
|
||||
@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,
|
||||
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;
|
||||
}
|
||||
|
||||
/* Public */
|
||||
- (void)selectAll
|
||||
{
|
||||
[[self model] selectAll];
|
||||
}
|
||||
|
||||
/* Delegate */
|
||||
- (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,
|
||||
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)refreshRemoveButtonText;
|
||||
- (void)markAll;
|
||||
|
||||
@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,
|
||||
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 setDelegate:self];
|
||||
if ([op runModal] == NSOKButton) {
|
||||
for (NSString *directory in [op filenames]) {
|
||||
[self addDirectory:directory];
|
||||
for (NSURL *directoryURL in [op URLs]) {
|
||||
[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 */
|
||||
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)path
|
||||
{
|
||||
@@ -171,6 +179,14 @@ http://www.hardcoded.net/licenses/bsd_license
|
||||
[self addDirectory:path];
|
||||
}
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
||||
{
|
||||
if ([item action] == @selector(markAll)) {
|
||||
[item setTitle:NSLocalizedString(@"Select All", @"")];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
/* Notifications */
|
||||
|
||||
- (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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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 setTitle:NSLocalizedString(@"Select a file to save your results to", @"")];
|
||||
if ([sp runModal] == NSOKButton) {
|
||||
[model saveResultsAs:[sp filename]];
|
||||
[[app recentResults] addFile:[sp filename]];
|
||||
[model saveResultsAs:[[sp URL] path]];
|
||||
[[app recentResults] addFile:[[sp URL] path]];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,6 +344,9 @@ http://www.hardcoded.net/licenses/bsd_license
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
||||
{
|
||||
if ([item action] == @selector(markAll)) {
|
||||
[item setTitle:NSLocalizedString(@"Mark All", @"")];
|
||||
}
|
||||
return ![[ProgressController mainProgressController] isShown];
|
||||
}
|
||||
@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,
|
||||
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,
|
||||
which should be included with this package. The terms are also available at
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
"%@ Results" = "%@ Results";
|
||||
"A previous action is still hanging in there. You can't start a new one yet. Wait a few seconds, then try again." = "A previous action is still hanging in there. You can't start a new one yet. Wait a few seconds, then try again.";
|
||||
"About dupeGuru" = "About dupeGuru";
|
||||
"Action" = "Action";
|
||||
"Actions" = "Actions";
|
||||
@@ -127,6 +126,7 @@
|
||||
"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 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\".";
|
||||
"Selected" = "Selected";
|
||||
"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,
|
||||
which should be included with this package. The terms are also available at
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
import logging
|
||||
|
||||
from objp.util import pyref, dontwrap
|
||||
from cocoa import install_exception_hook, install_cocoa_logger, patch_threaded_job_performer, proxy
|
||||
from cocoa.inter import PyFairware, FairwareView
|
||||
from cocoa import install_exception_hook, install_cocoa_logger, patch_threaded_job_performer
|
||||
from cocoa.inter import PyBaseApp, BaseAppView
|
||||
|
||||
class DupeGuruView(FairwareView):
|
||||
class DupeGuruView(BaseAppView):
|
||||
def askYesNoWithPrompt_(self, prompt: str) -> bool: pass
|
||||
def showProblemDialog(self): pass
|
||||
def selectDestFolderWithPrompt_(self, prompt: str) -> str: pass
|
||||
def selectDestFileWithPrompt_extension_(self, prompt: str, extension: str) -> str: pass
|
||||
|
||||
class PyDupeGuruBase(PyFairware):
|
||||
class PyDupeGuruBase(PyBaseApp):
|
||||
@dontwrap
|
||||
def _init(self, modelclass):
|
||||
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()
|
||||
patch_threaded_job_performer()
|
||||
appdata = proxy.getAppdataPath()
|
||||
self.model = modelclass(self, appdata)
|
||||
self.model = modelclass(self)
|
||||
|
||||
#---Sub-proxies
|
||||
def detailsPanel(self) -> pyref:
|
||||
@@ -144,14 +143,6 @@ class PyDupeGuruBase(PyFairware):
|
||||
self.model.options['copymove_dest_type'] = copymove_dest_type
|
||||
|
||||
#--- model --> view
|
||||
@dontwrap
|
||||
def open_path(self, path):
|
||||
proxy.openPath_(str(path))
|
||||
|
||||
@dontwrap
|
||||
def reveal_path(self, path):
|
||||
proxy.revealPath_(str(path))
|
||||
|
||||
@dontwrap
|
||||
def ask_yes_no(self, prompt):
|
||||
return self.callback.askYesNoWithPrompt_(prompt)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Created By: Virgil Dupras
|
||||
# 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,
|
||||
# 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 core import directories
|
||||
from core.app import JobType
|
||||
from core.app import JobType, JOBID2TITLE
|
||||
from core.scanner import ScanType
|
||||
from core_me.app import DupeGuru as DupeGuruBase
|
||||
from core_me import fs
|
||||
from .app import JOBID2TITLE, PyDupeGuruBase
|
||||
from .app import PyDupeGuruBase
|
||||
|
||||
tr = trget('ui')
|
||||
|
||||
@@ -143,16 +143,13 @@ class Directories(directories.Directories):
|
||||
|
||||
|
||||
class DupeGuruME(DupeGuruBase):
|
||||
def __init__(self, view, appdata):
|
||||
appdata = op.join(appdata, 'dupeGuru Music Edition')
|
||||
DupeGuruBase.__init__(self, view, appdata)
|
||||
def __init__(self, view):
|
||||
DupeGuruBase.__init__(self, view)
|
||||
# Use fileclasses set in DupeGuruBase.__init__()
|
||||
self.directories = Directories(fileclasses=self.directories.fileclasses)
|
||||
self.dead_tracks = []
|
||||
|
||||
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):
|
||||
j.add_progress()
|
||||
return self._do_delete_dupe(dupe, *args)
|
||||
@@ -174,7 +171,7 @@ class DupeGuruME(DupeGuruBase):
|
||||
DupeGuruBase._do_delete_dupe(self, dupe, *args)
|
||||
|
||||
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'):
|
||||
songs = get_itunes_songs(self.directories.itunes_libpath)
|
||||
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
|
||||
return DupeGuruBase._create_file(self, path)
|
||||
|
||||
def _job_completed(self, jobid, exc):
|
||||
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
|
||||
def _job_completed(self, jobid):
|
||||
# XXX Just before release, I'm realizing that this piece of code below is why I was passing
|
||||
# job exception as an argument to _job_completed(). I have to comment it for now. It's not
|
||||
# the end of the world, but I should find an elegant solution to this at some point.
|
||||
# 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:
|
||||
dead_tracks_count = len(self.dead_tracks)
|
||||
if dead_tracks_count > 0:
|
||||
@@ -202,7 +202,7 @@ class DupeGuruME(DupeGuruBase):
|
||||
if hasattr(self, 'itunes_songs'):
|
||||
# If we load another file, we want a refresh song list
|
||||
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):
|
||||
if isinstance(dupe, ITunesSong):
|
||||
@@ -230,7 +230,7 @@ class DupeGuruME(DupeGuruBase):
|
||||
except CommandError as 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 do(j):
|
||||
@@ -248,7 +248,7 @@ class DupeGuruME(DupeGuruBase):
|
||||
self.dead_tracks.append(track)
|
||||
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):
|
||||
def __init__(self):
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
# Created By: Virgil Dupras
|
||||
# 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,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/bsd_license
|
||||
|
||||
import os.path as op
|
||||
import plistlib
|
||||
import logging
|
||||
import re
|
||||
import io
|
||||
|
||||
from appscript import app, its, k, CommandError, ApplicationNotFoundError
|
||||
|
||||
from hscommon import io
|
||||
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 cocoa import proxy
|
||||
|
||||
@@ -25,6 +23,7 @@ from core.app import JobType
|
||||
from core_pe import _block_osx
|
||||
from core_pe.photo import Photo as PhotoBase
|
||||
from core_pe.app import DupeGuru as DupeGuruBase
|
||||
from core_pe.iphoto_plist import IPhotoPlistParser
|
||||
from .app import PyDupeGuruBase
|
||||
|
||||
tr = trget('ui')
|
||||
@@ -48,6 +47,16 @@ class Photo(PhotoBase):
|
||||
raise IOError('The picture %s could not be read' % str(self.path))
|
||||
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):
|
||||
def __init__(self, path, db_id):
|
||||
@@ -67,11 +76,12 @@ class AperturePhoto(Photo):
|
||||
def display_folder_path(self):
|
||||
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.
|
||||
if not io.exists(plistpath):
|
||||
if not plistpath.exists():
|
||||
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
|
||||
s = remove_invalid_xml(s, replace_with='')
|
||||
# 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)
|
||||
if 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 = []
|
||||
for key, photo_data in plist['Master Image List'].items():
|
||||
if photo_data['MediaType'] != 'Image':
|
||||
@@ -114,12 +129,12 @@ class Directories(directories.Directories):
|
||||
directories.Directories.__init__(self, fileclasses=[Photo])
|
||||
try:
|
||||
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:
|
||||
self.iphoto_libpath = None
|
||||
try:
|
||||
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:
|
||||
self.aperture_libpath = None
|
||||
|
||||
@@ -171,9 +186,8 @@ class Directories(directories.Directories):
|
||||
|
||||
|
||||
class DupeGuruPE(DupeGuruBase):
|
||||
def __init__(self, view, appdata):
|
||||
appdata = op.join(appdata, 'dupeGuru Picture Edition')
|
||||
DupeGuruBase.__init__(self, view, appdata)
|
||||
def __init__(self, view):
|
||||
DupeGuruBase.__init__(self, view)
|
||||
self.directories = Directories()
|
||||
|
||||
def _do_delete(self, j, *args):
|
||||
@@ -247,20 +261,20 @@ class DupeGuruPE(DupeGuruBase):
|
||||
DupeGuruBase._do_delete_dupe(self, dupe, *args)
|
||||
|
||||
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'):
|
||||
photos = get_iphoto_pictures(self.directories.iphoto_libpath)
|
||||
self.path2iphoto = {p.path: p for p in photos}
|
||||
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'):
|
||||
photos = get_aperture_pictures(self.directories.aperture_libpath)
|
||||
self.path2aperture = {p.path: p for p in photos}
|
||||
return self.path2aperture.get(path)
|
||||
return DupeGuruBase._create_file(self, path)
|
||||
|
||||
def _job_completed(self, jobid, exc):
|
||||
DupeGuruBase._job_completed(self, jobid, exc)
|
||||
def _job_completed(self, jobid):
|
||||
DupeGuruBase._job_completed(self, jobid)
|
||||
if jobid == JobType.Load:
|
||||
if hasattr(self, 'path2iphoto'):
|
||||
del self.path2iphoto
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Created By: Virgil Dupras
|
||||
# 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,
|
||||
# which should be included with this package. The terms are also available at
|
||||
@@ -9,15 +9,13 @@
|
||||
import logging
|
||||
import os.path as op
|
||||
|
||||
from hscommon import io
|
||||
from hscommon.path import Path
|
||||
from hscommon.path import Path, pathify
|
||||
from cocoa import proxy
|
||||
|
||||
from core.scanner import ScanType
|
||||
from core import fs
|
||||
from core.directories import Directories as DirectoriesBase, DirectoryState
|
||||
from core_se.app import DupeGuru as DupeGuruBase
|
||||
from core_se.fs import File
|
||||
from core_se import fs
|
||||
from .app import PyDupeGuruBase
|
||||
|
||||
def is_bundle(str_path):
|
||||
@@ -28,15 +26,17 @@ def is_bundle(str_path):
|
||||
|
||||
class Bundle(fs.Folder):
|
||||
@classmethod
|
||||
def can_handle(cls, path):
|
||||
return not io.islink(path) and io.isdir(path) and is_bundle(str(path))
|
||||
@pathify
|
||||
def can_handle(cls, path: Path):
|
||||
return not path.islink() and path.isdir() and is_bundle(str(path))
|
||||
|
||||
|
||||
class Directories(DirectoriesBase):
|
||||
ROOT_PATH_TO_EXCLUDE = list(map(Path, ['/Library', '/Volumes', '/System', '/bin', '/sbin', '/opt', '/private', '/dev']))
|
||||
HOME_PATH_TO_EXCLUDE = [Path('Library')]
|
||||
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):
|
||||
result = DirectoriesBase._default_state_for_path(self, path)
|
||||
@@ -68,9 +68,10 @@ class Directories(DirectoriesBase):
|
||||
|
||||
|
||||
class DupeGuru(DupeGuruBase):
|
||||
def __init__(self, view, appdata):
|
||||
appdata = op.join(appdata, 'dupeGuru')
|
||||
DupeGuruBase.__init__(self, view, appdata)
|
||||
def __init__(self, view):
|
||||
# appdata = op.join(appdata, 'dupeGuru')
|
||||
# print(repr(appdata))
|
||||
DupeGuruBase.__init__(self, view)
|
||||
self.directories = Directories()
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# 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,
|
||||
# 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):
|
||||
def updateMsg_(self, msg: str): pass
|
||||
def show(self) -> bool: pass
|
||||
def setHardlinkOptionEnabled_(self, enabled: bool): pass
|
||||
|
||||
class PyDeletionOptions(PyGUIObject):
|
||||
def setLinkDeleted_(self, link_deleted: bool):
|
||||
@@ -31,3 +32,6 @@ class PyDeletionOptions(PyGUIObject):
|
||||
def show(self):
|
||||
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):
|
||||
self.model.remove_selected()
|
||||
|
||||
def selectAll(self):
|
||||
self.model.select_all()
|
||||
|
||||
# python --> cocoa
|
||||
@dontwrap
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
# 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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
# 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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
# 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)
|
||||
# The rest is standard WAF code that you can find the the python and macapp demos.
|
||||
conf.load('compiler_c python')
|
||||
conf.check_python_version((3,2,0))
|
||||
conf.check_python_version((3,3,0))
|
||||
conf.check_python_headers()
|
||||
conf.env.FRAMEWORK_COCOA = 'Cocoa'
|
||||
conf.env.ARCH_COCOA = ['x86_64']
|
||||
@@ -44,7 +44,7 @@ def build(ctx):
|
||||
cocoalib_node = ctx.srcnode.find_dir('..').find_dir('cocoalib')
|
||||
cocoalib_folders = ['controllers', 'views']
|
||||
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',
|
||||
'NSImageAdditions', 'NSNotificationAdditions',
|
||||
'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,
|
||||
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,
|
||||
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,
|
||||
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 *versionTextField;
|
||||
NSTextField *copyrightTextField;
|
||||
NSTextField *registeredTextField;
|
||||
NSButton *registerButton;
|
||||
|
||||
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,
|
||||
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,
|
||||
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
|
||||
{
|
||||
NSTextView *contentTextView;
|
||||
NSString *githubUrl;
|
||||
}
|
||||
|
||||
@property (readwrite, retain) NSTextView *contentTextView;
|
||||
@property (readwrite, retain) NSString *githubUrl;
|
||||
|
||||
+ (void)showErrorReportWithContent:(NSString *)content;
|
||||
- (id)initWithContent:(NSString *)content;
|
||||
// True if the user wants to send the report
|
||||
+ (void)showErrorReportWithContent:(NSString *)content githubUrl:(NSString *)githubUrl;
|
||||
- (id)initWithContent:(NSString *)content githubUrl:(NSString *)githubUrl;
|
||||
|
||||
- (void)send;
|
||||
- (void)dontSend;
|
||||
- (void)goToGithub;
|
||||
- (void)close;
|
||||
@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,
|
||||
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
|
||||
|
||||
@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]];
|
||||
[report release];
|
||||
}
|
||||
|
||||
- (id)initWithContent:(NSString *)content
|
||||
- (id)initWithContent:(NSString *)content githubUrl:(NSString *)aGithubUrl
|
||||
{
|
||||
self = [super initWithWindow:nil];
|
||||
[self setWindow:createHSErrorReportWindow_UI(self)];
|
||||
[contentTextView alignLeft:nil];
|
||||
[[[contentTextView textStorage] mutableString] setString:content];
|
||||
self.githubUrl = aGithubUrl;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)send
|
||||
- (void)goToGithub
|
||||
{
|
||||
NSString *text = [[contentTextView textStorage] string];
|
||||
NSString *URL = [NSString stringWithFormat:@"mailto:support@hardcoded.net?SUBJECT=Error Report&BODY=%@",text];
|
||||
NSString *encodedURL = [URL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:encodedURL]];
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:self.githubUrl]];
|
||||
}
|
||||
|
||||
- (void)close
|
||||
{
|
||||
[[self window] orderOut:self];
|
||||
[NSApp stopModalWithCode:NSOKButton];
|
||||
}
|
||||
|
||||
- (void)dontSend
|
||||
{
|
||||
[[self window] orderOut:self];
|
||||
[NSApp stopModalWithCode:NSCancelButton];
|
||||
}
|
||||
@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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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.
|
||||
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
which should be included with this package. The terms are also available at
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
- (NSString *)bundleIdentifier;
|
||||
- (NSString *)appVersion;
|
||||
- (NSString *)osxVersion;
|
||||
- (NSString *)bundleInfo:(NSString *)key;
|
||||
- (void)postNotification:(NSString *)name userInfo:(NSDictionary *)userInfo;
|
||||
- (id)prefValue:(NSString *)prefname;
|
||||
- (void)setPrefValue:(NSString *)prefname value:(id)value;
|
||||
@@ -27,6 +28,7 @@
|
||||
- (NSString *)url2path:(NSString *)url;
|
||||
- (void)createPool;
|
||||
- (void)destroyPool;
|
||||
- (void)reportCrash:(NSString *)crashReport;
|
||||
- (void)reportCrash:(NSString *)crashReport withGithubUrl:(NSString *)githubUrl;
|
||||
- (void)log:(NSString *)s;
|
||||
- (NSDictionary *)readExifData:(NSString *)imagePath;
|
||||
@end
|
||||
@@ -1,5 +1,4 @@
|
||||
#import "CocoaProxy.h"
|
||||
#import <CoreServices/CoreServices.h>
|
||||
#import "HSErrorReportWindow.h"
|
||||
|
||||
@implementation CocoaProxy
|
||||
@@ -92,13 +91,14 @@
|
||||
return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
|
||||
}
|
||||
|
||||
- (NSString *)bundleInfo:(NSString *)key
|
||||
{
|
||||
return [[NSBundle mainBundle] objectForInfoDictionaryKey:key];
|
||||
}
|
||||
|
||||
- (NSString *)osxVersion
|
||||
{
|
||||
SInt32 major, minor, bugfix;
|
||||
Gestalt(gestaltSystemVersionMajor, &major);
|
||||
Gestalt(gestaltSystemVersionMinor, &minor);
|
||||
Gestalt(gestaltSystemVersionBugFix, &bugfix);
|
||||
return [NSString stringWithFormat:@"%d.%d.%d", major, minor, bugfix];
|
||||
return [[NSProcessInfo processInfo] operatingSystemVersionString];
|
||||
}
|
||||
|
||||
- (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
|
||||
{
|
||||
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
|
||||
@@ -1,6 +1,6 @@
|
||||
# Created By: Virgil Dupras
|
||||
# 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,
|
||||
# which should be included with this package. The terms are also available at
|
||||
@@ -9,7 +9,6 @@
|
||||
import logging
|
||||
import time
|
||||
import traceback
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from .CocoaProxy import CocoaProxy
|
||||
@@ -81,6 +80,7 @@ def safe_format_exception(type, value, tb):
|
||||
result.extend(traceback.format_exception_only(type, value))
|
||||
return result
|
||||
|
||||
def install_exception_hook(github_url):
|
||||
def report_crash(type, value, tb):
|
||||
app_identifier = proxy.bundleIdentifier()
|
||||
app_version = proxy.appVersion()
|
||||
@@ -89,22 +89,22 @@ def report_crash(type, value, tb):
|
||||
s += "Application Version: {}\n".format(app_version)
|
||||
s += "Mac OS X Version: {}\n\n".format(osx_version)
|
||||
s += ''.join(safe_format_exception(type, value, tb))
|
||||
if app_identifier:
|
||||
if LOG_BUFFER:
|
||||
s += '\nRelevant Console logs:\n\n'
|
||||
p = subprocess.Popen(['grep', app_identifier, '/var/log/system.log'], stdout=subprocess.PIPE)
|
||||
try:
|
||||
s += str(p.communicate()[0], encoding='utf-8')
|
||||
except IndexError:
|
||||
# This can happen if something went wrong with the grep (permission errors?)
|
||||
pass
|
||||
proxy.reportCrash_(s)
|
||||
s += '\n'.join(LOG_BUFFER)
|
||||
proxy.reportCrash_withGithubUrl_(s, github_url)
|
||||
|
||||
def install_exception_hook():
|
||||
sys.excepthook = report_crash
|
||||
|
||||
# A global log buffer to use for error reports
|
||||
LOG_BUFFER = []
|
||||
|
||||
class CocoaHandler(logging.Handler):
|
||||
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():
|
||||
logging.getLogger().addHandler(CocoaHandler())
|
||||
|
||||
@@ -294,45 +294,7 @@ class PyBaseApp(PyGUIObject):
|
||||
def set_default(self, key_name, value):
|
||||
proxy.setPrefValue_value_(key_name, value)
|
||||
|
||||
@dontwrap
|
||||
def open_url(self, url):
|
||||
proxy.openURL_(url)
|
||||
|
||||
@dontwrap
|
||||
def show_message(self, 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