From b47b1e11af7e893114aa5e9d5657ad3e73c4261b Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Mon, 6 Jun 2016 11:20:45 -0400 Subject: [PATCH] cocoa: remove inter.app_se The last remnant of the pre-merge era. --- build.py | 7 +-- cocoa/dg_cocoa.py | 2 +- cocoa/inter/app.py | 37 ++++++++++- cocoa/inter/app_se.py | 124 ------------------------------------- cocoa/inter/directories.py | 53 ++++++++++++++++ cocoa/inter/photo.py | 35 +++++++++++ 6 files changed, 126 insertions(+), 132 deletions(-) delete mode 100644 cocoa/inter/app_se.py create mode 100644 cocoa/inter/directories.py create mode 100644 cocoa/inter/photo.py diff --git a/build.py b/build.py index 2b34668e..e716c39a 100644 --- a/build.py +++ b/build.py @@ -277,13 +277,12 @@ def build_cocoa_bridging_interfaces(): from inter.ignore_list_dialog import PyIgnoreListDialog, IgnoreListDialogView from inter.result_table import PyResultTable, ResultTableView from inter.stats_label import PyStatsLabel, StatsLabelView - from inter.app import PyDupeGuruBase, DupeGuruView - appmod = importlib.import_module('inter.app_se') + from inter.app import PyDupeGuru, DupeGuruView allclasses = [ PyGUIObject, PyColumns, PyOutline, PySelectableList, PyTable, PyBaseApp, PyDetailsPanel, PyDirectoryOutline, PyPrioritizeDialog, PyPrioritizeList, PyProblemDialog, - PyIgnoreListDialog, PyDeletionOptions, PyResultTable, PyStatsLabel, PyDupeGuruBase, - PyTextField, PyProgressWindow, appmod.PyDupeGuru + PyIgnoreListDialog, PyDeletionOptions, PyResultTable, PyStatsLabel, PyDupeGuru, + PyTextField, PyProgressWindow ] for class_ in allclasses: objp.o2p.generate_objc_code(class_, 'cocoa/autogen', inherit=True) diff --git a/cocoa/dg_cocoa.py b/cocoa/dg_cocoa.py index 19567eab..312d9e2c 100644 --- a/cocoa/dg_cocoa.py +++ b/cocoa/dg_cocoa.py @@ -10,7 +10,7 @@ install_gettext_trans_under_cocoa() from cocoa.inter import PySelectableList, PyColumns, PyTable from inter.all import * -from inter.app_se import PyDupeGuru +from inter.app import PyDupeGuru # When built under virtualenv, the dependency collector misses this module, so we have to force it # to see the module. diff --git a/cocoa/inter/app.py b/cocoa/inter/app.py index 2efd47c9..280ecd1f 100644 --- a/cocoa/inter/app.py +++ b/cocoa/inter/app.py @@ -1,9 +1,39 @@ import logging from objp.util import pyref, dontwrap +from hscommon.path import Path, pathify from cocoa import install_exception_hook, install_cocoa_logger, patch_threaded_job_performer from cocoa.inter import PyBaseApp, BaseAppView +import core.pe.photo +from core.app import DupeGuru as DupeGuruBase, AppMode +from .directories import Directories, Bundle +from .photo import Photo + +class DupeGuru(DupeGuruBase): + def __init__(self, view): + DupeGuruBase.__init__(self, view) + self.directories = Directories() + + 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 + if ref is self.selected_dupes[0]: # we don't want the same pic to be displayed on both sides + return None + return ref.path + + def _get_fileclasses(self): + result = DupeGuruBase._get_fileclasses(self) + if self.app_mode == AppMode.Standard: + result = [Bundle] + result + return result + class DupeGuruView(BaseAppView): def askYesNoWithPrompt_(self, prompt: str) -> bool: pass def createResultsWindow(self): pass @@ -12,14 +42,15 @@ class DupeGuruView(BaseAppView): def selectDestFolderWithPrompt_(self, prompt: str) -> str: pass def selectDestFileWithPrompt_extension_(self, prompt: str, extension: str) -> str: pass -class PyDupeGuruBase(PyBaseApp): +class PyDupeGuru(PyBaseApp): @dontwrap - def _init(self, modelclass): + def __init__(self): + core.pe.photo.PLAT_SPECIFIC_PHOTO_CLASS = Photo logging.basicConfig(level=logging.WARNING, format='%(levelname)s %(message)s') install_exception_hook('https://github.com/hsoft/dupeguru/issues') install_cocoa_logger() patch_threaded_job_performer() - self.model = modelclass(self) + self.model = DupeGuru(self) #---Sub-proxies def detailsPanel(self) -> pyref: diff --git a/cocoa/inter/app_se.py b/cocoa/inter/app_se.py deleted file mode 100644 index c4bd2385..00000000 --- a/cocoa/inter/app_se.py +++ /dev/null @@ -1,124 +0,0 @@ -# Created By: Virgil Dupras -# Created On: 2009-05-24 -# Copyright 2015 Hardcoded Software (http://www.hardcoded.net) -# -# This software is licensed under the "GPLv3" License as described in the "LICENSE" file, -# which should be included with this package. The terms are also available at -# http://www.gnu.org/licenses/gpl-3.0.html - -import logging -import os.path as op - -from hscommon.path import Path, pathify -from cocoa import proxy - -from core.directories import Directories as DirectoriesBase, DirectoryState -import core.pe.photo -from core.pe import _block_osx -from core.pe.photo import Photo as PhotoBase -from core.app import DupeGuru as DupeGuruBase, AppMode -from core.se import fs -from .app import PyDupeGuruBase - -def is_bundle(str_path): - uti = proxy.getUTI_(str_path) - if uti is None: - logging.warning('There was an error trying to detect the UTI of %s', str_path) - return proxy.type_conformsToType_(uti, 'com.apple.bundle') or proxy.type_conformsToType_(uti, 'com.apple.package') - -class Bundle(fs.Folder): - @classmethod - @pathify - def can_handle(cls, path: Path): - return not path.islink() and path.isdir() and is_bundle(str(path)) - - -class Photo(PhotoBase): - HANDLED_EXTS = PhotoBase.HANDLED_EXTS.copy() - HANDLED_EXTS.update({'psd', 'nef', 'cr2', 'orf'}) - - def _plat_get_dimensions(self): - return _block_osx.get_image_size(str(self.path)) - - def _plat_get_blocks(self, block_count_per_side, orientation): - try: - blocks = _block_osx.getblocks(str(self.path), block_count_per_side, orientation) - except Exception as e: - raise IOError('The reading of "%s" failed with "%s"' % (str(self.path), str(e))) - if not blocks: - raise IOError('The picture %s could not be read' % str(self.path)) - return blocks - - def _get_exif_timestamp(self): - exifdata = proxy.readExifData_(str(self.path)) - if exifdata: - try: - return exifdata['{Exif}']['DateTimeOriginal'] - except KeyError: - return '' - else: - return '' - - -class Directories(DirectoriesBase): - ROOT_PATH_TO_EXCLUDE = list(map(Path, ['/Library', '/Volumes', '/System', '/bin', '/sbin', '/opt', '/private', '/dev'])) - HOME_PATH_TO_EXCLUDE = [Path('Library')] - - def _default_state_for_path(self, path): - result = DirectoriesBase._default_state_for_path(self, path) - if result is not None: - return result - if path in self.ROOT_PATH_TO_EXCLUDE: - return DirectoryState.Excluded - if path[:2] == Path('/Users') and path[3:] in self.HOME_PATH_TO_EXCLUDE: - return DirectoryState.Excluded - - def _get_folders(self, from_folder, j): - # We don't want to scan bundle's subfolder even in Folders mode. Bundle's integrity has to - # stay intact. - if is_bundle(str(from_folder.path)): - # just yield the current folder and bail - state = self.get_state(from_folder.path) - if state != DirectoryState.Excluded: - from_folder.is_ref = state == DirectoryState.Reference - yield from_folder - return - else: - yield from DirectoriesBase._get_folders(self, from_folder, j) - - @staticmethod - def get_subfolders(path): - result = DirectoriesBase.get_subfolders(path) - return [p for p in result if not is_bundle(str(p))] - - -class DupeGuru(DupeGuruBase): - def __init__(self, view): - DupeGuruBase.__init__(self, view) - self.directories = Directories() - - 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 - if ref is self.selected_dupes[0]: # we don't want the same pic to be displayed on both sides - return None - return ref.path - - def _get_fileclasses(self): - result = DupeGuruBase._get_fileclasses(self) - if self.app_mode == AppMode.Standard: - result = [Bundle] + result - return result - -class PyDupeGuru(PyDupeGuruBase): - def __init__(self): - core.pe.photo.PLAT_SPECIFIC_PHOTO_CLASS = Photo - self._init(DupeGuru) - - diff --git a/cocoa/inter/directories.py b/cocoa/inter/directories.py new file mode 100644 index 00000000..2b316059 --- /dev/null +++ b/cocoa/inter/directories.py @@ -0,0 +1,53 @@ +# Copyright 2016 Hardcoded Software (http://www.hardcoded.net) +# +# This software is licensed under the "GPLv3" License as described in the "LICENSE" file, +# which should be included with this package. The terms are also available at +# http://www.gnu.org/licenses/gpl-3.0.html + +from cocoa import proxy +from hscommon.path import Path, pathify +from core.se import fs +from core.directories import Directories as DirectoriesBase, DirectoryState + +def is_bundle(str_path): + uti = proxy.getUTI_(str_path) + if uti is None: + logging.warning('There was an error trying to detect the UTI of %s', str_path) + return proxy.type_conformsToType_(uti, 'com.apple.bundle') or proxy.type_conformsToType_(uti, 'com.apple.package') + +class Bundle(fs.Folder): + @classmethod + @pathify + def can_handle(cls, path: Path): + return not path.islink() and path.isdir() and is_bundle(str(path)) + +class Directories(DirectoriesBase): + ROOT_PATH_TO_EXCLUDE = list(map(Path, ['/Library', '/Volumes', '/System', '/bin', '/sbin', '/opt', '/private', '/dev'])) + HOME_PATH_TO_EXCLUDE = [Path('Library')] + + def _default_state_for_path(self, path): + result = DirectoriesBase._default_state_for_path(self, path) + if result is not None: + return result + if path in self.ROOT_PATH_TO_EXCLUDE: + return DirectoryState.Excluded + if path[:2] == Path('/Users') and path[3:] in self.HOME_PATH_TO_EXCLUDE: + return DirectoryState.Excluded + + def _get_folders(self, from_folder, j): + # We don't want to scan bundle's subfolder even in Folders mode. Bundle's integrity has to + # stay intact. + if is_bundle(str(from_folder.path)): + # just yield the current folder and bail + state = self.get_state(from_folder.path) + if state != DirectoryState.Excluded: + from_folder.is_ref = state == DirectoryState.Reference + yield from_folder + return + else: + yield from DirectoriesBase._get_folders(self, from_folder, j) + + @staticmethod + def get_subfolders(path): + result = DirectoriesBase.get_subfolders(path) + return [p for p in result if not is_bundle(str(p))] diff --git a/cocoa/inter/photo.py b/cocoa/inter/photo.py new file mode 100644 index 00000000..3e52c8aa --- /dev/null +++ b/cocoa/inter/photo.py @@ -0,0 +1,35 @@ +# Copyright 2016 Hardcoded Software (http://www.hardcoded.net) +# +# This software is licensed under the "GPLv3" License as described in the "LICENSE" file, +# which should be included with this package. The terms are also available at +# http://www.gnu.org/licenses/gpl-3.0.html + +from cocoa import proxy +from core.pe import _block_osx +from core.pe.photo import Photo as PhotoBase + +class Photo(PhotoBase): + HANDLED_EXTS = PhotoBase.HANDLED_EXTS.copy() + HANDLED_EXTS.update({'psd', 'nef', 'cr2', 'orf'}) + + def _plat_get_dimensions(self): + return _block_osx.get_image_size(str(self.path)) + + def _plat_get_blocks(self, block_count_per_side, orientation): + try: + blocks = _block_osx.getblocks(str(self.path), block_count_per_side, orientation) + except Exception as e: + raise IOError('The reading of "%s" failed with "%s"' % (str(self.path), str(e))) + if not blocks: + raise IOError('The picture %s could not be read' % str(self.path)) + return blocks + + def _get_exif_timestamp(self): + exifdata = proxy.readExifData_(str(self.path)) + if exifdata: + try: + return exifdata['{Exif}']['DateTimeOriginal'] + except KeyError: + return '' + else: + return '' \ No newline at end of file