mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
storage->collection
This commit is contained in:
parent
c49c378296
commit
50fdf9b03d
29 changed files with 82 additions and 92 deletions
|
@ -4,7 +4,7 @@
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from anki.buildinfo import version
|
from anki.buildinfo import version
|
||||||
from anki.storage import Collection
|
from anki.collection import Collection
|
||||||
|
|
||||||
if sys.version_info[0] < 3 or sys.version_info[1] < 7:
|
if sys.version_info[0] < 3 or sys.version_info[1] < 7:
|
||||||
raise Exception("Anki requires Python 3.7+")
|
raise Exception("Anki requires Python 3.7+")
|
||||||
|
|
|
@ -33,7 +33,9 @@ class Card:
|
||||||
lastIvl: int
|
lastIvl: int
|
||||||
ord: int
|
ord: int
|
||||||
|
|
||||||
def __init__(self, col: anki.storage._Collection, id: Optional[int] = None) -> None:
|
def __init__(
|
||||||
|
self, col: anki.collection.Collection, id: Optional[int] = None
|
||||||
|
) -> None:
|
||||||
self.col = col.weakref()
|
self.col = col.weakref()
|
||||||
self.timerStarted = None
|
self.timerStarted = None
|
||||||
self._render_output: Optional[anki.template.TemplateRenderOutput] = None
|
self._render_output: Optional[anki.template.TemplateRenderOutput] = None
|
||||||
|
|
|
@ -33,21 +33,19 @@ from anki.tags import TagManager
|
||||||
from anki.utils import devMode, ids2str, intTime
|
from anki.utils import devMode, ids2str, intTime
|
||||||
|
|
||||||
|
|
||||||
# this is initialized by storage.Collection
|
class Collection:
|
||||||
class _Collection:
|
|
||||||
db: Optional[DBProxy]
|
|
||||||
sched: Union[V1Scheduler, V2Scheduler]
|
sched: Union[V1Scheduler, V2Scheduler]
|
||||||
_undo: List[Any]
|
_undo: List[Any]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
path: str,
|
path: str,
|
||||||
backend: Optional[RustBackend],
|
backend: Optional[RustBackend] = None,
|
||||||
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 = None
|
self.db: Optional[DBProxy] = None
|
||||||
self._should_log = log
|
self._should_log = log
|
||||||
self.server = server
|
self.server = server
|
||||||
self.path = os.path.abspath(path)
|
self.path = os.path.abspath(path)
|
||||||
|
@ -70,7 +68,7 @@ class _Collection:
|
||||||
def tr(self, key: TR, **kwargs: Union[str, int, float]) -> str:
|
def tr(self, key: TR, **kwargs: Union[str, int, float]) -> str:
|
||||||
return self.backend.translate(key, **kwargs)
|
return self.backend.translate(key, **kwargs)
|
||||||
|
|
||||||
def weakref(self) -> anki.storage._Collection:
|
def weakref(self) -> 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)
|
||||||
|
|
||||||
|
@ -654,3 +652,7 @@ select id from notes where mid = ?) limit 1"""
|
||||||
self.usn(),
|
self.usn(),
|
||||||
intTime(),
|
intTime(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# legacy name
|
||||||
|
_Collection = Collection
|
||||||
|
|
|
@ -26,7 +26,7 @@ import anki
|
||||||
|
|
||||||
|
|
||||||
class ConfigManager:
|
class ConfigManager:
|
||||||
def __init__(self, col: anki.storage._Collection):
|
def __init__(self, col: anki.collection.Collection):
|
||||||
self.col = col.weakref()
|
self.col = col.weakref()
|
||||||
|
|
||||||
def get_immutable(self, key: str) -> Any:
|
def get_immutable(self, key: str) -> Any:
|
||||||
|
|
|
@ -21,7 +21,7 @@ defaultDynamicDeck = 1
|
||||||
|
|
||||||
|
|
||||||
class DecksDictProxy:
|
class DecksDictProxy:
|
||||||
def __init__(self, col: anki.storage._Collection):
|
def __init__(self, col: anki.collection.Collection):
|
||||||
self._col = col.weakref()
|
self._col = col.weakref()
|
||||||
|
|
||||||
def _warn(self):
|
def _warn(self):
|
||||||
|
@ -60,7 +60,7 @@ class DeckManager:
|
||||||
# Registry save/load
|
# Registry save/load
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
def __init__(self, col: anki.storage._Collection) -> None:
|
def __init__(self, col: anki.collection.Collection) -> None:
|
||||||
self.col = col.weakref()
|
self.col = col.weakref()
|
||||||
self.decks = DecksDictProxy(col)
|
self.decks = DecksDictProxy(col)
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,8 @@ from typing import Any, Dict, List, Optional, Tuple, Union
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
from anki import hooks
|
from anki import hooks
|
||||||
from anki.collection import _Collection
|
from anki.collection import Collection
|
||||||
from anki.lang import _
|
from anki.lang import _
|
||||||
from anki.storage import Collection
|
|
||||||
from anki.utils import ids2str, namedtmp, splitFields, stripHTML
|
from anki.utils import ids2str, namedtmp, splitFields, stripHTML
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,7 +22,7 @@ class Exporter:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
col: _Collection,
|
col: Collection,
|
||||||
did: Optional[int] = None,
|
did: Optional[int] = None,
|
||||||
cids: Optional[List[int]] = None,
|
cids: Optional[List[int]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -122,7 +121,7 @@ class TextNoteExporter(Exporter):
|
||||||
includeTags = True
|
includeTags = True
|
||||||
includeHTML = True
|
includeHTML = True
|
||||||
|
|
||||||
def __init__(self, col: _Collection) -> None:
|
def __init__(self, col: Collection) -> None:
|
||||||
Exporter.__init__(self, col)
|
Exporter.__init__(self, col)
|
||||||
self.includeID = False
|
self.includeID = False
|
||||||
|
|
||||||
|
@ -164,7 +163,7 @@ class AnkiExporter(Exporter):
|
||||||
includeSched: Union[bool, None] = False
|
includeSched: Union[bool, None] = False
|
||||||
includeMedia = True
|
includeMedia = True
|
||||||
|
|
||||||
def __init__(self, col: _Collection) -> None:
|
def __init__(self, col: Collection) -> None:
|
||||||
Exporter.__init__(self, col)
|
Exporter.__init__(self, col)
|
||||||
|
|
||||||
def deckIds(self) -> List[int]:
|
def deckIds(self) -> List[int]:
|
||||||
|
@ -311,7 +310,7 @@ class AnkiPackageExporter(AnkiExporter):
|
||||||
key = _("Anki Deck Package")
|
key = _("Anki Deck Package")
|
||||||
ext = ".apkg"
|
ext = ".apkg"
|
||||||
|
|
||||||
def __init__(self, col: _Collection) -> None:
|
def __init__(self, col: Collection) -> None:
|
||||||
AnkiExporter.__init__(self, col)
|
AnkiExporter.__init__(self, col)
|
||||||
|
|
||||||
def exportInto(self, path: str) -> None:
|
def exportInto(self, path: str) -> None:
|
||||||
|
|
|
@ -9,11 +9,11 @@ from anki.hooks import *
|
||||||
from anki.utils import ids2str, splitFields, stripHTMLMedia
|
from anki.utils import ids2str, splitFields, stripHTMLMedia
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from anki.collection import _Collection
|
from anki.collection import Collection
|
||||||
|
|
||||||
|
|
||||||
class Finder:
|
class Finder:
|
||||||
def __init__(self, col: Optional[_Collection]) -> None:
|
def __init__(self, col: Optional[Collection]) -> None:
|
||||||
self.col = col.weakref()
|
self.col = col.weakref()
|
||||||
print("Finder() is deprecated, please use col.find_cards() or .find_notes()")
|
print("Finder() is deprecated, please use col.find_cards() or .find_notes()")
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class Finder:
|
||||||
|
|
||||||
|
|
||||||
def findReplace(
|
def findReplace(
|
||||||
col: _Collection,
|
col: Collection,
|
||||||
nids: List[int],
|
nids: List[int],
|
||||||
src: str,
|
src: str,
|
||||||
dst: str,
|
dst: str,
|
||||||
|
@ -41,7 +41,7 @@ def findReplace(
|
||||||
return col.backend.find_and_replace(nids, src, dst, regex, fold, field)
|
return col.backend.find_and_replace(nids, src, dst, regex, fold, field)
|
||||||
|
|
||||||
|
|
||||||
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_note_ids(nids))
|
return list(col.backend.field_names_for_note_ids(nids))
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ def fieldNames(col, downcase=True) -> List:
|
||||||
|
|
||||||
# returns array of ("dupestr", [nids])
|
# returns array of ("dupestr", [nids])
|
||||||
def findDupes(
|
def findDupes(
|
||||||
col: _Collection, fieldName: str, search: str = ""
|
col: Collection, fieldName: str, search: str = ""
|
||||||
) -> List[Tuple[Any, List]]:
|
) -> List[Tuple[Any, List]]:
|
||||||
# limit search to notes with applicable field name
|
# limit search to notes with applicable field name
|
||||||
if search:
|
if search:
|
||||||
|
|
|
@ -358,21 +358,21 @@ note_will_flush = _NoteWillFlushHook()
|
||||||
|
|
||||||
|
|
||||||
class _NotesWillBeDeletedHook:
|
class _NotesWillBeDeletedHook:
|
||||||
_hooks: List[Callable[["anki.storage._Collection", List[int]], None]] = []
|
_hooks: List[Callable[["anki.collection.Collection", List[int]], None]] = []
|
||||||
|
|
||||||
def append(
|
def append(
|
||||||
self, cb: Callable[["anki.storage._Collection", List[int]], None]
|
self, cb: Callable[["anki.collection.Collection", List[int]], None]
|
||||||
) -> None:
|
) -> None:
|
||||||
"""(col: anki.storage._Collection, ids: List[int])"""
|
"""(col: anki.storage._Collection, ids: List[int])"""
|
||||||
self._hooks.append(cb)
|
self._hooks.append(cb)
|
||||||
|
|
||||||
def remove(
|
def remove(
|
||||||
self, cb: Callable[["anki.storage._Collection", List[int]], None]
|
self, cb: Callable[["anki.collection.Collection", List[int]], None]
|
||||||
) -> None:
|
) -> None:
|
||||||
if cb in self._hooks:
|
if cb in self._hooks:
|
||||||
self._hooks.remove(cb)
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
def __call__(self, col: anki.storage._Collection, ids: List[int]) -> None:
|
def __call__(self, col: anki.collection.Collection, ids: List[int]) -> None:
|
||||||
for hook in self._hooks:
|
for hook in self._hooks:
|
||||||
try:
|
try:
|
||||||
hook(col, ids)
|
hook(col, ids)
|
||||||
|
|
|
@ -5,12 +5,11 @@ import os
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from typing import Any, Dict, List, Optional, Tuple
|
from typing import Any, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
from anki.collection import _Collection
|
from anki.collection import Collection
|
||||||
from anki.consts import *
|
from anki.consts import *
|
||||||
from anki.decks import DeckManager
|
from anki.decks import DeckManager
|
||||||
from anki.importing.base import Importer
|
from anki.importing.base import Importer
|
||||||
from anki.lang import _
|
from anki.lang import _
|
||||||
from anki.storage import Collection
|
|
||||||
from anki.utils import intTime, joinFields, splitFields
|
from anki.utils import intTime, joinFields, splitFields
|
||||||
|
|
||||||
GUID = 1
|
GUID = 1
|
||||||
|
@ -23,10 +22,10 @@ class Anki2Importer(Importer):
|
||||||
needMapper = False
|
needMapper = False
|
||||||
deckPrefix: Optional[str] = None
|
deckPrefix: Optional[str] = None
|
||||||
allowUpdate = True
|
allowUpdate = True
|
||||||
src: _Collection
|
src: Collection
|
||||||
dst: _Collection
|
dst: Collection
|
||||||
|
|
||||||
def __init__(self, col: _Collection, file: str) -> None:
|
def __init__(self, col: Collection, file: str) -> None:
|
||||||
super().__init__(col, file)
|
super().__init__(col, file)
|
||||||
|
|
||||||
# set later, defined here for typechecking
|
# set later, defined here for typechecking
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
from typing import Any, List, Optional
|
from typing import Any, List, Optional
|
||||||
|
|
||||||
from anki.collection import _Collection
|
from anki.collection import Collection
|
||||||
from anki.utils import maxID
|
from anki.utils import maxID
|
||||||
|
|
||||||
# Base importer
|
# Base importer
|
||||||
|
@ -14,9 +14,9 @@ class Importer:
|
||||||
|
|
||||||
needMapper = False
|
needMapper = False
|
||||||
needDelimiter = False
|
needDelimiter = False
|
||||||
dst: Optional[_Collection]
|
dst: Optional[Collection]
|
||||||
|
|
||||||
def __init__(self, col: _Collection, file: str) -> None:
|
def __init__(self, col: Collection, file: str) -> None:
|
||||||
self.file = file
|
self.file = file
|
||||||
self.log: List[str] = []
|
self.log: List[str] = []
|
||||||
self.col = col.weakref()
|
self.col = col.weakref()
|
||||||
|
|
|
@ -5,7 +5,7 @@ import csv
|
||||||
import re
|
import re
|
||||||
from typing import Any, List, Optional, TextIO, Union
|
from typing import Any, List, Optional, TextIO, Union
|
||||||
|
|
||||||
from anki.collection import _Collection
|
from anki.collection import Collection
|
||||||
from anki.importing.noteimp import ForeignNote, NoteImporter
|
from anki.importing.noteimp import ForeignNote, NoteImporter
|
||||||
from anki.lang import _
|
from anki.lang import _
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ class TextImporter(NoteImporter):
|
||||||
needDelimiter = True
|
needDelimiter = True
|
||||||
patterns = "\t|,;:"
|
patterns = "\t|,;:"
|
||||||
|
|
||||||
def __init__(self, col: _Collection, file: str) -> None:
|
def __init__(self, col: Collection, file: str) -> None:
|
||||||
NoteImporter.__init__(self, col, file)
|
NoteImporter.__init__(self, col, file)
|
||||||
self.lines = None
|
self.lines = None
|
||||||
self.fileobj: Optional[TextIO] = None
|
self.fileobj: Optional[TextIO] = None
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import html
|
import html
|
||||||
from typing import Dict, List, Optional, Tuple, Union
|
from typing import Dict, List, Optional, Tuple, Union
|
||||||
|
|
||||||
from anki.collection import _Collection
|
from anki.collection import Collection
|
||||||
from anki.consts import NEW_CARDS_RANDOM, STARTING_FACTOR
|
from anki.consts import NEW_CARDS_RANDOM, STARTING_FACTOR
|
||||||
from anki.importing.base import Importer
|
from anki.importing.base import Importer
|
||||||
from anki.lang import _, ngettext
|
from anki.lang import _, ngettext
|
||||||
|
@ -68,7 +68,7 @@ class NoteImporter(Importer):
|
||||||
mapping: Optional[List[str]]
|
mapping: Optional[List[str]]
|
||||||
tagModified: Optional[str]
|
tagModified: Optional[str]
|
||||||
|
|
||||||
def __init__(self, col: _Collection, file: str) -> None:
|
def __init__(self, col: Collection, file: str) -> None:
|
||||||
Importer.__init__(self, col, file)
|
Importer.__init__(self, col, file)
|
||||||
self.model = col.models.current()
|
self.model = col.models.current()
|
||||||
self.mapping = None
|
self.mapping = None
|
||||||
|
|
|
@ -12,7 +12,7 @@ from typing import List, Optional, Union
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
from xml.dom.minidom import Element, Text
|
from xml.dom.minidom import Element, Text
|
||||||
|
|
||||||
from anki.collection import _Collection
|
from anki.collection import Collection
|
||||||
from anki.importing.noteimp import ForeignCard, ForeignNote, NoteImporter
|
from anki.importing.noteimp import ForeignCard, ForeignNote, NoteImporter
|
||||||
from anki.lang import _, ngettext
|
from anki.lang import _, ngettext
|
||||||
from anki.stdmodels import addBasicModel
|
from anki.stdmodels import addBasicModel
|
||||||
|
@ -83,7 +83,7 @@ class SupermemoXmlImporter(NoteImporter):
|
||||||
Code should be upgrade to support importing of SM2006 exports.
|
Code should be upgrade to support importing of SM2006 exports.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, col: _Collection, file: str) -> None:
|
def __init__(self, col: Collection, file: str) -> None:
|
||||||
"""Initialize internal varables.
|
"""Initialize internal varables.
|
||||||
Pameters to be exposed to GUI are stored in self.META"""
|
Pameters to be exposed to GUI are stored in self.META"""
|
||||||
NoteImporter.__init__(self, col, file)
|
NoteImporter.__init__(self, col, file)
|
||||||
|
|
|
@ -42,7 +42,7 @@ def on_card_did_render(
|
||||||
output.answer_text = render_latex(output.answer_text, ctx.note_type(), ctx.col())
|
output.answer_text = render_latex(output.answer_text, ctx.note_type(), ctx.col())
|
||||||
|
|
||||||
|
|
||||||
def render_latex(html: str, model: NoteType, col: anki.storage._Collection) -> str:
|
def render_latex(html: str, model: NoteType, col: anki.collection.Collection) -> str:
|
||||||
"Convert embedded latex tags in text to image links."
|
"Convert embedded latex tags in text to image links."
|
||||||
html, err = render_latex_returning_errors(html, model, col)
|
html, err = render_latex_returning_errors(html, model, col)
|
||||||
if err:
|
if err:
|
||||||
|
@ -53,7 +53,7 @@ def render_latex(html: str, model: NoteType, col: anki.storage._Collection) -> s
|
||||||
def render_latex_returning_errors(
|
def render_latex_returning_errors(
|
||||||
html: str,
|
html: str,
|
||||||
model: NoteType,
|
model: NoteType,
|
||||||
col: anki.storage._Collection,
|
col: anki.collection.Collection,
|
||||||
expand_clozes: bool = False,
|
expand_clozes: bool = False,
|
||||||
) -> Tuple[str, List[str]]:
|
) -> Tuple[str, List[str]]:
|
||||||
"""Returns (text, errors).
|
"""Returns (text, errors).
|
||||||
|
@ -80,7 +80,7 @@ def render_latex_returning_errors(
|
||||||
|
|
||||||
|
|
||||||
def _save_latex_image(
|
def _save_latex_image(
|
||||||
col: anki.storage._Collection,
|
col: anki.collection.Collection,
|
||||||
extracted: ExtractedLatex,
|
extracted: ExtractedLatex,
|
||||||
header: str,
|
header: str,
|
||||||
footer: str,
|
footer: str,
|
||||||
|
|
|
@ -41,7 +41,7 @@ class MediaManager:
|
||||||
]
|
]
|
||||||
regexps = soundRegexps + imgRegexps
|
regexps = soundRegexps + imgRegexps
|
||||||
|
|
||||||
def __init__(self, col: anki.storage._Collection, server: bool) -> None:
|
def __init__(self, col: anki.collection.Collection, server: bool) -> None:
|
||||||
self.col = col.weakref()
|
self.col = col.weakref()
|
||||||
if server:
|
if server:
|
||||||
self._dir = None
|
self._dir = None
|
||||||
|
|
|
@ -22,7 +22,7 @@ Template = Dict[str, Union[str, int, None]]
|
||||||
|
|
||||||
|
|
||||||
class ModelsDictProxy:
|
class ModelsDictProxy:
|
||||||
def __init__(self, col: anki.storage._Collection):
|
def __init__(self, col: anki.collection.Collection):
|
||||||
self._col = col.weakref()
|
self._col = col.weakref()
|
||||||
|
|
||||||
def _warn(self):
|
def _warn(self):
|
||||||
|
@ -61,7 +61,7 @@ class ModelManager:
|
||||||
# Saving/loading registry
|
# Saving/loading registry
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
def __init__(self, col: anki.storage._Collection) -> None:
|
def __init__(self, col: anki.collection.Collection) -> None:
|
||||||
self.col = col.weakref()
|
self.col = col.weakref()
|
||||||
self.models = ModelsDictProxy(col)
|
self.models = ModelsDictProxy(col)
|
||||||
# do not access this directly!
|
# do not access this directly!
|
||||||
|
|
|
@ -19,7 +19,7 @@ class Note:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
col: anki.storage._Collection,
|
col: anki.collection.Collection,
|
||||||
model: Optional[NoteType] = None,
|
model: Optional[NoteType] = None,
|
||||||
id: Optional[int] = None,
|
id: Optional[int] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
|
@ -27,7 +27,7 @@ class Scheduler(V2):
|
||||||
_burySiblingsOnAnswer = True
|
_burySiblingsOnAnswer = True
|
||||||
|
|
||||||
def __init__( # pylint: disable=super-init-not-called
|
def __init__( # pylint: disable=super-init-not-called
|
||||||
self, col: anki.storage._Collection
|
self, col: anki.collection.Collection
|
||||||
) -> None:
|
) -> None:
|
||||||
self.col = col.weakref()
|
self.col = col.weakref()
|
||||||
self.queueLimit = 50
|
self.queueLimit = 50
|
||||||
|
|
|
@ -6,8 +6,6 @@ from __future__ import annotations
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
from heapq import *
|
from heapq import *
|
||||||
|
|
||||||
# from anki.collection import _Collection
|
|
||||||
from typing import Any, Callable, Dict, List, Optional, Sequence, Set, Tuple, Union
|
from typing import Any, Callable, Dict, List, Optional, Sequence, Set, Tuple, Union
|
||||||
|
|
||||||
import anki # pylint: disable=unused-import
|
import anki # pylint: disable=unused-import
|
||||||
|
@ -33,7 +31,7 @@ class Scheduler:
|
||||||
_burySiblingsOnAnswer = True
|
_burySiblingsOnAnswer = True
|
||||||
revCount: int
|
revCount: int
|
||||||
|
|
||||||
def __init__(self, col: anki.storage._Collection) -> None:
|
def __init__(self, col: anki.collection.Collection) -> None:
|
||||||
self.col = col.weakref()
|
self.col = col.weakref()
|
||||||
self.queueLimit = 50
|
self.queueLimit = 50
|
||||||
self.reportLimit = 1000
|
self.reportLimit = 1000
|
||||||
|
|
|
@ -24,7 +24,7 @@ PERIOD_LIFE = 2
|
||||||
|
|
||||||
|
|
||||||
class CardStats:
|
class CardStats:
|
||||||
def __init__(self, col: anki.storage._Collection, card: anki.cards.Card) -> None:
|
def __init__(self, col: anki.collection.Collection, card: anki.cards.Card) -> None:
|
||||||
if col:
|
if col:
|
||||||
self.col = col.weakref()
|
self.col = col.weakref()
|
||||||
self.card = card
|
self.card = card
|
||||||
|
@ -108,7 +108,7 @@ colSusp = "#ff0"
|
||||||
|
|
||||||
|
|
||||||
class CollectionStats:
|
class CollectionStats:
|
||||||
def __init__(self, col: anki.storage._Collection) -> None:
|
def __init__(self, col: anki.collection.Collection) -> None:
|
||||||
self.col = col.weakref()
|
self.col = col.weakref()
|
||||||
self._stats = None
|
self._stats = None
|
||||||
self.type = PERIOD_MONTH
|
self.type = PERIOD_MONTH
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
from typing import Callable, List, Tuple
|
from typing import Callable, List, Tuple
|
||||||
|
|
||||||
from anki.collection import _Collection
|
from anki.collection import Collection
|
||||||
from anki.models import NoteType
|
from anki.models import NoteType
|
||||||
from anki.rsbackend import StockNoteType
|
from anki.rsbackend import StockNoteType
|
||||||
|
|
||||||
|
@ -12,38 +12,38 @@ from anki.rsbackend import StockNoteType
|
||||||
models: List[Tuple] = []
|
models: List[Tuple] = []
|
||||||
|
|
||||||
|
|
||||||
def add_stock_notetype(col: _Collection, kind: StockNoteType) -> NoteType:
|
def add_stock_notetype(col: Collection, kind: StockNoteType) -> NoteType:
|
||||||
m = col.backend.get_stock_notetype_legacy(kind)
|
m = col.backend.get_stock_notetype_legacy(kind)
|
||||||
col.models.add(m)
|
col.models.add(m)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
||||||
def addBasicModel(col: _Collection) -> NoteType:
|
def addBasicModel(col: Collection) -> NoteType:
|
||||||
return add_stock_notetype(col, StockNoteType.STOCK_NOTE_TYPE_BASIC)
|
return add_stock_notetype(col, StockNoteType.STOCK_NOTE_TYPE_BASIC)
|
||||||
|
|
||||||
|
|
||||||
def addBasicTypingModel(col: _Collection) -> NoteType:
|
def addBasicTypingModel(col: Collection) -> NoteType:
|
||||||
return add_stock_notetype(col, StockNoteType.STOCK_NOTE_TYPE_BASIC_TYPING)
|
return add_stock_notetype(col, StockNoteType.STOCK_NOTE_TYPE_BASIC_TYPING)
|
||||||
|
|
||||||
|
|
||||||
def addForwardReverse(col: _Collection) -> NoteType:
|
def addForwardReverse(col: Collection) -> NoteType:
|
||||||
return add_stock_notetype(col, StockNoteType.STOCK_NOTE_TYPE_BASIC_AND_REVERSED)
|
return add_stock_notetype(col, StockNoteType.STOCK_NOTE_TYPE_BASIC_AND_REVERSED)
|
||||||
|
|
||||||
|
|
||||||
def addForwardOptionalReverse(col: _Collection) -> NoteType:
|
def addForwardOptionalReverse(col: Collection) -> NoteType:
|
||||||
return add_stock_notetype(
|
return add_stock_notetype(
|
||||||
col, StockNoteType.STOCK_NOTE_TYPE_BASIC_OPTIONAL_REVERSED
|
col, StockNoteType.STOCK_NOTE_TYPE_BASIC_OPTIONAL_REVERSED
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def addClozeModel(col: _Collection) -> NoteType:
|
def addClozeModel(col: Collection) -> NoteType:
|
||||||
return add_stock_notetype(col, StockNoteType.STOCK_NOTE_TYPE_CLOZE)
|
return add_stock_notetype(col, StockNoteType.STOCK_NOTE_TYPE_CLOZE)
|
||||||
|
|
||||||
|
|
||||||
def get_stock_notetypes(
|
def get_stock_notetypes(
|
||||||
col: _Collection,
|
col: Collection,
|
||||||
) -> List[Tuple[str, Callable[[_Collection], NoteType]]]:
|
) -> List[Tuple[str, Callable[[Collection], NoteType]]]:
|
||||||
out: List[Tuple[str, Callable[[_Collection], NoteType]]] = []
|
out: List[Tuple[str, Callable[[Collection], NoteType]]] = []
|
||||||
# add standard
|
# add standard
|
||||||
for (kind, func) in [
|
for (kind, func) in [
|
||||||
(StockNoteType.STOCK_NOTE_TYPE_BASIC, addBasicModel),
|
(StockNoteType.STOCK_NOTE_TYPE_BASIC, addBasicModel),
|
||||||
|
|
|
@ -1,17 +1,8 @@
|
||||||
# Copyright: Ankitects Pty Ltd and contributors
|
# Copyright: Ankitects Pty Ltd and contributors
|
||||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
from typing import Optional
|
# Legacy code expects to find Collection in this module.
|
||||||
|
|
||||||
from anki.collection import _Collection
|
from anki.collection import Collection
|
||||||
from anki.rsbackend import RustBackend
|
|
||||||
|
|
||||||
|
_Collection = Collection
|
||||||
def Collection(
|
|
||||||
path: str,
|
|
||||||
backend: Optional[RustBackend] = None,
|
|
||||||
server: bool = False,
|
|
||||||
log: bool = False,
|
|
||||||
) -> _Collection:
|
|
||||||
"Open a new or existing collection. Path must be unicode."
|
|
||||||
return _Collection(path, backend, server, log)
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ class UnexpectedSchemaChange(Exception):
|
||||||
class Syncer:
|
class Syncer:
|
||||||
chunkRows: Optional[List[Sequence]]
|
chunkRows: Optional[List[Sequence]]
|
||||||
|
|
||||||
def __init__(self, col: anki.storage._Collection, server=None) -> None:
|
def __init__(self, col: anki.collection.Collection, server=None) -> None:
|
||||||
self.col = col.weakref()
|
self.col = col.weakref()
|
||||||
self.server = server
|
self.server = server
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ from anki.utils import ids2str
|
||||||
|
|
||||||
|
|
||||||
class TagManager:
|
class TagManager:
|
||||||
def __init__(self, col: anki.storage._Collection) -> None:
|
def __init__(self, col: anki.collection.Collection) -> None:
|
||||||
self.col = col.weakref()
|
self.col = col.weakref()
|
||||||
|
|
||||||
# all tags
|
# all tags
|
||||||
|
|
|
@ -74,7 +74,7 @@ class TemplateRenderContext:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
col: anki.storage._Collection,
|
col: anki.collection.Collection,
|
||||||
card: Card,
|
card: Card,
|
||||||
note: Note,
|
note: Note,
|
||||||
browser: bool = False,
|
browser: bool = False,
|
||||||
|
@ -97,7 +97,7 @@ class TemplateRenderContext:
|
||||||
# hooks, you can insert it into this dictionary
|
# hooks, you can insert it into this dictionary
|
||||||
self.extra_state: Dict[str, Any] = {}
|
self.extra_state: Dict[str, Any] = {}
|
||||||
|
|
||||||
def col(self) -> anki.storage._Collection:
|
def col(self) -> anki.collection.Collection:
|
||||||
return self._col
|
return self._col
|
||||||
|
|
||||||
# legacy
|
# legacy
|
||||||
|
|
|
@ -16,7 +16,7 @@ import aqt
|
||||||
import aqt.forms
|
import aqt.forms
|
||||||
from anki import hooks
|
from anki import hooks
|
||||||
from anki.cards import Card
|
from anki.cards import Card
|
||||||
from anki.collection import _Collection
|
from anki.collection import Collection
|
||||||
from anki.consts import *
|
from anki.consts import *
|
||||||
from anki.lang import _, ngettext
|
from anki.lang import _, ngettext
|
||||||
from anki.models import NoteType
|
from anki.models import NoteType
|
||||||
|
@ -569,7 +569,7 @@ class SidebarModel(QAbstractItemModel):
|
||||||
class Browser(QMainWindow):
|
class Browser(QMainWindow):
|
||||||
model: DataModel
|
model: DataModel
|
||||||
mw: AnkiQt
|
mw: AnkiQt
|
||||||
col: _Collection
|
col: Collection
|
||||||
editor: Optional[Editor]
|
editor: Optional[Editor]
|
||||||
|
|
||||||
def __init__(self, mw: AnkiQt) -> None:
|
def __init__(self, mw: AnkiQt) -> None:
|
||||||
|
|
|
@ -702,17 +702,17 @@ card_will_show = _CardWillShowFilter()
|
||||||
|
|
||||||
|
|
||||||
class _CollectionDidLoadHook:
|
class _CollectionDidLoadHook:
|
||||||
_hooks: List[Callable[["anki.storage._Collection"], None]] = []
|
_hooks: List[Callable[["anki.collection.Collection"], None]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[["anki.storage._Collection"], None]) -> None:
|
def append(self, cb: Callable[["anki.collection.Collection"], None]) -> None:
|
||||||
"""(col: anki.storage._Collection)"""
|
"""(col: anki.storage._Collection)"""
|
||||||
self._hooks.append(cb)
|
self._hooks.append(cb)
|
||||||
|
|
||||||
def remove(self, cb: Callable[["anki.storage._Collection"], None]) -> None:
|
def remove(self, cb: Callable[["anki.collection.Collection"], None]) -> None:
|
||||||
if cb in self._hooks:
|
if cb in self._hooks:
|
||||||
self._hooks.remove(cb)
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
def __call__(self, col: anki.storage._Collection) -> None:
|
def __call__(self, col: anki.collection.Collection) -> None:
|
||||||
for hook in self._hooks:
|
for hook in self._hooks:
|
||||||
try:
|
try:
|
||||||
hook(col)
|
hook(col)
|
||||||
|
|
|
@ -27,12 +27,11 @@ import aqt.stats
|
||||||
import aqt.toolbar
|
import aqt.toolbar
|
||||||
import aqt.webview
|
import aqt.webview
|
||||||
from anki import hooks
|
from anki import hooks
|
||||||
from anki.collection import _Collection
|
from anki.collection import Collection
|
||||||
from anki.hooks import runHook
|
from anki.hooks import runHook
|
||||||
from anki.lang import _, ngettext
|
from anki.lang import _, ngettext
|
||||||
from anki.rsbackend import RustBackend
|
from anki.rsbackend import RustBackend
|
||||||
from anki.sound import AVTag, SoundOrVideoTag
|
from anki.sound import AVTag, SoundOrVideoTag
|
||||||
from anki.storage import Collection
|
|
||||||
from anki.utils import devMode, ids2str, intTime, isMac, isWin, splitFields
|
from anki.utils import devMode, ids2str, intTime, isMac, isWin, splitFields
|
||||||
from aqt import gui_hooks
|
from aqt import gui_hooks
|
||||||
from aqt.addons import DownloadLogEntry, check_and_prompt_for_updates, show_log_to_user
|
from aqt.addons import DownloadLogEntry, check_and_prompt_for_updates, show_log_to_user
|
||||||
|
@ -71,7 +70,7 @@ class ResetRequired:
|
||||||
|
|
||||||
|
|
||||||
class AnkiQt(QMainWindow):
|
class AnkiQt(QMainWindow):
|
||||||
col: _Collection
|
col: Collection
|
||||||
pm: ProfileManagerType
|
pm: ProfileManagerType
|
||||||
web: aqt.webview.AnkiWebView
|
web: aqt.webview.AnkiWebView
|
||||||
bottomWeb: aqt.webview.AnkiWebView
|
bottomWeb: aqt.webview.AnkiWebView
|
||||||
|
@ -88,7 +87,7 @@ class AnkiQt(QMainWindow):
|
||||||
self.backend = backend
|
self.backend = backend
|
||||||
self.state = "startup"
|
self.state = "startup"
|
||||||
self.opts = opts
|
self.opts = opts
|
||||||
self.col: Optional[_Collection] = None
|
self.col: Optional[Collection] = None
|
||||||
self.taskman = TaskManager(self)
|
self.taskman = TaskManager(self)
|
||||||
self.media_syncer = MediaSyncer(self)
|
self.media_syncer = MediaSyncer(self)
|
||||||
aqt.mw = self
|
aqt.mw = self
|
||||||
|
@ -1265,7 +1264,7 @@ and if the problem comes up again, please ask on the support site."""
|
||||||
# Log note deletion
|
# Log note deletion
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def onRemNotes(self, col: _Collection, nids: List[int]) -> None:
|
def onRemNotes(self, col: Collection, nids: List[int]) -> None:
|
||||||
path = os.path.join(self.pm.profileFolder(), "deleted.txt")
|
path = os.path.join(self.pm.profileFolder(), "deleted.txt")
|
||||||
existed = os.path.exists(path)
|
existed = os.path.exists(path)
|
||||||
with open(path, "ab") as f:
|
with open(path, "ab") as f:
|
||||||
|
|
|
@ -9,7 +9,7 @@ import threading
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from anki.collection import _Collection
|
from anki.collection import Collection
|
||||||
from anki.utils import devMode
|
from anki.utils import devMode
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
from aqt.utils import aqt_data_folder
|
from aqt.utils import aqt_data_folder
|
||||||
|
@ -74,7 +74,7 @@ class MediaServer(threading.Thread):
|
||||||
class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
|
|
||||||
timeout = 1
|
timeout = 1
|
||||||
mw: Optional[_Collection] = None
|
mw: Optional[Collection] = None
|
||||||
|
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
f = self.send_head()
|
f = self.send_head()
|
||||||
|
|
Loading…
Reference in a new issue