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

Compare commits

..

124 Commits

Author SHA1 Message Date
Virgil Dupras
79800bc6ed Added --arch-pkg option to package.py
Otherwise, AUR packages don't work with Arch lookalikes like Manjaro.
2014-10-17 15:58:45 -04:00
Virgil Dupras
6e7b95b2cf se v3.9.1 2014-10-17 15:51:48 -04:00
Virgil Dupras
bf09c4ce8a Nicely wrap PermissionDenied errors on save
In fact, all `OSError`.

ref #266
2014-10-17 15:46:43 -04:00
Virgil Dupras
b4a73771c2 Fix iCCP: known incorrect sRGB profile warnings in stderr
I processed all images through `convert -strip`.

It's still possible, however, to get these error if PE tries to open an
image with an invalid profile.
2014-10-17 15:45:07 -04:00
Virgil Dupras
2166a0996c Added tox configuration
... and fixed pep8 warnings. There's a lot of them that are still
ignored, but that's because it's too much of a step to take at once.
2014-10-13 15:08:59 -04:00
Virgil Dupras
24643a9b5d Updated copyright year to 2014 in Cocoa about boxes
Better late than never.
2014-10-12 13:19:55 -04:00
Virgil Dupras
045051ce06 Fixed formatting in changelog_pe 2014-10-12 10:52:41 -04:00
Virgil Dupras
7c3728ca47 Converted hscommon.jobprogress.qt to Qt5 2014-10-12 10:52:21 -04:00
Virgil Dupras
91be1c7336 pe v2.10.1 2014-10-12 10:47:18 -04:00
Virgil Dupras
162378bb0a Updated hscommon 2014-10-12 10:39:21 -04:00
Virgil Dupras
4e3cad5702 Fixed minor typo 2014-10-12 10:15:07 -04:00
Virgil Dupras
321f8ab406 Catch MemoryError better in PE's block matching algo
fixes #264 (for good this time, hopefully)
2014-10-05 22:22:59 -04:00
Virgil Dupras
5b3d5f5d1c Tweaked the main dev help page to have actual reflinks 2014-10-05 20:12:38 -04:00
Virgil Dupras
372a682610 Catch MemoryError in PE's block matching algo
fixes #264 (hopefully)
2014-10-05 17:13:36 -04:00
Virgil Dupras
44266273bf Included hscommon.jobprogress in the devdocs 2014-10-05 17:12:10 -04:00
Virgil Dupras
ac32305532 Integrated the jobprogress library into hscommon
I have a fix to make in it and it's really silly to pretend that this
lib is of any use to anybody outside HS apps. Bringing it back here will
make things more simple.
2014-10-05 16:31:16 -04:00
Virgil Dupras
87c2fa2573 Updated README which was a bit outdated 2014-10-04 17:01:22 -04:00
Virgil Dupras
db63b63cfd Fix crash in PE when reading some EXIF tags
The crash was caused by ObjP, which crashed when converting `NSDictionary` containing unsupported types.

Updating ObjP to v1.3.1 does the trick.

fixes #263
fixes #265
2014-10-04 16:35:26 -04:00
Virgil Dupras
6725b2bf0f Updated German localisation, by Frank Weber 2014-09-28 13:40:09 -04:00
Virgil Dupras
990e73c383 Catch Spinx SystemExit when building help
In a recent Sphinx release, it started calling `sys.exit()` and that
caused our whole build process to exit prematurely.
2014-09-13 16:05:40 -04:00
Virgil Dupras
9e9e73aa6b qtlib: Fix broken SelectableList
It was still using `.reset()`, which disappeared in Qt5.

Fixes #254.
2014-07-01 08:30:56 -04:00
Virgil Dupras
8434befe1f me v6.8.0 2014-05-11 09:26:55 -04:00
Virgil Dupras
1114ac5613 Fixed debian packaging 2014-05-11 09:11:38 -04:00
Virgil Dupras
f5f29d775c Adapt IPhotoPlistParser to Python 3.4
This also means that Python 3.3 isn't supported anymore for that part.
Updated README accordingly.
2014-05-03 15:12:13 -04:00
Virgil Dupras
ebd7f1b4ce pe v2.10.0 2014-05-03 13:57:00 -04:00
Virgil Dupras
279b7ad10c Fix typo in README 2014-05-03 13:53:16 -04:00
Virgil Dupras
878205fc49 Fix empty ignore List dialog bug in PE
Re-instantiating a new scanner for PE  made the ignore list dialog
target the wrong ignore list. We now only instantiate a scanner once.

Fixes #253
2014-05-03 13:44:38 -04:00
Virgil Dupras
b16df32150 I'm giving PyCharm a try 2014-05-03 13:39:39 -04:00
Virgil Dupras
04b06f7704 Removed the setNativeMenuBar() call under Qt
I put it there to make the menu usable under Ubuntu 13.10, but since
14.04, this line actually brakes it.
2014-05-03 09:34:41 -04:00
Virgil Dupras
c6ea1c62d4 Fixed Windows packaging 2014-04-21 10:00:53 -04:00
Virgil Dupras
6ce0f66601 Fixed debian packaging 2014-04-19 18:32:11 -04:00
Virgil Dupras
ac3a9e3ba8 Removed Qt's "Check for updates"
It only worked on 32bit Windows, and it's gone now.
2014-04-19 18:21:56 -04:00
Virgil Dupras
903d2f9183 Improved arch packaging
No need to bundle a .desktop file with arch source packages anymore.
dupeGuru's source package takes care of that.
2014-04-19 17:50:40 -04:00
Virgil Dupras
ca709a60cf Updated copyright year to 2014 2014-04-19 12:19:11 -04:00
Virgil Dupras
a9b4ce5529 se v3.9.0 2014-04-19 12:17:26 -04:00
Virgil Dupras
9b82ceca67 Updated windows packaging for Qt5
We now only support 64bit Windows.
2014-04-18 13:22:04 -04:00
Virgil Dupras
4c7c279dd2 Avoid crashes on quit under Windows 2014-04-18 10:55:01 -04:00
Virgil Dupras
79db31685e Fixed crash on results double-click
Introduced by the Qt5 move. Looks like passing `None` to
`doubleClicked.emit()` doesn't cut it anymore.
2014-04-18 10:44:59 -04:00
Virgil Dupras
ba13b700b0 Fixed crashing save dialogs under Qt5 2014-03-30 15:57:07 -04:00
Virgil Dupras
640561a534 Updated F.A.Q.
Fixes #252
2014-03-30 13:43:29 -04:00
Virgil Dupras
e4f81cbf04 Update loc 2014-03-30 10:47:37 -04:00
Virgil Dupras
4be4825112 Bootstrapping: don't use system-site-packages under OS X 2014-03-30 10:26:09 -04:00
Virgil Dupras
7d107d8efa Moved Cocoa error reporting to Github mode. 2014-03-30 10:07:01 -04:00
Virgil Dupras
10d1363334 Changed the error report so it brings the user to Github directly
Making error reporting too easy results in too much context-less
tracebacks which demand attention and, in the end, aren't of much use.

Requiring the user to report errors on Github will reduce the number of
reports, but hopefully make these reports have better context.
2014-03-29 17:42:23 -04:00
Virgil Dupras
b76820ebde Fixed bootstrapping under Python 3.3 2014-03-28 16:27:45 -04:00
Virgil Dupras
72b3cfb364 Adapted bootstrapping procedure to Python 3.4 2014-03-28 16:21:05 -04:00
Virgil Dupras
8b83ed0e5c Removed needless PyQt signal overloading
After a PyQt5 update, dupeGuru wouldn't run anymore because it choked on
signal overloading that weren't necessary.
2014-03-27 19:09:10 -04:00
Virgil Dupras
781f13ae1a Overwrite subfolders' state when setting states in folder dialog
Fixes #248
2014-03-15 17:31:33 -04:00
Virgil Dupras
8193bbae6e Fixed broken tests in core_me 2014-03-15 14:09:36 -04:00
Virgil Dupras
4cafeaff91 Don't crash on malformed integer in iPhoto plist
Simply default to 0. Fixes #214.
2014-03-15 14:06:20 -04:00
Virgil Dupras
95c6a7d41f Add debugging data to iPhoto plist parsing
Fixes #233.
2014-03-15 13:59:15 -04:00
Virgil Dupras
a29e007475 cocoalib: Replaced the "Relevant Console log" mechanism
The old grepping method wasn't reliable and now, we simply keep the last
20 logs in memory to place in that section of error reporting.
2014-03-15 13:57:34 -04:00
Virgil Dupras
d924d7797a Qt: Don't use a native menubar for the Result Window
Having two native menu bars in the app made the result window all
glitchy under Ubuntu 13.10.
2014-02-15 21:02:38 -05:00
Virgil Dupras
33c217ecc8 Straightened out Qt window parenting chain 2014-02-15 15:05:46 -05:00
Virgil Dupras
c9035046ae Updated cocoalib 2014-02-01 17:54:30 -05:00
Virgil Dupras
ad31016825 Updated qtlib 2014-02-01 17:17:15 -05:00
Virgil Dupras
c809066a93 Updated hscommon 2014-02-01 16:18:00 -05:00
Virgil Dupras
60ca27b5e1 Make Cocoa use the new FTP report-sender 2014-01-26 15:27:02 -05:00
Virgil Dupras
1104e24408 Error reports are now dropped by FTP on drop.hardcoded.net 2014-01-26 15:03:24 -05:00
Virgil Dupras
f66db94ffd Merge branch 'master' into develop
Conflicts:
	bootstrap.sh
2014-01-26 09:49:57 -05:00
Virgil Dupras
d98b5b22da polib is now on PyPI 2014-01-26 09:48:30 -05:00
Virgil Dupras
937748e838 Improved source packaging and bootstrapping 2014-01-26 09:41:15 -05:00
Virgil Dupras
37ebf36cee Merge branch 'master' into develop
Conflicts:
	bootstrap.sh
2014-01-11 13:30:30 -05:00
Virgil Dupras
1c84bdd198 Fixed bootstrapping and README for pip 1.5 2014-01-11 13:27:31 -05:00
Virgil Dupras
4a2fa7cd2c Updated FAQ 2014-01-10 15:05:45 -05:00
Virgil Dupras
7d4110f6d3 Merge branch 'master' into develop
Conflicts:
	README.md
