2016-06-02 02:34:16 +00:00
|
|
|
# Copyright 2016 Hardcoded Software (http://www.hardcoded.net)
|
2009-08-05 08:59:46 +00:00
|
|
|
#
|
2015-01-03 21:33:16 +00:00
|
|
|
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
2009-08-05 08:59:46 +00:00
|
|
|
# which should be included with this package. The terms are also available at
|
2015-01-03 21:33:16 +00:00
|
|
|
# http://www.gnu.org/licenses/gpl-3.0.html
|
2009-06-18 19:42:27 +00:00
|
|
|
|
2012-01-05 21:57:31 +00:00
|
|
|
from cocoa import proxy
|
2009-06-01 09:55:11 +00:00
|
|
|
|
2012-01-16 15:30:45 +00:00
|
|
|
from core.scanner import ScanType
|
2011-09-21 20:02:13 +00:00
|
|
|
from core_pe import _block_osx
|
|
|
|
from core_pe.photo import Photo as PhotoBase
|
|
|
|
from core_pe.app import DupeGuru as DupeGuruBase
|
2012-01-16 15:30:45 +00:00
|
|
|
from .app import PyDupeGuruBase
|
2009-06-01 09:55:11 +00:00
|
|
|
|
2010-12-31 11:10:44 +00:00
|
|
|
|
2011-05-29 14:18:03 +00:00
|
|
|
class Photo(PhotoBase):
|
|
|
|
HANDLED_EXTS = PhotoBase.HANDLED_EXTS.copy()
|
2011-06-14 17:54:50 +00:00
|
|
|
HANDLED_EXTS.update({'psd', 'nef', 'cr2', 'orf'})
|
2009-06-01 09:55:11 +00:00
|
|
|
|
2011-05-31 14:05:12 +00:00
|
|
|
def _plat_get_dimensions(self):
|
|
|
|
return _block_osx.get_image_size(str(self.path))
|
2009-06-01 09:55:11 +00:00
|
|
|
|
2011-05-31 14:05:12 +00:00
|
|
|
def _plat_get_blocks(self, block_count_per_side, orientation):
|
2009-06-01 09:55:11 +00:00
|
|
|
try:
|
2011-05-31 14:05:12 +00:00
|
|
|
blocks = _block_osx.getblocks(str(self.path), block_count_per_side, orientation)
|
2009-10-24 12:21:39 +00:00
|
|
|
except Exception as e:
|
2010-08-11 14:39:06 +00:00
|
|
|
raise IOError('The reading of "%s" failed with "%s"' % (str(self.path), str(e)))
|
2009-06-01 09:55:11 +00:00
|
|
|
if not blocks:
|
2010-08-11 14:39:06 +00:00
|
|
|
raise IOError('The picture %s could not be read' % str(self.path))
|
2010-02-04 12:13:08 +00:00
|
|
|
return blocks
|
2009-06-01 09:55:11 +00:00
|
|
|
|
2013-11-10 17:00:16 +00:00
|
|
|
def _get_exif_timestamp(self):
|
|
|
|
exifdata = proxy.readExifData_(str(self.path))
|
|
|
|
if exifdata:
|
|
|
|
try:
|
|
|
|
return exifdata['{Exif}']['DateTimeOriginal']
|
|
|
|
except KeyError:
|
|
|
|
return ''
|
|
|
|
else:
|
|
|
|
return ''
|
2012-06-05 17:56:28 +00:00
|
|
|
|
2009-06-01 09:55:11 +00:00
|
|
|
|
2011-09-20 22:40:27 +00:00
|
|
|
class DupeGuruPE(DupeGuruBase):
|
2013-11-10 16:05:03 +00:00
|
|
|
def __init__(self, view):
|
|
|
|
DupeGuruBase.__init__(self, view)
|
2016-06-02 01:56:18 +00:00
|
|
|
self.fileclasses = [Photo]
|
2016-06-02 02:34:16 +00:00
|
|
|
|
2009-06-01 09:55:11 +00:00
|
|
|
def selected_dupe_path(self):
|
|
|
|
if not self.selected_dupes:
|
|
|
|
return None
|
|
|
|
return self.selected_dupes[0].path
|
|
|
|
|
|
|
|
def selected_dupe_ref_path(self):
|
|
|
|
if not self.selected_dupes:
|
|
|
|
return None
|
|
|
|
ref = self.results.get_group_of_duplicate(self.selected_dupes[0]).ref
|
2009-10-25 11:46:26 +00:00
|
|
|
if ref is self.selected_dupes[0]: # we don't want the same pic to be displayed on both sides
|
|
|
|
return None
|
2009-06-01 09:55:11 +00:00
|
|
|
return ref.path
|
2016-06-02 02:34:16 +00:00
|
|
|
|
|
|
|
|
2012-01-16 15:30:45 +00:00
|
|
|
class PyDupeGuru(PyDupeGuruBase):
|
|
|
|
def __init__(self):
|
|
|
|
self._init(DupeGuruPE)
|
|
|
|
|
|
|
|
def clearPictureCache(self):
|
2016-06-02 01:56:18 +00:00
|
|
|
self.model.clear_picture_cache()
|
2012-01-16 15:30:45 +00:00
|
|
|
|
|
|
|
#---Information
|
|
|
|
def getSelectedDupePath(self) -> str:
|
|
|
|
return str(self.model.selected_dupe_path())
|
|
|
|
|
|
|
|
def getSelectedDupeRefPath(self) -> str:
|
|
|
|
return str(self.model.selected_dupe_ref_path())
|
|
|
|
|
|
|
|
#---Properties
|
|
|
|
def setScanType_(self, scan_type: int):
|
|
|
|
try:
|
2016-06-02 01:56:18 +00:00
|
|
|
self.model.options['scan_type'] = [
|
2012-01-16 15:30:45 +00:00
|
|
|
ScanType.FuzzyBlock,
|
|
|
|
ScanType.ExifTimestamp,
|
|
|
|
][scan_type]
|
|
|
|
except IndexError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
def setMatchScaled_(self, match_scaled: bool):
|
2016-06-02 01:56:18 +00:00
|
|
|
self.model.options['match_scaled'] = match_scaled
|
2012-01-16 15:30:45 +00:00
|
|
|
|
|
|
|
def setMinMatchPercentage_(self, percentage: int):
|
2016-06-02 01:56:18 +00:00
|
|
|
self.model.options['threshold'] = percentage
|