Compare commits

...

12 Commits

Author SHA1 Message Date
Stanislav 5d67511315
Merge cd70c99c67 into 3a97ba941a 2024-06-03 22:15:47 +02:00
Andrew Senetar 3a97ba941a
ci: Merge artifacts
- Merge the resulting artifacts
- Use only the .so files from build
2024-05-11 01:21:58 -07:00
Andrew Senetar e3bcf9d686
chore: Update VS Code configuration 2024-05-11 00:12:19 -07:00
Andrew Senetar a81069be61
fix: Photo matching fixes
- Correct bad query introduced in rotation matching
- Promote get_orientation from "private" on photo class
- Fix prepare_pictures to only generate the needed blocks, add check for missing blocks when rotation matchin is true
- Fix cache test inputs to match schema
2024-05-11 00:11:27 -07:00
Stanislav cd70c99c67
Merge branch 'arsenetar:master' into i18n_Russian 2023-12-07 21:52:39 +03:00
Stanislav 7eafb86c2b
Merge branch 'arsenetar:master' into i18n_Russian 2023-08-13 18:35:41 +03:00
Stanislav 71672bc2c9
Update ui.po 2023-06-25 20:39:10 +03:00
Stanislav f4e6768caf
Update core.po 2023-06-24 12:39:40 +03:00
Stanislav 8ce4080c4e
Update ui.po 2023-06-24 12:38:57 +03:00
Stanislav f191b64cca
Update columns.po 2023-06-24 12:34:42 +03:00
Stanislav a714a0860c
Update core.po 2023-06-24 12:33:16 +03:00
Stanislav 5fb8caefa9
Small fix Russian language 2023-06-24 12:04:47 +03:00
10 changed files with 83 additions and 66 deletions

View File

@ -52,4 +52,14 @@ jobs:
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: modules ${{ matrix.python-version }} name: modules ${{ matrix.python-version }}
path: ${{ github.workspace }}/**/*.so path: build/**/*.so
merge-artifacts:
needs: [test]
runs-on: ubuntu-latest
steps:
- name: Merge Artifacts
uses: actions/upload-artifact/merge@v4
with:
name: modules
pattern: modules*
delete-merged: true

2
.vscode/launch.json vendored
View File

