make backend instance on col private

This commit is contained in:
Damien Elmes 2021-01-31 18:54:13 +10:00
parent 6c483bb577
commit 5d810dd799
16 changed files with 140 additions and 129 deletions

View File

@ -48,7 +48,7 @@ class Card:
self._load_from_backend_card(_pb.Card()) self._load_from_backend_card(_pb.Card())
def load(self) -> None: def load(self) -> None:
c = self.col.backend.get_card(self.id) c = self.col._backend.get_card(self.id)
assert c assert c
self._load_from_backend_card(c) self._load_from_backend_card(c)
@ -105,9 +105,9 @@ class Card:
data=self.data, data=self.data,
) )
if self.id != 0: if self.id != 0:
self.col.backend.update_card(card) self.col._backend.update_card(card)
else: 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: def question(self, reload: bool = False, browser: bool = False) -> str:
return self.render_output(reload, browser).question_and_style() return self.render_output(reload, browser).question_and_style()

View File

@ -75,7 +75,7 @@ class Collection:
server: bool = False, server: bool = False,
log: bool = False, log: bool = False,
) -> None: ) -> None:
self.backend = backend or RustBackend(server=server) self._backend = backend or RustBackend(server=server)
self.db: Optional[DBProxy] = None self.db: Optional[DBProxy] = None
self._should_log = log self._should_log = log
self.server = server self.server = server
@ -105,24 +105,33 @@ class Collection:
"Shortcut to create a weak reference that doesn't break code completion." "Shortcut to create a weak reference that doesn't break code completion."
return weakref.proxy(self) 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 # I18n/messages
########################################################################## ##########################################################################
def tr(self, key: TRValue, **kwargs: Union[str, int, float]) -> str: 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( def format_timespan(
self, self,
seconds: float, seconds: float,
context: FormatTimeSpanContextValue = FormatTimeSpanContext.INTERVALS, context: FormatTimeSpanContextValue = FormatTimeSpanContext.INTERVALS,
) -> str: ) -> str:
return self.backend.format_timespan(seconds=seconds, context=context) return self._backend.format_timespan(seconds=seconds, context=context)
# Progress # Progress
########################################################################## ##########################################################################
def latest_progress(self) -> Progress: def latest_progress(self) -> Progress:
return Progress.from_proto(self.backend.latest_progress()) return Progress.from_proto(self._backend.latest_progress())
# Scheduler # Scheduler
########################################################################## ##########################################################################
@ -253,7 +262,7 @@ class Collection:
else: else:
self.db.rollback() self.db.rollback()
self.models._clear_cache() self.models._clear_cache()
self.backend.close_collection(downgrade_to_schema11=downgrade) self._backend.close_collection(downgrade_to_schema11=downgrade)
self.db = None self.db = None
self.media.close() self.media.close()
self._closeLog() self._closeLog()
@ -284,7 +293,7 @@ class Collection:
# connect # connect
if not after_full_sync: if not after_full_sync:
self.backend.open_collection( self._backend.open_collection(
collection_path=self.path, collection_path=self.path,
media_folder_path=media_dir, media_folder_path=media_dir,
media_db_path=media_db, media_db_path=media_db,
@ -292,7 +301,7 @@ class Collection:
) )
else: else:
self.media.connect() self.media.connect()
self.db = DBProxy(weakref.proxy(self.backend)) self.db = DBProxy(weakref.proxy(self._backend))
self.db.begin() self.db.begin()
self._openLog() self._openLog()
@ -316,7 +325,7 @@ class Collection:
def beforeUpload(self) -> None: def beforeUpload(self) -> None:
"Called before a full upload." "Called before a full upload."
self.save(trx=False) self.save(trx=False)
self.backend.before_upload() self._backend.before_upload()
self.close(save=False, downgrade=True) self.close(save=False, downgrade=True)
# Object creation helpers # Object creation helpers
@ -362,11 +371,11 @@ class Collection:
return Note(self, self.models.current(forDeck)) return Note(self, self.models.current(forDeck))
def add_note(self, note: Note, deck_id: int) -> None: 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: def remove_notes(self, note_ids: Sequence[int]) -> None:
hooks.notes_will_be_deleted(self, note_ids) 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: def remove_notes_by_card(self, card_ids: List[int]) -> None:
if hooks.notes_will_be_deleted.count(): if hooks.notes_will_be_deleted.count():
@ -374,10 +383,10 @@ class Collection:
"select nid from cards where id in " + ids2str(card_ids) "select nid from cards where id in " + ids2str(card_ids)
) )
hooks.notes_will_be_deleted(self, nids) 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]: 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 # legacy
@ -402,13 +411,13 @@ class Collection:
def remove_cards_and_orphaned_notes(self, card_ids: Sequence[int]): def remove_cards_and_orphaned_notes(self, card_ids: Sequence[int]):
"You probably want .remove_notes_by_card() instead." "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: 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: def get_empty_cards(self) -> EmptyCardsReport:
return self.backend.get_empty_cards() return self._backend.get_empty_cards()
# legacy # legacy
@ -425,7 +434,7 @@ class Collection:
def after_note_updates( def after_note_updates(
self, nids: List[int], mark_modified: bool, generate_cards: bool = True self, nids: List[int], mark_modified: bool, generate_cards: bool = True
) -> None: ) -> None:
self.backend.after_note_updates( self._backend.after_note_updates(
nids=nids, generate_cards=generate_cards, mark_notes_modified=mark_modified nids=nids, generate_cards=generate_cards, mark_notes_modified=mark_modified
) )
@ -472,10 +481,10 @@ class Collection:
mode = _pb.SortOrder( mode = _pb.SortOrder(
builtin=_pb.SortOrder.Builtin(kind=order, reverse=reverse) 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]: 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( def find_and_replace(
self, self,
@ -544,19 +553,19 @@ class Collection:
searches = [] searches = []
for term in terms: for term in terms:
if isinstance(term, SearchTerm): if isinstance(term, SearchTerm):
term = self.backend.filter_to_search(term) term = self._backend.filter_to_search(term)
searches.append(term) searches.append(term)
if match_any: if match_any:
sep = _pb.ConcatenateSearchesIn.Separator.OR sep = _pb.ConcatenateSearchesIn.Separator.OR
else: else:
sep = _pb.ConcatenateSearchesIn.Separator.AND 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: if negate:
search_string = self.backend.negate_search(search_string) search_string = self._backend.negate_search(search_string)
return search_string return search_string
def replace_search_term(self, search: str, replacement: str) -> str: 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 # Config
########################################################################## ##########################################################################
@ -577,14 +586,14 @@ class Collection:
def all_config(self) -> Dict[str, Any]: def all_config(self) -> Dict[str, Any]:
"This is a debugging aid. Prefer .get_config() when you know the key you need." "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: 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: def set_config_bool(self, key: ConfigBoolKeyValue, value: bool) -> None:
self.setMod() self.setMod()
self.backend.set_config_bool(key=key, value=value) self._backend.set_config_bool(key=key, value=value)
# Stats # Stats
########################################################################## ##########################################################################
@ -610,23 +619,23 @@ class Collection:
table.review-log {{ {revlog_style} }} table.review-log {{ {revlog_style} }}
</style>""" </style>"""
return style + self.backend.card_stats(card_id) return style + self._backend.card_stats(card_id)
def studied_today(self) -> str: def studied_today(self) -> str:
return self.backend.studied_today() return self._backend.studied_today()
def graph_data(self, search: str, days: int) -> bytes: 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: 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: 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: def congrats_info(self) -> bytes:
"Don't use this, it will likely go away in the future." "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 # legacy
@ -747,7 +756,7 @@ table.review-log {{ {revlog_style} }}
""" """
self.save(trx=False) self.save(trx=False)
try: try:
problems = list(self.backend.check_database()) problems = list(self._backend.check_database())
ok = not problems ok = not problems
problems.append(self.tr(TR.DATABASE_CHECK_REBUILT)) problems.append(self.tr(TR.DATABASE_CHECK_REBUILT))
except DBError as e: except DBError as e:
@ -824,40 +833,40 @@ table.review-log {{ {revlog_style} }}
########################################################################## ##########################################################################
def set_wants_abort(self) -> None: def set_wants_abort(self) -> None:
self.backend.set_wants_abort() self._backend.set_wants_abort()
def i18n_resources(self) -> bytes: def i18n_resources(self) -> bytes:
return self.backend.i18n_resources() return self._backend.i18n_resources()
def abort_media_sync(self) -> None: def abort_media_sync(self) -> None:
self.backend.abort_media_sync() self._backend.abort_media_sync()
def abort_sync(self) -> None: def abort_sync(self) -> None:
self.backend.abort_sync() self._backend.abort_sync()
def full_upload(self, auth: SyncAuth) -> None: def full_upload(self, auth: SyncAuth) -> None:
self.backend.full_upload(auth) self._backend.full_upload(auth)
def full_download(self, auth: SyncAuth) -> None: 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: 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: 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: def sync_media(self, auth: SyncAuth) -> None:
self.backend.sync_media(auth) self._backend.sync_media(auth)
def sync_status(self, auth: SyncAuth) -> SyncStatus: def sync_status(self, auth: SyncAuth) -> SyncStatus:
return self.backend.sync_status(auth) return self._backend.sync_status(auth)
def get_preferences(self) -> Preferences: def get_preferences(self) -> Preferences:
return self.backend.get_preferences() return self._backend.get_preferences()
def set_preferences(self, prefs: Preferences): def set_preferences(self, prefs: Preferences):
self.backend.set_preferences(prefs) self._backend.set_preferences(prefs)
class ProgressKind(enum.Enum): class ProgressKind(enum.Enum):

View File

@ -33,15 +33,15 @@ class ConfigManager:
def get_immutable(self, key: str) -> Any: def get_immutable(self, key: str) -> Any:
try: 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: except NotFoundError as exc:
raise KeyError from exc raise KeyError from exc
def set(self, key: str, val: Any) -> None: 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: def remove(self, key: str) -> None:
self.col.backend.remove_config(key) self.col._backend.remove_config(key)
# Legacy dict interface # Legacy dict interface
######################### #########################

View File

@ -132,25 +132,25 @@ class DeckManager:
if isinstance(did, str): if isinstance(did, str):
did = int(did) did = int(did)
assert cardsToo and childrenToo assert cardsToo and childrenToo
self.col.backend.remove_deck(did) self.col._backend.remove_deck(did)
def all_names_and_ids( def all_names_and_ids(
self, skip_empty_default=False, include_filtered=True self, skip_empty_default=False, include_filtered=True
) -> Sequence[DeckNameID]: ) -> Sequence[DeckNameID]:
"A sorted sequence of deck names and IDs." "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 skip_empty_default=skip_empty_default, include_filtered=include_filtered
) )
def id_for_name(self, name: str) -> Optional[int]: def id_for_name(self, name: str) -> Optional[int]:
try: try:
return self.col.backend.get_deck_id_by_name(name) return self.col._backend.get_deck_id_by_name(name)
except NotFoundError: except NotFoundError:
return None return None
def get_legacy(self, did: int) -> Optional[Deck]: def get_legacy(self, did: int) -> Optional[Deck]:
try: 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: except NotFoundError:
return None return None
@ -158,13 +158,13 @@ class DeckManager:
return not self.get_legacy(int(id)) return not self.get_legacy(int(id))
def get_all_legacy(self) -> List[Deck]: 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: 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: 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 @classmethod
def find_deck_in_tree( def find_deck_in_tree(
@ -244,7 +244,7 @@ class DeckManager:
def update(self, g: Deck, preserve_usn=True) -> None: def update(self, g: Deck, preserve_usn=True) -> None:
"Add or update an existing deck. Used for syncing and merging." "Add or update an existing deck. Used for syncing and merging."
try: 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 deck=to_json_bytes(g), preserve_usn_and_mtime=preserve_usn
) )
except DeckIsFilteredError as exc: except DeckIsFilteredError as exc:
@ -262,7 +262,7 @@ class DeckManager:
def drag_drop_decks(self, source_decks: List[DeckID], target_deck: DeckID) -> None: 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`. """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.""" 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 source_deck_ids=source_decks, target_deck_id=target_deck
) )
@ -281,7 +281,7 @@ class DeckManager:
def all_config(self) -> List[Config]: def all_config(self) -> List[Config]:
"A list of all deck 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: def confForDid(self, did: int) -> DeckConfig:
deck = self.get(did, default=False) deck = self.get(did, default=False)
@ -299,12 +299,12 @@ class DeckManager:
def get_config(self, conf_id: int) -> Optional[DeckConfig]: def get_config(self, conf_id: int) -> Optional[DeckConfig]:
try: 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: except NotFoundError:
return None return None
def update_config(self, conf: DeckConfig, preserve_usn=False) -> 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 config=to_json_bytes(conf), preserve_usn_and_mtime=preserve_usn
) )
@ -315,7 +315,7 @@ class DeckManager:
conf = copy.deepcopy(clone_from) conf = copy.deepcopy(clone_from)
conf["id"] = 0 conf["id"] = 0
else: 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 conf["name"] = name
self.update_config(conf) self.update_config(conf)
return conf return conf
@ -335,7 +335,7 @@ class DeckManager:
if str(g["conf"]) == str(id): if str(g["conf"]) == str(id):
g["conf"] = 1 g["conf"] = 1
self.save(g) 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: def setConf(self, grp: DeckConfig, id: int) -> None:
grp["conf"] = id grp["conf"] = id
@ -350,7 +350,7 @@ class DeckManager:
def restoreToDefault(self, conf) -> None: def restoreToDefault(self, conf) -> None:
oldOrder = conf["new"]["order"] 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["id"] = conf["id"]
new["name"] = conf["name"] new["name"] = conf["name"]
self.update_config(new) self.update_config(new)

View File

@ -37,7 +37,7 @@ def findReplace(
fold: bool = True, fold: bool = True,
) -> int: ) -> int:
"Find and replace fields in a note. Returns changed note count." "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, nids=nids,
search=src, search=src,
replacement=dst, replacement=dst,
@ -48,7 +48,7 @@ def findReplace(
def fieldNamesForNotes(col: Collection, nids: List[int]) -> List[str]: 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 # Find duplicates

View File

@ -86,7 +86,7 @@ def render_latex_returning_errors(
header = model["latexPre"] header = model["latexPre"]
footer = model["latexPost"] 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) out = ExtractedLatexOutput.from_proto(proto)
errors = [] errors = []
html = out.html html = out.html

View File

@ -101,17 +101,17 @@ class MediaManager:
pass pass
def empty_trash(self) -> None: def empty_trash(self) -> None:
self.col.backend.empty_trash() self.col._backend.empty_trash()
def restore_trash(self) -> None: def restore_trash(self) -> None:
self.col.backend.restore_trash() self.col._backend.restore_trash()
def strip_av_tags(self, text: str) -> str: 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]: def _extract_filenames(self, text: str) -> List[str]:
"This only exists do support a legacy function; do not use." "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 [ return [
x.filename x.filename
for x in av_tags_to_native(out.av_tags) 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. """Write the file to the media folder, renaming if not unique.
Returns possibly-renamed filename.""" 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: def add_extension_based_on_mime(self, fname: str, content_type: str) -> str:
"If jpg or png mime, add .png/.jpg if missing extension." "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: def trash_files(self, fnames: List[str]) -> None:
"Move provided files to the trash." "Move provided files to the trash."
self.col.backend.trash_media_files(fnames) self.col._backend.trash_media_files(fnames)
# String manipulation # String manipulation
########################################################################## ##########################################################################
@ -212,7 +212,7 @@ class MediaManager:
########################################################################## ##########################################################################
def check(self) -> CheckMediaOut: 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 # files may have been renamed on disk, so an undo at this point could
# break file references # break file references
self.col.save() self.col.save()

View File

@ -130,10 +130,10 @@ class ModelManager:
############################################################# #############################################################
def all_names_and_ids(self) -> Sequence[NoteTypeNameID]: 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]: 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 # legacy
@ -170,7 +170,7 @@ class ModelManager:
def id_for_name(self, name: str) -> Optional[int]: def id_for_name(self, name: str) -> Optional[int]:
try: try:
return self.col.backend.get_notetype_id_by_name(name) return self.col._backend.get_notetype_id_by_name(name)
except NotFoundError: except NotFoundError:
return None return None
@ -185,7 +185,7 @@ class ModelManager:
nt = self._get_cached(id) nt = self._get_cached(id)
if not nt: if not nt:
try: 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) self._update_cache(nt)
except NotFoundError: except NotFoundError:
return None return None
@ -207,7 +207,7 @@ class ModelManager:
"Create a new model, and return it." "Create a new model, and return it."
# caller should call save() after modifying # caller should call save() after modifying
nt = from_json_bytes( 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["flds"] = []
nt["tmpls"] = [] nt["tmpls"] = []
@ -221,12 +221,12 @@ class ModelManager:
def remove_all_notetypes(self): def remove_all_notetypes(self):
for nt in self.all_names_and_ids(): for nt in self.all_names_and_ids():
self._remove_from_cache(nt.id) 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: def remove(self, id: int) -> None:
"Modifies schema." "Modifies schema."
self._remove_from_cache(id) self._remove_from_cache(id)
self.col.backend.remove_notetype(id) self.col._backend.remove_notetype(id)
def add(self, m: NoteType) -> None: def add(self, m: NoteType) -> None:
self.save(m) self.save(m)
@ -240,7 +240,7 @@ class ModelManager:
"Add or update an existing model. Use .save() instead." "Add or update an existing model. Use .save() instead."
self._remove_from_cache(m["id"]) self._remove_from_cache(m["id"])
self.ensureNameUnique(m) 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 json=to_json_bytes(m), preserve_usn_and_mtime=preserve_usn
) )
self.setCurrent(m) self.setCurrent(m)
@ -298,7 +298,7 @@ class ModelManager:
def new_field(self, name: str) -> Field: def new_field(self, name: str) -> Field:
assert isinstance(name, str) assert isinstance(name, str)
nt = from_json_bytes( 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 = nt["flds"][0]
field["name"] = name field["name"] = name
@ -357,7 +357,7 @@ class ModelManager:
def new_template(self, name: str) -> Template: def new_template(self, name: str) -> Template:
nt = from_json_bytes( 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 = nt["tmpls"][0]
template["name"] = name template["name"] = name
@ -511,4 +511,4 @@ and notes.mid = ? and cards.ord = ?""",
) -> List[int]: ) -> List[int]:
print("_availClozeOrds() is deprecated; use note.cloze_numbers_in_fields()") print("_availClozeOrds() is deprecated; use note.cloze_numbers_in_fields()")
note = _pb.Note(fields=[flds]) 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))

View File

@ -34,10 +34,10 @@ class Note:
self.load() self.load()
else: else:
# new note for provided notetype # 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: def load(self) -> None:
n = self.col.backend.get_note(self.id) n = self.col._backend.get_note(self.id)
assert n assert n
self._load_from_backend_note(n) self._load_from_backend_note(n)
@ -65,7 +65,7 @@ class Note:
def flush(self) -> None: def flush(self) -> None:
assert self.id != 0 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: def __repr__(self) -> str:
d = dict(self.__dict__) d = dict(self.__dict__)
@ -87,7 +87,7 @@ class Note:
_model = property(model) _model = property(model)
def cloze_numbers_in_fields(self) -> Sequence[int]: 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 # Dict interface
################################################## ##################################################
@ -145,4 +145,6 @@ class Note:
def dupeOrEmpty(self) -> int: def dupeOrEmpty(self) -> int:
"1 if first is empty; 2 if first is a duplicate, 0 otherwise." "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

View File

@ -231,7 +231,7 @@ order by due"""
def update_stats( def update_stats(
self, deck_id: int, new_delta=0, review_delta=0, milliseconds_delta=0 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, deck_id=deck_id,
new_delta=new_delta, new_delta=new_delta,
review_delta=review_delta, review_delta=review_delta,
@ -239,11 +239,11 @@ order by due"""
) )
def counts_for_deck_today(self, deck_id: int) -> CountsForDeckToday: 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: def extendLimits(self, new: int, rev: int) -> None:
did = self.col.decks.current()["id"] 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 # legacy
@ -264,12 +264,12 @@ order by due"""
print( print(
"deckDueTree() is deprecated; use decks.deck_tree() for a tree without counts, or sched.deck_due_tree()" "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: def deck_due_tree(self, top_deck_id: int = 0) -> DeckTreeNode:
"""Returns a tree of decks with counts. """Returns a tree of decks with counts.
If top_deck_id provided, counts are limited to that node.""" 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 # 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: 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: 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: def _removeFromFiltered(self, card: Card) -> None:
if card.odid: 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() self.reset()
def _timing_today(self) -> SchedTimingToday: def _timing_today(self) -> SchedTimingToday:
return self.col.backend.sched_timing_today() return self.col._backend.sched_timing_today()
# Deck finished state # Deck finished state
########################################################################## ##########################################################################
def congratulations_info(self) -> CongratsInfo: def congratulations_info(self) -> CongratsInfo:
return self.col.backend.congrats_info() return self.col._backend.congrats_info()
def finishedMsg(self) -> str: def finishedMsg(self) -> str:
print("finishedMsg() is obsolete") 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: 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: 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( def unbury_cards_in_current_deck(
self, self,
mode: UnburyCurrentDeckModeValue = UnburyCurrentDeckMode.ALL, mode: UnburyCurrentDeckModeValue = UnburyCurrentDeckMode.ALL,
) -> None: ) -> 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: 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 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 mode = BuryOrSuspendMode.BURY_USER
else: else:
mode = BuryOrSuspendMode.BURY_SCHED 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): def bury_note(self, note: Note):
self.bury_cards(note.card_ids()) 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: def schedule_cards_as_new(self, card_ids: List[int]) -> None:
"Put cards at the end of the new queue." "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( def schedule_cards_as_reviews(
self, card_ids: List[int], min_interval: int, max_interval: int self, card_ids: List[int], min_interval: int, max_interval: int
) -> None: ) -> None:
"Make cards review cards, with a new interval randomly selected from range." "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 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 " where id in %s" % sids
) )
# and forget any non-new cards, changing their due numbers # 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 # legacy
@ -1458,7 +1458,7 @@ and (queue={QUEUE_TYPE_NEW} or (queue={QUEUE_TYPE_REV} and due<=?))""",
shuffle: bool = False, shuffle: bool = False,
shift: bool = False, shift: bool = False,
) -> None: ) -> None:
self.col.backend.sort_cards( self.col._backend.sort_cards(
card_ids=cids, card_ids=cids,
starting_from=start, starting_from=start,
step_size=step, 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: 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: 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: def resortConf(self, conf) -> None:
for did in self.col.decks.didsForConf(conf): for did in self.col.decks.didsForConf(conf):

View File

@ -144,7 +144,7 @@ from revlog where id > ? """
return "<b>" + str(s) + "</b>" return "<b>" + str(s) + "</b>"
if cards: if cards:
b += self.col.backend.studied_today_message( b += self.col._backend.studied_today_message(
cards=cards, seconds=float(thetime) cards=cards, seconds=float(thetime)
) )
# again/pass count # again/pass count

View File

@ -25,7 +25,7 @@ models: List[Tuple] = []
def _add_stock_notetype( def _add_stock_notetype(
col: anki.collection.Collection, kind: StockNotetypeKindValue col: anki.collection.Collection, kind: StockNotetypeKindValue
) -> anki.models.NoteType: ) -> 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) col.models.add(m)
return m return m
@ -67,7 +67,7 @@ def get_stock_notetypes(
), ),
(StockNotetypeKind.CLOZE, addClozeModel), (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)) out.append((m["name"], func))
# add extras from add-ons # add extras from add-ons
for (name_or_func, func) in models: for (name_or_func, func) in models:

View File

@ -70,7 +70,7 @@ def handle_sync_request(method_str: str) -> Response:
if full: if full:
col.close_for_full_sync() col.close_for_full_sync()
try: 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: except Exception as e:
if method == Method.META: if method == Method.META:
# if parallel syncing requests come in, block them # if parallel syncing requests come in, block them

View File

@ -30,7 +30,7 @@ class TagManager:
# all tags # all tags
def all(self) -> List[str]: 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: def __repr__(self) -> str:
d = dict(self.__dict__) d = dict(self.__dict__)
@ -39,10 +39,10 @@ class TagManager:
# # List of (tag, usn) # # List of (tag, usn)
def allItems(self) -> List[Tuple[str, int]]: 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: def tree(self) -> TagTreeNode:
return self.col.backend.tag_tree() return self.col._backend.tag_tree()
# Registering and fetching tags # Registering and fetching tags
############################################################# #############################################################
@ -57,7 +57,7 @@ class TagManager:
self.clear_unused_tags() self.clear_unused_tags()
def clear_unused_tags(self): 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]: def byDeck(self, did, children=False) -> List[str]:
basequery = "select n.tags from cards c, notes n WHERE c.nid = n.id" 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): def set_collapsed(self, tag: str, collapsed: bool):
"Set browser collapse state for tag, registering the tag if missing." "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 # Bulk addition/removal from notes
############################################################# #############################################################
def bulk_add(self, nids: List[int], tags: str) -> int: def bulk_add(self, nids: List[int], tags: str) -> int:
"""Add space-separate tags to provided notes, returning changed count.""" """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( def bulk_update(
self, nids: Sequence[int], tags: str, replacement: str, regex: bool self, nids: Sequence[int], tags: str, replacement: str, regex: bool
) -> int: ) -> int:
"""Replace space-separated tags, returning changed count. """Replace space-separated tags, returning changed count.
Tags replaced with an empty string will be removed.""" 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 nids=nids, tags=tags, replacement=replacement, regex=regex
) )
@ -101,7 +101,7 @@ class TagManager:
return self.bulk_update(nids, escaped_name, new, False) return self.bulk_update(nids, escaped_name, new, False)
def remove(self, tag: str) -> None: def remove(self, tag: str) -> None:
self.col.backend.clear_tag(tag) self.col._backend.clear_tag(tag)
# legacy routines # legacy routines

View File

@ -217,10 +217,10 @@ class TemplateRenderContext:
) )
qtext = apply_custom_filters(partial.qnodes, self, front_side=None) 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) 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( output = TemplateRenderOutput(
question_text=qout.text, question_text=qout.text,
@ -238,7 +238,7 @@ class TemplateRenderContext:
def _partially_render(self) -> PartiallyRenderedCard: def _partially_render(self) -> PartiallyRenderedCard:
if self._template: if self._template:
# card layout screen # card layout screen
out = self._col.backend.render_uncommitted_card( out = self._col._backend.render_uncommitted_card(
note=self._note.to_backend_note(), note=self._note.to_backend_note(),
card_ord=self._card.ord, card_ord=self._card.ord,
template=to_json_bytes(self._template), template=to_json_bytes(self._template),
@ -246,7 +246,7 @@ class TemplateRenderContext:
) )
else: else:
# existing card (eg study mode) # 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 card_id=self._card.id, browser=self._browser
) )
return PartiallyRenderedCard.from_proto(out) return PartiallyRenderedCard.from_proto(out)

View File

@ -51,8 +51,8 @@ def test_genrem():
t = m["tmpls"][1] t = m["tmpls"][1]
t["qfmt"] = "{{Back}}" t["qfmt"] = "{{Back}}"
mm.save(m, templates=True) 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: for n in rep.notes:
col.remove_cards_and_orphaned_notes(n.card_ids) col.remove_cards_and_orphaned_notes(n.card_ids)
assert len(note.cards()) == 1 assert len(note.cards()) == 1