2014-01-10 15:00:02 -05:00
Virgil Dupras
8497343d7f Updated FAQ in docs 2014-01-05 21:45:57 -05:00
Virgil Dupras
235a2c2904 Added a "contribute" page to the docs. 2014-01-05 21:44:56 -05:00
Virgil Dupras
25169cfc20 Create an empty site.py in collect_stdlib_dependencies()
Since we have Python 3.3 as a minimum requirement, we don't need to
patch our site.py with copy_sysconfig_files_for_embed() anymore, but we
still need a site.py file on startup. We create it when we collect
stdlib deps.
2013-12-22 12:13:39 -05:00
Virgil Dupras
152f5f37ce pe v2.9.0 2013-12-22 10:23:54 -05:00
Virgil Dupras
3e42ad8469 Minimum Python version is now 3.3 2013-12-22 09:52:19 -05:00
Virgil Dupras
7ba2e38cd6 Package PyPI dependencies right into our source package 2013-12-21 12:13:26 -05:00
Virgil Dupras
c7c7a73384 me v6.7.0 2013-12-08 10:34:04 -05:00
Virgil Dupras
46f8984bdc Merge branch 'qt5' into develop
Conflicts:
	README.md
	qtlib/about_box.py
	qtlib/reg.py
	qtlib/reg_demo_dialog.py
	qtlib/reg_submit_dialog.py
2013-12-07 19:49:27 -05:00
Virgil Dupras
c7d306b7d5 Minimum Python version is now 3.3 2013-12-07 17:23:18 -05:00
Virgil Dupras
47e636e949 Merge branch 'develop' 2013-12-07 11:15:39 -05:00
Virgil Dupras
0562729d8b Improved build script's --clean. 2013-12-07 11:14:59 -05:00
Virgil Dupras
4a36227a18 v3.8.0 2013-12-07 10:57:30 -05:00
Virgil Dupras
28b8b2e415 Sync locs with Transifex 2013-12-07 10:26:01 -05:00
Virgil Dupras
fd82464564 Removed .tx config in hscommon (useless now) 2013-12-07 10:20:13 -05:00
Virgil Dupras
418acf6e5e Merge branch 'regless' into develop
Conflicts:
	cocoa/inter/app.py
	core/app.py
	hscommon/reg.py
	locale/cs/LC_MESSAGES/ui.po
	locale/de/LC_MESSAGES/ui.po
	locale/fr/LC_MESSAGES/ui.po
	locale/hy/LC_MESSAGES/ui.po
	locale/it/LC_MESSAGES/ui.po
	locale/pt_BR/LC_MESSAGES/ui.po
	locale/ru/LC_MESSAGES/ui.po
	locale/ui.pot
	locale/uk/LC_MESSAGES/ui.po
	locale/vi/LC_MESSAGES/ui.po
	locale/zh_CN/LC_MESSAGES/ui.po
	qt/base/app.py
2013-12-07 10:19:31 -05:00
Virgil Dupras
d14d076989 Disable symlink/hardlink option when not relevant (Cocoa)
Fixes #247.
2013-12-06 16:17:04 -05:00
Virgil Dupras
cb8bb5a70e Disable symlink/hardlink option when not relevant (Qt)
When the "Replace with links" option is not enabled, the choice of
symlink or hardlink is irrelevant and causes confusion. Implemented core
mechanism for controlling the enabled state of that option. Also
implemented the Qt interface for it. Cocoa-part is still to be done.

I used this opportunity to greatly enhance documentation of this part of
the code. I'm beginning to like documenting...

Ref #247.
2013-12-06 15:48:01 -05:00
Virgil Dupras
563c9aeff3 Updated README 2013-12-01 11:26:30 -05:00
Virgil Dupras
a0cc1f2e03 Fixed regless cocoa and updated locs 2013-11-30 18:23:42 -05:00
Virgil Dupras
01403a3f92 Removed fairware 2013-11-30 17:54:40 -05:00
Virgil Dupras
7116674663 Improved hscommon docs 2013-11-30 16:13:12 -05:00
Virgil Dupras
b6bc5de79c Improved hscommon docs
TIL sphinx is rather smart about partial class refrences (starting with
a ".")
2013-11-30 12:29:25 -05:00
Virgil Dupras
5a275db67d Improved hscommon doc
* Completed hscommon.gui.table's doc
* Use sphinx.ext.autosummary.
* Moved attribute docstrings directly into properties.
2013-11-30 12:15:03 -05:00
Virgil Dupras
31395d8794 Fix typos in docs 2013-11-28 22:49:26 -05:00
Virgil Dupras
3734bd6f6c Improved hscommon.gui docs
Added docs for Table and Row in hscommon.gui.table.
2013-11-28 22:38:07 -05:00
Virgil Dupras
da06ef8cad Improved hscommon.gui docs 2013-11-24 13:53:52 -05:00
Virgil Dupras
0b00171655 pygettext: explicitly open files as utf-8
When running it through SSH, I couldn't open files with non-ascii chars.
2013-11-24 10:22:05 -05:00
Virgil Dupras
c1cfa86ad1 Make Cmd+A select all folders in the Folder Selection dialog (Cocoa)
Fixes #228.
2013-11-24 10:12:47 -05:00
Virgil Dupras
c34c9562d3 Make non-numeric delta comparison case insensitive
Fixes #239.
2013-11-23 15:31:20 -05:00
Virgil Dupras
0e542577b0 Merge branch 'master' into develop 2013-11-23 12:39:59 -05:00
Virgil Dupras
42be49da83 Fix surrogate-related UnicodeEncodeError on CSV export
Fixes #210.
2013-11-23 12:38:55 -05:00
Virgil Dupras
398ac9b7c6 Greatly improved docs
Added a new scan.rst page, laying out in much more details than before
the inner workings of the scanning process.

Fixes #208, but does much more than that.
2013-11-17 12:03:48 -05:00
Virgil Dupras
508e9a5d94 Reorganized hscommon documentation
Removed hscommon's "docs" folder and moved all documentation directly
into docstrings. Then, in dupeGuru's developer documentation, added
autodoc references to relevant modules.

The result is a much more usable hscommon documentation.
2013-11-16 14:46:34 -05:00
Virgil Dupras
cc5ea1dbc1 Fixed qt5 migration for ME and PE 2013-11-16 13:38:07 -05:00
Virgil Dupras
3b8d355b9e Merge branch 'develop' into qt5
Conflicts:
	hscommon/desktop.py
2013-11-16 12:11:32 -05:00
Virgil Dupras
10dbfa9b38 Refactoring: Path API compatibility with pathlib
Refactored dupeGuru to make hscommon.path's API a bit close to pathlib's
API. It's not 100% compatible yet, but it's much better than before.

This is more of a hscommon refactoring than a dupeguru one, but since
duepGuru is the main user of Path, it was the driver behind the
refactoring.

This refactoring also see the introduction of @pathify, which ensure
Path arguments. Previously, we were often unsure of whether the caller
of a function was passing a Path or a str. This problem is now solved
and this allows us to remove hscommon.io, an ill-conceived attempt to
solve that same ambiguity problem.

Fixes #235.
2013-11-16 12:06:16 -05:00
Virgil Dupras
e8c42740cf Fixed tests which were broken 2013-11-10 12:54:35 -05:00
Virgil Dupras
4b6c4f048d Fixed compilation warnings on OS X 2013-11-10 12:41:10 -05:00
Virgil Dupras
7594cccf8c Fixed build on OS X which was broken 2013-11-10 12:39:02 -05:00
Virgil Dupras
1d9573cf6f On OS X, read Exif tags using Cocoa's built-in functionality
This allows for RAW files Exif reading. Fixes #234.
2013-11-10 12:00:16 -05:00
Virgil Dupras
76f45fb5a6 Fixed appdata logic which was broken on OS X. 2013-11-10 11:05:03 -05:00
Virgil Dupras
12cf9b800b Merge branch 'master' into develop 2013-11-09 16:21:59 -05:00
Virgil Dupras
ba7e6494c6 Fixed crash on Dupe Count sorting with Delta + Dupes Only
Fixes #238
2013-11-09 16:20:33 -05:00
Virgil Dupras
72d8160b28 Fix boken tests 2013-11-08 16:45:14 -05:00
Virgil Dupras
6d53511cee Merge branch 'master' into develop 2013-11-08 16:03:35 -05:00
Virgil Dupras
64d3c211e6 Updated README 2013-10-20 16:26:16 -04:00
Virgil Dupras
fad112f554 Merge branch 'develop' into qt5 2013-10-20 16:02:36 -04:00
Virgil Dupras
a563327723 Updated cocoalib 2013-10-20 16:01:59 -04:00
Virgil Dupras
096e2bb78a Updated hscommon 2013-10-20 16:01:27 -04:00
Virgil Dupras
5a8cb6f5e3 Implemented super() inheritance style suggested by PyQt5 2013-10-20 15:53:59 -04:00
Virgil Dupras
664d630b96 Fixed occasional core dumps on exit 2013-10-20 15:38:24 -04:00
Virgil Dupras
a4256d3d2b First Qt5 conversion commit
Replaced PyQt4 with PyQt5 and made all adjustments necessary to make
dupeGuru start up.
2013-10-20 15:15:09 -04:00
Virgil Dupras
8e65f15e1a Fixed core.engine.Match docstring
The way it was set made dupeGuru crash under Python 3.2
2013-10-20 13:33:27 -04:00
Virgil Dupras
9ea9f60e92 Added packaging support for ubuntu 13.10 2013-10-19 14:37:01 -04:00
Virgil Dupras
8efefaf0bf Improved API docs 2013-10-12 13:55:36 -04:00
Virgil Dupras
33d9569427 Refactoring: Created hscommon.desktop
This unit hosts previously awkward UI view methods which weren't related
to the view itself, but to the current desktop environment. These
functions are now at their appropriate place.
2013-10-12 13:54:13 -04:00
Virgil Dupras
2fdfacb34e Docs: Fix ugly nulljob repr in method signatures 2013-10-11 12:15:02 -04:00
Virgil Dupras
97fcf1ffa8 Fixed debian packaging
.so files were included in the source package, which messed up builds
under archs that weren't the same as the srcpkg creator (namely, i386
builds).
2013-09-22 09:38:52 -04:00
454 changed files with 28330 additions and 8519 deletions

3
.gitignore vendored
View File

