mirror of
https://github.com/arsenetar/dupeguru.git
synced 2025-03-10 05:34:36 +00:00
Replaced dependencies from hsutil to hscommon.
This commit is contained in:
parent
33c0ba808c
commit
eefe464fba
1
README
1
README
@ -26,7 +26,6 @@ General dependencies
|
||||
|
||||
- Python 3.1 (http://www.python.org)
|
||||
- Send2Trash3k (http://hg.hardcoded.net/send2trash)
|
||||
- hsutil3k (http://hg.hardcoded.net/hsutil)
|
||||
- hsaudiotag3k 1.1.0 (for ME) (http://hg.hardcoded.net/hsaudiotag)
|
||||
- jobprogress (http://hg.hardcoded.net/jobprogress)
|
||||
- Markdown, to generate help files. (http://pypi.python.org/pypi/Markdown)
|
||||
|
@ -15,7 +15,7 @@ import core_me.app_cocoa, core_me.data, core_me.fs, core_me.scanner
|
||||
import hsaudiotag.aiff, hsaudiotag.flac, hsaudiotag.genres, hsaudiotag.id3v1,\
|
||||
hsaudiotag.id3v2, hsaudiotag.mp4, hsaudiotag.mpeg, hsaudiotag.ogg, hsaudiotag.wma
|
||||
from hsaudiotag import aiff, flac, genres, id3v1, id3v2, mp4, mpeg, ogg, wma
|
||||
import hsutil.conflict
|
||||
import hscommon.conflict
|
||||
import core.engine, core.fs, core.app
|
||||
import xml.etree.ElementPath
|
||||
import gzip
|
||||
|
@ -8,7 +8,7 @@ from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel
|
||||
from core_pe import app_cocoa as app_pe_cocoa
|
||||
|
||||
# Fix py2app imports which chokes on relative imports and other stuff
|
||||
import hsutil.conflict
|
||||
import hscommon.conflict
|
||||
import core.engine, core.fs, core.app
|
||||
import core_pe.block, core_pe.cache, core_pe.matchbase, core_pe.data, core_pe._block_osx
|
||||
import xml.etree.ElementPath
|
||||
|
@ -11,7 +11,7 @@ from core.app_cocoa_inter import PyDupeGuruBase, PyDetailsPanel
|
||||
from core_se.app_cocoa import DupeGuru
|
||||
|
||||
# Fix py2app imports with chokes on relative imports and other stuff
|
||||
import hsutil.conflict
|
||||
import hscommon.conflict
|
||||
import core.engine, core.fs, core.app
|
||||
import core_se.fs, core_se.data
|
||||
import xml.etree.ElementPath
|
||||
|
13
core/app.py
13
core/app.py
@ -17,9 +17,8 @@ from hscommon import io
|
||||
from hscommon.reg import RegistrableApplication
|
||||
from hscommon.notify import Broadcaster
|
||||
from hscommon.path import Path
|
||||
from hsutil import files
|
||||
from hsutil.misc import flatten, first
|
||||
from hsutil.str import escape
|
||||
from hscommon.conflict import smart_move, smart_copy
|
||||
from hscommon.util import delete_if_empty, first, escape
|
||||
|
||||
from . import directories, results, scanner, export, fs
|
||||
|
||||
@ -156,14 +155,14 @@ class DupeGuru(RegistrableApplication, Broadcaster):
|
||||
def apply_filter(self, filter):
|
||||
self.results.apply_filter(None)
|
||||
if self.options['escape_filter_regexp']:
|
||||
filter = escape(filter, '()[]\\.|+?^')
|
||||
filter = escape(filter, set('()[]\\.|+?^'))
|
||||
filter = escape(filter, '*', '.')
|
||||
self.results.apply_filter(filter)
|
||||
self.notify('results_changed')
|
||||
|
||||
def clean_empty_dirs(self, path):
|
||||
if self.options['clean_empty_dirs']:
|
||||
while files.delete_if_empty(path, ['.DS_Store']):
|
||||
while delete_if_empty(path, ['.DS_Store']):
|
||||
path = path[:-1]
|
||||
|
||||
def copy_or_move(self, dupe, copy, destination, dest_type):
|
||||
@ -185,9 +184,9 @@ class DupeGuru(RegistrableApplication, Broadcaster):
|
||||
io.makedirs(dest_path)
|
||||
# Raises an EnvironmentError if there's a problem
|
||||
if copy:
|
||||
files.copy(source_path, dest_path)
|
||||
smart_copy(source_path, dest_path)
|
||||
else:
|
||||
files.move(source_path, dest_path)
|
||||
smart_move(source_path, dest_path)
|
||||
self.clean_empty_dirs(source_path[:-1])
|
||||
|
||||
def copy_or_move_marked(self, copy, destination, recreate_path):
|
||||
|
@ -20,7 +20,7 @@ from .gui.stats_label import StatsLabel
|
||||
|
||||
# Fix py2app's problems on relative imports
|
||||
from core import app, app_cocoa, data, directories, engine, export, ignore, results, fs, scanner
|
||||
from hsutil import conflict
|
||||
from hscommon import conflict
|
||||
|
||||
class PyDupeGuruBase(PyFairware):
|
||||
#---Directories
|
||||
|
@ -6,7 +6,7 @@
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/bsd_license
|
||||
|
||||
from hsutil.str import format_time, FT_DECIMAL, format_size
|
||||
from hscommon.util import format_time_decimal, format_size
|
||||
|
||||
import time
|
||||
|
||||
@ -15,7 +15,7 @@ def format_path(p):
|
||||
|
||||
def format_timestamp(t, delta):
|
||||
if delta:
|
||||
return format_time(t, FT_DECIMAL)
|
||||
return format_time_decimal(t)
|
||||
else:
|
||||
if t > 0:
|
||||
return time.strftime('%Y/%m/%d %H:%M:%S', time.localtime(t))
|
||||
|
@ -10,7 +10,7 @@ from xml.etree import ElementTree as ET
|
||||
|
||||
from hscommon import io
|
||||
from hscommon.path import Path
|
||||
from hsutil.files import FileOrPath
|
||||
from hscommon.util import FileOrPath
|
||||
|
||||
from . import fs
|
||||
|
||||
|
@ -14,8 +14,7 @@ import string
|
||||
from collections import defaultdict, namedtuple
|
||||
from unicodedata import normalize
|
||||
|
||||
from hsutil.misc import flatten
|
||||
from hsutil.str import multi_replace
|
||||
from hscommon.util import flatten, multi_replace
|
||||
from jobprogress import job
|
||||
|
||||
(WEIGHT_WORDS,
|
||||
|
@ -15,8 +15,7 @@ import hashlib
|
||||
import logging
|
||||
|
||||
from hscommon import io
|
||||
from hsutil.misc import nonone, flatten
|
||||
from hsutil.str import get_file_ext
|
||||
from hscommon.util import nonone, flatten, get_file_ext
|
||||
|
||||
class FSError(Exception):
|
||||
cls_message = "An error has occured on '{name}' in '{parent}'"
|
||||
|
@ -8,9 +8,9 @@
|
||||
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
from hsutil.files import FileOrPath
|
||||
from hscommon.util import FileOrPath
|
||||
|
||||
class IgnoreList(object):
|
||||
class IgnoreList:
|
||||
"""An ignore list implementation that is iterable, filterable and exportable to XML.
|
||||
|
||||
Call Ignore to add an ignore list entry, and AreIgnore to check if 2 items are in the list.
|
||||
|
@ -13,9 +13,7 @@ from xml.etree import ElementTree as ET
|
||||
from . import engine
|
||||
from jobprogress.job import nulljob
|
||||
from hscommon.markable import Markable
|
||||
from hsutil.misc import flatten, nonone
|
||||
from hsutil.str import format_size
|
||||
from hsutil.files import FileOrPath
|
||||
from hscommon.util import flatten, nonone, FileOrPath, format_size
|
||||
|
||||
class Results(Markable):
|
||||
#---Override
|
||||
|
@ -11,8 +11,7 @@ import re
|
||||
|
||||
from jobprogress import job
|
||||
from hscommon import io
|
||||
from hsutil.misc import dedupe
|
||||
from hsutil.str import get_file_ext, rem_file_ext
|
||||
from hscommon.util import dedupe, rem_file_ext, get_file_ext
|
||||
|
||||
from . import engine
|
||||
from .ignore import IgnoreList
|
||||
|
@ -13,9 +13,9 @@ import logging
|
||||
from pytest import mark
|
||||
from hscommon import io
|
||||
from hscommon.path import Path
|
||||
from hsutil.decorators import log_calls
|
||||
import hsutil.files
|
||||
from hscommon.testutil import CallLogger, eq_
|
||||
import hscommon.conflict
|
||||
import hscommon.util
|
||||
from hscommon.testutil import CallLogger, eq_, log_calls
|
||||
from jobprogress.job import nulljob, Job, JobCancelled
|
||||
|
||||
from . import data
|
||||
@ -46,27 +46,27 @@ def add_fake_files_to_directories(directories, files):
|
||||
|
||||
class TestCaseDupeGuru:
|
||||
def test_apply_filter_calls_results_apply_filter(self, monkeypatch):
|
||||
app = DupeGuru()
|
||||
monkeypatch.setattr(app.results, 'apply_filter', log_calls(app.results.apply_filter))
|
||||
app.apply_filter('foo')
|
||||
eq_(2, len(app.results.apply_filter.calls))
|
||||
call = app.results.apply_filter.calls[0]
|
||||
dgapp = DupeGuru()
|
||||
monkeypatch.setattr(dgapp.results, 'apply_filter', log_calls(dgapp.results.apply_filter))
|
||||
dgapp.apply_filter('foo')
|
||||
eq_(2, len(dgapp.results.apply_filter.calls))
|
||||
call = dgapp.results.apply_filter.calls[0]
|
||||
assert call['filter_str'] is None
|
||||
call = app.results.apply_filter.calls[1]
|
||||
call = dgapp.results.apply_filter.calls[1]
|
||||
eq_('foo', call['filter_str'])
|
||||
|
||||
def test_apply_filter_escapes_regexp(self, monkeypatch):
|
||||
app = DupeGuru()
|
||||
monkeypatch.setattr(app.results, 'apply_filter', log_calls(app.results.apply_filter))
|
||||
app.apply_filter('()[]\\.|+?^abc')
|
||||
call = app.results.apply_filter.calls[1]
|
||||
dgapp = DupeGuru()
|
||||
monkeypatch.setattr(dgapp.results, 'apply_filter', log_calls(dgapp.results.apply_filter))
|
||||
dgapp.apply_filter('()[]\\.|+?^abc')
|
||||
call = dgapp.results.apply_filter.calls[1]
|
||||
eq_('\\(\\)\\[\\]\\\\\\.\\|\\+\\?\\^abc', call['filter_str'])
|
||||
app.apply_filter('(*)') # In "simple mode", we want the * to behave as a wilcard
|
||||
call = app.results.apply_filter.calls[3]
|
||||
dgapp.apply_filter('(*)') # In "simple mode", we want the * to behave as a wilcard
|
||||
call = dgapp.results.apply_filter.calls[3]
|
||||
eq_('\(.*\)', call['filter_str'])
|
||||
app.options['escape_filter_regexp'] = False
|
||||
app.apply_filter('(abc)')
|
||||
call = app.results.apply_filter.calls[5]
|
||||
dgapp.options['escape_filter_regexp'] = False
|
||||
dgapp.apply_filter('(abc)')
|
||||
call = dgapp.results.apply_filter.calls[5]
|
||||
eq_('(abc)', call['filter_str'])
|
||||
|
||||
def test_copy_or_move(self, tmpdir, monkeypatch):
|
||||
@ -75,14 +75,16 @@ class TestCaseDupeGuru:
|
||||
# every change I want to make. The blowup was caused by a missing import.
|
||||
p = Path(str(tmpdir))
|
||||
io.open(p + 'foo', 'w').close()
|
||||
monkeypatch.setattr(hsutil.files, 'copy', log_calls(lambda source_path, dest_path: None))
|
||||
monkeypatch.setattr(hscommon.conflict, 'smart_copy', log_calls(lambda source_path, dest_path: None))
|
||||
# XXX This monkeypatch is temporary. will be fixed in a better monkeypatcher.
|
||||
monkeypatch.setattr(app, 'smart_copy', hscommon.conflict.smart_copy)
|
||||
monkeypatch.setattr(os, 'makedirs', lambda path: None) # We don't want the test to create that fake directory
|
||||
app = DupeGuru()
|
||||
app.directories.add_path(p)
|
||||
[f] = app.directories.get_files()
|
||||
app.copy_or_move(f, True, 'some_destination', 0)
|
||||
eq_(1, len(hsutil.files.copy.calls))
|
||||
call = hsutil.files.copy.calls[0]
|
||||
dgapp = DupeGuru()
|
||||
dgapp.directories.add_path(p)
|
||||
[f] = dgapp.directories.get_files()
|
||||
dgapp.copy_or_move(f, True, 'some_destination', 0)
|
||||
eq_(1, len(hscommon.conflict.smart_copy.calls))
|
||||
call = hscommon.conflict.smart_copy.calls[0]
|
||||
eq_('some_destination', call['dest_path'])
|
||||
eq_(f.path, call['source_path'])
|
||||
|
||||
@ -132,17 +134,19 @@ class TestCaseDupeGuru:
|
||||
class TestCaseDupeGuru_clean_empty_dirs:
|
||||
def pytest_funcarg__do_setup(self, request):
|
||||
monkeypatch = request.getfuncargvalue('monkeypatch')
|
||||
monkeypatch.setattr(hsutil.files, 'delete_if_empty', log_calls(lambda path, files_to_delete=[]: None))
|
||||
monkeypatch.setattr(hscommon.util, 'delete_if_empty', log_calls(lambda path, files_to_delete=[]: None))
|
||||
# XXX This monkeypatch is temporary. will be fixed in a better monkeypatcher.
|
||||
monkeypatch.setattr(app, 'delete_if_empty', hscommon.util.delete_if_empty)
|
||||
self.app = DupeGuru()
|
||||
|
||||
def test_option_off(self, do_setup):
|
||||
self.app.clean_empty_dirs(Path('/foo/bar'))
|
||||
eq_(0, len(hsutil.files.delete_if_empty.calls))
|
||||
eq_(0, len(hscommon.util.delete_if_empty.calls))
|
||||
|
||||
def test_option_on(self, do_setup):
|
||||
self.app.options['clean_empty_dirs'] = True
|
||||
self.app.clean_empty_dirs(Path('/foo/bar'))
|
||||
calls = hsutil.files.delete_if_empty.calls
|
||||
calls = hscommon.util.delete_if_empty.calls
|
||||
eq_(1, len(calls))
|
||||
eq_(Path('/foo/bar'), calls[0]['path'])
|
||||
eq_(['.DS_Store'], calls[0]['files_to_delete'])
|
||||
@ -153,10 +157,12 @@ class TestCaseDupeGuru_clean_empty_dirs:
|
||||
def mock_delete_if_empty(path, files_to_delete=[]):
|
||||
return len(path) > 1
|
||||
|
||||
monkeypatch.setattr(hsutil.files, 'delete_if_empty', mock_delete_if_empty)
|
||||
monkeypatch.setattr(hscommon.util, 'delete_if_empty', mock_delete_if_empty)
|
||||
# XXX This monkeypatch is temporary. will be fixed in a better monkeypatcher.
|
||||
monkeypatch.setattr(app, 'delete_if_empty', mock_delete_if_empty)
|
||||
self.app.options['clean_empty_dirs'] = True
|
||||
self.app.clean_empty_dirs(Path('not-empty/empty/empty'))
|
||||
calls = hsutil.files.delete_if_empty.calls
|
||||
calls = hscommon.util.delete_if_empty.calls
|
||||
eq_(3, len(calls))
|
||||
eq_(Path('not-empty/empty/empty'), calls[0]['path'])
|
||||
eq_(Path('not-empty/empty'), calls[1]['path'])
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
# data module for tests
|
||||
|
||||
from hsutil.str import format_size
|
||||
from hscommon.util import format_size
|
||||
from ..data import format_path, cmp_value
|
||||
|
||||
COLUMNS = [
|
||||
|
@ -9,9 +9,8 @@
|
||||
import sys
|
||||
|
||||
from jobprogress import job
|
||||
from hsutil.decorators import log_calls
|
||||
from hsutil.misc import first
|
||||
from hscommon.testutil import eq_
|
||||
from hscommon.util import first
|
||||
from hscommon.testutil import eq_, log_calls
|
||||
|
||||
from .. import engine
|
||||
from ..engine import *
|
||||
|
@ -14,7 +14,7 @@ from xml.etree import ElementTree as ET
|
||||
|
||||
from hscommon.path import Path
|
||||
from hscommon.testutil import eq_
|
||||
from hsutil.misc import first
|
||||
from hscommon.util import first
|
||||
|
||||
from . import engine_test, data
|
||||
from .. import engine
|
||||
|
@ -6,7 +6,7 @@
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/bsd_license
|
||||
|
||||
from hsutil.str import format_time, FT_MINUTES, format_size
|
||||
from hscommon.util import format_time, format_size
|
||||
from core.data import (format_path, format_timestamp, format_words, format_perc,
|
||||
format_dupe_count, cmp_value)
|
||||
|
||||
@ -61,7 +61,7 @@ def GetDisplayInfo(dupe, group, delta):
|
||||
dupe.name,
|
||||
format_path(dupe.path),
|
||||
format_size(size, 2, 2, False),
|
||||
format_time(duration, FT_MINUTES),
|
||||
format_time(duration, with_hours=False),
|
||||
str(bitrate),
|
||||
str(samplerate),
|
||||
dupe.extension,
|
||||
|
@ -7,7 +7,7 @@
|
||||
# http://www.hardcoded.net/licenses/bsd_license
|
||||
|
||||
from hsaudiotag import auto
|
||||
from hsutil.str import get_file_ext
|
||||
from hscommon.util import get_file_ext
|
||||
from core import fs
|
||||
|
||||
TAG_FIELDS = {'audiosize', 'duration', 'bitrate', 'samplerate', 'title', 'artist',
|
||||
|
@ -14,7 +14,7 @@ import re
|
||||
from appscript import app, k, CommandError, ApplicationNotFoundError
|
||||
|
||||
from hscommon import io
|
||||
from hsutil.str import get_file_ext, remove_invalid_xml
|
||||
from hscommon.util import get_file_ext, remove_invalid_xml
|
||||
from hscommon.path import Path
|
||||
from hscommon.cocoa import as_fetch
|
||||
from hscommon.cocoa.objcmin import NSUserDefaults, NSURL
|
||||
|
@ -6,7 +6,7 @@
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/bsd_license
|
||||
|
||||
from hsutil.str import format_size
|
||||
from hscommon.util import format_size
|
||||
from core.data import format_path, format_timestamp, format_perc, format_dupe_count, cmp_value
|
||||
|
||||
def format_dimensions(dimensions):
|
||||
|
@ -6,7 +6,7 @@
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/bsd_license
|
||||
|
||||
from hsutil.str import format_size
|
||||
from hscommon.util import format_size
|
||||
from core.data import (format_path, format_timestamp, format_words, format_perc,
|
||||
format_dupe_count, cmp_value)
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
import hashlib
|
||||
|
||||
from hscommon import io
|
||||
from hsutil.misc import nonone
|
||||
from hscommon.util import nonone
|
||||
|
||||
from core import fs
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
import hashlib
|
||||
|
||||
from hsutil.path import Path
|
||||
from hscommon.path import Path
|
||||
from hscommon.testutil import eq_
|
||||
from core.fs import File
|
||||
from core.tests.directories_test import create_fake_fs
|
||||
|
@ -86,7 +86,7 @@ def package_debian(edition):
|
||||
os.makedirs(destpath)
|
||||
os.makedirs(srcpath)
|
||||
shutil.copy('run.py', op.join(srcpath, 'run.py'))
|
||||
packages = ['hscommon', 'core', ed('core_{0}'), 'qtlib', 'qt', 'hsutil', 'send2trash', 'jobprogress']
|
||||
packages = ['hscommon', 'core', ed('core_{0}'), 'qtlib', 'qt', 'send2trash', 'jobprogress']
|
||||
if edition == 'me':
|
||||
packages.append('hsaudiotag')
|
||||
copy_packages(packages, srcpath)
|
||||
|
@ -13,7 +13,7 @@ from PyQt4.QtGui import (QMainWindow, QMenu, QPixmap, QIcon, QToolButton, QLabel
|
||||
QMessageBox, QInputDialog, QLineEdit, QDesktopServices, QFileDialog, QAction, QMenuBar,
|
||||
QToolBar, QWidget, QVBoxLayout, QAbstractItemView, QStatusBar)
|
||||
|
||||
from hsutil.misc import nonone
|
||||
from hscommon.util import nonone
|
||||
|
||||
from core.app import NoScannableFileError
|
||||
|
||||
|
@ -11,7 +11,7 @@ import logging
|
||||
|
||||
from PyQt4.QtGui import QImage, QImageReader
|
||||
|
||||
from hsutil.str import get_file_ext
|
||||
from hscommon.util import get_file_ext
|
||||
|
||||
from core import fs
|
||||
from core_pe import data as data_pe
|
||||
|
@ -11,7 +11,7 @@ from PyQt4.QtCore import SIGNAL, Qt, QSize
|
||||
from PyQt4.QtGui import (QDialog, QDialogButtonBox, QVBoxLayout, QHBoxLayout, QLabel, QComboBox,
|
||||
QSlider, QSizePolicy, QSpacerItem, QWidget, QCheckBox, QLineEdit, QDialogButtonBox, QApplication)
|
||||
|
||||
from hsutil.misc import tryint
|
||||
from hscommon.util import tryint
|
||||
|
||||
from core.scanner import ScanType
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user