From 5d810dd7991865cdabc963549c4748e2e26e533d Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sun, 31 Jan 2021 18:54:13 +1000 Subject: [PATCH] make backend instance on col private --- pylib/anki/cards.py | 6 +- pylib/anki/collection.py | 97 +++++++++++++++++-------------- pylib/anki/config.py | 6 +- pylib/anki/decks.py | 30 +++++----- pylib/anki/find.py | 4 +- pylib/anki/latex.py | 2 +- pylib/anki/media.py | 14 ++--- pylib/anki/models.py | 22 +++---- pylib/anki/notes.py | 12 ++-- pylib/anki/schedv2.py | 40 ++++++------- pylib/anki/stats.py | 2 +- pylib/anki/stdmodels.py | 4 +- pylib/anki/syncserver/__init__.py | 2 +- pylib/anki/tags.py | 16 ++--- pylib/anki/template.py | 8 +-- pylib/tests/test_cards.py | 4 +- 16 files changed, 140 insertions(+), 129 deletions(-) diff --git a/pylib/anki/cards.py b/pylib/anki/cards.py index 9feb923ea..9b5068b45 100644 --- a/pylib/anki/cards.py +++ b/pylib/anki/cards.py @@ -48,7 +48,7 @@ class Card: self._load_from_backend_card(_pb.Card()) def load(self) -> None: - c = self.col.backend.get_card(self.id) + c = self.col._backend.get_card(self.id) assert c self._load_from_backend_card(c) @@ -105,9 +105,9 @@ class Card: data=self.data, ) if self.id != 0: - self.col.backend.update_card(card) + self.col._backend.update_card(card) else: - self.id = self.col.backend.add_card(card) + self.id = self.col._backend.add_card(card) def question(self, reload: bool = False, browser: bool = False) -> str: return self.render_output(reload, browser).question_and_style() diff --git a/pylib/anki/collection.py b/pylib/anki/collection.py index 8cc135703..c21fc57ac 100644 --- a/pylib/anki/collection.py +++ b/pylib/anki/collection.py @@ -75,7 +75,7 @@ class Collection: server: bool = False, log: bool = False, ) -> None: - self.backend = backend or RustBackend(server=server) + self._backend = backend or RustBackend(server=server) self.db: Optional[DBProxy] = None self._should_log = log self.server = server @@ -105,24 +105,33 @@ class Collection: "Shortcut to create a weak reference that doesn't break code completion." return weakref.proxy(self) + @property + def backend(self) -> RustBackend: + traceback.print_stack() + print() + print( + "Accessing the backend directly will break in the future. Please use the public methods on Collection instead." + ) + return self._backend + # I18n/messages ########################################################################## def tr(self, key: TRValue, **kwargs: Union[str, int, float]) -> str: - return self.backend.translate(key, **kwargs) + return self._backend.translate(key, **kwargs) def format_timespan( self, seconds: float, context: FormatTimeSpanContextValue = FormatTimeSpanContext.INTERVALS, ) -> str: - return self.backend.format_timespan(seconds=seconds, context=context) + return self._backend.format_timespan(seconds=seconds, context=context) # Progress ########################################################################## def latest_progress(self) -> Progress: - return Progress.from_proto(self.backend.latest_progress()) + return Progress.from_proto(self._backend.latest_progress()) # Scheduler ########################################################################## @@ -253,7 +262,7 @@ class Collection: else: self.db.rollback() self.models._clear_cache() - self.backend.close_collection(downgrade_to_schema11=downgrade) + self._backend.close_collection(downgrade_to_schema11=downgrade) self.db = None self.media.close() self._closeLog() @@ -284,7 +293,7 @@ class Collection: # connect if not after_full_sync: - self.backend.open_collection( + self._backend.open_collection( collection_path=self.path, media_folder_path=media_dir, media_db_path=media_db, @@ -292,7 +301,7 @@ class Collection: ) else: self.media.connect() - self.db = DBProxy(weakref.proxy(self.backend)) + self.db = DBProxy(weakref.proxy(self._backend)) self.db.begin() self._openLog() @@ -316,7 +325,7 @@ class Collection: def beforeUpload(self) -> None: "Called before a full upload." self.save(trx=False) - self.backend.before_upload() + self._backend.before_upload() self.close(save=False, downgrade=True) # Object creation helpers @@ -362,11 +371,11 @@ class Collection: return Note(self, self.models.current(forDeck)) def add_note(self, note: Note, deck_id: int) -> None: - note.id = self.backend.add_note(note=note.to_backend_note(), deck_id=deck_id) + note.id = self._backend.add_note(note=note.to_backend_note(), deck_id=deck_id) def remove_notes(self, note_ids: Sequence[int]) -> None: hooks.notes_will_be_deleted(self, note_ids) - self.backend.remove_notes(note_ids=note_ids, card_ids=[]) + self._backend.remove_notes(note_ids=note_ids, card_ids=[]) def remove_notes_by_card(self, card_ids: List[int]) -> None: if hooks.notes_will_be_deleted.count(): @@ -374,10 +383,10 @@ class Collection: "select nid from cards where id in " + ids2str(card_ids) ) hooks.notes_will_be_deleted(self, nids) - self.backend.remove_notes(note_ids=[], card_ids=card_ids) + self._backend.remove_notes(note_ids=[], card_ids=card_ids) def card_ids_of_note(self, note_id: int) -> Sequence[int]: - return self.backend.cards_of_note(note_id) + return self._backend.cards_of_note(note_id) # legacy @@ -402,13 +411,13 @@ class Collection: def remove_cards_and_orphaned_notes(self, card_ids: Sequence[int]): "You probably want .remove_notes_by_card() instead." - self.backend.remove_cards(card_ids=card_ids) + self._backend.remove_cards(card_ids=card_ids) def set_deck(self, card_ids: List[int], deck_id: int) -> None: - self.backend.set_deck(card_ids=card_ids, deck_id=deck_id) + self._backend.set_deck(card_ids=card_ids, deck_id=deck_id) def get_empty_cards(self) -> EmptyCardsReport: - return self.backend.get_empty_cards() + return self._backend.get_empty_cards() # legacy @@ -425,7 +434,7 @@ class Collection: def after_note_updates( self, nids: List[int], mark_modified: bool, generate_cards: bool = True ) -> None: - self.backend.after_note_updates( + self._backend.after_note_updates( nids=nids, generate_cards=generate_cards, mark_notes_modified=mark_modified ) @@ -472,10 +481,10 @@ class Collection: mode = _pb.SortOrder( builtin=_pb.SortOrder.Builtin(kind=order, reverse=reverse) ) - return self.backend.search_cards(search=query, order=mode) + return self._backend.search_cards(search=query, order=mode) def find_notes(self, *terms: Union[str, SearchTerm]) -> Sequence[int]: - return self.backend.search_notes(self.build_search_string(*terms)) + return self._backend.search_notes(self.build_search_string(*terms)) def find_and_replace( self, @@ -544,19 +553,19 @@ class Collection: searches = [] for term in terms: if isinstance(term, SearchTerm): - term = self.backend.filter_to_search(term) + term = self._backend.filter_to_search(term) searches.append(term) if match_any: sep = _pb.ConcatenateSearchesIn.Separator.OR else: sep = _pb.ConcatenateSearchesIn.Separator.AND - search_string = self.backend.concatenate_searches(sep=sep, searches=searches) + search_string = self._backend.concatenate_searches(sep=sep, searches=searches) if negate: - search_string = self.backend.negate_search(search_string) + search_string = self._backend.negate_search(search_string) return search_string def replace_search_term(self, search: str, replacement: str) -> str: - return self.backend.replace_search_term(search=search, replacement=replacement) + return self._backend.replace_search_term(search=search, replacement=replacement) # Config ########################################################################## @@ -577,14 +586,14 @@ class Collection: def all_config(self) -> Dict[str, Any]: "This is a debugging aid. Prefer .get_config() when you know the key you need." - return from_json_bytes(self.backend.get_all_config()) + return from_json_bytes(self._backend.get_all_config()) def get_config_bool(self, key: ConfigBoolKeyValue) -> bool: - return self.backend.get_config_bool(key) + return self._backend.get_config_bool(key) def set_config_bool(self, key: ConfigBoolKeyValue, value: bool) -> None: self.setMod() - self.backend.set_config_bool(key=key, value=value) + self._backend.set_config_bool(key=key, value=value) # Stats ########################################################################## @@ -610,23 +619,23 @@ class Collection: table.review-log {{ {revlog_style} }} """ - return style + self.backend.card_stats(card_id) + return style + self._backend.card_stats(card_id) def studied_today(self) -> str: - return self.backend.studied_today() + return self._backend.studied_today() def graph_data(self, search: str, days: int) -> bytes: - return self.backend.graphs(search=search, days=days) + return self._backend.graphs(search=search, days=days) def get_graph_preferences(self) -> bytes: - return self.backend.get_graph_preferences() + return self._backend.get_graph_preferences() def set_graph_preferences(self, prefs: GraphPreferences) -> None: - self.backend.set_graph_preferences(input=prefs) + self._backend.set_graph_preferences(input=prefs) def congrats_info(self) -> bytes: "Don't use this, it will likely go away in the future." - return self.backend.congrats_info().SerializeToString() + return self._backend.congrats_info().SerializeToString() # legacy @@ -747,7 +756,7 @@ table.review-log {{ {revlog_style} }} """ self.save(trx=False) try: - problems = list(self.backend.check_database()) + problems = list(self._backend.check_database()) ok = not problems problems.append(self.tr(TR.DATABASE_CHECK_REBUILT)) except DBError as e: @@ -824,40 +833,40 @@ table.review-log {{ {revlog_style} }} ########################################################################## def set_wants_abort(self) -> None: - self.backend.set_wants_abort() + self._backend.set_wants_abort() def i18n_resources(self) -> bytes: - return self.backend.i18n_resources() + return self._backend.i18n_resources() def abort_media_sync(self) -> None: - self.backend.abort_media_sync() + self._backend.abort_media_sync() def abort_sync(self) -> None: - self.backend.abort_sync() + self._backend.abort_sync() def full_upload(self, auth: SyncAuth) -> None: - self.backend.full_upload(auth) + self._backend.full_upload(auth) def full_download(self, auth: SyncAuth) -> None: - self.backend.full_download(auth) + self._backend.full_download(auth) def sync_login(self, username: str, password: str) -> SyncAuth: - return self.backend.sync_login(username=username, password=password) + return self._backend.sync_login(username=username, password=password) def sync_collection(self, auth: SyncAuth) -> SyncOutput: - return self.backend.sync_collection(auth) + return self._backend.sync_collection(auth) def sync_media(self, auth: SyncAuth) -> None: - self.backend.sync_media(auth) + self._backend.sync_media(auth) def sync_status(self, auth: SyncAuth) -> SyncStatus: - return self.backend.sync_status(auth) + return self._backend.sync_status(auth) def get_preferences(self) -> Preferences: - return self.backend.get_preferences() + return self._backend.get_preferences() def set_preferences(self, prefs: Preferences): - self.backend.set_preferences(prefs) + self._backend.set_preferences(prefs) class ProgressKind(enum.Enum): diff --git a/pylib/anki/config.py b/pylib/anki/config.py index bad5a804f..46bb1e1b7 100644 --- a/pylib/anki/config.py +++ b/pylib/anki/config.py @@ -33,15 +33,15 @@ class ConfigManager: def get_immutable(self, key: str) -> Any: try: - return from_json_bytes(self.col.backend.get_config_json(key)) + return from_json_bytes(self.col._backend.get_config_json(key)) except NotFoundError as exc: raise KeyError from exc def set(self, key: str, val: Any) -> None: - self.col.backend.set_config_json(key=key, value_json=to_json_bytes(val)) + self.col._backend.set_config_json(key=key, value_json=to_json_bytes(val)) def remove(self, key: str) -> None: - self.col.backend.remove_config(key) + self.col._backend.remove_config(key) # Legacy dict interface ######################### diff --git a/pylib/anki/decks.py b/pylib/anki/decks.py index d50c4b611..9c0aec102 100644 --- a/pylib/anki/decks.py +++ b/pylib/anki/decks.py @@ -132,25 +132,25 @@ class DeckManager: if isinstance(did, str): did = int(did) assert cardsToo and childrenToo - self.col.backend.remove_deck(did) + self.col._backend.remove_deck(did) def all_names_and_ids( self, skip_empty_default=False, include_filtered=True ) -> Sequence[DeckNameID]: "A sorted sequence of deck names and IDs." - return self.col.backend.get_deck_names( + return self.col._backend.get_deck_names( skip_empty_default=skip_empty_default, include_filtered=include_filtered ) def id_for_name(self, name: str) -> Optional[int]: try: - return self.col.backend.get_deck_id_by_name(name) + return self.col._backend.get_deck_id_by_name(name) except NotFoundError: return None def get_legacy(self, did: int) -> Optional[Deck]: try: - return from_json_bytes(self.col.backend.get_deck_legacy(did)) + return from_json_bytes(self.col._backend.get_deck_legacy(did)) except NotFoundError: return None @@ -158,13 +158,13 @@ class DeckManager: return not self.get_legacy(int(id)) def get_all_legacy(self) -> List[Deck]: - return list(from_json_bytes(self.col.backend.get_all_decks_legacy()).values()) + return list(from_json_bytes(self.col._backend.get_all_decks_legacy()).values()) def new_deck_legacy(self, filtered: bool) -> Deck: - return from_json_bytes(self.col.backend.new_deck_legacy(filtered)) + return from_json_bytes(self.col._backend.new_deck_legacy(filtered)) def deck_tree(self) -> DeckTreeNode: - return self.col.backend.deck_tree(top_deck_id=0, now=0) + return self.col._backend.deck_tree(top_deck_id=0, now=0) @classmethod def find_deck_in_tree( @@ -244,7 +244,7 @@ class DeckManager: def update(self, g: Deck, preserve_usn=True) -> None: "Add or update an existing deck. Used for syncing and merging." try: - g["id"] = self.col.backend.add_or_update_deck_legacy( + g["id"] = self.col._backend.add_or_update_deck_legacy( deck=to_json_bytes(g), preserve_usn_and_mtime=preserve_usn ) except DeckIsFilteredError as exc: @@ -262,7 +262,7 @@ class DeckManager: def drag_drop_decks(self, source_decks: List[DeckID], target_deck: DeckID) -> None: """Rename one or more source decks that were dropped on `target_deck`. If target_deck is 0, decks will be placed at the top level.""" - self.col.backend.drag_drop_decks( + self.col._backend.drag_drop_decks( source_deck_ids=source_decks, target_deck_id=target_deck ) @@ -281,7 +281,7 @@ class DeckManager: def all_config(self) -> List[Config]: "A list of all deck config." - return list(from_json_bytes(self.col.backend.all_deck_config_legacy())) + return list(from_json_bytes(self.col._backend.all_deck_config_legacy())) def confForDid(self, did: int) -> DeckConfig: deck = self.get(did, default=False) @@ -299,12 +299,12 @@ class DeckManager: def get_config(self, conf_id: int) -> Optional[DeckConfig]: try: - return from_json_bytes(self.col.backend.get_deck_config_legacy(conf_id)) + return from_json_bytes(self.col._backend.get_deck_config_legacy(conf_id)) except NotFoundError: return None def update_config(self, conf: DeckConfig, preserve_usn=False) -> None: - conf["id"] = self.col.backend.add_or_update_deck_config_legacy( + conf["id"] = self.col._backend.add_or_update_deck_config_legacy( config=to_json_bytes(conf), preserve_usn_and_mtime=preserve_usn ) @@ -315,7 +315,7 @@ class DeckManager: conf = copy.deepcopy(clone_from) conf["id"] = 0 else: - conf = from_json_bytes(self.col.backend.new_deck_config_legacy()) + conf = from_json_bytes(self.col._backend.new_deck_config_legacy()) conf["name"] = name self.update_config(conf) return conf @@ -335,7 +335,7 @@ class DeckManager: if str(g["conf"]) == str(id): g["conf"] = 1 self.save(g) - self.col.backend.remove_deck_config(id) + self.col._backend.remove_deck_config(id) def setConf(self, grp: DeckConfig, id: int) -> None: grp["conf"] = id @@ -350,7 +350,7 @@ class DeckManager: def restoreToDefault(self, conf) -> None: oldOrder = conf["new"]["order"] - new = from_json_bytes(self.col.backend.new_deck_config_legacy()) + new = from_json_bytes(self.col._backend.new_deck_config_legacy()) new["id"] = conf["id"] new["name"] = conf["name"] self.update_config(new) diff --git a/pylib/anki/find.py b/pylib/anki/find.py index ff83d5e2e..553c9b35e 100644 --- a/pylib/anki/find.py +++ b/pylib/anki/find.py @@ -37,7 +37,7 @@ def findReplace( fold: bool = True, ) -> int: "Find and replace fields in a note. Returns changed note count." - return col.backend.find_and_replace( + return col._backend.find_and_replace( nids=nids, search=src, replacement=dst, @@ -48,7 +48,7 @@ def findReplace( def fieldNamesForNotes(col: Collection, nids: List[int]) -> List[str]: - return list(col.backend.field_names_for_notes(nids)) + return list(col._backend.field_names_for_notes(nids)) # Find duplicates diff --git a/pylib/anki/latex.py b/pylib/anki/latex.py index 4fb5138e8..486331406 100644 --- a/pylib/anki/latex.py +++ b/pylib/anki/latex.py @@ -86,7 +86,7 @@ def render_latex_returning_errors( header = model["latexPre"] footer = model["latexPost"] - proto = col.backend.extract_latex(text=html, svg=svg, expand_clozes=expand_clozes) + proto = col._backend.extract_latex(text=html, svg=svg, expand_clozes=expand_clozes) out = ExtractedLatexOutput.from_proto(proto) errors = [] html = out.html diff --git a/pylib/anki/media.py b/pylib/anki/media.py index 4721f1efb..0b294d45c 100644 --- a/pylib/anki/media.py +++ b/pylib/anki/media.py @@ -101,17 +101,17 @@ class MediaManager: pass def empty_trash(self) -> None: - self.col.backend.empty_trash() + self.col._backend.empty_trash() def restore_trash(self) -> None: - self.col.backend.restore_trash() + self.col._backend.restore_trash() def strip_av_tags(self, text: str) -> str: - return self.col.backend.strip_av_tags(text) + 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) + 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) @@ -132,7 +132,7 @@ class MediaManager: """Write the file to the media folder, renaming if not unique. Returns possibly-renamed filename.""" - return self.col.backend.add_media_file(desired_name=desired_fname, data=data) + return self.col._backend.add_media_file(desired_name=desired_fname, data=data) def add_extension_based_on_mime(self, fname: str, content_type: str) -> str: "If jpg or png mime, add .png/.jpg if missing extension." @@ -153,7 +153,7 @@ class MediaManager: def trash_files(self, fnames: List[str]) -> None: "Move provided files to the trash." - self.col.backend.trash_media_files(fnames) + self.col._backend.trash_media_files(fnames) # String manipulation ########################################################################## @@ -212,7 +212,7 @@ class MediaManager: ########################################################################## def check(self) -> CheckMediaOut: - output = self.col.backend.check_media() + output = self.col._backend.check_media() # files may have been renamed on disk, so an undo at this point could # break file references self.col.save() diff --git a/pylib/anki/models.py b/pylib/anki/models.py index 09b5f756d..e437171b3 100644 --- a/pylib/anki/models.py +++ b/pylib/anki/models.py @@ -130,10 +130,10 @@ class ModelManager: ############################################################# def all_names_and_ids(self) -> Sequence[NoteTypeNameID]: - return self.col.backend.get_notetype_names() + return self.col._backend.get_notetype_names() def all_use_counts(self) -> Sequence[NoteTypeNameIDUseCount]: - return self.col.backend.get_notetype_names_and_counts() + return self.col._backend.get_notetype_names_and_counts() # legacy @@ -170,7 +170,7 @@ class ModelManager: def id_for_name(self, name: str) -> Optional[int]: try: - return self.col.backend.get_notetype_id_by_name(name) + return self.col._backend.get_notetype_id_by_name(name) except NotFoundError: return None @@ -185,7 +185,7 @@ class ModelManager: nt = self._get_cached(id) if not nt: try: - nt = from_json_bytes(self.col.backend.get_notetype_legacy(id)) + nt = from_json_bytes(self.col._backend.get_notetype_legacy(id)) self._update_cache(nt) except NotFoundError: return None @@ -207,7 +207,7 @@ class ModelManager: "Create a new model, and return it." # caller should call save() after modifying nt = from_json_bytes( - self.col.backend.get_stock_notetype_legacy(StockNotetypeKind.BASIC) + self.col._backend.get_stock_notetype_legacy(StockNotetypeKind.BASIC) ) nt["flds"] = [] nt["tmpls"] = [] @@ -221,12 +221,12 @@ class ModelManager: def remove_all_notetypes(self): for nt in self.all_names_and_ids(): self._remove_from_cache(nt.id) - self.col.backend.remove_notetype(nt.id) + self.col._backend.remove_notetype(nt.id) def remove(self, id: int) -> None: "Modifies schema." self._remove_from_cache(id) - self.col.backend.remove_notetype(id) + self.col._backend.remove_notetype(id) def add(self, m: NoteType) -> None: self.save(m) @@ -240,7 +240,7 @@ class ModelManager: "Add or update an existing model. Use .save() instead." self._remove_from_cache(m["id"]) self.ensureNameUnique(m) - m["id"] = self.col.backend.add_or_update_notetype( + m["id"] = self.col._backend.add_or_update_notetype( json=to_json_bytes(m), preserve_usn_and_mtime=preserve_usn ) self.setCurrent(m) @@ -298,7 +298,7 @@ class ModelManager: def new_field(self, name: str) -> Field: assert isinstance(name, str) nt = from_json_bytes( - self.col.backend.get_stock_notetype_legacy(StockNotetypeKind.BASIC) + self.col._backend.get_stock_notetype_legacy(StockNotetypeKind.BASIC) ) field = nt["flds"][0] field["name"] = name @@ -357,7 +357,7 @@ class ModelManager: def new_template(self, name: str) -> Template: nt = from_json_bytes( - self.col.backend.get_stock_notetype_legacy(StockNotetypeKind.BASIC) + self.col._backend.get_stock_notetype_legacy(StockNotetypeKind.BASIC) ) template = nt["tmpls"][0] template["name"] = name @@ -511,4 +511,4 @@ and notes.mid = ? and cards.ord = ?""", ) -> List[int]: print("_availClozeOrds() is deprecated; use note.cloze_numbers_in_fields()") note = _pb.Note(fields=[flds]) - return list(self.col.backend.cloze_numbers_in_note(note)) + return list(self.col._backend.cloze_numbers_in_note(note)) diff --git a/pylib/anki/notes.py b/pylib/anki/notes.py index 0cf0ff3f3..4b33da9f8 100644 --- a/pylib/anki/notes.py +++ b/pylib/anki/notes.py @@ -34,10 +34,10 @@ class Note: self.load() else: # new note for provided notetype - self._load_from_backend_note(self.col.backend.new_note(model["id"])) + self._load_from_backend_note(self.col._backend.new_note(model["id"])) def load(self) -> None: - n = self.col.backend.get_note(self.id) + n = self.col._backend.get_note(self.id) assert n self._load_from_backend_note(n) @@ -65,7 +65,7 @@ class Note: def flush(self) -> None: assert self.id != 0 - self.col.backend.update_note(self.to_backend_note()) + self.col._backend.update_note(self.to_backend_note()) def __repr__(self) -> str: d = dict(self.__dict__) @@ -87,7 +87,7 @@ class Note: _model = property(model) def cloze_numbers_in_fields(self) -> Sequence[int]: - return self.col.backend.cloze_numbers_in_note(self.to_backend_note()) + return self.col._backend.cloze_numbers_in_note(self.to_backend_note()) # Dict interface ################################################## @@ -145,4 +145,6 @@ class Note: def dupeOrEmpty(self) -> int: "1 if first is empty; 2 if first is a duplicate, 0 otherwise." - return self.col.backend.note_is_duplicate_or_empty(self.to_backend_note()).state + return self.col._backend.note_is_duplicate_or_empty( + self.to_backend_note() + ).state diff --git a/pylib/anki/schedv2.py b/pylib/anki/schedv2.py index 5eec5ce5d..682974a29 100644 --- a/pylib/anki/schedv2.py +++ b/pylib/anki/schedv2.py @@ -231,7 +231,7 @@ order by due""" def update_stats( self, deck_id: int, new_delta=0, review_delta=0, milliseconds_delta=0 ): - self.col.backend.update_stats( + self.col._backend.update_stats( deck_id=deck_id, new_delta=new_delta, review_delta=review_delta, @@ -239,11 +239,11 @@ order by due""" ) def counts_for_deck_today(self, deck_id: int) -> CountsForDeckToday: - return self.col.backend.counts_for_deck_today(deck_id) + return self.col._backend.counts_for_deck_today(deck_id) def extendLimits(self, new: int, rev: int) -> None: did = self.col.decks.current()["id"] - self.col.backend.extend_limits(deck_id=did, new_delta=new, review_delta=rev) + self.col._backend.extend_limits(deck_id=did, new_delta=new, review_delta=rev) # legacy @@ -264,12 +264,12 @@ order by due""" print( "deckDueTree() is deprecated; use decks.deck_tree() for a tree without counts, or sched.deck_due_tree()" ) - return from_json_bytes(self.col.backend.deck_tree_legacy())[5] + return from_json_bytes(self.col._backend.deck_tree_legacy())[5] def deck_due_tree(self, top_deck_id: int = 0) -> DeckTreeNode: """Returns a tree of decks with counts. If top_deck_id provided, counts are limited to that node.""" - return self.col.backend.deck_tree(top_deck_id=top_deck_id, now=intTime()) + return self.col._backend.deck_tree(top_deck_id=top_deck_id, now=intTime()) # Getting the next card ########################################################################## @@ -1074,10 +1074,10 @@ select id from cards where did in %s and queue = {QUEUE_TYPE_REV} and due <= ? l ########################################################################## def rebuild_filtered_deck(self, deck_id: int) -> int: - return self.col.backend.rebuild_filtered_deck(deck_id) + return self.col._backend.rebuild_filtered_deck(deck_id) def empty_filtered_deck(self, deck_id: int) -> None: - self.col.backend.empty_filtered_deck(deck_id) + self.col._backend.empty_filtered_deck(deck_id) def _removeFromFiltered(self, card: Card) -> None: if card.odid: @@ -1233,13 +1233,13 @@ due = (case when odue>0 then odue else due end), odue = 0, odid = 0, usn = ? whe self.reset() def _timing_today(self) -> SchedTimingToday: - return self.col.backend.sched_timing_today() + return self.col._backend.sched_timing_today() # Deck finished state ########################################################################## def congratulations_info(self) -> CongratsInfo: - return self.col.backend.congrats_info() + return self.col._backend.congrats_info() def finishedMsg(self) -> str: print("finishedMsg() is obsolete") @@ -1321,19 +1321,19 @@ due = (case when odue>0 then odue else due end), odue = 0, odid = 0, usn = ? whe ########################################################################## def unsuspend_cards(self, ids: List[int]) -> None: - self.col.backend.restore_buried_and_suspended_cards(ids) + self.col._backend.restore_buried_and_suspended_cards(ids) def unbury_cards(self, ids: List[int]) -> None: - self.col.backend.restore_buried_and_suspended_cards(ids) + self.col._backend.restore_buried_and_suspended_cards(ids) def unbury_cards_in_current_deck( self, mode: UnburyCurrentDeckModeValue = UnburyCurrentDeckMode.ALL, ) -> None: - self.col.backend.unbury_cards_in_current_deck(mode) + self.col._backend.unbury_cards_in_current_deck(mode) def suspend_cards(self, ids: Sequence[int]) -> None: - self.col.backend.bury_or_suspend_cards( + self.col._backend.bury_or_suspend_cards( card_ids=ids, mode=BuryOrSuspendMode.SUSPEND ) @@ -1342,7 +1342,7 @@ due = (case when odue>0 then odue else due end), odue = 0, odid = 0, usn = ? whe mode = BuryOrSuspendMode.BURY_USER else: mode = BuryOrSuspendMode.BURY_SCHED - self.col.backend.bury_or_suspend_cards(card_ids=ids, mode=mode) + self.col._backend.bury_or_suspend_cards(card_ids=ids, mode=mode) def bury_note(self, note: Note): self.bury_cards(note.card_ids()) @@ -1416,13 +1416,13 @@ and (queue={QUEUE_TYPE_NEW} or (queue={QUEUE_TYPE_REV} and due<=?))""", def schedule_cards_as_new(self, card_ids: List[int]) -> None: "Put cards at the end of the new queue." - self.col.backend.schedule_cards_as_new(card_ids=card_ids, log=True) + self.col._backend.schedule_cards_as_new(card_ids=card_ids, log=True) def schedule_cards_as_reviews( self, card_ids: List[int], min_interval: int, max_interval: int ) -> None: "Make cards review cards, with a new interval randomly selected from range." - self.col.backend.schedule_cards_as_reviews( + self.col._backend.schedule_cards_as_reviews( card_ids=card_ids, min_interval=min_interval, max_interval=max_interval ) @@ -1440,7 +1440,7 @@ and (queue={QUEUE_TYPE_NEW} or (queue={QUEUE_TYPE_REV} and due<=?))""", " where id in %s" % sids ) # and forget any non-new cards, changing their due numbers - self.col.backend.schedule_cards_as_new(card_ids=nonNew, log=False) + self.col._backend.schedule_cards_as_new(card_ids=nonNew, log=False) # legacy @@ -1458,7 +1458,7 @@ and (queue={QUEUE_TYPE_NEW} or (queue={QUEUE_TYPE_REV} and due<=?))""", shuffle: bool = False, shift: bool = False, ) -> None: - self.col.backend.sort_cards( + self.col._backend.sort_cards( card_ids=cids, starting_from=start, step_size=step, @@ -1467,10 +1467,10 @@ and (queue={QUEUE_TYPE_NEW} or (queue={QUEUE_TYPE_REV} and due<=?))""", ) def randomizeCards(self, did: int) -> None: - self.col.backend.sort_deck(deck_id=did, randomize=True) + self.col._backend.sort_deck(deck_id=did, randomize=True) def orderCards(self, did: int) -> None: - self.col.backend.sort_deck(deck_id=did, randomize=False) + self.col._backend.sort_deck(deck_id=did, randomize=False) def resortConf(self, conf) -> None: for did in self.col.decks.didsForConf(conf): diff --git a/pylib/anki/stats.py b/pylib/anki/stats.py index 0fb451ea1..24cdcc1b9 100644 --- a/pylib/anki/stats.py +++ b/pylib/anki/stats.py @@ -144,7 +144,7 @@ from revlog where id > ? """ return "" + str(s) + "" if cards: - b += self.col.backend.studied_today_message( + b += self.col._backend.studied_today_message( cards=cards, seconds=float(thetime) ) # again/pass count diff --git a/pylib/anki/stdmodels.py b/pylib/anki/stdmodels.py index 38ef8465d..f51dab968 100644 --- a/pylib/anki/stdmodels.py +++ b/pylib/anki/stdmodels.py @@ -25,7 +25,7 @@ models: List[Tuple] = [] def _add_stock_notetype( col: anki.collection.Collection, kind: StockNotetypeKindValue ) -> anki.models.NoteType: - m = from_json_bytes(col.backend.get_stock_notetype_legacy(kind)) + m = from_json_bytes(col._backend.get_stock_notetype_legacy(kind)) col.models.add(m) return m @@ -67,7 +67,7 @@ def get_stock_notetypes( ), (StockNotetypeKind.CLOZE, addClozeModel), ]: - m = from_json_bytes(col.backend.get_stock_notetype_legacy(kind)) + m = from_json_bytes(col._backend.get_stock_notetype_legacy(kind)) out.append((m["name"], func)) # add extras from add-ons for (name_or_func, func) in models: diff --git a/pylib/anki/syncserver/__init__.py b/pylib/anki/syncserver/__init__.py index 04d5c10ce..71ae39196 100644 --- a/pylib/anki/syncserver/__init__.py +++ b/pylib/anki/syncserver/__init__.py @@ -70,7 +70,7 @@ def handle_sync_request(method_str: str) -> Response: if full: col.close_for_full_sync() try: - outdata = col.backend.sync_server_method(method=method, data=data) + outdata = col._backend.sync_server_method(method=method, data=data) except Exception as e: if method == Method.META: # if parallel syncing requests come in, block them diff --git a/pylib/anki/tags.py b/pylib/anki/tags.py index d07101aee..2699cfdab 100644 --- a/pylib/anki/tags.py +++ b/pylib/anki/tags.py @@ -30,7 +30,7 @@ class TagManager: # all tags def all(self) -> List[str]: - return [t.name for t in self.col.backend.all_tags()] + return [t.name for t in self.col._backend.all_tags()] def __repr__(self) -> str: d = dict(self.__dict__) @@ -39,10 +39,10 @@ class TagManager: # # List of (tag, usn) def allItems(self) -> List[Tuple[str, int]]: - return [(t.name, t.usn) for t in self.col.backend.all_tags()] + return [(t.name, t.usn) for t in self.col._backend.all_tags()] def tree(self) -> TagTreeNode: - return self.col.backend.tag_tree() + return self.col._backend.tag_tree() # Registering and fetching tags ############################################################# @@ -57,7 +57,7 @@ class TagManager: self.clear_unused_tags() def clear_unused_tags(self): - self.col.backend.clear_unused_tags() + self.col._backend.clear_unused_tags() def byDeck(self, did, children=False) -> List[str]: basequery = "select n.tags from cards c, notes n WHERE c.nid = n.id" @@ -74,21 +74,21 @@ class TagManager: def set_collapsed(self, tag: str, collapsed: bool): "Set browser collapse state for tag, registering the tag if missing." - self.col.backend.set_tag_collapsed(name=tag, collapsed=collapsed) + self.col._backend.set_tag_collapsed(name=tag, collapsed=collapsed) # Bulk addition/removal from notes ############################################################# def bulk_add(self, nids: List[int], tags: str) -> int: """Add space-separate tags to provided notes, returning changed count.""" - return self.col.backend.add_note_tags(nids=nids, tags=tags) + return self.col._backend.add_note_tags(nids=nids, tags=tags) def bulk_update( self, nids: Sequence[int], tags: str, replacement: str, regex: bool ) -> int: """Replace space-separated tags, returning changed count. Tags replaced with an empty string will be removed.""" - return self.col.backend.update_note_tags( + return self.col._backend.update_note_tags( nids=nids, tags=tags, replacement=replacement, regex=regex ) @@ -101,7 +101,7 @@ class TagManager: return self.bulk_update(nids, escaped_name, new, False) def remove(self, tag: str) -> None: - self.col.backend.clear_tag(tag) + self.col._backend.clear_tag(tag) # legacy routines diff --git a/pylib/anki/template.py b/pylib/anki/template.py index 535d0c80f..253e4a50b 100644 --- a/pylib/anki/template.py +++ b/pylib/anki/template.py @@ -217,10 +217,10 @@ class TemplateRenderContext: ) qtext = apply_custom_filters(partial.qnodes, self, front_side=None) - qout = self.col().backend.extract_av_tags(text=qtext, question_side=True) + qout = self.col()._backend.extract_av_tags(text=qtext, question_side=True) atext = apply_custom_filters(partial.anodes, self, front_side=qout.text) - aout = self.col().backend.extract_av_tags(text=atext, question_side=False) + aout = self.col()._backend.extract_av_tags(text=atext, question_side=False) output = TemplateRenderOutput( question_text=qout.text, @@ -238,7 +238,7 @@ class TemplateRenderContext: def _partially_render(self) -> PartiallyRenderedCard: if self._template: # card layout screen - out = self._col.backend.render_uncommitted_card( + out = self._col._backend.render_uncommitted_card( note=self._note.to_backend_note(), card_ord=self._card.ord, template=to_json_bytes(self._template), @@ -246,7 +246,7 @@ class TemplateRenderContext: ) else: # existing card (eg study mode) - out = self._col.backend.render_existing_card( + out = self._col._backend.render_existing_card( card_id=self._card.id, browser=self._browser ) return PartiallyRenderedCard.from_proto(out) diff --git a/pylib/tests/test_cards.py b/pylib/tests/test_cards.py index 8ed06fa17..1b1e428d8 100644 --- a/pylib/tests/test_cards.py +++ b/pylib/tests/test_cards.py @@ -51,8 +51,8 @@ def test_genrem(): t = m["tmpls"][1] t["qfmt"] = "{{Back}}" mm.save(m, templates=True) - rep = col.backend.get_empty_cards() - rep = col.backend.get_empty_cards() + rep = col._backend.get_empty_cards() + rep = col._backend.get_empty_cards() for n in rep.notes: col.remove_cards_and_orphaned_notes(n.card_ids) assert len(note.cards()) == 1