@@ -5,12 +5,15 @@
*.pyd *.pyd
*.waf* *.waf*
.lock-waf* .lock-waf*
.idea
.tox
build build
dist dist
install install
installer_tmp-cache installer_tmp-cache
env env
/deps
cocoa/autogen cocoa/autogen
/run.py /run.py

View File

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

View File

@@ -1,14 +1,24 @@
# dupeGuru # dupeGuru
This package contains the source for dupeGuru. Its documentation is [dupeGuru][dupeguru] is a cross-platform (Linux, OS X, Windows) GUI tool to find duplicate files in
[available online][documentation]. Here's how this source tree is organised: a system. It's written mostly in Python 3 and has the peculiarity of using
[multiple GUI toolkits][cross-toolkit], all using the same core Python code. On OS X, the UI layer
is written in Objective-C and uses Cocoa. On Linux and Windows, it's written in Python and uses Qt5.
dupeGuru comes in 3 editions (standard, music and picture) which are all buildable from this same
source tree. You choose the edition you want to build in a ``configure.py`` flag.
# Contents of this folder
This folder contains the source for dupeGuru. Its documentation is in ``help``, but is also
[available online][documentation] in its built form. Here's how this source tree is organised:
* core: Contains the core logic code for dupeGuru. It's Python code. * core: Contains the core logic code for dupeGuru. It's Python code.
* core_*: Edition-specific-cross-toolkit code written in Python. * core_*: Edition-specific-cross-toolkit code written in Python.
* cocoa: UI code for the Cocoa toolkit. It's Objective-C code. * cocoa: UI code for the Cocoa toolkit. It's Objective-C code.
* qt: UI code for the Qt toolkit. It's written in Python and uses PyQt. * qt: UI code for the Qt toolkit. It's written in Python and uses PyQt.
* images: Images used by the different UI codebases. * images: Images used by the different UI codebases.
* debian: Skeleton files required to create a .deb package * pkg: Skeleton files required to create different packages
* help: Help document, written for Sphinx. * help: Help document, written for Sphinx.
* locale: .po files for localisation. * locale: .po files for localisation.
@@ -36,26 +46,29 @@ and follow instructions from the script. You can then ignore the rest of the bui
Prerequisites are installed through `pip`. However, some of them are not "pip installable" and have Prerequisites are installed through `pip`. However, some of them are not "pip installable" and have
to be installed manually. to be installed manually.
* All systems: [Python 3.2+][python] and [setuptools][setuptools] * All systems: [Python 3.3+][python] and [setuptools][setuptools]
* Mac OS X: The last XCode to have the 10.6 SDK included. * Mac OS X: The last XCode to have the 10.7 SDK included. Python 3.4+.
* Windows: Visual Studio 2008, [PyQt 4.7+][pyqt], [cx_Freeze][cxfreeze] and * Windows: Visual Studio 2010, [PyQt 5.0+][pyqt], [cx_Freeze][cxfreeze] and
[Advanced Installer][advinst] (you only need the last two if you want to create an installer) [Advanced Installer][advinst] (you only need the last two if you want to create an installer)
On Ubuntu, the apt-get command to install all pre-requisites is: On Ubuntu (14.04+), the apt-get command to install all pre-requisites is:
$ apt-get install python3-dev python3-pyqt4 pyqt4-dev-tools python3-setuptools $ apt-get install python3-dev python3-pyqt5 pyqt5-dev-tools
## Virtualenv setup On Arch, it's:
First, you need `pip` and `virtualenv` in your system Python install: $ pacman -S python-pyqt5
$ sudo easy_install pip ## Setting up the virtual environment
$ sudo pip install virtualenv
Then, in dupeGuru's source folder, create a virtual environment and activate it: Use Python's built-in `pyvenv` to create a virtual environment in which we're going to install our.
Python-related dependencies. `pyvenv` is built-in Python but, unlike its `virtualenv` predecessor,
it doesn't install setuptools and pip (unless you use Python 3.4+), so it has to be installed
manually:
$ virtualenv --system-site-packages env $ pyvenv --system-site-packages env
$ source env/bin/activate $ source env/bin/activate
$ python get-pip.py
Then, you can install pip requirements in your virtualenv: Then, you can install pip requirements in your virtualenv:
@@ -63,17 +76,6 @@ Then, you can install pip requirements in your virtualenv:
([osx|win] depends, of course, on your platform. On other platforms, just use requirements.txt). ([osx|win] depends, of course, on your platform. On other platforms, just use requirements.txt).
## Alternative: pyvenv
If you're on Python 3.3+, you can use the built-in `pyvenv` instead of `virtualenv`. `pyvenv` is
pretty much the same thing as `virtualenv`, except that it doesn't install setuptools and pip, so it
has to be installed manually:
$ pyvenv --system-site-packages env
$ source env/bin/activate
$ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python
$ easy_install pip
## Actual building and running ## Actual building and running
With your virtualenv activated, you can build and run dupeGuru with these commands: With your virtualenv activated, you can build and run dupeGuru with these commands:
@@ -86,9 +88,12 @@ You can also package dupeGuru into an installable package with:
$ python package.py $ python package.py
[dupeguru]: http://www.hardcoded.net/dupeguru/
[cross-toolkit]: http://www.hardcoded.net/articles/cross-toolkit-software
[documentation]: http://www.hardcoded.net/dupeguru/help/en/ [documentation]: http://www.hardcoded.net/dupeguru/help/en/
[python]: http://www.python.org/ [python]: http://www.python.org/
[setuptools]: https://pypi.python.org/pypi/setuptools [setuptools]: https://pypi.python.org/pypi/setuptools
[pyqt]: http://www.riverbankcomputing.com [pyqt]: http://www.riverbankcomputing.com
[cxfreeze]: http://cx-freeze.sourceforge.net/ [cxfreeze]: http://cx-freeze.sourceforge.net/
[advinst]: http://www.advancedinstaller.com [advinst]: http://www.advancedinstaller.com

View File

@@ -2,24 +2,39 @@
command -v python3 -m venv >/dev/null 2>&1 || { echo >&2 "Python 3.3 required. Install it and try again. Aborting"; exit 1; } command -v python3 -m venv >/dev/null 2>&1 || { echo >&2 "Python 3.3 required. Install it and try again. Aborting"; exit 1; }
if [ -d "deps" ]; then
# We have a collection of dependencies in our source package. We might as well use it instead
# of downloading it from PyPI.
PIPARGS="--no-index --find-links=deps"
fi
if [ ! -d "env" ]; then if [ ! -d "env" ]; then
echo "No virtualenv. Creating one" echo "No virtualenv. Creating one"
command -v curl >/dev/null 2>&1 || { echo >&2 "curl required. Install it and try again. Aborting"; exit 1; } # We need a "system-site-packages" env to have PyQt, but we also need to ensure a local pip
python3 -m venv --system-site-packages env # install. To achieve our latter goal, we start with a normal venv, which we later upgrade to
source env/bin/activate # a system-site-packages once pip is installed.
curl https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py | python python3 -m venv env
easy_install pip
else
echo "There's already an env. Activating it"
source env/bin/activate source env/bin/activate
if python -m ensurepip; then
echo "We're under Python 3.4+, no need to try to install pip!"
else
python get-pip.py $PIPARGS --force-reinstall
fi
deactivate
if [ "$(uname)" != "Darwin" ]; then
# We only need system site packages for PyQt, so under OS X, we don't enable it
python3 -m venv env --upgrade --system-site-packages
fi
fi fi
source env/bin/activate
echo "Installing pip requirements" echo "Installing pip requirements"
if [ "$(uname)" == "Darwin" ]; then if [ "$(uname)" == "Darwin" ]; then
pip install -r requirements-osx.txt pip install $PIPARGS -r requirements-osx.txt
else else
python3 -c "import PyQt4" >/dev/null 2>&1 || { echo >&2 "PyQt 4.8+ required. Install it and try again. Aborting"; exit 1; } python3 -c "import PyQt5" >/dev/null 2>&1 || { echo >&2 "PyQt 5.1+ required. Install it and try again. Aborting"; exit 1; }
pip install -r requirements.txt pip install $PIPARGS -r requirements.txt
fi fi
echo "Bootstrapping complete! You can now configure, build and run dupeGuru with:" echo "Bootstrapping complete! You can now configure, build and run dupeGuru with:"

