1
0
mirror of https://github.com/arsenetar/dupeguru.git synced 2025-05-08 17:59:50 +00:00

Compare commits

...

2 Commits

14 changed files with 53 additions and 82 deletions

View File

@ -132,7 +132,7 @@ class DupeGuru(Broadcaster):
logging.debug("Debug mode enabled") logging.debug("Debug mode enabled")
Broadcaster.__init__(self) Broadcaster.__init__(self)
self.view = view self.view = view
self.appdata = desktop.special_folder_path(desktop.SpecialFolder.AppData, appname=self.NAME, portable=portable) self.appdata = desktop.special_folder_path(desktop.SpecialFolder.APPDATA, appname=self.NAME, portable=portable)
if not op.exists(self.appdata): if not op.exists(self.appdata):
os.makedirs(self.appdata) os.makedirs(self.appdata)
self.app_mode = AppMode.Standard self.app_mode = AppMode.Standard

View File

@ -336,7 +336,6 @@ def read_changelog_file(filename):
with open(filename, "rt", encoding="utf-8") as fp: with open(filename, "rt", encoding="utf-8") as fp:
contents = fp.read() contents = fp.read()
splitted = re_changelog_header.split(contents)[1:] # the first item is empty splitted = re_changelog_header.split(contents)[1:] # the first item is empty
# splitted = [version1, date1, desc1, version2, date2, ...]
result = [] result = []
for version, date_str, description in iter_by_three(iter(splitted)): for version, date_str, description in iter_by_three(iter(splitted)):
date = datetime.strptime(date_str, "%Y-%m-%d").date() date = datetime.strptime(date_str, "%Y-%m-%d").date()
@ -399,8 +398,8 @@ def create_osx_app_structure(
# `resources`: A list of paths of files or folders going in the "Resources" folder. # `resources`: A list of paths of files or folders going in the "Resources" folder.
# `frameworks`: Same as above for "Frameworks". # `frameworks`: Same as above for "Frameworks".
# `symlink_resources`: If True, will symlink resources into the structure instead of copying them. # `symlink_resources`: If True, will symlink resources into the structure instead of copying them.
app = OSXAppStructure(dest, infoplist) app = OSXAppStructure(dest)
app.create() app.create(infoplist)
app.copy_executable(executable) app.copy_executable(executable)
app.copy_resources(*resources, use_symlinks=symlink_resources) app.copy_resources(*resources, use_symlinks=symlink_resources)
app.copy_frameworks(*frameworks) app.copy_frameworks(*frameworks)

View File

@ -13,8 +13,8 @@ import traceback
# Taken from http://bzimmer.ziclix.com/2008/12/17/python-thread-dumps/ # Taken from http://bzimmer.ziclix.com/2008/12/17/python-thread-dumps/
def stacktraces(): def stacktraces():
code = [] code = []
for threadId, stack in sys._current_frames().items(): for thread_id, stack in sys._current_frames().items():
code.append("\n# ThreadID: %s" % threadId) code.append("\n# ThreadID: %s" % thread_id)
for filename, lineno, name, line in traceback.extract_stack(stack): for filename, lineno, name, line in traceback.extract_stack(stack):
code.append('File: "%s", line %d, in %s' % (filename, lineno, name)) code.append('File: "%s", line %d, in %s' % (filename, lineno, name))
if line: if line:

View File

@ -11,8 +11,8 @@ import logging
class SpecialFolder: class SpecialFolder:
AppData = 1 APPDATA = 1
Cache = 2 CACHE = 2
def open_url(url): def open_url(url):
@ -55,7 +55,7 @@ try:
_reveal_path = proxy.revealPath_ _reveal_path = proxy.revealPath_
def _special_folder_path(special_folder, appname=None, portable=False): def _special_folder_path(special_folder, appname=None, portable=False):
if special_folder == SpecialFolder.Cache: if special_folder == SpecialFolder.CACHE:
base = proxy.getCachePath() base = proxy.getCachePath()
else: else:
base = proxy.getAppdataPath() base = proxy.getAppdataPath()
@ -89,7 +89,7 @@ except ImportError:
_open_path(op.dirname(str(path))) _open_path(op.dirname(str(path)))
def _special_folder_path(special_folder, appname=None, portable=False): def _special_folder_path(special_folder, appname=None, portable=False):
if special_folder == SpecialFolder.Cache: if special_folder == SpecialFolder.CACHE:
if ISWINDOWS and portable: if ISWINDOWS and portable:
folder = op.join(executable_folder(), "cache") folder = op.join(executable_folder(), "cache")
else: else:
@ -104,9 +104,11 @@ except ImportError:
logging.warning("Can't setup desktop functions!") logging.warning("Can't setup desktop functions!")
def _open_path(path): def _open_path(path):
# Dummy for tests
pass pass
def _reveal_path(path): def _reveal_path(path):
# Dummy for tests
pass pass
def _special_folder_path(special_folder, appname=None, portable=False): def _special_folder_path(special_folder, appname=None, portable=False):

View File

@ -146,24 +146,29 @@ class Job:
class NullJob: class NullJob:
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
# Null job does nothing
pass pass
def add_progress(self, *args, **kwargs): def add_progress(self, *args, **kwargs):
# Null job does nothing
pass pass
def check_if_cancelled(self): def check_if_cancelled(self):
# Null job does nothing
pass pass
def iter_with_progress(self, sequence, *args, **kwargs): def iter_with_progress(self, sequence, *args, **kwargs):
return iter(sequence) return iter(sequence)
def start_job(self, *args, **kwargs): def start_job(self, *args, **kwargs):
# Null job does nothing
pass pass
def start_subjob(self, *args, **kwargs): def start_subjob(self, *args, **kwargs):
return NullJob() return NullJob()
def set_progress(self, *args, **kwargs): def set_progress(self, *args, **kwargs):
# Null job does nothing
pass pass

View File

@ -21,6 +21,8 @@ PO2COCOA = {
COCOA2PO = {v: k for k, v in PO2COCOA.items()} COCOA2PO = {v: k for k, v in PO2COCOA.items()}
STRING_EXT = ".strings"
def get_langs(folder): def get_langs(folder):
return [name for name in os.listdir(folder) if op.isdir(op.join(folder, name))] return [name for name in os.listdir(folder) if op.isdir(op.join(folder, name))]
@ -152,7 +154,7 @@ def strings2pot(target, dest):
def allstrings2pot(lprojpath, dest, excludes=None): def allstrings2pot(lprojpath, dest, excludes=None):
allstrings = files_with_ext(lprojpath, ".strings") allstrings = files_with_ext(lprojpath, STRING_EXT)
if excludes: if excludes:
allstrings = [p for p in allstrings if op.splitext(op.basename(p))[0] not in excludes] allstrings = [p for p in allstrings if op.splitext(op.basename(p))[0] not in excludes]
for strings_path in allstrings: for strings_path in allstrings:
@ -210,7 +212,7 @@ def generate_cocoa_strings_from_code(code_folder, dest_folder):
def generate_cocoa_strings_from_xib(xib_folder): def generate_cocoa_strings_from_xib(xib_folder):
xibs = [op.join(xib_folder, fn) for fn in os.listdir(xib_folder) if fn.endswith(".xib")] xibs = [op.join(xib_folder, fn) for fn in os.listdir(xib_folder) if fn.endswith(".xib")]
for xib in xibs: for xib in xibs:
dest = xib.replace(".xib", ".strings") dest = xib.replace(".xib", STRING_EXT)
print_and_do("ibtool {} --generate-strings-file {}".format(xib, dest)) print_and_do("ibtool {} --generate-strings-file {}".format(xib, dest))
print_and_do("iconv -f utf-16 -t utf-8 {0} | tee {0}".format(dest)) print_and_do("iconv -f utf-16 -t utf-8 {0} | tee {0}".format(dest))
@ -226,6 +228,6 @@ def localize_stringsfile(stringsfile, dest_root_folder):
def localize_all_stringsfiles(src_folder, dest_root_folder): def localize_all_stringsfiles(src_folder, dest_root_folder):
stringsfiles = [op.join(src_folder, fn) for fn in os.listdir(src_folder) if fn.endswith(".strings")] stringsfiles = [op.join(src_folder, fn) for fn in os.listdir(src_folder) if fn.endswith(STRING_EXT)]
for path in stringsfiles: for path in stringsfiles:
localize_stringsfile(path, dest_root_folder) localize_stringsfile(path, dest_root_folder)

View File

@ -167,10 +167,10 @@ def getFilesForName(name):
# check for glob chars # check for glob chars
if containsAny(name, "*?[]"): if containsAny(name, "*?[]"):
files = glob.glob(name) files = glob.glob(name)
list = [] file_list = []
for file in files: for file in files:
list.extend(getFilesForName(file)) file_list.extend(getFilesForName(file))
return list return file_list
# try to find module or package # try to find module or package
name = _get_modpkg_path(name) name = _get_modpkg_path(name)
@ -179,9 +179,9 @@ def getFilesForName(name):
if os.path.isdir(name): if os.path.isdir(name):
# find all python files in directory # find all python files in directory
list = [] file_list = []
os.walk(name, _visit_pyfiles, list) os.walk(name, _visit_pyfiles, file_list)
return list return file_list
elif os.path.exists(name): elif os.path.exists(name):
# a single file # a single file
return [name] return [name]

View File

@ -19,7 +19,7 @@ from ..path import Path
from ..testutil import eq_ from ..testutil import eq_
class TestCase_GetConflictedName: class TestCaseGetConflictedName:
def test_simple(self): def test_simple(self):
name = get_conflicted_name(["bar"], "bar") name = get_conflicted_name(["bar"], "bar")
eq_("[000] bar", name) eq_("[000] bar", name)
@ -46,7 +46,7 @@ class TestCase_GetConflictedName:
eq_("[000] bar", name) eq_("[000] bar", name)
class TestCase_GetUnconflictedName: class TestCaseGetUnconflictedName:
def test_main(self): def test_main(self):
eq_("foobar", get_unconflicted_name("[000] foobar")) eq_("foobar", get_unconflicted_name("[000] foobar"))
eq_("foobar", get_unconflicted_name("[9999] foobar")) eq_("foobar", get_unconflicted_name("[9999] foobar"))
@ -56,7 +56,7 @@ class TestCase_GetUnconflictedName:
eq_("foo [000] bar", get_unconflicted_name("foo [000] bar")) eq_("foo [000] bar", get_unconflicted_name("foo [000] bar"))
class TestCase_IsConflicted: class TestCaseIsConflicted:
def test_main(self): def test_main(self):
assert is_conflicted("[000] foobar") assert is_conflicted("[000] foobar")
assert is_conflicted("[9999] foobar") assert is_conflicted("[9999] foobar")
@ -66,7 +66,7 @@ class TestCase_IsConflicted:
assert not is_conflicted("foo [000] bar") assert not is_conflicted("foo [000] bar")
class TestCase_move_copy: class TestCaseMoveCopy:
@pytest.fixture @pytest.fixture
def do_setup(self, request): def do_setup(self, request):
tmpdir = request.getfixturevalue("tmpdir") tmpdir = request.getfixturevalue("tmpdir")

View File

@ -51,7 +51,7 @@ def test_init_with_tuple_and_list(force_ossep):
def test_init_with_invalid_value(force_ossep): def test_init_with_invalid_value(force_ossep):
try: try:
path = Path(42) # noqa: F841 Path(42)
assert False assert False
except TypeError: except TypeError:
pass pass
@ -142,8 +142,6 @@ def test_path_slice(force_ossep):
eq_((), foobar[:foobar]) eq_((), foobar[:foobar])
abcd = Path("a/b/c/d") abcd = Path("a/b/c/d")
a = Path("a") a = Path("a")
b = Path("b") # noqa: #F841
c = Path("c") # noqa: #F841
d = Path("d") d = Path("d")
z = Path("z") z = Path("z")
eq_("b/c", abcd[a:d]) eq_("b/c", abcd[a:d])
@ -216,7 +214,7 @@ def test_str_repr_of_mix_between_non_ascii_str_and_unicode(force_ossep):
eq_("foo\u00e9/bar".encode(sys.getfilesystemencoding()), p.tobytes()) eq_("foo\u00e9/bar".encode(sys.getfilesystemencoding()), p.tobytes())
def test_Path_of_a_Path_returns_self(force_ossep): def test_path_of_a_path_returns_self(force_ossep):
# if Path() is called with a path as value, just return value. # if Path() is called with a path as value, just return value.
p = Path("foo/bar") p = Path("foo/bar")
assert Path(p) is p assert Path(p) is p

View File

@ -91,7 +91,7 @@ def test_make_sure_theres_no_messup_between_queries():
threads = [] threads = []
for i in range(1, 101): for i in range(1, 101):
t = threading.Thread(target=run, args=(i,)) t = threading.Thread(target=run, args=(i,))
t.start t.start()
threads.append(t) threads.append(t)
while threads: while threads:
time.sleep(0.1) time.sleep(0.1)

View File

@ -19,6 +19,7 @@ class TestRow(Row):
self._index = index self._index = index
def load(self): def load(self):
# Does nothing for test
pass pass
def save(self): def save(self):
@ -75,14 +76,17 @@ def test_allow_edit_when_attr_is_property_with_fset():
class TestRow(Row): class TestRow(Row):
@property @property
def foo(self): def foo(self):
# property only for existence checks
pass pass
@property @property
def bar(self): def bar(self):
# property only for existence checks
pass pass
@bar.setter @bar.setter
def bar(self, value): def bar(self, value):
# setter only for existence checks
pass pass
row = TestRow(Table()) row = TestRow(Table())
@ -97,10 +101,12 @@ def test_can_edit_prop_has_priority_over_fset_checks():
class TestRow(Row): class TestRow(Row):
@property @property
def bar(self): def bar(self):
# property only for existence checks
pass pass
@bar.setter @bar.setter
def bar(self, value): def bar(self, value):
# setter only for existence checks
pass pass
can_edit_bar = False can_edit_bar = False

View File

@ -236,49 +236,8 @@ def test_multi_replace():
# --- Files # --- Files
# These test cases needed https://github.com/hsoft/pytest-monkeyplus/ which appears to not be compatible with latest
# pytest, looking at where this is used only appears to be in hscommon.localize_all_stringfiles at top level.
# Right now this repo does not seem to utilize any of that functionality so going to leave these tests out for now.
# TODO decide if fixing these tests is worth it or not.
# class TestCase_modified_after: class TestCaseDeleteIfEmpty:
# def test_first_is_modified_after(self, monkeyplus):
# monkeyplus.patch_osstat("first", st_mtime=42)
# monkeyplus.patch_osstat("second", st_mtime=41)
# assert modified_after("first", "second")
# def test_second_is_modified_after(self, monkeyplus):
# monkeyplus.patch_osstat("first", st_mtime=42)
# monkeyplus.patch_osstat("second", st_mtime=43)
# assert not modified_after("first", "second")
# def test_same_mtime(self, monkeyplus):
# monkeyplus.patch_osstat("first", st_mtime=42)
# monkeyplus.patch_osstat("second", st_mtime=42)
# assert not modified_after("first", "second")
# def test_first_file_does_not_exist(self, monkeyplus):
# # when the first file doesn't exist, we return False
# monkeyplus.patch_osstat("second", st_mtime=42)
# assert not modified_after("does_not_exist", "second") # no crash
# def test_second_file_does_not_exist(self, monkeyplus):
# # when the second file doesn't exist, we return True
# monkeyplus.patch_osstat("first", st_mtime=42)
# assert modified_after("first", "does_not_exist") # no crash
# def test_first_file_is_none(self, monkeyplus):
# # when the first file is None, we return False
# monkeyplus.patch_osstat("second", st_mtime=42)
# assert not modified_after(None, "second") # no crash
# def test_second_file_is_none(self, monkeyplus):
# # when the second file is None, we return True
# monkeyplus.patch_osstat("first", st_mtime=42)
# assert modified_after("first", None) # no crash
class TestCase_delete_if_empty:
def test_is_empty(self, tmpdir): def test_is_empty(self, tmpdir):
testpath = Path(str(tmpdir)) testpath = Path(str(tmpdir))
assert delete_if_empty(testpath) assert delete_if_empty(testpath)
@ -330,7 +289,7 @@ class TestCase_delete_if_empty:
delete_if_empty(Path(str(tmpdir))) # no crash delete_if_empty(Path(str(tmpdir))) # no crash
class TestCase_open_if_filename: class TestCaseOpenIfFilename:
def test_file_name(self, tmpdir): def test_file_name(self, tmpdir):
filepath = str(tmpdir.join("test.txt")) filepath = str(tmpdir.join("test.txt"))
open(filepath, "wb").write(b"test_data") open(filepath, "wb").write(b"test_data")
@ -355,7 +314,7 @@ class TestCase_open_if_filename:
file.close() file.close()
class TestCase_FileOrPath: class TestCaseFileOrPath:
def test_path(self, tmpdir): def test_path(self, tmpdir):
filepath = str(tmpdir.join("test.txt")) filepath = str(tmpdir.join("test.txt"))
open(filepath, "wb").write(b"test_data") open(filepath, "wb").write(b"test_data")

View File

@ -131,11 +131,11 @@ def install_gettext_trans(base_folder, lang):
def install_gettext_trans_under_cocoa(): def install_gettext_trans_under_cocoa():
from cocoa import proxy from cocoa import proxy
resFolder = proxy.getResourcePath() res_folder = proxy.getResourcePath()
baseFolder = op.join(resFolder, "locale") base_folder = op.join(res_folder, "locale")
currentLang = proxy.systemLang() current_lang = proxy.systemLang()
install_gettext_trans(baseFolder, currentLang) install_gettext_trans(base_folder, current_lang)
localename = get_locale_name(currentLang) localename = get_locale_name(current_lang)
if localename is not None: if localename is not None:
locale.setlocale(locale.LC_ALL, localename) locale.setlocale(locale.LC_ALL, localename)

View File

@ -177,13 +177,13 @@ def pluralize(number, word, decimals=0, plural_word=None):
``plural_word``: If the plural rule for word is more complex than adding a 's', specify a plural ``plural_word``: If the plural rule for word is more complex than adding a 's', specify a plural
""" """
number = round(number, decimals) number = round(number, decimals)
format = "%%1.%df %%s" % decimals plural_format = "%%1.%df %%s" % decimals
if number > 1: if number > 1:
if plural_word is None: if plural_word is None:
word += "s" word += "s"
else: else:
word = plural_word word = plural_word
return format % (number, word) return plural_format % (number, word)
def format_time(seconds, with_hours=True): def format_time(seconds, with_hours=True):
@ -252,7 +252,7 @@ def format_size(size, decimal=0, forcepower=-1, showdesc=True):
div = SIZE_VALS[i - 1] div = SIZE_VALS[i - 1]
else: else:
div = 1 div = 1
format = "%%%d.%df" % (decimal, decimal) size_format = "%%%d.%df" % (decimal, decimal)
negative = size < 0 negative = size < 0
divided_size = (0.0 + abs(size)) / div divided_size = (0.0 + abs(size)) / div
if decimal == 0: if decimal == 0:
@ -261,7 +261,7 @@ def format_size(size, decimal=0, forcepower=-1, showdesc=True):
divided_size = ceil(divided_size * (10 ** decimal)) / (10 ** decimal) divided_size = ceil(divided_size * (10 ** decimal)) / (10 ** decimal)
if negative: if negative:
divided_size *= -1 divided_size *= -1
result = format % divided_size result = size_format % divided_size
if showdesc: if showdesc:
result += " " + SIZE_DESC[i] result += " " + SIZE_DESC[i]
return result return result
@ -292,7 +292,7 @@ def multi_replace(s, replace_from, replace_to=""):
the same length as ``replace_from``, it will be transformed into a list. the same length as ``replace_from``, it will be transformed into a list.
""" """
if isinstance(replace_to, str) and (len(replace_from) != len(replace_to)): if isinstance(replace_to, str) and (len(replace_from) != len(replace_to)):
replace_to = [replace_to for r in replace_from] replace_to = [replace_to for _ in replace_from]
if len(replace_from) != len(replace_to): if len(replace_from) != len(replace_to):
raise ValueError("len(replace_from) must be equal to len(replace_to)") raise ValueError("len(replace_from) must be equal to len(replace_to)")
replace = list(zip(replace_from, replace_to)) replace = list(zip(replace_from, replace_to))