add public wrappers for remaining backend functions

This commit is contained in:
Damien Elmes 2021-01-31 18:46:43 +10:00
parent c7f92f0737
commit 6c483bb577
12 changed files with 94 additions and 36 deletions

View file

@ -20,6 +20,7 @@ from . import rsbridge
if TYPE_CHECKING:
from anki.lang import FormatTimeSpanContextValue, TRValue
# pylint: disable=c-extension-no-member
assert rsbridge.buildhash() == anki.buildinfo.buildhash

View file

@ -33,7 +33,9 @@ LABEL_REQUIRED = 2
LABEL_REPEATED = 3
# messages we don't want to unroll in codegen
SKIP_UNROLL_INPUT = {"TranslateString"}
SKIP_UNROLL_INPUT = {"TranslateString", "SetPreferences"}
SKIP_UNROLL_OUTPUT = {"GetPreferences"}
SKIP_DECODE = {"Graphs", "GetGraphPreferences"}
@ -114,6 +116,7 @@ def render_method(method, idx):
if (
len(method.output_type.fields) == 1
and method.output_type.fields[0].type != TYPE_ENUM
and method.name not in SKIP_UNROLL_OUTPUT
):
# unwrap single return arg
f = method.output_type.fields[0]

View file

@ -32,6 +32,7 @@ from anki.models import ModelManager
from anki.notes import Note
from anki.sched import Scheduler as V1Scheduler
from anki.schedv2 import Scheduler as V2Scheduler
from anki.sync import SyncAuth, SyncOutput, SyncStatus
from anki.tags import TagManager
from anki.utils import (
devMode,
@ -53,6 +54,7 @@ EmptyCardsReport = _pb.EmptyCardsReport
NoteWithEmptyCards = _pb.NoteWithEmptyCards
GraphPreferences = _pb.GraphPreferences
BuiltinSortKind = _pb.SortOrder.Builtin.Kind # pylint: disable=no-member
Preferences = _pb.Preferences
# pylint: disable=no-member
if TYPE_CHECKING:
@ -819,6 +821,44 @@ table.review-log {{ {revlog_style} }}
intTime(),
)
##########################################################################
def set_wants_abort(self) -> None:
self.backend.set_wants_abort()
def i18n_resources(self) -> bytes:
return self.backend.i18n_resources()
def abort_media_sync(self) -> None:
self.backend.abort_media_sync()
def abort_sync(self) -> None:
self.backend.abort_sync()
def full_upload(self, auth: SyncAuth) -> None:
self.backend.full_upload(auth)
def full_download(self, auth: SyncAuth) -> None:
self.backend.full_download(auth)
def sync_login(self, username: str, password: str) -> SyncAuth:
return self.backend.sync_login(username=username, password=password)
def sync_collection(self, auth: SyncAuth) -> SyncOutput:
return self.backend.sync_collection(auth)
def sync_media(self, auth: SyncAuth) -> None:
self.backend.sync_media(auth)
def sync_status(self, auth: SyncAuth) -> SyncStatus:
return self.backend.sync_status(auth)
def get_preferences(self) -> Preferences:
return self.backend.get_preferences()
def set_preferences(self, prefs: Preferences):
self.backend.set_preferences(prefs)
class ProgressKind(enum.Enum):
NoProgress = 0

View file

@ -17,6 +17,8 @@ import anki
import anki._backend.backend_pb2 as _pb
from anki.consts import *
from anki.latex import render_latex, render_latex_returning_errors
from anki.sound import SoundOrVideoTag
from anki.template import av_tags_to_native
from anki.utils import intTime
@ -98,6 +100,24 @@ class MediaManager:
except FileNotFoundError:
pass
def empty_trash(self) -> None:
self.col.backend.empty_trash()
def restore_trash(self) -> None:
self.col.backend.restore_trash()
def strip_av_tags(self, text: str) -> str:
return self.col.backend.strip_av_tags(text)
def _extract_filenames(self, text: str) -> List[str]:
"This only exists do support a legacy function; do not use."
out = self.col.backend.extract_av_tags(text=text, question_side=True)
return [
x.filename
for x in av_tags_to_native(out.av_tags)
if isinstance(x, SoundOrVideoTag)
]
# File manipulation
##########################################################################

View file