154
build.py
View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2009-12-30 # Created On: 2009-12-30
# Copyright 2013 Hardcoded Software (http://www.hardcoded.net) # Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -18,10 +18,12 @@ import compileall
from setuptools import setup, Extension from setuptools import setup, Extension
from hscommon import sphinxgen from hscommon import sphinxgen
from hscommon.build import (add_to_pythonpath, print_and_do, copy_packages, filereplace, from hscommon.build import (
get_module_version, move_all, copy_sysconfig_files_for_embed, copy_all, OSXAppStructure, add_to_pythonpath, print_and_do, copy_packages, filereplace,
get_module_version, move_all, copy_all, OSXAppStructure,
build_cocoalib_xibless, fix_qt_resource_file, build_cocoa_ext, copy_embeddable_python_dylib, build_cocoalib_xibless, fix_qt_resource_file, build_cocoa_ext, copy_embeddable_python_dylib,
collect_stdlib_dependencies, copy) collect_stdlib_dependencies, copy
)
from hscommon import loc from hscommon import loc
from hscommon.plat import ISOSX, ISLINUX from hscommon.plat import ISOSX, ISLINUX
from hscommon.util import ensure_folder, delete_files_with_pattern from hscommon.util import ensure_folder, delete_files_with_pattern
@@ -29,24 +31,42 @@ from hscommon.util import ensure_folder, delete_files_with_pattern
def parse_args(): def parse_args():
usage = "usage: %prog [options]" usage = "usage: %prog [options]"
parser = OptionParser(usage=usage) parser = OptionParser(usage=usage)
parser.add_option('--clean', action='store_true', dest='clean', parser.add_option(
help="Clean build folder before building") '--clean', action='store_true', dest='clean',
parser.add_option('--doc', action='store_true', dest='doc', help="Clean build folder before building"
help="Build only the help file") )
parser.add_option('--loc', action='store_true', dest='loc', parser.add_option(
help="Build only localization") '--doc', action='store_true', dest='doc',
parser.add_option('--cocoa-ext', action='store_true', dest='cocoa_ext', help="Build only the help file"
help="Build only Cocoa extensions") )
parser.add_option('--cocoa-compile', action='store_true', dest='cocoa_compile', parser.add_option(
help="Build only Cocoa executable") '--loc', action='store_true', dest='loc',
parser.add_option('--xibless', action='store_true', dest='xibless', help="Build only localization"
help="Build only xibless UIs") )
parser.add_option('--updatepot', action='store_true', dest='updatepot', parser.add_option(
help="Generate .pot files from source code.") '--cocoa-ext', action='store_true', dest='cocoa_ext',
parser.add_option('--mergepot', action='store_true', dest='mergepot', help="Build only Cocoa extensions"
help="Update all .po files based on .pot files.") )
parser.add_option('--normpo', action='store_true', dest='normpo', parser.add_option(
help="Normalize all PO files (do this before commit).") '--cocoa-compile', action='store_true', dest='cocoa_compile',
help="Build only Cocoa executable"
)
parser.add_option(
'--xibless', action='store_true', dest='xibless',
help="Build only xibless UIs"
)
parser.add_option(
'--updatepot', action='store_true', dest='updatepot',
help="Generate .pot files from source code."
)
parser.add_option(
'--mergepot', action='store_true', dest='mergepot',
help="Update all .po files based on .pot files."
)
parser.add_option(
'--normpo', action='store_true', dest='normpo',
help="Normalize all PO files (do this before commit)."
)
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
return options return options
@@ -75,12 +95,20 @@ def build_xibless(edition, dest='cocoa/autogen'):
('preferences_panel.py', 'PreferencesPanel_UI'), ('preferences_panel.py', 'PreferencesPanel_UI'),
] ]
for srcname, dstname in FNPAIRS: for srcname, dstname in FNPAIRS:
xibless.generate(op.join('cocoa', 'base', 'ui', srcname), op.join(dest, dstname), xibless.generate(
localizationTable='Localizable', args={'edition': edition}) op.join('cocoa', 'base', 'ui', srcname), op.join(dest, dstname),
localizationTable='Localizable', args={'edition': edition}
)
if edition == 'pe': if edition == 'pe':
xibless.generate('cocoa/pe/ui/details_panel.py', op.join(dest, 'DetailsPanel_UI'), localizationTable='Localizable') xibless.generate(
'cocoa/pe/ui/details_panel.py', op.join(dest, 'DetailsPanel_UI'),
localizationTable='Localizable'
)
else: else:
xibless.generate('cocoa/base/ui/details_panel.py', op.join(dest, 'DetailsPanel_UI'), localizationTable='Localizable') xibless.generate(
'cocoa/base/ui/details_panel.py', op.join(dest, 'DetailsPanel_UI'),
localizationTable='Localizable'
)
def build_cocoa(edition, dev): def build_cocoa(edition, dev):
print("Creating OS X app structure") print("Creating OS X app structure")
@@ -110,20 +138,20 @@ def build_cocoa(edition, dev):
'me': ['core_me'] + appscript_pkgs + ['hsaudiotag'], 'me': ['core_me'] + appscript_pkgs + ['hsaudiotag'],
'pe': ['core_pe'] + appscript_pkgs, 'pe': ['core_pe'] + appscript_pkgs,
}[edition] }[edition]
tocopy = ['core', 'hscommon', 'cocoa/inter', 'cocoalib/cocoa', 'jobprogress', 'objp', tocopy = [
'send2trash'] + specific_packages 'core', 'hscommon', 'cocoa/inter', 'cocoalib/cocoa', 'objp', 'send2trash'
] + specific_packages
copy_packages(tocopy, pydep_folder, create_links=dev) copy_packages(tocopy, pydep_folder, create_links=dev)
sys.path.insert(0, 'build') sys.path.insert(0, 'build')
extra_deps = None extra_deps = None
if edition == 'pe': if edition == 'pe':
# ModuleFinder can't seem to correctly detect the multiprocessing dependency, so we have # ModuleFinder can't seem to correctly detect the multiprocessing dependency, so we have
# to manually specify it. # to manually specify it.
extra_deps=['multiprocessing'] extra_deps = ['multiprocessing']
collect_stdlib_dependencies('build/dg_cocoa.py', pydep_folder, extra_deps=extra_deps) collect_stdlib_dependencies('build/dg_cocoa.py', pydep_folder, extra_deps=extra_deps)
del sys.path[0] del sys.path[0]
# Views are not referenced by python code, so they're not found by the collector. # Views are not referenced by python code, so they're not found by the collector.
copy_all('build/inter/*.so', op.join(pydep_folder, 'inter')) copy_all('build/inter/*.so', op.join(pydep_folder, 'inter'))
copy_sysconfig_files_for_embed(pydep_folder)
if not dev: if not dev:
# Important: Don't ever run delete_files_with_pattern('*.py') on dev builds because you'll # Important: Don't ever run delete_files_with_pattern('*.py') on dev builds because you'll
# be deleting all py files in symlinked folders. # be deleting all py files in symlinked folders.
@@ -135,6 +163,7 @@ def build_cocoa(edition, dev):
print_and_do(cocoa_compile_command(edition)) print_and_do(cocoa_compile_command(edition))
os.chdir('..') os.chdir('..')
app.copy_executable('cocoa/build/dupeGuru') app.copy_executable('cocoa/build/dupeGuru')
build_help(edition)
print("Copying resources and frameworks") print("Copying resources and frameworks")
image_path = ed('cocoa/{}/dupeguru.icns') image_path = ed('cocoa/{}/dupeguru.icns')
resources = [image_path, 'cocoa/base/dsa_pub.pem', 'build/dg_cocoa.py', 'build/help'] resources = [image_path, 'cocoa/base/dsa_pub.pem', 'build/dg_cocoa.py', 'build/help']
@@ -149,8 +178,9 @@ def build_qt(edition, dev, conf):
print("Building localizations") print("Building localizations")
build_localizations('qt', edition) build_localizations('qt', edition)
print("Building Qt stuff") print("Building Qt stuff")
print_and_do("pyrcc4 -py3 {0} > {1}".format(op.join('qt', 'base', 'dg.qrc'), op.join('qt', 'base', 'dg_rc.py'))) print_and_do("pyrcc5 {0} > {1}".format(op.join('qt', 'base', 'dg.qrc'), op.join('qt', 'base', 'dg_rc.py')))
fix_qt_resource_file(op.join('qt', 'base', 'dg_rc.py')) fix_qt_resource_file(op.join('qt', 'base', 'dg_rc.py'))
build_help(edition)
print("Creating the run.py file") print("Creating the run.py file")
filereplace(op.join('qt', 'run_template.py'), 'run.py', edition=edition) filereplace(op.join('qt', 'run_template.py'), 'run.py', edition=edition)
@@ -168,17 +198,12 @@ def build_help(edition):
conftmpl = op.join(current_path, 'help', 'conf.tmpl') conftmpl = op.join(current_path, 'help', 'conf.tmpl')
sphinxgen.gen(help_basepath, help_destpath, changelog_path, tixurl, confrepl, conftmpl, changelogtmpl) sphinxgen.gen(help_basepath, help_destpath, changelog_path, tixurl, confrepl, conftmpl, changelogtmpl)
def build_base_localizations():
loc.compile_all_po('locale')
loc.compile_all_po(op.join('hscommon', 'locale'))
loc.merge_locale_dir(op.join('hscommon', 'locale'), 'locale')
def build_qt_localizations(): def build_qt_localizations():
loc.compile_all_po(op.join('qtlib', 'locale')) loc.compile_all_po(op.join('qtlib', 'locale'))
loc.merge_locale_dir(op.join('qtlib', 'locale'), 'locale') loc.merge_locale_dir(op.join('qtlib', 'locale'), 'locale')
def build_localizations(ui, edition): def build_localizations(ui, edition):
build_base_localizations() loc.compile_all_po('locale')
if ui == 'cocoa': if ui == 'cocoa':
app = cocoa_app(edition) app = cocoa_app(edition)
loc.build_cocoa_localizations(app, en_stringsfile=op.join('cocoa', 'base', 'en.lproj', 'Localizable.strings')) loc.build_cocoa_localizations(app, en_stringsfile=op.join('cocoa', 'base', 'en.lproj', 'Localizable.strings'))
@@ -191,7 +216,7 @@ def build_localizations(ui, edition):
shutil.copytree('locale', locale_dest, ignore=shutil.ignore_patterns('*.po', '*.pot')) shutil.copytree('locale', locale_dest, ignore=shutil.ignore_patterns('*.po', '*.pot'))
if ui == 'qt' and not ISLINUX: if ui == 'qt' and not ISLINUX:
print("Copying qt_*.qm files into the 'locale' folder") print("Copying qt_*.qm files into the 'locale' folder")
from PyQt4.QtCore import QLibraryInfo from PyQt5.QtCore import QLibraryInfo
trfolder = QLibraryInfo.location(QLibraryInfo.TranslationsPath) trfolder = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
for lang in loc.get_langs('locale'): for lang in loc.get_langs('locale'):
qmname = 'qt_%s.qm' % lang qmname = 'qt_%s.qm' % lang
@@ -220,8 +245,6 @@ def build_updatepot():
# We want to merge the generated pot with the old pot in the most preserving way possible. # We want to merge the generated pot with the old pot in the most preserving way possible.
ui_packages = ['qt', op.join('cocoa', 'inter')] ui_packages = ['qt', op.join('cocoa', 'inter')]
loc.generate_pot(ui_packages, op.join('locale', 'ui.pot'), ['tr'], merge=(not ISOSX)) loc.generate_pot(ui_packages, op.join('locale', 'ui.pot'), ['tr'], merge=(not ISOSX))
print("Building hscommon.pot")
loc.generate_pot(['hscommon'], op.join('hscommon', 'locale', 'hscommon.pot'), ['tr'])
print("Building qtlib.pot") print("Building qtlib.pot")
loc.generate_pot(['qtlib'], op.join('qtlib', 'locale', 'qtlib.pot'), ['tr']) loc.generate_pot(['qtlib'], op.join('qtlib', 'locale', 'qtlib.pot'), ['tr'])
if ISOSX: if ISOSX:
@@ -230,19 +253,19 @@ def build_updatepot():
os.remove(cocoalib_pot) os.remove(cocoalib_pot)
loc.strings2pot(op.join('cocoalib', 'en.lproj', 'cocoalib.strings'), cocoalib_pot) loc.strings2pot(op.join('cocoalib', 'en.lproj', 'cocoalib.strings'), cocoalib_pot)
print("Enhancing ui.pot with Cocoa's strings files") print("Enhancing ui.pot with Cocoa's strings files")
loc.strings2pot(op.join('cocoa', 'base', 'en.lproj', 'Localizable.strings'), loc.strings2pot(
op.join('locale', 'ui.pot')) op.join('cocoa', 'base', 'en.lproj', 'Localizable.strings'),
op.join('locale', 'ui.pot')
)
def build_mergepot(): def build_mergepot():
print("Updating .po files using .pot files") print("Updating .po files using .pot files")
loc.merge_pots_into_pos('locale') loc.merge_pots_into_pos('locale')
loc.merge_pots_into_pos(op.join('hscommon', 'locale'))
loc.merge_pots_into_pos(op.join('qtlib', 'locale')) loc.merge_pots_into_pos(op.join('qtlib', 'locale'))
loc.merge_pots_into_pos(op.join('cocoalib', 'locale')) loc.merge_pots_into_pos(op.join('cocoalib', 'locale'))
def build_normpo(): def build_normpo():
loc.normalize_all_pos('locale') loc.normalize_all_pos('locale')
loc.normalize_all_pos(op.join('hscommon', 'locale'))
loc.normalize_all_pos(op.join('qtlib', 'locale')) loc.normalize_all_pos(op.join('qtlib', 'locale'))
loc.normalize_all_pos(op.join('cocoalib', 'locale')) loc.normalize_all_pos(op.join('cocoalib', 'locale'))
@@ -250,11 +273,15 @@ def build_cocoa_proxy_module():
print("Building Cocoa Proxy") print("Building Cocoa Proxy")
import objp.p2o import objp.p2o
objp.p2o.generate_python_proxy_code('cocoalib/cocoa/CocoaProxy.h', 'build/CocoaProxy.m') objp.p2o.generate_python_proxy_code('cocoalib/cocoa/CocoaProxy.h', 'build/CocoaProxy.m')
build_cocoa_ext("CocoaProxy", 'cocoalib/cocoa', build_cocoa_ext(
['cocoalib/cocoa/CocoaProxy.m', 'build/CocoaProxy.m', 'build/ObjP.m', "CocoaProxy", 'cocoalib/cocoa',
'cocoalib/HSErrorReportWindow.m', 'cocoa/autogen/HSErrorReportWindow_UI.m'], [
'cocoalib/cocoa/CocoaProxy.m', 'build/CocoaProxy.m', 'build/ObjP.m',
'cocoalib/HSErrorReportWindow.m', 'cocoa/autogen/HSErrorReportWindow_UI.m'
],
['AppKit', 'CoreServices'], ['AppKit', 'CoreServices'],
['cocoalib', 'cocoa/autogen']) ['cocoalib', 'cocoa/autogen']
)
def build_cocoa_bridging_interfaces(edition): def build_cocoa_bridging_interfaces(edition):
print("Building Cocoa Bridging Interfaces") print("Building Cocoa Bridging Interfaces")
@@ -262,9 +289,11 @@ def build_cocoa_bridging_interfaces(edition):
import objp.p2o import objp.p2o
add_to_pythonpath('cocoa') add_to_pythonpath('cocoa')
add_to_pythonpath('cocoalib') add_to_pythonpath('cocoalib')
from cocoa.inter import (PyGUIObject, GUIObjectView, PyColumns, ColumnsView, PyOutline, from cocoa.inter import (
PyGUIObject, GUIObjectView, PyColumns, ColumnsView, PyOutline,
OutlineView, PySelectableList, SelectableListView, PyTable, TableView, PyBaseApp, OutlineView, PySelectableList, SelectableListView, PyTable, TableView, PyBaseApp,
PyFairware, PyTextField, ProgressWindowView, PyProgressWindow) PyTextField, ProgressWindowView, PyProgressWindow
)
from inter.deletion_options import PyDeletionOptions, DeletionOptionsView from inter.deletion_options import PyDeletionOptions, DeletionOptionsView
from inter.details_panel import PyDetailsPanel, DetailsPanelView from inter.details_panel import PyDetailsPanel, DetailsPanelView
from inter.directory_outline import PyDirectoryOutline, DirectoryOutlineView from inter.directory_outline import PyDirectoryOutline, DirectoryOutlineView
@@ -276,16 +305,20 @@ def build_cocoa_bridging_interfaces(edition):
from inter.stats_label import PyStatsLabel, StatsLabelView from inter.stats_label import PyStatsLabel, StatsLabelView
from inter.app import PyDupeGuruBase, DupeGuruView from inter.app import PyDupeGuruBase, DupeGuruView
appmod = importlib.import_module('inter.app_{}'.format(edition)) appmod = importlib.import_module('inter.app_{}'.format(edition))
allclasses = [PyGUIObject, PyColumns, PyOutline, PySelectableList, PyTable, PyBaseApp, PyFairware, allclasses = [
PyGUIObject, PyColumns, PyOutline, PySelectableList, PyTable, PyBaseApp,
PyDetailsPanel, PyDirectoryOutline, PyPrioritizeDialog, PyPrioritizeList, PyProblemDialog, PyDetailsPanel, PyDirectoryOutline, PyPrioritizeDialog, PyPrioritizeList, PyProblemDialog,
PyIgnoreListDialog, PyDeletionOptions, PyResultTable, PyStatsLabel, PyDupeGuruBase, PyIgnoreListDialog, PyDeletionOptions, PyResultTable, PyStatsLabel, PyDupeGuruBase,
PyTextField, PyProgressWindow, appmod.PyDupeGuru] PyTextField, PyProgressWindow, appmod.PyDupeGuru
]
for class_ in allclasses: for class_ in allclasses:
objp.o2p.generate_objc_code(class_, 'cocoa/autogen', inherit=True) objp.o2p.generate_objc_code(class_, 'cocoa/autogen', inherit=True)
allclasses = [GUIObjectView, ColumnsView, OutlineView, SelectableListView, TableView, allclasses = [
GUIObjectView, ColumnsView, OutlineView, SelectableListView, TableView,
DetailsPanelView, DirectoryOutlineView, PrioritizeDialogView, PrioritizeListView, DetailsPanelView, DirectoryOutlineView, PrioritizeDialogView, PrioritizeListView,
IgnoreListDialogView, DeletionOptionsView, ResultTableView, StatsLabelView, IgnoreListDialogView, DeletionOptionsView, ResultTableView, StatsLabelView,
ProgressWindowView, DupeGuruView] ProgressWindowView, DupeGuruView
]
clsspecs = [objp.o2p.spec_from_python_class(class_) for class_ in allclasses] clsspecs = [objp.o2p.spec_from_python_class(class_) for class_ in allclasses]
objp.p2o.generate_python_proxy_code_from_clsspec(clsspecs, 'build/CocoaViews.m') objp.p2o.generate_python_proxy_code_from_clsspec(clsspecs, 'build/CocoaViews.m')
build_cocoa_ext('CocoaViews', 'cocoa/inter', ['build/CocoaViews.m', 'build/ObjP.m']) build_cocoa_ext('CocoaViews', 'cocoa/inter', ['build/CocoaViews.m', 'build/ObjP.m'])
@@ -304,11 +337,12 @@ def build_pe_modules(ui):
extra_link_args=[ extra_link_args=[
"-framework", "CoreFoundation", "-framework", "CoreFoundation",
"-framework", "Foundation", "-framework", "Foundation",
"-framework", "ApplicationServices",] "-framework", "ApplicationServices",
]
)) ))
setup( setup(
script_args = ['build_ext', '--inplace'], script_args=['build_ext', '--inplace'],
ext_modules = exts, ext_modules=exts,
) )
move_all('_block_qt*', op.join('qt', 'pe')) move_all('_block_qt*', op.join('qt', 'pe'))
move_all('_block*', 'core_pe') move_all('_block*', 'core_pe')
@@ -317,7 +351,6 @@ def build_pe_modules(ui):
def build_normal(edition, ui, dev, conf): def build_normal(edition, ui, dev, conf):
print("Building dupeGuru {0} with UI {1}".format(edition.upper(), ui)) print("Building dupeGuru {0} with UI {1}".format(edition.upper(), ui))
add_to_pythonpath('.') add_to_pythonpath('.')
build_help(edition)
print("Building dupeGuru") print("Building dupeGuru")
if edition == 'pe': if edition == 'pe':
build_pe_modules(ui) build_pe_modules(ui)
@@ -335,8 +368,9 @@ def main():
if dev: if dev:
print("Building in Dev mode") print("Building in Dev mode")
if options.clean: if options.clean:
if op.exists('build'): for path in ['build', op.join('cocoa', 'build'), op.join('cocoa', 'autogen')]:
shutil.rmtree('build') if op.exists(path):
shutil.rmtree(path)
if not op.exists('build'): if not op.exists('build'):
os.mkdir('build') os.mkdir('build')
if options.doc: if options.doc:

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2013 Hardcoded Software (http://www.hardcoded.net) Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at
@@ -13,7 +13,7 @@ http://www.hardcoded.net/licenses/bsd_license
#import "DetailsPanel.h" #import "DetailsPanel.h"
#import "DirectoryPanel.h" #import "DirectoryPanel.h"
#import "IgnoreListDialog.h" #import "IgnoreListDialog.h"
#import "HSFairwareAboutBox.h" #import "HSAboutBox.h"
#import "HSRecentFiles.h" #import "HSRecentFiles.h"
#import "HSProgressWindow.h" #import "HSProgressWindow.h"
@@ -30,7 +30,7 @@ http://www.hardcoded.net/licenses/bsd_license
IgnoreListDialog *_ignoreListDialog; IgnoreListDialog *_ignoreListDialog;
HSProgressWindow *_progressWindow; HSProgressWindow *_progressWindow;
NSWindowController *_preferencesPanel; NSWindowController *_preferencesPanel;
HSFairwareAboutBox *_aboutBox; HSAboutBox *_aboutBox;
HSRecentFiles *_recentResults; HSRecentFiles *_recentResults;
} }
@@ -73,6 +73,4 @@ http://www.hardcoded.net/licenses/bsd_license
/* model --> view */ /* model --> view */
- (void)showMessage:(NSString *)msg; - (void)showMessage:(NSString *)msg;
- (void)setupAsRegistered;
- (void)showDemoNagWithPrompt:(NSString *)prompt;
@end @end

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2013 Hardcoded Software (http://www.hardcoded.net) Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at
@@ -8,7 +8,6 @@ http://www.hardcoded.net/licenses/bsd_license
#import "AppDelegateBase.h" #import "AppDelegateBase.h"
#import "ProgressController.h" #import "ProgressController.h"
#import "HSFairwareReminder.h"
#import "HSPyUtil.h" #import "HSPyUtil.h"
#import "Consts.h" #import "Consts.h"
#import "Dialogs.h" #import "Dialogs.h"
@@ -140,7 +139,7 @@ http://www.hardcoded.net/licenses/bsd_license
[op setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]]; [op setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]];
[op setTitle:NSLocalizedString(@"Select a results file to load", @"")]; [op setTitle:NSLocalizedString(@"Select a results file to load", @"")];
if ([op runModal] == NSOKButton) { if ([op runModal] == NSOKButton) {
NSString *filename = [[op filenames] objectAtIndex:0]; NSString *filename = [[[op URLs] objectAtIndex:0] path];
[model loadResultsFrom:filename]; [model loadResultsFrom:filename];
[[self recentResults] addFile:filename]; [[self recentResults] addFile:filename];
} }
@@ -162,7 +161,7 @@ http://www.hardcoded.net/licenses/bsd_license
- (void)showAboutBox - (void)showAboutBox
{ {
if (_aboutBox == nil) { if (_aboutBox == nil) {
_aboutBox = [[HSFairwareAboutBox alloc] initWithApp:model]; _aboutBox = [[HSAboutBox alloc] initWithApp:model];
} }
[[_aboutBox window] makeKeyAndOrderFront:nil]; [[_aboutBox window] makeKeyAndOrderFront:nil];
} }
@@ -199,7 +198,6 @@ http://www.hardcoded.net/licenses/bsd_license
/* Delegate */ /* Delegate */
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{ {
[model initialRegistrationSetup];
[model loadSession]; [model loadSession];
} }
@@ -261,16 +259,6 @@ http://www.hardcoded.net/licenses/bsd_license
[[self resultWindow] showProblemDialog]; [[self resultWindow] showProblemDialog];
} }
- (void)setupAsRegistered
{
// Nothing to do.
}
- (void)showDemoNagWithPrompt:(NSString *)prompt
{
[HSFairwareReminder showDemoNagWithApp:[self model] prompt:prompt];
}
- (NSString *)selectDestFolderWithPrompt:(NSString *)prompt - (NSString *)selectDestFolderWithPrompt:(NSString *)prompt
{ {
NSOpenPanel *op = [NSOpenPanel openPanel]; NSOpenPanel *op = [NSOpenPanel openPanel];
@@ -280,7 +268,7 @@ http://www.hardcoded.net/licenses/bsd_license
[op setAllowsMultipleSelection:NO]; [op setAllowsMultipleSelection:NO];
[op setTitle:prompt]; [op setTitle:prompt];
if ([op runModal] == NSOKButton) { if ([op runModal] == NSOKButton) {
return [[op filenames] objectAtIndex:0]; return [[[op URLs] objectAtIndex:0] path];
} }
else { else {
return nil; return nil;
@@ -294,7 +282,7 @@ http://www.hardcoded.net/licenses/bsd_license
[sp setAllowedFileTypes:[NSArray arrayWithObject:extension]]; [sp setAllowedFileTypes:[NSArray arrayWithObject:extension]];
[sp setTitle:prompt]; [sp setTitle:prompt];
if ([sp runModal] == NSOKButton) { if ([sp runModal] == NSOKButton) {
return [sp filename]; return [[sp URL] path];
} }
else { else {
return nil; return nil;

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2013 Hardcoded Software (http://www.hardcoded.net) Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at
@@ -64,4 +64,9 @@ http://www.hardcoded.net/licenses/bsd_license
[[self window] close]; [[self window] close];
return r == NSOKButton; return r == NSOKButton;
} }
- (void)setHardlinkOptionEnabled:(BOOL)enabled
{
[linkTypeRadio setEnabled:enabled];
}
@end @end

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2013 Hardcoded Software (http://www.hardcoded.net) Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at
@@ -16,4 +16,6 @@ http://www.hardcoded.net/licenses/bsd_license
@interface DirectoryOutline : HSOutline {} @interface DirectoryOutline : HSOutline {}
- (id)initWithPyRef:(PyObject *)aPyRef outlineView:(HSOutlineView *)aOutlineView; - (id)initWithPyRef:(PyObject *)aPyRef outlineView:(HSOutlineView *)aOutlineView;
- (PyDirectoryOutline *)model; - (PyDirectoryOutline *)model;
- (void)selectAll;
@end; @end;

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2013 Hardcoded Software (http://www.hardcoded.net) Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at
@@ -22,6 +22,12 @@ http://www.hardcoded.net/licenses/bsd_license
return (PyDirectoryOutline *)model; return (PyDirectoryOutline *)model;
} }
/* Public */
- (void)selectAll
{
[[self model] selectAll];
}
/* Delegate */ /* Delegate */
- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id < NSDraggingInfo >)info proposedItem:(id)item proposedChildIndex:(NSInteger)index - (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id < NSDraggingInfo >)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
{ {

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2013 Hardcoded Software (http://www.hardcoded.net) Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at
@@ -46,4 +46,6 @@ http://www.hardcoded.net/licenses/bsd_license
- (void)addDirectory:(NSString *)directory; - (void)addDirectory:(NSString *)directory;
- (void)refreshRemoveButtonText; - (void)refreshRemoveButtonText;
- (void)markAll;
@end @end

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2013 Hardcoded Software (http://www.hardcoded.net) Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at
@@ -91,8 +91,8 @@ http://www.hardcoded.net/licenses/bsd_license
[op setTitle:NSLocalizedString(@"Select a folder to add to the scanning list", @"")]; [op setTitle:NSLocalizedString(@"Select a folder to add to the scanning list", @"")];
[op setDelegate:self]; [op setDelegate:self];
if ([op runModal] == NSOKButton) { if ([op runModal] == NSOKButton) {
for (NSString *directory in [op filenames]) { for (NSURL *directoryURL in [op URLs]) {
[self addDirectory:directory]; [self addDirectory:[directoryURL path]];
} }
} }
} }
@@ -158,6 +158,14 @@ http://www.hardcoded.net/licenses/bsd_license
} }
} }
- (void)markAll
{
/* markAll isn't very descriptive of what we do, but since we re-use the Mark All button from
the result window, we don't have much choice.
*/
[outline selectAll];
}
/* Delegate */ /* Delegate */
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)path - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)path
{ {
@@ -171,6 +179,14 @@ http://www.hardcoded.net/licenses/bsd_license
[self addDirectory:path]; [self addDirectory:path];
} }
- (BOOL)validateMenuItem:(NSMenuItem *)item
{
if ([item action] == @selector(markAll)) {
[item setTitle:NSLocalizedString(@"Select All", @"")];
}
return YES;
}
/* Notifications */ /* Notifications */
- (void)directorySelectionChanged:(NSNotification *)aNotification - (void)directorySelectionChanged:(NSNotification *)aNotification

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2013 Hardcoded Software (http://www.hardcoded.net) Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at
@@ -258,8 +258,8 @@ http://www.hardcoded.net/licenses/bsd_license
[sp setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]]; [sp setAllowedFileTypes:[NSArray arrayWithObject:@"dupeguru"]];
[sp setTitle:NSLocalizedString(@"Select a file to save your results to", @"")]; [sp setTitle:NSLocalizedString(@"Select a file to save your results to", @"")];
if ([sp runModal] == NSOKButton) { if ([sp runModal] == NSOKButton) {
[model saveResultsAs:[sp filename]]; [model saveResultsAs:[[sp URL] path]];
[[app recentResults] addFile:[sp filename]]; [[app recentResults] addFile:[[sp URL] path]];
} }
} }
@@ -344,6 +344,9 @@ http://www.hardcoded.net/licenses/bsd_license
- (BOOL)validateMenuItem:(NSMenuItem *)item - (BOOL)validateMenuItem:(NSMenuItem *)item
{ {
if ([item action] == @selector(markAll)) {
[item setTitle:NSLocalizedString(@"Mark All", @"")];
}
return ![[ProgressController mainProgressController] isShown]; return ![[ProgressController mainProgressController] isShown];
} }
@end @end