@ -6,7 +6,7 @@
"configurations": [ "configurations": [
{ {
"name": "DupuGuru", "name": "DupuGuru",
"type": "python", "type": "debugpy",
"request": "launch", "request": "launch",
"program": "run.py", "program": "run.py",
"console": "integratedTerminal", "console": "integratedTerminal",

View File

@ -12,5 +12,6 @@
"[python]": { "[python]": {
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.defaultFormatter": "ms-python.black-formatter" "editor.defaultFormatter": "ms-python.black-formatter"
} },
"python.testing.pytestEnabled": true
} }

View File

@ -158,7 +158,7 @@ class SqliteCache:
ids = ",".join(map(str, rowids)) ids = ",".join(map(str, rowids))
sql = ( sql = (
"select rowid, blocks, blocks2, blocks3, blocks4, blocks5, blocks6, blocks7, blocks8 " "select rowid, blocks, blocks2, blocks3, blocks4, blocks5, blocks6, blocks7, blocks8 "
f"from pictures where rowid in {ids}" f"from pictures where rowid in ({ids})"
) )
cur = self.con.execute(sql) cur = self.con.execute(sql)
return ( return (

View File

@ -54,7 +54,7 @@ def get_cache(cache_path, readonly=False):
return SqliteCache(cache_path, readonly=readonly) return SqliteCache(cache_path, readonly=readonly)
def prepare_pictures(pictures, cache_path, with_dimensions, j=job.nulljob): def prepare_pictures(pictures, cache_path, with_dimensions, match_rotated, j=job.nulljob):
# The MemoryError handlers in there use logging without first caring about whether or not # The MemoryError handlers in there use logging without first caring about whether or not
# there is enough memory left to carry on the operation because it is assumed that the # there is enough memory left to carry on the operation because it is assumed that the
# MemoryError happens when trying to read an image file, which is freed from memory by the # MemoryError happens when trying to read an image file, which is freed from memory by the
@ -76,8 +76,14 @@ def prepare_pictures(pictures, cache_path, with_dimensions, j=job.nulljob):
if with_dimensions: if with_dimensions:
picture.dimensions # pre-read dimensions picture.dimensions # pre-read dimensions
try: try:
if picture.unicode_path not in cache: if picture.unicode_path not in cache or (
blocks = [picture.get_blocks(BLOCK_COUNT_PER_SIDE, orientation) for orientation in range(1, 9)] match_rotated and any(block == [] for block in cache[picture.unicode_path])
):
if match_rotated:
blocks = [picture.get_blocks(BLOCK_COUNT_PER_SIDE, orientation) for orientation in range(1, 9)]
else:
blocks = [[]] * 8
blocks[max(picture.get_orientation() - 1, 0)] = picture.get_blocks(BLOCK_COUNT_PER_SIDE)
cache[picture.unicode_path] = blocks cache[picture.unicode_path] = blocks
prepared.append(picture) prepared.append(picture)
except (OSError, ValueError) as e: except (OSError, ValueError) as e:
@ -187,7 +193,7 @@ def getmatches(pictures, cache_path, threshold, match_scaled=False, match_rotate
j.set_progress(comparison_count, progress_msg) j.set_progress(comparison_count, progress_msg)
j = j.start_subjob([3, 7]) j = j.start_subjob([3, 7])
pictures = prepare_pictures(pictures, cache_path, with_dimensions=not match_scaled, j=j) pictures = prepare_pictures(pictures, cache_path, not match_scaled, match_rotated, j=j)
j = j.start_subjob([9, 1], tr("Preparing for matching")) j = j.start_subjob([9, 1], tr("Preparing for matching"))
cache = get_cache(cache_path) cache = get_cache(cache_path)
id2picture = {} id2picture = {}

View File

@ -37,7 +37,7 @@ class Photo(fs.File):
def _plat_get_blocks(self, block_count_per_side, orientation): def _plat_get_blocks(self, block_count_per_side, orientation):
raise NotImplementedError() raise NotImplementedError()
def _get_orientation(self): def get_orientation(self):
if not hasattr(self, "_cached_orientation"): if not hasattr(self, "_cached_orientation"):
try: try:
with self.path.open("rb") as fp: with self.path.open("rb") as fp:
@ -95,13 +95,13 @@ class Photo(fs.File):
fs.File._read_info(self, field) fs.File._read_info(self, field)
if field == "dimensions": if field == "dimensions":
self.dimensions = self._plat_get_dimensions() self.dimensions = self._plat_get_dimensions()
if self._get_orientation() in {5, 6, 7, 8}: if self.get_orientation() in {5, 6, 7, 8}:
self.dimensions = (self.dimensions[1], self.dimensions[0]) self.dimensions = (self.dimensions[1], self.dimensions[0])
elif field == "exif_timestamp": elif field == "exif_timestamp":
self.exif_timestamp = self._get_exif_timestamp() self.exif_timestamp = self._get_exif_timestamp()
def get_blocks(self, block_count_per_side, orientation: int = None): def get_blocks(self, block_count_per_side, orientation: int = None):
if orientation is None: if orientation is None:
return self._plat_get_blocks(block_count_per_side, self._get_orientation()) return self._plat_get_blocks(block_count_per_side, self.get_orientation())
else: else:
return self._plat_get_blocks(block_count_per_side, orientation) return self._plat_get_blocks(block_count_per_side, orientation)

View File

@ -59,13 +59,13 @@ class BaseTestCaseCache:
def test_set_then_retrieve_blocks(self): def test_set_then_retrieve_blocks(self):
c = self.get_cache() c = self.get_cache()
b = [(0, 0, 0), (1, 2, 3)] b = [[(0, 0, 0), (1, 2, 3)]] * 8
c["foo"] = b c["foo"] = b
eq_(b, c["foo"]) eq_(b, c["foo"])
def test_delitem(self): def test_delitem(self):
c = self.get_cache() c = self.get_cache()
c["foo"] = "" c["foo"] = [[]] * 8
del c["foo"] del c["foo"]
assert "foo" not in c assert "foo" not in c
with raises(KeyError): with raises(KeyError):
@ -74,16 +74,16 @@ class BaseTestCaseCache:
def test_persistance(self, tmpdir): def test_persistance(self, tmpdir):
DBNAME = tmpdir.join("hstest.db") DBNAME = tmpdir.join("hstest.db")
c = self.get_cache(str(DBNAME)) c = self.get_cache(str(DBNAME))
c["foo"] = [(1, 2, 3)] c["foo"] = [[(1, 2, 3)]] * 8
del c del c
c = self.get_cache(str(DBNAME)) c = self.get_cache(str(DBNAME))
eq_([(1, 2, 3)], c["foo"]) eq_([[(1, 2, 3)]] * 8, c["foo"])
def test_filter(self): def test_filter(self):
c = self.get_cache() c = self.get_cache()
c["foo"] = "" c["foo"] = [[]] * 8
c["bar"] = "" c["bar"] = [[]] * 8
c["baz"] = "" c["baz"] = [[]] * 8
c.filter(lambda p: p != "bar") # only 'bar' is removed c.filter(lambda p: p != "bar") # only 'bar' is removed
eq_(2, len(c)) eq_(2, len(c))
assert "foo" in c assert "foo" in c
@ -92,9 +92,9 @@ class BaseTestCaseCache:
def test_clear(self): def test_clear(self):
c = self.get_cache() c = self.get_cache()
c["foo"] = "" c["foo"] = [[]] * 8
c["bar"] = "" c["bar"] = [[]] * 8
c["baz"] = "" c["baz"] = [[]] * 8
c.clear() c.clear()
eq_(0, len(c)) eq_(0, len(c))
assert "foo" not in c assert "foo" not in c
@ -104,7 +104,7 @@ class BaseTestCaseCache:
def test_by_id(self): def test_by_id(self):
# it's possible to use the cache by referring to the files by their row_id # it's possible to use the cache by referring to the files by their row_id
c = self.get_cache() c = self.get_cache()
b = [(0, 0, 0), (1, 2, 3)] b = [[(0, 0, 0), (1, 2, 3)]] * 8
c["foo"] = b c["foo"] = b
foo_id = c.get_id("foo") foo_id = c.get_id("foo")
eq_(c[foo_id], b) eq_(c[foo_id], b)
@ -127,10 +127,10 @@ class TestCaseSqliteCache(BaseTestCaseCache):
fp.write("invalid sqlite content") fp.write("invalid sqlite content")
fp.close() fp.close()
c = self.get_cache(dbname) # should not raise a DatabaseError c = self.get_cache(dbname) # should not raise a DatabaseError
c["foo"] = [(1, 2, 3)] c["foo"] = [[(1, 2, 3)]] * 8
del c del c
c = self.get_cache(dbname) c = self.get_cache(dbname)
eq_(c["foo"], [(1, 2, 3)]) eq_(c["foo"], [[(1, 2, 3)]] * 8)
class TestCaseCacheSQLEscape: class TestCaseCacheSQLEscape:
@ -152,7 +152,7 @@ class TestCaseCacheSQLEscape:
def test_delitem(self): def test_delitem(self):
c = self.get_cache() c = self.get_cache()
c["foo'bar"] = [] c["foo'bar"] = [[]] * 8
try: try:
del c["foo'bar"] del c["foo'bar"]
except KeyError: except KeyError:

View File

@ -112,7 +112,7 @@ msgstr "Размеры"
#: core\pe\result_table.py:21 core\se\result_table.py:21 #: core\pe\result_table.py:21 core\se\result_table.py:21
msgid "Size (KB)" msgid "Size (KB)"
msgstr "Размер (КБ)" msgstr "Размер (кБ)"
#: core\pe\result_table.py:24 #: core\pe\result_table.py:24
msgid "EXIF Timestamp" msgid "EXIF Timestamp"

View File

@ -100,15 +100,15 @@ msgstr ""
#: core\app.py:469 #: core\app.py:469
msgid "Select a directory to copy marked files to" msgid "Select a directory to copy marked files to"
msgstr "Выберите каталог, в который вы хотите скопировать отмеченные файлы" msgstr "Выберите каталог, в который Вы хотите скопировать отмеченные файлы"
#: core\app.py:471 #: core\app.py:471
msgid "Select a directory to move marked files to" msgid "Select a directory to move marked files to"
msgstr "Выберите каталог, в который вы хотите переместить отмеченные файлы" msgstr "Выберите каталог для перемещения отмеченных файлов"
#: core\app.py:510 #: core\app.py:510
msgid "Select a destination for your exported CSV" msgid "Select a destination for your exported CSV"
msgstr "Выберите назначение для экспортируемого " msgstr "Выберите назначение для Вашего экспортируемого CSV"
#: core\app.py:516 core\app.py:777 core\app.py:787 #: core\app.py:516 core\app.py:777 core\app.py:787
msgid "Couldn't write to file: {}" msgid "Couldn't write to file: {}"
@ -124,7 +124,7 @@ msgstr "Вы собираетесь удалить %d файлов из резу
#: core\app.py:749 #: core\app.py:749
msgid "{} duplicate groups were changed by the re-prioritization." msgid "{} duplicate groups were changed by the re-prioritization."
msgstr "{} групп дубликатов было изменено при реприоритезации." msgstr "{} групп дубликатов было изменено при обновлении приоритета."
#: core\app.py:797 #: core\app.py:797
msgid "The selected directories contain no scannable file." msgid "The selected directories contain no scannable file."
@ -136,7 +136,7 @@ msgstr "Сбор файлов для сканирования"
#: core\app.py:863 #: core\app.py:863
msgid "%s (%d discarded)" msgid "%s (%d discarded)"
msgstr "%s. (%d отменено)" msgstr "%s (%d отменено)"
#: core\directories.py:191 #: core\directories.py:191
msgid "Collected {} files to scan" msgid "Collected {} files to scan"
@ -148,7 +148,7 @@ msgstr "Собрано {} каталогов для сканирования"
#: core\engine.py:27 #: core\engine.py:27
msgid "%d matches found from %d groups" msgid "%d matches found from %d groups"
msgstr "Найдено %d совпадений из %d групп" msgstr "%d совпадений найдено из %d групп"
#: core\gui\deletion_options.py:71 #: core\gui\deletion_options.py:71
msgid "You are sending {} file(s) to the Trash." msgid "You are sending {} file(s) to the Trash."
@ -249,7 +249,7 @@ msgstr "%d / %d (%s / %s) дубликатов отмечено."
#: core\results.py:142 #: core\results.py:142
msgid " filter: %s" msgid " filter: %s"
msgstr "фильтр: %s" msgstr " фильтр: %s"
#: core\scanner.py:114 #: core\scanner.py:114
msgid "Read metadata of %d/%d files" msgid "Read metadata of %d/%d files"
@ -262,3 +262,4 @@ msgstr "Почти готово! Вожусь с результатами..."
#: core\se\scanner.py:18 #: core\se\scanner.py:18
msgid "Folders" msgid "Folders"
msgstr "Папки" msgstr "Папки"

View File

@ -93,8 +93,8 @@ msgid ""
"Instead of sending files to trash, delete them directly. This option is " "Instead of sending files to trash, delete them directly. This option is "
"usually used as a workaround when the normal deletion method doesn't work." "usually used as a workaround when the normal deletion method doesn't work."
msgstr "" msgstr ""
"Удалить файлы с диска вместо отправки в Корзину. Используйте если нормальный" "Удалить файлы с диска вместо отправки в Корзину. Используйте, если нормальный "
" метод удаления не работает." "метод удаления не работает."
#: qt/deletion_options.py:59 cocoa/en.lproj/Localizable.strings:0 #: qt/deletion_options.py:59 cocoa/en.lproj/Localizable.strings:0
msgid "Proceed" msgid "Proceed"
@ -189,7 +189,7 @@ msgstr "Несохранённые результаты"
#: qt/directories_dialog.py:231 cocoa/en.lproj/Localizable.strings:0 #: qt/directories_dialog.py:231 cocoa/en.lproj/Localizable.strings:0
msgid "You have unsaved results, do you really want to quit?" msgid "You have unsaved results, do you really want to quit?"
msgstr "Имеются несохранённые результаты, вы действительно хотите выйти?" msgstr "Имеются несохранённые результаты, Вы действительно хотите выйти?"
#: qt/directories_dialog.py:239 cocoa/en.lproj/Localizable.strings:0 #: qt/directories_dialog.py:239 cocoa/en.lproj/Localizable.strings:0
msgid "Select a folder to add to the scanning list" msgid "Select a folder to add to the scanning list"
@ -205,7 +205,7 @@ msgstr "Все файлы (*.*)"
#: qt/directories_dialog.py:267 qt/result_window.py:311 #: qt/directories_dialog.py:267 qt/result_window.py:311
msgid "dupeGuru Results (*.dupeguru)" msgid "dupeGuru Results (*.dupeguru)"
msgstr "Результаты dupeGuru (*. dupeguru)" msgstr "Результаты dupeGuru (*.dupeguru)"
#: qt/directories_dialog.py:278 #: qt/directories_dialog.py:278
msgid "Start a new scan" msgid "Start a new scan"
@ -213,7 +213,7 @@ msgstr "Начать новую проверку"
#: qt/directories_dialog.py:279 cocoa/en.lproj/Localizable.strings:0 #: qt/directories_dialog.py:279 cocoa/en.lproj/Localizable.strings:0
msgid "You have unsaved results, do you really want to continue?" msgid "You have unsaved results, do you really want to continue?"
msgstr "Имеются несохранённые результаты, вы действительно хотите продолжить?" msgstr "Имеются несохранённые результаты, Вы действительно хотите продолжить?"
#: qt/directories_model.py:23 cocoa/en.lproj/Localizable.strings:0 #: qt/directories_model.py:23 cocoa/en.lproj/Localizable.strings:0
msgid "Name" msgid "Name"
@ -256,7 +256,7 @@ msgstr "Теги для проверки:"
#: qt/me/preferences_dialog.py:36 cocoa/en.lproj/Localizable.strings:0 #: qt/me/preferences_dialog.py:36 cocoa/en.lproj/Localizable.strings:0
msgid "Track" msgid "Track"
msgstr "Трек" msgstr "Дорожка"
#: qt/me/preferences_dialog.py:38 cocoa/en.lproj/Localizable.strings:0 #: qt/me/preferences_dialog.py:38 cocoa/en.lproj/Localizable.strings:0
msgid "Artist" msgid "Artist"
@ -323,7 +323,7 @@ msgstr "Уровень фильтрации:"
#: qt/preferences_dialog.py:69 #: qt/preferences_dialog.py:69
msgid "More Results" msgid "More Results"
msgstr "Дополнительные результаты" msgstr "Больше результатов"
#: qt/preferences_dialog.py:74 #: qt/preferences_dialog.py:74
msgid "Fewer Results" msgid "Fewer Results"
@ -379,7 +379,7 @@ msgstr ""
#: qt/problem_dialog.py:33 cocoa/en.lproj/Localizable.strings:0 #: qt/problem_dialog.py:33 cocoa/en.lproj/Localizable.strings:0
msgid "Problems!" msgid "Problems!"
msgstr "Проблемка!" msgstr "Проблема!"
#: qt/problem_dialog.py:37 cocoa/en.lproj/Localizable.strings:0 #: qt/problem_dialog.py:37 cocoa/en.lproj/Localizable.strings:0
msgid "" msgid ""
@ -409,15 +409,15 @@ msgstr "Показать значения разницы"
#: qt/result_window.py:60 #: qt/result_window.py:60
msgid "Send Marked to Recycle Bin..." msgid "Send Marked to Recycle Bin..."
msgstr "Переместить отмеченные в Корзину" msgstr "Переместить отмеченные в Корзину..."
#: qt/result_window.py:61 cocoa/en.lproj/Localizable.strings:0 #: qt/result_window.py:61 cocoa/en.lproj/Localizable.strings:0
msgid "Move Marked to..." msgid "Move Marked to..."
msgstr "Переместить отмеченные в" msgstr "Переместить отмеченные в..."
#: qt/result_window.py:62 cocoa/en.lproj/Localizable.strings:0 #: qt/result_window.py:62 cocoa/en.lproj/Localizable.strings:0
msgid "Copy Marked to..." msgid "Copy Marked to..."
msgstr "Скопировать отмеченные в" msgstr "Скопировать отмеченные в..."
#: qt/result_window.py:63 cocoa/en.lproj/Localizable.strings:0 #: qt/result_window.py:63 cocoa/en.lproj/Localizable.strings:0
msgid "Remove Marked from Results" msgid "Remove Marked from Results"
@ -477,7 +477,7 @@ msgstr "Экспорт в CSV"
#: qt/result_window.py:89 cocoa/en.lproj/Localizable.strings:0 #: qt/result_window.py:89 cocoa/en.lproj/Localizable.strings:0
msgid "Save Results..." msgid "Save Results..."
msgstr "Сохранить результаты" msgstr "Сохранить результаты..."
#: qt/result_window.py:90 cocoa/en.lproj/Localizable.strings:0 #: qt/result_window.py:90 cocoa/en.lproj/Localizable.strings:0
msgid "Invoke Custom Command" msgid "Invoke Custom Command"
@ -509,15 +509,15 @@ msgstr "Значения разницы"
#: qt/result_window.py:310 cocoa/en.lproj/Localizable.strings:0 #: qt/result_window.py:310 cocoa/en.lproj/Localizable.strings:0
msgid "Select a file to save your results to" msgid "Select a file to save your results to"
msgstr "Выберите файл, чтобы сохранить ваши результаты" msgstr "Выберите файл для сохранения Ваших результатов"
#: qt/se/preferences_dialog.py:41 #: qt/se/preferences_dialog.py:41
msgid "Ignore files smaller than" msgid "Ignore files smaller than"
msgstr "Игнорировать файлы меньше чем" msgstr "Игнорировать файлы меньше, чем"
#: qt/se/preferences_dialog.py:52 cocoa/en.lproj/Localizable.strings:0 #: qt/se/preferences_dialog.py:52 cocoa/en.lproj/Localizable.strings:0
msgid "KB" msgid "KB"
msgstr "КБ" msgstr "кБ"
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "%@ Results" msgid "%@ Results"
@ -549,7 +549,7 @@ msgstr "Все на передний план"
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "Check for update..." msgid "Check for update..."
msgstr "Проверка обновлений" msgstr "Проверка обновлений..."
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "Close Window" msgid "Close Window"
@ -594,7 +594,7 @@ msgstr "Настройки dupeGuru"
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "dupeGuru Results" msgid "dupeGuru Results"
msgstr "Результаты dupeGuru " msgstr "Результаты dupeGuru"
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "dupeGuru Website" msgid "dupeGuru Website"
@ -626,7 +626,7 @@ msgstr "Уровень фильтрации:"
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "Filter Results..." msgid "Filter Results..."
msgstr "Отфильтровать результаты" msgstr "Отфильтровать результаты..."
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "Folder Selection Window" msgid "Folder Selection Window"
@ -646,11 +646,11 @@ msgstr "Скрыть остальные"
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "Ignore files smaller than:" msgid "Ignore files smaller than:"
msgstr "Пропускать файлы меньше чем:" msgstr "Пропускать файлы меньше, чем:"
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "Load from file..." msgid "Load from file..."
msgstr "Загрузить из файла" msgstr "Загрузить из файла..."
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "Minimize" msgid "Minimize"
@ -674,7 +674,7 @@ msgstr "Вставить"
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "Preferences..." msgid "Preferences..."
msgstr "Настройки" msgstr "Настройки..."
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "Quick Look" msgid "Quick Look"
@ -686,7 +686,7 @@ msgstr "Выйти из dupeGuru"
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "Reset to Default" msgid "Reset to Default"
msgstr "Восстановить значения по умолчанию" msgstr "Восстановить значение по умолчанию"
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "Reset To Defaults" msgid "Reset To Defaults"
@ -706,7 +706,7 @@ msgstr "Выбрать все"
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "Send Marked to Trash..." msgid "Send Marked to Trash..."
msgstr "Переместить отмеченные в Корзину" msgstr "Переместить отмеченные в Корзину..."
#: cocoa/en.lproj/Localizable.strings:0 #: cocoa/en.lproj/Localizable.strings:0
msgid "Services" msgid "Services"
@ -754,11 +754,11 @@ msgstr "Выберите файл каталогов для загрузки"
#: qt\directories_dialog.py:338 #: qt\directories_dialog.py:338
msgid "dupeGuru Results (*.dupegurudirs)" msgid "dupeGuru Results (*.dupegurudirs)"
msgstr "Каталоги dupeGuru (*.dupegurudirs)" msgstr "Результаты dupeGuru (*.dupegurudirs)"
#: qt\directories_dialog.py:347 #: qt\directories_dialog.py:347
msgid "Select a file to save your directories to" msgid "Select a file to save your directories to"
msgstr "Выберите файл для сохранения каталогов" msgstr "Выберите файл для сохранения Ваших каталогов"
#: qt\directories_dialog.py:348 #: qt\directories_dialog.py:348
msgid "dupeGuru Directories (*.dupegurudirs)" msgid "dupeGuru Directories (*.dupegurudirs)"
@ -798,7 +798,7 @@ msgstr ""
#: qt\exclude_list_table.py:36 #: qt\exclude_list_table.py:36
msgid "Compilation error: " msgid "Compilation error: "
msgstr "Ошибка компиляции:" msgstr "Ошибка компиляции: "
#: qt\pe\image_viewer.py:56 #: qt\pe\image_viewer.py:56
msgid "Increase zoom" msgid "Increase zoom"
@ -835,7 +835,7 @@ msgstr "Переопределить значки темы на панели и
#: qt\pe\preferences_dialog.py:58 #: qt\pe\preferences_dialog.py:58
msgid "" msgid ""
"Use our own internal icons instead of those provided by the theme engine" "Use our own internal icons instead of those provided by the theme engine"
msgstr "Используйте внутренние значки вместо значков, встроенных в тему" msgstr "Использовать наши внутренние значки вместо значков, встроенных в тему"
#: qt\pe\preferences_dialog.py:66 #: qt\pe\preferences_dialog.py:66
msgid "Show scrollbars in image viewers" msgid "Show scrollbars in image viewers"
@ -965,7 +965,7 @@ msgstr ""
#: qt\se\preferences_dialog.py:68 #: qt\se\preferences_dialog.py:68
msgid "Ignore files larger than" msgid "Ignore files larger than"
msgstr "Игнорировать файлы больше чем" msgstr "Игнорировать файлы больше, чем"
#: qt\app.py:135 qt\app.py:293 #: qt\app.py:135 qt\app.py:293
msgid "Clear Cache" msgid "Clear Cache"
@ -981,7 +981,7 @@ msgstr ""
#: qt\app.py:299 #: qt\app.py:299
msgid "Cache cleared." msgid "Cache cleared."
msgstr "Кэш очищен " msgstr "Кэш очищен."
#: qt\preferences_dialog.py:173 #: qt\preferences_dialog.py:173
msgid "Use dark style" msgid "Use dark style"
@ -994,8 +994,7 @@ msgstr "Сохранить профиль сканирования"
#: qt\preferences_dialog.py:242 #: qt\preferences_dialog.py:242
msgid "Profile the scan operation and save logs for optimization." msgid "Profile the scan operation and save logs for optimization."
msgstr "" msgstr ""
"В папке установленной или портативной программы, есть папка Data в которую " "Настройте операцию сканирования и сохраните журналы для оптимизации."
"сохраняется логи и файл с раширением *.profile для оптимизации."
#: qt\preferences_dialog.py:246 #: qt\preferences_dialog.py:246
msgid "Logs located in: <a href=\"{}\">{}</a>" msgid "Logs located in: <a href=\"{}\">{}</a>"
@ -1023,11 +1022,11 @@ msgstr "Под лицензией GPLv3"
#: qt\about_box.py:68 #: qt\about_box.py:68
msgid "No update available." msgid "No update available."
msgstr "У вас самая свежая версия" msgstr "Обновления недоступны."
#: qt\about_box.py:71 #: qt\about_box.py:71
msgid "New version {} available, download <a href=\"{}\">here</a>." msgid "New version {} available, download <a href=\"{}\">here</a>."
msgstr "Обнаружена новая {} версия, загружать <a href=\"{}\">тут</a>." msgstr "Обнаружена новая {} версия, загрузить <a href=\"{}\">тут</a>."
#: qt\error_report_dialog.py:50 #: qt\error_report_dialog.py:50
msgid "Error Report" msgid "Error Report"