use new i18n infrastructure for more media check / media sync strings
This commit is contained in:
parent
0217cff099
commit
67a741958c
@ -10,10 +10,15 @@ from typing import Iterable, List, Optional, TypeVar
|
|||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
from anki import hooks
|
from anki import hooks
|
||||||
from anki.lang import _, ngettext
|
from anki.rsbackend import (
|
||||||
from anki.rsbackend import Interrupted, MediaCheckOutput, Progress, ProgressKind
|
Interrupted,
|
||||||
|
MediaCheckOutput,
|
||||||
|
Progress,
|
||||||
|
ProgressKind,
|
||||||
|
StringsGroup,
|
||||||
|
)
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
from aqt.utils import askUser, restoreGeom, saveGeom, showText, tooltip
|
from aqt.utils import askUser, restoreGeom, saveGeom, showText, tooltip, tr
|
||||||
|
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
||||||
@ -84,14 +89,14 @@ class MediaChecker:
|
|||||||
layout.addWidget(box)
|
layout.addWidget(box)
|
||||||
|
|
||||||
if output.unused:
|
if output.unused:
|
||||||
b = QPushButton(_("Delete Unused Files"))
|
b = QPushButton(tr(StringsGroup.MEDIA_CHECK, "delete-unused"))
|
||||||
b.setAutoDefault(False)
|
b.setAutoDefault(False)
|
||||||
box.addButton(b, QDialogButtonBox.RejectRole)
|
box.addButton(b, QDialogButtonBox.RejectRole)
|
||||||
b.clicked.connect(lambda c: self._on_trash_files(output.unused)) # type: ignore
|
b.clicked.connect(lambda c: self._on_trash_files(output.unused)) # type: ignore
|
||||||
|
|
||||||
if output.missing:
|
if output.missing:
|
||||||
if any(map(lambda x: x.startswith("latex-"), output.missing)):
|
if any(map(lambda x: x.startswith("latex-"), output.missing)):
|
||||||
b = QPushButton(_("Render LaTeX"))
|
b = QPushButton(tr(StringsGroup.MEDIA_CHECK, "render-latex"))
|
||||||
b.setAutoDefault(False)
|
b.setAutoDefault(False)
|
||||||
box.addButton(b, QDialogButtonBox.RejectRole)
|
box.addButton(b, QDialogButtonBox.RejectRole)
|
||||||
b.clicked.connect(self._on_render_latex) # type: ignore
|
b.clicked.connect(self._on_render_latex) # type: ignore
|
||||||
@ -120,37 +125,34 @@ class MediaChecker:
|
|||||||
browser.onSearchActivated()
|
browser.onSearchActivated()
|
||||||
showText(err, type="html")
|
showText(err, type="html")
|
||||||
else:
|
else:
|
||||||
tooltip(_("All LaTeX rendered."))
|
tooltip(tr(StringsGroup.MEDIA_CHECK, "all-latex-rendered"))
|
||||||
|
|
||||||
def _on_render_latex_progress(self, count: int) -> bool:
|
def _on_render_latex_progress(self, count: int) -> bool:
|
||||||
if self.progress_dialog.wantCancel:
|
if self.progress_dialog.wantCancel:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.mw.progress.update(_("Checked {}...").format(count))
|
self.mw.progress.update(tr(StringsGroup.MEDIA_CHECK, "checked", count=count))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _on_trash_files(self, fnames: List[str]):
|
def _on_trash_files(self, fnames: List[str]):
|
||||||
if not askUser(_("Delete unused media?")):
|
if not askUser(tr(StringsGroup.MEDIA_CHECK, "delete-unused-confirm")):
|
||||||
return
|
return
|
||||||
|
|
||||||
self.progress_dialog = self.mw.progress.start()
|
self.progress_dialog = self.mw.progress.start()
|
||||||
|
|
||||||
last_progress = time.time()
|
last_progress = time.time()
|
||||||
remaining = len(fnames)
|
remaining = len(fnames)
|
||||||
|
total = len(fnames)
|
||||||
try:
|
try:
|
||||||
for chunk in chunked_list(fnames, 25):
|
for chunk in chunked_list(fnames, 25):
|
||||||
self.mw.col.media.trash_files(chunk)
|
self.mw.col.media.trash_files(chunk)
|
||||||
remaining -= len(chunk)
|
remaining -= len(chunk)
|
||||||
if time.time() - last_progress >= 0.3:
|
if time.time() - last_progress >= 0.3:
|
||||||
label = (
|
self.mw.progress.update(
|
||||||
ngettext(
|
tr(StringsGroup.MEDIA_CHECK, "files-remaining", count=remaining)
|
||||||
"%d file remaining...", "%d files remaining...", remaining,
|
|
||||||
)
|
|
||||||
% remaining
|
|
||||||
)
|
)
|
||||||
self.mw.progress.update(label)
|
|
||||||
finally:
|
finally:
|
||||||
self.mw.progress.finish()
|
self.mw.progress.finish()
|
||||||
self.progress_dialog = None
|
self.progress_dialog = None
|
||||||
|
|
||||||
tooltip(_("Files moved to trash."))
|
tooltip(tr(StringsGroup.MEDIA_CHECK, "delete-unused-complete", count=total))
|
||||||
|
@ -19,6 +19,7 @@ from anki.rsbackend import (
|
|||||||
NetworkErrorKind,
|
NetworkErrorKind,
|
||||||
Progress,
|
Progress,
|
||||||
ProgressKind,
|
ProgressKind,
|
||||||
|
StringsGroup,
|
||||||
SyncError,
|
SyncError,
|
||||||
SyncErrorKind,
|
SyncErrorKind,
|
||||||
)
|
)
|
||||||
@ -26,7 +27,7 @@ from anki.types import assert_impossible
|
|||||||
from anki.utils import intTime
|
from anki.utils import intTime
|
||||||
from aqt import gui_hooks
|
from aqt import gui_hooks
|
||||||
from aqt.qt import QDialog, QDialogButtonBox, QPushButton
|
from aqt.qt import QDialog, QDialogButtonBox, QPushButton
|
||||||
from aqt.utils import showWarning
|
from aqt.utils import showWarning, tr
|
||||||
|
|
||||||
LogEntry = Union[MediaSyncProgress, str]
|
LogEntry = Union[MediaSyncProgress, str]
|
||||||
|
|
||||||
@ -68,10 +69,10 @@ class MediaSyncer:
|
|||||||
return
|
return
|
||||||
|
|
||||||
if not self.mw.pm.media_syncing_enabled():
|
if not self.mw.pm.media_syncing_enabled():
|
||||||
self._log_and_notify(_("Media syncing disabled."))
|
self._log_and_notify(tr(StringsGroup.SYNC, "media-disabled"))
|
||||||
return
|
return
|
||||||
|
|
||||||
self._log_and_notify(_("Media sync starting..."))
|
self._log_and_notify(tr(StringsGroup.SYNC, "media-starting"))
|
||||||
self._syncing = True
|
self._syncing = True
|
||||||
self._want_stop = False
|
self._want_stop = False
|
||||||
gui_hooks.media_sync_did_start_or_stop(True)
|
gui_hooks.media_sync_did_start_or_stop(True)
|
||||||
@ -104,14 +105,14 @@ class MediaSyncer:
|
|||||||
if exc is not None:
|
if exc is not None:
|
||||||
self._handle_sync_error(exc)
|
self._handle_sync_error(exc)
|
||||||
else:
|
else:
|
||||||
self._log_and_notify(_("Media sync complete."))
|
self._log_and_notify(tr(StringsGroup.SYNC, "media-complete"))
|
||||||
|
|
||||||
def _handle_sync_error(self, exc: BaseException):
|
def _handle_sync_error(self, exc: BaseException):
|
||||||
if isinstance(exc, Interrupted):
|
if isinstance(exc, Interrupted):
|
||||||
self._log_and_notify(_("Media sync aborted."))
|
self._log_and_notify(tr(StringsGroup.SYNC, "media-aborted"))
|
||||||
return
|
return
|
||||||
|
|
||||||
self._log_and_notify(_("Media sync failed."))
|
self._log_and_notify(tr(StringsGroup.SYNC, "media-failed"))
|
||||||
if isinstance(exc, SyncError):
|
if isinstance(exc, SyncError):
|
||||||
kind = exc.kind()
|
kind = exc.kind()
|
||||||
if kind == SyncErrorKind.AUTH_FAILED:
|
if kind == SyncErrorKind.AUTH_FAILED:
|
||||||
@ -156,7 +157,7 @@ class MediaSyncer:
|
|||||||
def abort(self) -> None:
|
def abort(self) -> None:
|
||||||
if not self.is_syncing():
|
if not self.is_syncing():
|
||||||
return
|
return
|
||||||
self._log_and_notify(_("Media sync aborting..."))
|
self._log_and_notify(tr(StringsGroup.SYNC, "media-aborting"))
|
||||||
self._want_stop = True
|
self._want_stop = True
|
||||||
|
|
||||||
def is_syncing(self) -> bool:
|
def is_syncing(self) -> bool:
|
||||||
@ -199,7 +200,7 @@ class MediaSyncDialog(QDialog):
|
|||||||
self._close_when_done = close_when_done
|
self._close_when_done = close_when_done
|
||||||
self.form = aqt.forms.synclog.Ui_Dialog()
|
self.form = aqt.forms.synclog.Ui_Dialog()
|
||||||
self.form.setupUi(self)
|
self.form.setupUi(self)
|
||||||
self.abort_button = QPushButton(_("Abort"))
|
self.abort_button = QPushButton(tr(StringsGroup.SYNC, "abort"))
|
||||||
self.abort_button.clicked.connect(self._on_abort) # type: ignore
|
self.abort_button.clicked.connect(self._on_abort) # type: ignore
|
||||||
self.abort_button.setAutoDefault(False)
|
self.abort_button.setAutoDefault(False)
|
||||||
self.form.buttonBox.addButton(self.abort_button, QDialogButtonBox.ActionRole)
|
self.form.buttonBox.addButton(self.abort_button, QDialogButtonBox.ActionRole)
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
# Copyright: Ankitects Pty Ltd and contributors
|
# Copyright: Ankitects Pty Ltd and contributors
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional, Union
|
||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
from anki.lang import _
|
from anki.lang import _
|
||||||
|
from anki.rsbackend import StringsGroup
|
||||||
from anki.utils import invalidFilename, isMac, isWin, noBundledLibs, versionWithBuild
|
from anki.utils import invalidFilename, isMac, isWin, noBundledLibs, versionWithBuild
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
from aqt.theme import theme_manager
|
from aqt.theme import theme_manager
|
||||||
@ -27,6 +31,12 @@ def locale_dir() -> str:
|
|||||||
return os.path.join(aqt_data_folder(), "locale")
|
return os.path.join(aqt_data_folder(), "locale")
|
||||||
|
|
||||||
|
|
||||||
|
def tr(group: StringsGroup, key: str, **kwargs: Union[str, int, float]) -> str:
|
||||||
|
"""Shortcut to access translations from the backend.
|
||||||
|
(Currently) requires an open collection."""
|
||||||
|
return aqt.mw.col.backend.translate(group, key, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def openHelp(section):
|
def openHelp(section):
|
||||||
link = aqt.appHelpSite
|
link = aqt.appHelpSite
|
||||||
if section:
|
if section:
|
||||||
|
@ -19,3 +19,17 @@ missing-file = Missing: {$filename}
|
|||||||
unused-file = Unused: {$filename}
|
unused-file = Unused: {$filename}
|
||||||
|
|
||||||
checked = Checked {$count}...
|
checked = Checked {$count}...
|
||||||
|
|
||||||
|
delete-unused = Delete Unused
|
||||||
|
delete-unused-confirm = Delete unused media?
|
||||||
|
files-remaining = {$count ->
|
||||||
|
[one] 1 file
|
||||||
|
*[other] {$count} files
|
||||||
|
} remaining.
|
||||||
|
delete-unused-complete = {$count ->
|
||||||
|
[one] 1 file
|
||||||
|
*[other] {$count} files
|
||||||
|
} moved to the trash.
|
||||||
|
|
||||||
|
render-latex = Render LaTeX
|
||||||
|
all-latex-rendered = All LaTeX rendered.
|
||||||
|
@ -1,3 +1,16 @@
|
|||||||
|
### Messages shown when synchronizing with AnkiWeb.
|
||||||
|
|
||||||
|
## Media synchronization
|
||||||
|
|
||||||
media-added-count = Added: {$up}↑ {$down}↓
|
media-added-count = Added: {$up}↑ {$down}↓
|
||||||
media-removed-count = Removed: {$up}↑ {$down}↓
|
media-removed-count = Removed: {$up}↑ {$down}↓
|
||||||
media-checked-count = Checked: {$count}
|
media-checked-count = Checked: {$count}
|
||||||
|
|
||||||
|
media-starting = Media sync starting...
|
||||||
|
media-complete = Media sync complete.
|
||||||
|
media-failed = Media sync failed.
|
||||||
|
media-aborting = Media sync aborting...
|
||||||
|
media-aborted = Media sync aborted.
|
||||||
|
media-disabled = Media sync disabled.
|
||||||
|
|
||||||
|
abort-button = Abort
|
||||||
|
Loading…
Reference in New Issue
Block a user