View File

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

View File

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

View File

@@ -1,6 +1,5 @@
"%@ Results" = "%@ Results"; "%@ Results" = "%@ Results";
"A previous action is still hanging in there. You can't start a new one yet. Wait a few seconds, then try again." = "A previous action is still hanging in there. You can't start a new one yet. Wait a few seconds, then try again.";
"About dupeGuru" = "About dupeGuru"; "About dupeGuru" = "About dupeGuru";
"Action" = "Action"; "Action" = "Action";
"Actions" = "Actions"; "Actions" = "Actions";
@@ -127,6 +126,7 @@
"Select a file to save your results to" = "Select a file to save your results to"; "Select a file to save your results to" = "Select a file to save your results to";
"Select a folder to add to the scanning list" = "Select a folder to add to the scanning list"; "Select a folder to add to the scanning list" = "Select a folder to add to the scanning list";
"Select a results file to load" = "Select a results file to load"; "Select a results file to load" = "Select a results file to load";
"Select All" = "Select All";
"Select folders to scan and press \"Scan\"." = "Select folders to scan and press \"Scan\"."; "Select folders to scan and press \"Scan\"." = "Select folders to scan and press \"Scan\".";
"Selected" = "Selected"; "Selected" = "Selected";
"Send Marked to Trash..." = "Send Marked to Trash..."; "Send Marked to Trash..." = "Send Marked to Trash...";