@ -92,7 +92,7 @@ class TagManager:
nids=nids, tags=tags, replacement=replacement, regex=regex
)
def rename_tag(self, old: str, new: str) -> int:
def rename(self, old: str, new: str) -> int:
"Rename provided tag, returning number of changed notes."
nids = self.col.find_notes(anki.collection.SearchTerm(tag=old))
if not nids:
@ -100,6 +100,9 @@ class TagManager:
escaped_name = re.sub(r"[*_\\]", r"\\\g<0>", old)
return self.bulk_update(nids, escaped_name, new, False)
def remove(self, tag: str) -> None:
self.col.backend.clear_tag(tag)
# legacy routines
def bulkAdd(self, ids: List[int], tags: str, add: bool = True) -> None:

View file

@ -10,8 +10,6 @@ from typing import List
import anki
import aqt
from anki.sound import SoundOrVideoTag
from anki.template import av_tags_to_native
from aqt.theme import theme_manager
# Routines removed from pylib/
@ -25,21 +23,16 @@ def bodyClass(col, card) -> str:
def allSounds(text) -> List:
print("allSounds() deprecated")
out = aqt.mw.col.backend.extract_av_tags(text=text, question_side=True)
return [
x.filename
for x in av_tags_to_native(out.av_tags)
if isinstance(x, SoundOrVideoTag)
]
return aqt.mw.col.media._extract_filenames(text)
def stripSounds(text) -> str:
print("stripSounds() deprecated")
return aqt.mw.col.backend.strip_av_tags(text)
return aqt.mw.col.media.strip_av_tags(text)
def fmtTimeSpan(time, pad=0, point=0, short=False, inTime=False, unit=99):
print("fmtTimeSpan() has become col.backend.format_time_span()")
print("fmtTimeSpan() has become col.format_timespan()")
return aqt.mw.col.format_timespan(time)

View file

@ -69,7 +69,7 @@ class MediaChecker:
try:
if self.progress_dialog.wantCancel:
self.mw.col.backend.set_wants_abort()
self.mw.col.set_wants_abort()
except AttributeError:
# dialog may not be active
pass
@ -188,7 +188,7 @@ class MediaChecker:
self._set_progress_enabled(True)
def empty_trash():
self.mw.col.backend.empty_trash()
self.mw.col.media.empty_trash()
def on_done(fut: Future):
self.mw.progress.finish()
@ -205,7 +205,7 @@ class MediaChecker:
self._set_progress_enabled(True)
def restore_trash():
self.mw.col.backend.restore_trash()
self.mw.col.media.restore_trash()
def on_done(fut: Future):
self.mw.progress.finish()

View file

@ -274,7 +274,7 @@ post_handlers = {
"graphPreferences": graph_preferences,
"setGraphPreferences": set_graph_preferences,
# pylint: disable=unnecessary-lambda
"i18nResources": lambda: aqt.mw.col.backend.i18n_resources(),
"i18nResources": lambda: aqt.mw.col.i18n_resources(),
"congratsInfo": congrats_info,
}

View file

@ -64,7 +64,7 @@ class MediaSyncer:
gui_hooks.media_sync_did_start_or_stop(True)
def run() -> None:
self.mw.col.backend.sync_media(auth)
self.mw.col.sync_media(auth)
self.mw.taskman.run_in_background(run, self._on_finished)
@ -107,8 +107,8 @@ class MediaSyncer:
if not self.is_syncing():
return
self._log_and_notify(tr(TR.SYNC_MEDIA_ABORTING))
self.mw.col.backend.set_wants_abort()
self.mw.col.backend.abort_media_sync()
self.mw.col.set_wants_abort()
self.mw.col.abort_media_sync()
def is_syncing(self) -> bool:
return self._syncing

View file