View File

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

View File

@@ -1,24 +1,23 @@
import logging import logging
from objp.util import pyref, dontwrap from objp.util import pyref, dontwrap
from cocoa import install_exception_hook, install_cocoa_logger, patch_threaded_job_performer, proxy from cocoa import install_exception_hook, install_cocoa_logger, patch_threaded_job_performer
from cocoa.inter import PyFairware, FairwareView from cocoa.inter import PyBaseApp, BaseAppView
class DupeGuruView(FairwareView): class DupeGuruView(BaseAppView):
def askYesNoWithPrompt_(self, prompt: str) -> bool: pass def askYesNoWithPrompt_(self, prompt: str) -> bool: pass
def showProblemDialog(self): pass def showProblemDialog(self): pass
def selectDestFolderWithPrompt_(self, prompt: str) -> str: pass def selectDestFolderWithPrompt_(self, prompt: str) -> str: pass
def selectDestFileWithPrompt_extension_(self, prompt: str, extension: str) -> str: pass def selectDestFileWithPrompt_extension_(self, prompt: str, extension: str) -> str: pass
class PyDupeGuruBase(PyFairware): class PyDupeGuruBase(PyBaseApp):
@dontwrap @dontwrap
def _init(self, modelclass): def _init(self, modelclass):
logging.basicConfig(level=logging.WARNING, format='%(levelname)s %(message)s') logging.basicConfig(level=logging.WARNING, format='%(levelname)s %(message)s')
install_exception_hook() install_exception_hook('https://github.com/hsoft/dupeguru/issues')
install_cocoa_logger() install_cocoa_logger()
patch_threaded_job_performer() patch_threaded_job_performer()
appdata = proxy.getAppdataPath() self.model = modelclass(self)
self.model = modelclass(self, appdata)
#---Sub-proxies #---Sub-proxies
def detailsPanel(self) -> pyref: def detailsPanel(self) -> pyref:
@@ -144,14 +143,6 @@ class PyDupeGuruBase(PyFairware):
self.model.options['copymove_dest_type'] = copymove_dest_type self.model.options['copymove_dest_type'] = copymove_dest_type
#--- model --> view #--- model --> view
@dontwrap
def open_path(self, path):
proxy.openPath_(str(path))
@dontwrap
def reveal_path(self, path):
proxy.revealPath_(str(path))
@dontwrap @dontwrap
def ask_yes_no(self, prompt): def ask_yes_no(self, prompt):
return self.callback.askYesNoWithPrompt_(prompt) return self.callback.askYesNoWithPrompt_(prompt)

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/11/16 # Created On: 2006/11/16
# Copyright 2013 Hardcoded Software (http://www.hardcoded.net) # Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -143,16 +143,13 @@ class Directories(directories.Directories):
class DupeGuruME(DupeGuruBase): class DupeGuruME(DupeGuruBase):
def __init__(self, view, appdata): def __init__(self, view):
appdata = op.join(appdata, 'dupeGuru Music Edition') DupeGuruBase.__init__(self, view)
DupeGuruBase.__init__(self, view, appdata)
# Use fileclasses set in DupeGuruBase.__init__() # Use fileclasses set in DupeGuruBase.__init__()
self.directories = Directories(fileclasses=self.directories.fileclasses) self.directories = Directories(fileclasses=self.directories.fileclasses)
self.dead_tracks = [] self.dead_tracks = []
def _do_delete(self, j, *args): def _do_delete(self, j, *args):
# XXX If I read correctly, Python 3.3 will allow us to go fetch inner function easily, so
# we'll be able to replace "op" below with DupeGuruBase._do_delete.op.
def op(dupe): def op(dupe):
j.add_progress() j.add_progress()
return self._do_delete_dupe(dupe, *args) return self._do_delete_dupe(dupe, *args)
@@ -174,7 +171,7 @@ class DupeGuruME(DupeGuruBase):
DupeGuruBase._do_delete_dupe(self, dupe, *args) DupeGuruBase._do_delete_dupe(self, dupe, *args)
def _create_file(self, path): def _create_file(self, path):
if (self.directories.itunes_libpath is not None) and (path in self.directories.itunes_libpath[:-1]): if (self.directories.itunes_libpath is not None) and (path in self.directories.itunes_libpath.parent()):
if not hasattr(self, 'itunes_songs'): if not hasattr(self, 'itunes_songs'):
songs = get_itunes_songs(self.directories.itunes_libpath) songs = get_itunes_songs(self.directories.itunes_libpath)
self.itunes_songs = {song.path: song for song in songs} self.itunes_songs = {song.path: song for song in songs}

View File

@@ -1,21 +1,19 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2006/11/13 # Created On: 2006/11/13
# Copyright 2013 Hardcoded Software (http://www.hardcoded.net) # Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
# http://www.hardcoded.net/licenses/bsd_license # http://www.hardcoded.net/licenses/bsd_license
import os.path as op
import plistlib
import logging import logging
import re import re
import io
from appscript import app, its, k, CommandError, ApplicationNotFoundError from appscript import app, its, k, CommandError, ApplicationNotFoundError
from hscommon import io
from hscommon.util import remove_invalid_xml, first from hscommon.util import remove_invalid_xml, first
from hscommon.path import Path from hscommon.path import Path, pathify
from hscommon.trans import trget from hscommon.trans import trget
from cocoa import proxy from cocoa import proxy
@@ -25,6 +23,7 @@ from core.app import JobType
from core_pe import _block_osx from core_pe import _block_osx
from core_pe.photo import Photo as PhotoBase from core_pe.photo import Photo as PhotoBase
from core_pe.app import DupeGuru as DupeGuruBase from core_pe.app import DupeGuru as DupeGuruBase
from core_pe.iphoto_plist import IPhotoPlistParser
from .app import PyDupeGuruBase from .app import PyDupeGuruBase
tr = trget('ui') tr = trget('ui')
@@ -48,6 +47,16 @@ class Photo(PhotoBase):
raise IOError('The picture %s could not be read' % str(self.path)) raise IOError('The picture %s could not be read' % str(self.path))
return blocks return blocks
def _get_exif_timestamp(self):
exifdata = proxy.readExifData_(str(self.path))
if exifdata:
try:
return exifdata['{Exif}']['DateTimeOriginal']
except KeyError:
return ''
else:
return ''
class IPhoto(Photo): class IPhoto(Photo):
def __init__(self, path, db_id): def __init__(self, path, db_id):
@@ -67,11 +76,12 @@ class AperturePhoto(Photo):
def display_folder_path(self): def display_folder_path(self):
return APERTURE_PATH return APERTURE_PATH
def get_iphoto_or_aperture_pictures(plistpath, photo_class): @pathify
def get_iphoto_or_aperture_pictures(plistpath: Path, photo_class):
# The structure of iPhoto and Aperture libraries for the base photo list are excactly the same. # The structure of iPhoto and Aperture libraries for the base photo list are excactly the same.
if not io.exists(plistpath): if not plistpath.exists():
return [] return []
s = io.open(plistpath, 'rt', encoding='utf-8').read() s = plistpath.open('rt', encoding='utf-8').read()
# There was a case where a guy had 0x10 chars in his plist, causing expat errors on loading # There was a case where a guy had 0x10 chars in his plist, causing expat errors on loading
s = remove_invalid_xml(s, replace_with='') s = remove_invalid_xml(s, replace_with='')
# It seems that iPhoto sometimes doesn't properly escape & chars. The regexp below is to find # It seems that iPhoto sometimes doesn't properly escape & chars. The regexp below is to find
@@ -80,7 +90,12 @@ def get_iphoto_or_aperture_pictures(plistpath, photo_class):
s, count = re.subn(r'&(?![a-zA-Z0-9_-]+|#[0-9]+|#x[0-9a-fA-F]+;)', '', s) s, count = re.subn(r'&(?![a-zA-Z0-9_-]+|#[0-9]+|#x[0-9a-fA-F]+;)', '', s)
if count: if count:
logging.warning("%d invalid XML entities replacement made", count) logging.warning("%d invalid XML entities replacement made", count)
plist = plistlib.readPlistFromBytes(s.encode('utf-8')) parser = IPhotoPlistParser()
try:
plist = parser.parse(io.BytesIO(s.encode('utf-8')))
except Exception:
logging.warning("iPhoto plist parsing choked on data: %r", parser.lastdata)
raise
result = [] result = []
for key, photo_data in plist['Master Image List'].items(): for key, photo_data in plist['Master Image List'].items():
if photo_data['MediaType'] != 'Image': if photo_data['MediaType'] != 'Image':
@@ -114,12 +129,12 @@ class Directories(directories.Directories):
directories.Directories.__init__(self, fileclasses=[Photo]) directories.Directories.__init__(self, fileclasses=[Photo])
try: try:
self.iphoto_libpath = get_iphoto_database_path() self.iphoto_libpath = get_iphoto_database_path()
self.set_state(self.iphoto_libpath[:-1], directories.DirectoryState.Excluded) self.set_state(self.iphoto_libpath.parent(), directories.DirectoryState.Excluded)
except directories.InvalidPathError: except directories.InvalidPathError:
self.iphoto_libpath = None self.iphoto_libpath = None
try: try:
self.aperture_libpath = get_aperture_database_path() self.aperture_libpath = get_aperture_database_path()
self.set_state(self.aperture_libpath[:-1], directories.DirectoryState.Excluded) self.set_state(self.aperture_libpath.parent(), directories.DirectoryState.Excluded)
except directories.InvalidPathError: except directories.InvalidPathError:
self.aperture_libpath = None self.aperture_libpath = None
@@ -171,9 +186,8 @@ class Directories(directories.Directories):
class DupeGuruPE(DupeGuruBase): class DupeGuruPE(DupeGuruBase):
def __init__(self, view, appdata): def __init__(self, view):
appdata = op.join(appdata, 'dupeGuru Picture Edition') DupeGuruBase.__init__(self, view)
DupeGuruBase.__init__(self, view, appdata)
self.directories = Directories() self.directories = Directories()
def _do_delete(self, j, *args): def _do_delete(self, j, *args):
@@ -247,12 +261,12 @@ class DupeGuruPE(DupeGuruBase):
DupeGuruBase._do_delete_dupe(self, dupe, *args) DupeGuruBase._do_delete_dupe(self, dupe, *args)
def _create_file(self, path): def _create_file(self, path):
if (self.directories.iphoto_libpath is not None) and (path in self.directories.iphoto_libpath[:-1]): if (self.directories.iphoto_libpath is not None) and (path in self.directories.iphoto_libpath.parent()):
if not hasattr(self, 'path2iphoto'): if not hasattr(self, 'path2iphoto'):
photos = get_iphoto_pictures(self.directories.iphoto_libpath) photos = get_iphoto_pictures(self.directories.iphoto_libpath)
self.path2iphoto = {p.path: p for p in photos} self.path2iphoto = {p.path: p for p in photos}
return self.path2iphoto.get(path) return self.path2iphoto.get(path)
if (self.directories.aperture_libpath is not None) and (path in self.directories.aperture_libpath[:-1]): if (self.directories.aperture_libpath is not None) and (path in self.directories.aperture_libpath.parent()):
if not hasattr(self, 'path2aperture'): if not hasattr(self, 'path2aperture'):
photos = get_aperture_pictures(self.directories.aperture_libpath) photos = get_aperture_pictures(self.directories.aperture_libpath)
self.path2aperture = {p.path: p for p in photos} self.path2aperture = {p.path: p for p in photos}