@ -47,7 +47,7 @@ class Preferences(QDialog):
self.form.buttonBox.helpRequested, lambda: openHelp(HelpPage.PREFERENCES)
)
self.silentlyClose = True
self.prefs = self.mw.col.backend.get_preferences()
self.prefs = self.mw.col.get_preferences()
self.setupLang()
self.setupCollection()
self.setupNetwork()
@ -114,7 +114,7 @@ class Preferences(QDialog):
f.useCurrent.setCurrentIndex(int(not qc.get("addToCur", True)))
s = self.prefs
s = self.prefs.sched
f.lrnCutoff.setValue(int(s.learn_ahead_secs / 60.0))
f.timeLimit.setValue(int(s.time_limit_secs / 60.0))
f.showEstimates.setChecked(s.show_intervals_on_buttons)
@ -156,7 +156,7 @@ class Preferences(QDialog):
qc = d.conf
qc["addToCur"] = not f.useCurrent.currentIndex()
s = self.prefs
s = self.prefs.sched
s.show_remaining_due_counts = f.showProgress.isChecked()
s.show_intervals_on_buttons = f.showEstimates.isChecked()
s.new_review_mix = f.newSpread.currentIndex()
@ -168,7 +168,7 @@ class Preferences(QDialog):
# if moving this, make sure scheduler change is moved to Rust or
# happens afterwards
self.mw.col.backend.set_preferences(self.prefs)
self.mw.col.set_preferences(self.prefs)
self._updateSchedVer(f.newSched.isChecked())
d.setMod()

View file

@ -691,8 +691,8 @@ class SidebarTreeView(QTreeView):
old_name = item.full_name
def do_remove():
self.mw.col.backend.clear_tag(old_name)
self.col.tags.rename_tag(old_name, "")
self.mw.col.tags.remove(old_name)
self.col.tags.rename(old_name, "")
def on_done(fut: Future):
self.mw.requireReset(reason=ResetReason.BrowserRemoveTags, context=self)
@ -714,8 +714,8 @@ class SidebarTreeView(QTreeView):
return
def do_rename():
self.mw.col.backend.clear_tag(old_name)
return self.col.tags.rename_tag(old_name, new_name)
self.mw.col.tags.remove(old_name)
return self.col.tags.rename(old_name, new_name)
def on_done(fut: Future):
self.mw.requireReset(reason=ResetReason.BrowserAddTags, context=self)

View file

@ -54,9 +54,7 @@ def get_sync_status(mw: aqt.main.AnkiQt, callback: Callable[[SyncStatus], None])
return
callback(out)
mw.taskman.run_in_background(
lambda: mw.col.backend.sync_status(auth), on_future_done
)
mw.taskman.run_in_background(lambda: mw.col.sync_status(auth), on_future_done)
def handle_sync_error(mw: aqt.main.AnkiQt, err: Exception):
@ -82,7 +80,7 @@ def on_normal_sync_timer(mw: aqt.main.AnkiQt) -> None:
mw.progress.set_title(progress.val.stage)
if mw.progress.want_cancel():
mw.col.backend.abort_sync()
mw.col.abort_sync()
def sync_collection(mw: aqt.main.AnkiQt, on_done: Callable[[], None]) -> None:
@ -116,7 +114,7 @@ def sync_collection(mw: aqt.main.AnkiQt, on_done: Callable[[], None]) -> None:
mw.col.save(trx=False)
mw.taskman.with_progress(
lambda: mw.col.backend.sync_collection(auth),
lambda: mw.col.sync_collection(auth),
on_future_done,
label=tr(TR.SYNC_CHECKING),
immediate=True,
@ -167,7 +165,7 @@ def on_full_sync_timer(mw: aqt.main.AnkiQt) -> None:
)
if mw.progress.want_cancel():
mw.col.backend.abort_sync()
mw.col.abort_sync()
def full_download(mw: aqt.main.AnkiQt, on_done: Callable[[], None]) -> None:
@ -192,7 +190,7 @@ def full_download(mw: aqt.main.AnkiQt, on_done: Callable[[], None]) -> None:
return on_done()
mw.taskman.with_progress(
lambda: mw.col.backend.full_download(mw.pm.sync_auth()),
lambda: mw.col.full_download(mw.pm.sync_auth()),
on_future_done,
label=tr(TR.SYNC_DOWNLOADING_FROM_ANKIWEB),
)
@ -221,7 +219,7 @@ def full_upload(mw: aqt.main.AnkiQt, on_done: Callable[[], None]) -> None:
return on_done()
mw.taskman.with_progress(
lambda: mw.col.backend.full_upload(mw.pm.sync_auth()),
lambda: mw.col.full_upload(mw.pm.sync_auth()),
on_future_done,
label=tr(TR.SYNC_UPLOADING_TO_ANKIWEB),
)
@ -258,7 +256,7 @@ def sync_login(
on_success()
mw.taskman.with_progress(
lambda: mw.col.backend.sync_login(username=username, password=password),
lambda: mw.col.sync_login(username=username, password=password),
on_future_done,
)