View File

@@ -1,6 +1,6 @@
# Created By: Virgil Dupras # Created By: Virgil Dupras
# Created On: 2009-05-24 # Created On: 2009-05-24
# Copyright 2013 Hardcoded Software (http://www.hardcoded.net) # Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -9,8 +9,7 @@
import logging import logging
import os.path as op import os.path as op
from hscommon import io from hscommon.path import Path, pathify
from hscommon.path import Path
from cocoa import proxy from cocoa import proxy
from core.scanner import ScanType from core.scanner import ScanType
@@ -27,8 +26,9 @@ def is_bundle(str_path):
class Bundle(fs.Folder): class Bundle(fs.Folder):
@classmethod @classmethod
def can_handle(cls, path): @pathify
return not io.islink(path) and io.isdir(path) and is_bundle(str(path)) def can_handle(cls, path: Path):
return not path.islink() and path.isdir() and is_bundle(str(path))
class Directories(DirectoriesBase): class Directories(DirectoriesBase):
@@ -68,9 +68,10 @@ class Directories(DirectoriesBase):
class DupeGuru(DupeGuruBase): class DupeGuru(DupeGuruBase):
def __init__(self, view, appdata): def __init__(self, view):
appdata = op.join(appdata, 'dupeGuru') # appdata = op.join(appdata, 'dupeGuru')
DupeGuruBase.__init__(self, view, appdata) # print(repr(appdata))
DupeGuruBase.__init__(self, view)
self.directories = Directories() self.directories = Directories()

View File

@@ -1,5 +1,5 @@
# Created On: 2012-05-30 # Created On: 2012-05-30
# Copyright 2013 Hardcoded Software (http://www.hardcoded.net) # Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
# #
# This software is licensed under the "BSD" License as described in the "LICENSE" file, # This software is licensed under the "BSD" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at # which should be included with this package. The terms are also available at
@@ -11,6 +11,7 @@ from cocoa.inter import PyGUIObject, GUIObjectView
class DeletionOptionsView(GUIObjectView): class DeletionOptionsView(GUIObjectView):
def updateMsg_(self, msg: str): pass def updateMsg_(self, msg: str): pass
def show(self) -> bool: pass def show(self) -> bool: pass
def setHardlinkOptionEnabled_(self, enabled: bool): pass
class PyDeletionOptions(PyGUIObject): class PyDeletionOptions(PyGUIObject):
def setLinkDeleted_(self, link_deleted: bool): def setLinkDeleted_(self, link_deleted: bool):
@@ -31,3 +32,6 @@ class PyDeletionOptions(PyGUIObject):
def show(self): def show(self):
return self.callback.show() return self.callback.show()
@dontwrap
def set_hardlink_option_enabled(self, enabled):
self.callback.setHardlinkOptionEnabled_(enabled)

View File

@@ -11,6 +11,9 @@ class PyDirectoryOutline(PyOutline):
def removeSelectedDirectory(self): def removeSelectedDirectory(self):
self.model.remove_selected() self.model.remove_selected()
def selectAll(self):
self.model.select_all()
# python --> cocoa # python --> cocoa
@dontwrap @dontwrap
def refresh_states(self): def refresh_states(self):

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -31,7 +31,7 @@ def configure(conf):
os.symlink('../build/Python', versioned_dylib_path) os.symlink('../build/Python', versioned_dylib_path)
# The rest is standard WAF code that you can find the the python and macapp demos. # The rest is standard WAF code that you can find the the python and macapp demos.
conf.load('compiler_c python') conf.load('compiler_c python')
conf.check_python_version((3,2,0)) conf.check_python_version((3,3,0))
conf.check_python_headers() conf.check_python_headers()
conf.env.FRAMEWORK_COCOA = 'Cocoa' conf.env.FRAMEWORK_COCOA = 'Cocoa'
conf.env.ARCH_COCOA = ['x86_64'] conf.env.ARCH_COCOA = ['x86_64']
@@ -44,7 +44,7 @@ def build(ctx):
cocoalib_node = ctx.srcnode.find_dir('..').find_dir('cocoalib') cocoalib_node = ctx.srcnode.find_dir('..').find_dir('cocoalib')
cocoalib_folders = ['controllers', 'views'] cocoalib_folders = ['controllers', 'views']
cocoalib_includes = [cocoalib_node] + [cocoalib_node.find_dir(folder) for folder in cocoalib_folders] cocoalib_includes = [cocoalib_node] + [cocoalib_node.find_dir(folder) for folder in cocoalib_folders]
cocoalib_uses = ['NSEventAdditions', 'Dialogs', 'HSFairwareAboutBox', 'HSFairwareReminder', 'Utils', cocoalib_uses = ['NSEventAdditions', 'Dialogs', 'HSAboutBox', 'Utils',
'HSPyUtil', 'ProgressController', 'HSRecentFiles', 'HSQuicklook', 'ValueTransformers', 'HSPyUtil', 'ProgressController', 'HSRecentFiles', 'HSQuicklook', 'ValueTransformers',
'NSImageAdditions', 'NSNotificationAdditions', 'NSImageAdditions', 'NSNotificationAdditions',
'views/HSTableView', 'views/HSOutlineView', 'views/NSIndexPathAdditions', 'views/HSTableView', 'views/HSOutlineView', 'views/NSIndexPathAdditions',

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2013 Hardcoded Software (http://www.hardcoded.net) Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at
@@ -14,8 +14,6 @@ http://www.hardcoded.net/licenses/bsd_license
NSTextField *titleTextField; NSTextField *titleTextField;
NSTextField *versionTextField; NSTextField *versionTextField;
NSTextField *copyrightTextField; NSTextField *copyrightTextField;
NSTextField *registeredTextField;
NSButton *registerButton;
PyBaseApp *app; PyBaseApp *app;
} }

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2013 Hardcoded Software (http://www.hardcoded.net) Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at
@@ -11,13 +11,16 @@ http://www.hardcoded.net/licenses/bsd_license
@interface HSErrorReportWindow : NSWindowController @interface HSErrorReportWindow : NSWindowController
{ {
NSTextView *contentTextView; NSTextView *contentTextView;
NSString *githubUrl;
} }
@property (readwrite, retain) NSTextView *contentTextView; @property (readwrite, retain) NSTextView *contentTextView;
@property (readwrite, retain) NSString *githubUrl;
+ (void)showErrorReportWithContent:(NSString *)content; // True if the user wants to send the report
- (id)initWithContent:(NSString *)content; + (void)showErrorReportWithContent:(NSString *)content githubUrl:(NSString *)githubUrl;
- (id)initWithContent:(NSString *)content githubUrl:(NSString *)githubUrl;
- (void)send; - (void)goToGithub;
- (void)dontSend; - (void)close;
@end @end

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2013 Hardcoded Software (http://www.hardcoded.net) Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
This software is licensed under the "BSD" License as described in the "LICENSE" file, This software is licensed under the "BSD" License as described in the "LICENSE" file,
which should be included with this package. The terms are also available at which should be included with this package. The terms are also available at
@@ -12,37 +12,33 @@ http://www.hardcoded.net/licenses/bsd_license
@implementation HSErrorReportWindow @implementation HSErrorReportWindow
@synthesize contentTextView; @synthesize contentTextView;
@synthesize githubUrl;
+ (void)showErrorReportWithContent:(NSString *)content + (void)showErrorReportWithContent:(NSString *)content githubUrl:(NSString *)githubUrl
{ {
HSErrorReportWindow *report = [[HSErrorReportWindow alloc] initWithContent:content]; HSErrorReportWindow *report = [[HSErrorReportWindow alloc] initWithContent:content githubUrl:githubUrl];
[NSApp runModalForWindow:[report window]]; [NSApp runModalForWindow:[report window]];
[report release]; [report release];
} }
- (id)initWithContent:(NSString *)content - (id)initWithContent:(NSString *)content githubUrl:(NSString *)aGithubUrl
{ {
self = [super initWithWindow:nil]; self = [super initWithWindow:nil];
[self setWindow:createHSErrorReportWindow_UI(self)]; [self setWindow:createHSErrorReportWindow_UI(self)];
[contentTextView alignLeft:nil]; [contentTextView alignLeft:nil];
[[[contentTextView textStorage] mutableString] setString:content]; [[[contentTextView textStorage] mutableString] setString:content];
self.githubUrl = aGithubUrl;
return self; return self;
} }
- (void)send - (void)goToGithub
{ {
NSString *text = [[contentTextView textStorage] string]; [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:self.githubUrl]];
NSString *URL = [NSString stringWithFormat:@"mailto:support@hardcoded.net?SUBJECT=Error Report&BODY=%@",text]; }
NSString *encodedURL = [URL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:encodedURL]];
- (void)close
{
[[self window] orderOut:self]; [[self window] orderOut:self];
[NSApp stopModalWithCode:NSOKButton]; [NSApp stopModalWithCode:NSOKButton];
} }
- (void)dontSend
{
[[self window] orderOut:self];
[NSApp stopModalWithCode:NSCancelButton];
}
@end @end

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -20,6 +20,7 @@
- (NSString *)bundleIdentifier; - (NSString *)bundleIdentifier;
- (NSString *)appVersion; - (NSString *)appVersion;
- (NSString *)osxVersion; - (NSString *)osxVersion;
- (NSString *)bundleInfo:(NSString *)key;
- (void)postNotification:(NSString *)name userInfo:(NSDictionary *)userInfo; - (void)postNotification:(NSString *)name userInfo:(NSDictionary *)userInfo;
- (id)prefValue:(NSString *)prefname; - (id)prefValue:(NSString *)prefname;
- (void)setPrefValue:(NSString *)prefname value:(id)value; - (void)setPrefValue:(NSString *)prefname value:(id)value;
@@ -27,6 +28,7 @@
- (NSString *)url2path:(NSString *)url; - (NSString *)url2path:(NSString *)url;
- (void)createPool; - (void)createPool;
- (void)destroyPool; - (void)destroyPool;
- (void)reportCrash:(NSString *)crashReport; - (void)reportCrash:(NSString *)crashReport withGithubUrl:(NSString *)githubUrl;
- (void)log:(NSString *)s; - (void)log:(NSString *)s;
- (NSDictionary *)readExifData:(NSString *)imagePath;
@end @end

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