commit
c3f8f7dd94
@ -19,6 +19,21 @@ from anki.utils import ids2str, intTime
|
|||||||
defaultDeck = 0
|
defaultDeck = 0
|
||||||
defaultDynamicDeck = 1
|
defaultDynamicDeck = 1
|
||||||
|
|
||||||
|
NonFilteredDeck = Dict[str, Any]
|
||||||
|
FilteredDeck = Dict[str, Any]
|
||||||
|
|
||||||
|
"""Any kind of deck """
|
||||||
|
Deck = Union[NonFilteredDeck, FilteredDeck]
|
||||||
|
|
||||||
|
"""Configuration of standard deck, as seen from the deck picker's gear."""
|
||||||
|
Config = Dict[str, Any]
|
||||||
|
|
||||||
|
"""Configurationf of some deck, filtered deck for filtered deck, config for standard deck"""
|
||||||
|
DeckConfig = Union[FilteredDeck, Config]
|
||||||
|
|
||||||
|
""" New/lrn/rev conf, from deck config"""
|
||||||
|
QueueConfig = Dict[str, Any]
|
||||||
|
|
||||||
|
|
||||||
class DecksDictProxy:
|
class DecksDictProxy:
|
||||||
def __init__(self, col: anki.collection.Collection):
|
def __init__(self, col: anki.collection.Collection):
|
||||||
@ -64,7 +79,7 @@ class DeckManager:
|
|||||||
self.col = col.weakref()
|
self.col = col.weakref()
|
||||||
self.decks = DecksDictProxy(col)
|
self.decks = DecksDictProxy(col)
|
||||||
|
|
||||||
def save(self, g: Dict = None) -> None:
|
def save(self, g: Union[Deck, Config] = None) -> None:
|
||||||
"Can be called with either a deck or a deck configuration."
|
"Can be called with either a deck or a deck configuration."
|
||||||
if not g:
|
if not g:
|
||||||
print("col.decks.save() should be passed the changed deck")
|
print("col.decks.save() should be passed the changed deck")
|
||||||
@ -124,7 +139,7 @@ class DeckManager:
|
|||||||
except NotFoundError:
|
except NotFoundError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_legacy(self, did: int) -> Optional[Dict]:
|
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:
|
||||||
@ -133,10 +148,10 @@ class DeckManager:
|
|||||||
def have(self, id: int) -> bool:
|
def have(self, id: int) -> bool:
|
||||||
return not self.get_legacy(int(id))
|
return not self.get_legacy(int(id))
|
||||||
|
|
||||||
def get_all_legacy(self) -> List[Dict]:
|
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) -> Dict:
|
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) -> pb.DeckTreeNode:
|
def deck_tree(self) -> pb.DeckTreeNode:
|
||||||
@ -154,7 +169,7 @@ class DeckManager:
|
|||||||
return match
|
return match
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def all(self) -> List:
|
def all(self) -> List[Deck]:
|
||||||
"All decks. Expensive; prefer all_names_and_ids()"
|
"All decks. Expensive; prefer all_names_and_ids()"
|
||||||
return self.get_all_legacy()
|
return self.get_all_legacy()
|
||||||
|
|
||||||
@ -162,7 +177,7 @@ class DeckManager:
|
|||||||
print("decks.allIds() is deprecated, use .all_names_and_ids()")
|
print("decks.allIds() is deprecated, use .all_names_and_ids()")
|
||||||
return [str(x.id) for x in self.all_names_and_ids()]
|
return [str(x.id) for x in self.all_names_and_ids()]
|
||||||
|
|
||||||
def allNames(self, dyn: bool = True, force_default: bool = True) -> List:
|
def allNames(self, dyn: bool = True, force_default: bool = True) -> List[str]:
|
||||||
print("decks.allNames() is deprecated, use .all_names_and_ids()")
|
print("decks.allNames() is deprecated, use .all_names_and_ids()")
|
||||||
return [
|
return [
|
||||||
x.name
|
x.name
|
||||||
@ -185,7 +200,7 @@ class DeckManager:
|
|||||||
def count(self) -> int:
|
def count(self) -> int:
|
||||||
return len(self.all_names_and_ids())
|
return len(self.all_names_and_ids())
|
||||||
|
|
||||||
def get(self, did: Union[int, str], default: bool = True) -> Optional[Dict]:
|
def get(self, did: Union[int, str], default: bool = True) -> Optional[Deck]:
|
||||||
if not did:
|
if not did:
|
||||||
if default:
|
if default:
|
||||||
return self.get_legacy(1)
|
return self.get_legacy(1)
|
||||||
@ -200,14 +215,14 @@ class DeckManager:
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def byName(self, name: str) -> Optional[Dict]:
|
def byName(self, name: str) -> Optional[Deck]:
|
||||||
"""Get deck with NAME, ignoring case."""
|
"""Get deck with NAME, ignoring case."""
|
||||||
id = self.id_for_name(name)
|
id = self.id_for_name(name)
|
||||||
if id:
|
if id:
|
||||||
return self.get_legacy(id)
|
return self.get_legacy(id)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def update(self, g: Dict[str, Any], 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(
|
||||||
@ -216,7 +231,7 @@ class DeckManager:
|
|||||||
except anki.rsbackend.DeckIsFilteredError:
|
except anki.rsbackend.DeckIsFilteredError:
|
||||||
raise DeckRenameError("deck was filtered")
|
raise DeckRenameError("deck was filtered")
|
||||||
|
|
||||||
def rename(self, g: Dict[str, Any], newName: str) -> None:
|
def rename(self, g: Deck, newName: str) -> None:
|
||||||
"Rename deck prefix to NAME if not exists. Updates children."
|
"Rename deck prefix to NAME if not exists. Updates children."
|
||||||
g["name"] = newName
|
g["name"] = newName
|
||||||
self.update(g, preserve_usn=False)
|
self.update(g, preserve_usn=False)
|
||||||
@ -225,7 +240,9 @@ class DeckManager:
|
|||||||
# Drag/drop
|
# Drag/drop
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
def renameForDragAndDrop(self, draggedDeckDid: int, ontoDeckDid: Any) -> None:
|
def renameForDragAndDrop(
|
||||||
|
self, draggedDeckDid: int, ontoDeckDid: Optional[Union[int, str]]
|
||||||
|
) -> None:
|
||||||
draggedDeck = self.get(draggedDeckDid)
|
draggedDeck = self.get(draggedDeckDid)
|
||||||
draggedDeckName = draggedDeck["name"]
|
draggedDeckName = draggedDeck["name"]
|
||||||
ontoDeckName = self.get(ontoDeckDid)["name"]
|
ontoDeckName = self.get(ontoDeckDid)["name"]
|
||||||
@ -252,23 +269,23 @@ class DeckManager:
|
|||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _isParent(self, parentDeckName: str, childDeckName: str) -> Any:
|
def _isParent(self, parentDeckName: str, childDeckName: str) -> bool:
|
||||||
return self.path(childDeckName) == self.path(parentDeckName) + [
|
return self.path(childDeckName) == self.path(parentDeckName) + [
|
||||||
self.basename(childDeckName)
|
self.basename(childDeckName)
|
||||||
]
|
]
|
||||||
|
|
||||||
def _isAncestor(self, ancestorDeckName: str, descendantDeckName: str) -> Any:
|
def _isAncestor(self, ancestorDeckName: str, descendantDeckName: str) -> bool:
|
||||||
ancestorPath = self.path(ancestorDeckName)
|
ancestorPath = self.path(ancestorDeckName)
|
||||||
return ancestorPath == self.path(descendantDeckName)[0 : len(ancestorPath)]
|
return ancestorPath == self.path(descendantDeckName)[0 : len(ancestorPath)]
|
||||||
|
|
||||||
# Deck configurations
|
# Deck configurations
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
def all_config(self) -> List:
|
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) -> Any:
|
def confForDid(self, did: int) -> DeckConfig:
|
||||||
deck = self.get(did, default=False)
|
deck = self.get(did, default=False)
|
||||||
assert deck
|
assert deck
|
||||||
if "conf" in deck:
|
if "conf" in deck:
|
||||||
@ -282,20 +299,20 @@ class DeckManager:
|
|||||||
# dynamic decks have embedded conf
|
# dynamic decks have embedded conf
|
||||||
return deck
|
return deck
|
||||||
|
|
||||||
def get_config(self, conf_id: int) -> Any:
|
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: Dict[str, Any], 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
|
||||||
)
|
)
|
||||||
|
|
||||||
def add_config(
|
def add_config(
|
||||||
self, name: str, clone_from: Optional[Dict[str, Any]] = None
|
self, name: str, clone_from: Optional[DeckConfig] = None
|
||||||
) -> Dict[str, Any]:
|
) -> DeckConfig:
|
||||||
if clone_from is not None:
|
if clone_from is not None:
|
||||||
conf = copy.deepcopy(clone_from)
|
conf = copy.deepcopy(clone_from)
|
||||||
conf["id"] = 0
|
conf["id"] = 0
|
||||||
@ -306,7 +323,7 @@ class DeckManager:
|
|||||||
return conf
|
return conf
|
||||||
|
|
||||||
def add_config_returning_id(
|
def add_config_returning_id(
|
||||||
self, name: str, clone_from: Optional[Dict[str, Any]] = None
|
self, name: str, clone_from: Optional[DeckConfig] = None
|
||||||
) -> int:
|
) -> int:
|
||||||
return self.add_config(name, clone_from)["id"]
|
return self.add_config(name, clone_from)["id"]
|
||||||
|
|
||||||
@ -322,11 +339,11 @@ class DeckManager:
|
|||||||
self.save(g)
|
self.save(g)
|
||||||
self.col.backend.remove_deck_config(id)
|
self.col.backend.remove_deck_config(id)
|
||||||
|
|
||||||
def setConf(self, grp: Dict[str, Any], id: int) -> None:
|
def setConf(self, grp: DeckConfig, id: int) -> None:
|
||||||
grp["conf"] = id
|
grp["conf"] = id
|
||||||
self.save(grp)
|
self.save(grp)
|
||||||
|
|
||||||
def didsForConf(self, conf) -> List:
|
def didsForConf(self, conf) -> List[int]:
|
||||||
dids = []
|
dids = []
|
||||||
for deck in self.all():
|
for deck in self.all():
|
||||||
if "conf" in deck and deck["conf"] == conf["id"]:
|
if "conf" in deck and deck["conf"] == conf["id"]:
|
||||||
@ -353,13 +370,13 @@ class DeckManager:
|
|||||||
# Deck utils
|
# Deck utils
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
def name(self, did: int, default: bool = False) -> Any:
|
def name(self, did: int, default: bool = False) -> str:
|
||||||
deck = self.get(did, default=default)
|
deck = self.get(did, default=default)
|
||||||
if deck:
|
if deck:
|
||||||
return deck["name"]
|
return deck["name"]
|
||||||
return _("[no deck]")
|
return _("[no deck]")
|
||||||
|
|
||||||
def nameOrNone(self, did: int) -> Any:
|
def nameOrNone(self, did: int) -> Optional[str]:
|
||||||
deck = self.get(did, default=False)
|
deck = self.get(did, default=False)
|
||||||
if deck:
|
if deck:
|
||||||
return deck["name"]
|
return deck["name"]
|
||||||
@ -373,7 +390,7 @@ class DeckManager:
|
|||||||
intTime(),
|
intTime(),
|
||||||
)
|
)
|
||||||
|
|
||||||
def cids(self, did: int, children: bool = False) -> Any:
|
def cids(self, did: int, children: bool = False) -> List[int]:
|
||||||
if not children:
|
if not children:
|
||||||
return self.col.db.list("select id from cards where did=?", did)
|
return self.col.db.list("select id from cards where did=?", did)
|
||||||
dids = [did]
|
dids = [did]
|
||||||
@ -387,15 +404,15 @@ class DeckManager:
|
|||||||
# Deck selection
|
# Deck selection
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
def active(self) -> Any:
|
def active(self) -> List[int]:
|
||||||
"The currrently active dids."
|
"The currrently active dids."
|
||||||
return self.col.get_config("activeDecks", [1])
|
return self.col.get_config("activeDecks", [1])
|
||||||
|
|
||||||
def selected(self) -> Any:
|
def selected(self) -> int:
|
||||||
"The currently selected did."
|
"The currently selected did."
|
||||||
return self.col.conf["curDeck"]
|
return self.col.conf["curDeck"]
|
||||||
|
|
||||||
def current(self) -> Any:
|
def current(self) -> Deck:
|
||||||
return self.get(self.selected())
|
return self.get(self.selected())
|
||||||
|
|
||||||
def select(self, did: int) -> None:
|
def select(self, did: int) -> None:
|
||||||
@ -416,32 +433,33 @@ class DeckManager:
|
|||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def path(name: str) -> Any:
|
def path(name: str) -> List[str]:
|
||||||
return name.split("::")
|
return name.split("::")
|
||||||
|
|
||||||
_path = path
|
_path = path
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def basename(cls, name: str) -> Any:
|
def basename(cls, name: str) -> str:
|
||||||
return cls.path(name)[-1]
|
return cls.path(name)[-1]
|
||||||
|
|
||||||
_basename = basename
|
_basename = basename
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def immediate_parent_path(cls, name: str) -> Any:
|
def immediate_parent_path(cls, name: str) -> List[str]:
|
||||||
return cls._path(name)[:-1]
|
return cls._path(name)[:-1]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def immediate_parent(cls, name: str) -> Any:
|
def immediate_parent(cls, name: str) -> Optional[str]:
|
||||||
pp = cls.immediate_parent_path(name)
|
pp = cls.immediate_parent_path(name)
|
||||||
if pp:
|
if pp:
|
||||||
return "::".join(pp)
|
return "::".join(pp)
|
||||||
|
return None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def key(cls, deck: Dict[str, Any]) -> List[str]:
|
def key(cls, deck: Deck) -> List[str]:
|
||||||
return cls.path(deck["name"])
|
return cls.path(deck["name"])
|
||||||
|
|
||||||
def children(self, did: int) -> List[Tuple[Any, Any]]:
|
def children(self, did: int) -> List[Tuple[str, int]]:
|
||||||
"All children of did, as (name, id)."
|
"All children of did, as (name, id)."
|
||||||
name = self.get(did)["name"]
|
name = self.get(did)["name"]
|
||||||
actv = []
|
actv = []
|
||||||
@ -460,19 +478,22 @@ class DeckManager:
|
|||||||
out.extend(self.child_ids(parent_name))
|
out.extend(self.child_ids(parent_name))
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def childDids(self, did: int, childMap: Dict[int, Any]) -> List:
|
childMapNode = Dict[int, Any]
|
||||||
def gather(node, arr):
|
# Change to Dict[int, "DeckManager.childMapNode"] when MyPy allow recursive type
|
||||||
|
|
||||||
|
def childDids(self, did: int, childMap: DeckManager.childMapNode) -> List:
|
||||||
|
def gather(node: DeckManager.childMapNode, arr):
|
||||||
for did, child in node.items():
|
for did, child in node.items():
|
||||||
arr.append(did)
|
arr.append(did)
|
||||||
gather(child, arr)
|
gather(child, arr)
|
||||||
|
|
||||||
arr: List = []
|
arr: List[int] = []
|
||||||
gather(childMap[did], arr)
|
gather(childMap[did], arr)
|
||||||
return arr
|
return arr
|
||||||
|
|
||||||
def childMap(self) -> Dict[Any, Dict[Any, dict]]:
|
def childMap(self) -> DeckManager.childMapNode:
|
||||||
nameMap = self.nameMap()
|
nameMap = self.nameMap()
|
||||||
childMap = {}
|
childMap: DeckManager.childMapNode = {}
|
||||||
|
|
||||||
# go through all decks, sorted by name
|
# go through all decks, sorted by name
|
||||||
for deck in sorted(self.all(), key=self.key):
|
for deck in sorted(self.all(), key=self.key):
|
||||||
@ -487,31 +508,34 @@ class DeckManager:
|
|||||||
|
|
||||||
return childMap
|
return childMap
|
||||||
|
|
||||||
def parents(self, did: int, nameMap: Optional[Any] = None) -> List:
|
def parents(
|
||||||
|
self, did: int, nameMap: Optional[Dict[str, Deck]] = None
|
||||||
|
) -> List[Deck]:
|
||||||
"All parents of did."
|
"All parents of did."
|
||||||
# get parent and grandparent names
|
# get parent and grandparent names
|
||||||
parents: List[str] = []
|
parents_names: List[str] = []
|
||||||
for part in self.immediate_parent_path(self.get(did)["name"]):
|
for part in self.immediate_parent_path(self.get(did)["name"]):
|
||||||
if not parents:
|
if not parents_names:
|
||||||
parents.append(part)
|
parents_names.append(part)
|
||||||
else:
|
else:
|
||||||
parents.append(parents[-1] + "::" + part)
|
parents_names.append(parents_names[-1] + "::" + part)
|
||||||
|
parents: List[Deck] = []
|
||||||
# convert to objects
|
# convert to objects
|
||||||
for c, p in enumerate(parents):
|
for parent_name in parents_names:
|
||||||
if nameMap:
|
if nameMap:
|
||||||
deck = nameMap[p]
|
deck = nameMap[parent_name]
|
||||||
else:
|
else:
|
||||||
deck = self.get(self.id(p))
|
deck = self.get(self.id(parent_name))
|
||||||
parents[c] = deck
|
parents.append(deck)
|
||||||
return parents
|
return parents
|
||||||
|
|
||||||
def parentsByName(self, name: str) -> List:
|
def parentsByName(self, name: str) -> List[Deck]:
|
||||||
"All existing parents of name"
|
"All existing parents of name"
|
||||||
if "::" not in name:
|
if "::" not in name:
|
||||||
return []
|
return []
|
||||||
names = self.immediate_parent_path(name)
|
names = self.immediate_parent_path(name)
|
||||||
head = []
|
head = []
|
||||||
parents = []
|
parents: List[Deck] = []
|
||||||
|
|
||||||
while names:
|
while names:
|
||||||
head.append(names.pop(0))
|
head.append(names.pop(0))
|
||||||
@ -521,7 +545,7 @@ class DeckManager:
|
|||||||
|
|
||||||
return parents
|
return parents
|
||||||
|
|
||||||
def nameMap(self) -> dict:
|
def nameMap(self) -> Dict[str, Deck]:
|
||||||
return dict((d["name"], d) for d in self.all())
|
return dict((d["name"], d) for d in self.all())
|
||||||
|
|
||||||
# Dynamic decks
|
# Dynamic decks
|
||||||
@ -533,5 +557,6 @@ class DeckManager:
|
|||||||
self.select(did)
|
self.select(did)
|
||||||
return did
|
return did
|
||||||
|
|
||||||
def isDyn(self, did: Union[int, str]) -> Any:
|
# 1 for dyn, 0 for standard
|
||||||
|
def isDyn(self, did: Union[int, str]) -> int:
|
||||||
return self.get(did)["dyn"]
|
return self.get(did)["dyn"]
|
||||||
|
@ -175,20 +175,20 @@ card_will_flush = _CardWillFlushHook()
|
|||||||
class _DeckAddedHook:
|
class _DeckAddedHook:
|
||||||
"""Obsolete, do not use."""
|
"""Obsolete, do not use."""
|
||||||
|
|
||||||
_hooks: List[Callable[[Dict[str, Any]], None]] = []
|
_hooks: List[Callable[["anki.decks.Deck"], None]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[[Dict[str, Any]], None]) -> None:
|
def append(self, cb: Callable[["anki.decks.Deck"], None]) -> None:
|
||||||
"""(deck: Dict[str, Any])"""
|
"""(deck: anki.decks.Deck)"""
|
||||||
self._hooks.append(cb)
|
self._hooks.append(cb)
|
||||||
|
|
||||||
def remove(self, cb: Callable[[Dict[str, Any]], None]) -> None:
|
def remove(self, cb: Callable[["anki.decks.Deck"], None]) -> None:
|
||||||
if cb in self._hooks:
|
if cb in self._hooks:
|
||||||
self._hooks.remove(cb)
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
def count(self) -> int:
|
def count(self) -> int:
|
||||||
return len(self._hooks)
|
return len(self._hooks)
|
||||||
|
|
||||||
def __call__(self, deck: Dict[str, Any]) -> None:
|
def __call__(self, deck: anki.decks.Deck) -> None:
|
||||||
for hook in self._hooks:
|
for hook in self._hooks:
|
||||||
try:
|
try:
|
||||||
hook(deck)
|
hook(deck)
|
||||||
@ -305,20 +305,20 @@ media_files_did_export = _MediaFilesDidExportHook()
|
|||||||
class _NoteTypeAddedHook:
|
class _NoteTypeAddedHook:
|
||||||
"""Obsolete, do not use."""
|
"""Obsolete, do not use."""
|
||||||
|
|
||||||
_hooks: List[Callable[[Dict[str, Any]], None]] = []
|
_hooks: List[Callable[["anki.models.NoteType"], None]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[[Dict[str, Any]], None]) -> None:
|
def append(self, cb: Callable[["anki.models.NoteType"], None]) -> None:
|
||||||
"""(notetype: Dict[str, Any])"""
|
"""(notetype: anki.models.NoteType)"""
|
||||||
self._hooks.append(cb)
|
self._hooks.append(cb)
|
||||||
|
|
||||||
def remove(self, cb: Callable[[Dict[str, Any]], None]) -> None:
|
def remove(self, cb: Callable[["anki.models.NoteType"], None]) -> None:
|
||||||
if cb in self._hooks:
|
if cb in self._hooks:
|
||||||
self._hooks.remove(cb)
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
def count(self) -> int:
|
def count(self) -> int:
|
||||||
return len(self._hooks)
|
return len(self._hooks)
|
||||||
|
|
||||||
def __call__(self, notetype: Dict[str, Any]) -> None:
|
def __call__(self, notetype: anki.models.NoteType) -> None:
|
||||||
for hook in self._hooks:
|
for hook in self._hooks:
|
||||||
try:
|
try:
|
||||||
hook(notetype)
|
hook(notetype)
|
||||||
@ -397,20 +397,20 @@ class _SchedulerNewLimitForSingleDeckFilter:
|
|||||||
"""Allows changing the number of new card for this deck (without
|
"""Allows changing the number of new card for this deck (without
|
||||||
considering descendants)."""
|
considering descendants)."""
|
||||||
|
|
||||||
_hooks: List[Callable[[int, Dict[str, Any]], int]] = []
|
_hooks: List[Callable[[int, "anki.decks.Deck"], int]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[[int, Dict[str, Any]], int]) -> None:
|
def append(self, cb: Callable[[int, "anki.decks.Deck"], int]) -> None:
|
||||||
"""(count: int, deck: Dict[str, Any])"""
|
"""(count: int, deck: anki.decks.Deck)"""
|
||||||
self._hooks.append(cb)
|
self._hooks.append(cb)
|
||||||
|
|
||||||
def remove(self, cb: Callable[[int, Dict[str, Any]], int]) -> None:
|
def remove(self, cb: Callable[[int, "anki.decks.Deck"], int]) -> None:
|
||||||
if cb in self._hooks:
|
if cb in self._hooks:
|
||||||
self._hooks.remove(cb)
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
def count(self) -> int:
|
def count(self) -> int:
|
||||||
return len(self._hooks)
|
return len(self._hooks)
|
||||||
|
|
||||||
def __call__(self, count: int, deck: Dict[str, Any]) -> int:
|
def __call__(self, count: int, deck: anki.decks.Deck) -> int:
|
||||||
for filter in self._hooks:
|
for filter in self._hooks:
|
||||||
try:
|
try:
|
||||||
count = filter(count, deck)
|
count = filter(count, deck)
|
||||||
@ -428,20 +428,20 @@ class _SchedulerReviewLimitForSingleDeckFilter:
|
|||||||
"""Allows changing the number of rev card for this deck (without
|
"""Allows changing the number of rev card for this deck (without
|
||||||
considering descendants)."""
|
considering descendants)."""
|
||||||
|
|
||||||
_hooks: List[Callable[[int, Dict[str, Any]], int]] = []
|
_hooks: List[Callable[[int, "anki.decks.Deck"], int]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[[int, Dict[str, Any]], int]) -> None:
|
def append(self, cb: Callable[[int, "anki.decks.Deck"], int]) -> None:
|
||||||
"""(count: int, deck: Dict[str, Any])"""
|
"""(count: int, deck: anki.decks.Deck)"""
|
||||||
self._hooks.append(cb)
|
self._hooks.append(cb)
|
||||||
|
|
||||||
def remove(self, cb: Callable[[int, Dict[str, Any]], int]) -> None:
|
def remove(self, cb: Callable[[int, "anki.decks.Deck"], int]) -> None:
|
||||||
if cb in self._hooks:
|
if cb in self._hooks:
|
||||||
self._hooks.remove(cb)
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
def count(self) -> int:
|
def count(self) -> int:
|
||||||
return len(self._hooks)
|
return len(self._hooks)
|
||||||
|
|
||||||
def __call__(self, count: int, deck: Dict[str, Any]) -> int:
|
def __call__(self, count: int, deck: anki.decks.Deck) -> int:
|
||||||
for filter in self._hooks:
|
for filter in self._hooks:
|
||||||
try:
|
try:
|
||||||
count = filter(count, deck)
|
count = filter(count, deck)
|
||||||
|
@ -138,7 +138,7 @@ class ModelManager:
|
|||||||
# Current note type
|
# Current note type
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
def current(self, forDeck: bool = True) -> Any:
|
def current(self, forDeck: bool = True) -> NoteType:
|
||||||
"Get current model."
|
"Get current model."
|
||||||
m = self.get(self.col.decks.current().get("mid"))
|
m = self.get(self.col.decks.current().get("mid"))
|
||||||
if not forDeck or not m:
|
if not forDeck or not m:
|
||||||
@ -243,21 +243,21 @@ class ModelManager:
|
|||||||
# Tools
|
# Tools
|
||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
def nids(self, ntid: int) -> Any:
|
def nids(self, ntid: int) -> List[int]:
|
||||||
"Note ids for M."
|
"Note ids for M."
|
||||||
if isinstance(ntid, dict):
|
if isinstance(ntid, dict):
|
||||||
# legacy callers passed in note type
|
# legacy callers passed in note type
|
||||||
ntid = ntid["id"]
|
ntid = ntid["id"]
|
||||||
return self.col.db.list("select id from notes where mid = ?", ntid)
|
return self.col.db.list("select id from notes where mid = ?", ntid)
|
||||||
|
|
||||||
def useCount(self, m: NoteType) -> Any:
|
def useCount(self, m: NoteType) -> int:
|
||||||
"Number of note using M."
|
"Number of note using M."
|
||||||
return self.col.db.scalar("select count() from notes where mid = ?", m["id"])
|
return self.col.db.scalar("select count() from notes where mid = ?", m["id"])
|
||||||
|
|
||||||
# Copying
|
# Copying
|
||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
def copy(self, m: NoteType) -> Any:
|
def copy(self, m: NoteType) -> NoteType:
|
||||||
"Copy, save and return."
|
"Copy, save and return."
|
||||||
m2 = copy.deepcopy(m)
|
m2 = copy.deepcopy(m)
|
||||||
m2["name"] = _("%s copy") % m2["name"]
|
m2["name"] = _("%s copy") % m2["name"]
|
||||||
@ -275,7 +275,7 @@ class ModelManager:
|
|||||||
def fieldNames(self, m: NoteType) -> List[str]:
|
def fieldNames(self, m: NoteType) -> List[str]:
|
||||||
return [f["name"] for f in m["flds"]]
|
return [f["name"] for f in m["flds"]]
|
||||||
|
|
||||||
def sortIdx(self, m: NoteType) -> Any:
|
def sortIdx(self, m: NoteType) -> int:
|
||||||
return m["sortf"]
|
return m["sortf"]
|
||||||
|
|
||||||
# Adding & changing fields
|
# Adding & changing fields
|
||||||
@ -406,7 +406,12 @@ and notes.mid = ? and cards.ord = ?""",
|
|||||||
# - newModel should be self if model is not changing
|
# - newModel should be self if model is not changing
|
||||||
|
|
||||||
def change(
|
def change(
|
||||||
self, m: NoteType, nids: List[int], newModel: NoteType, fmap: Any, cmap: Any
|
self,
|
||||||
|
m: NoteType,
|
||||||
|
nids: List[int],
|
||||||
|
newModel: NoteType,
|
||||||
|
fmap: Optional[Dict[int, Union[None, int]]],
|
||||||
|
cmap: Optional[Dict[int, Union[None, int]]],
|
||||||
) -> None:
|
) -> None:
|
||||||
self.col.modSchema(check=True)
|
self.col.modSchema(check=True)
|
||||||
assert newModel["id"] == m["id"] or (fmap and cmap)
|
assert newModel["id"] == m["id"] or (fmap and cmap)
|
||||||
@ -483,7 +488,9 @@ and notes.mid = ? and cards.ord = ?""",
|
|||||||
# Cloze
|
# Cloze
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def _availClozeOrds(self, m: NoteType, flds: str, allowEmpty: bool = True) -> List:
|
def _availClozeOrds(
|
||||||
|
self, m: NoteType, flds: str, allowEmpty: bool = True
|
||||||
|
) -> List[int]:
|
||||||
print("_availClozeOrds() is deprecated; use note.cloze_numbers_in_fields()")
|
print("_availClozeOrds() is deprecated; use note.cloze_numbers_in_fields()")
|
||||||
note = anki.rsbackend.BackendNote(fields=[flds])
|
note = anki.rsbackend.BackendNote(fields=[flds])
|
||||||
return list(self.col.backend.cloze_numbers_in_note(note))
|
return list(self.col.backend.cloze_numbers_in_note(note))
|
||||||
|
@ -6,12 +6,13 @@ from __future__ import annotations
|
|||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
from heapq import *
|
from heapq import *
|
||||||
from typing import Any, Dict, List, Optional, Sequence, Tuple, Union
|
from typing import Any, List, Optional, Sequence, Tuple, Union
|
||||||
|
|
||||||
import anki
|
import anki
|
||||||
from anki import hooks
|
from anki import hooks
|
||||||
from anki.cards import Card
|
from anki.cards import Card
|
||||||
from anki.consts import *
|
from anki.consts import *
|
||||||
|
from anki.decks import Deck, QueueConfig
|
||||||
from anki.schedv2 import Scheduler as V2
|
from anki.schedv2 import Scheduler as V2
|
||||||
from anki.utils import ids2str, intTime
|
from anki.utils import ids2str, intTime
|
||||||
|
|
||||||
@ -299,13 +300,13 @@ limit %d"""
|
|||||||
card.queue = QUEUE_TYPE_DAY_LEARN_RELEARN
|
card.queue = QUEUE_TYPE_DAY_LEARN_RELEARN
|
||||||
self._logLrn(card, ease, conf, leaving, type, lastLeft)
|
self._logLrn(card, ease, conf, leaving, type, lastLeft)
|
||||||
|
|
||||||
def _lrnConf(self, card: Card) -> Dict[str, Any]:
|
def _lrnConf(self, card: Card) -> QueueConfig:
|
||||||
if card.type == CARD_TYPE_REV:
|
if card.type == CARD_TYPE_REV:
|
||||||
return self._lapseConf(card)
|
return self._lapseConf(card)
|
||||||
else:
|
else:
|
||||||
return self._newConf(card)
|
return self._newConf(card)
|
||||||
|
|
||||||
def _rescheduleAsRev(self, card: Card, conf: Dict[str, Any], early: bool) -> None:
|
def _rescheduleAsRev(self, card: Card, conf: QueueConfig, early: bool) -> None:
|
||||||
lapse = card.type == CARD_TYPE_REV
|
lapse = card.type == CARD_TYPE_REV
|
||||||
if lapse:
|
if lapse:
|
||||||
if self._resched(card):
|
if self._resched(card):
|
||||||
@ -338,7 +339,7 @@ limit %d"""
|
|||||||
return tot + tod * 1000
|
return tot + tod * 1000
|
||||||
|
|
||||||
def _graduatingIvl(
|
def _graduatingIvl(
|
||||||
self, card: Card, conf: Dict[str, Any], early: bool, adj: bool = True
|
self, card: Card, conf: QueueConfig, early: bool, adj: bool = True
|
||||||
) -> int:
|
) -> int:
|
||||||
if card.type == CARD_TYPE_REV:
|
if card.type == CARD_TYPE_REV:
|
||||||
# lapsed card being relearnt
|
# lapsed card being relearnt
|
||||||
@ -357,7 +358,7 @@ limit %d"""
|
|||||||
else:
|
else:
|
||||||
return ideal
|
return ideal
|
||||||
|
|
||||||
def _rescheduleNew(self, card: Card, conf: Dict[str, Any], early: bool) -> None:
|
def _rescheduleNew(self, card: Card, conf: QueueConfig, early: bool) -> None:
|
||||||
"Reschedule a new card that's graduated for the first time."
|
"Reschedule a new card that's graduated for the first time."
|
||||||
card.ivl = self._graduatingIvl(card, conf, early)
|
card.ivl = self._graduatingIvl(card, conf, early)
|
||||||
card.due = self.today + card.ivl
|
card.due = self.today + card.ivl
|
||||||
@ -367,7 +368,7 @@ limit %d"""
|
|||||||
self,
|
self,
|
||||||
card: Card,
|
card: Card,
|
||||||
ease: int,
|
ease: int,
|
||||||
conf: Dict[str, Any],
|
conf: QueueConfig,
|
||||||
leaving: bool,
|
leaving: bool,
|
||||||
type: int,
|
type: int,
|
||||||
lastLeft: int,
|
lastLeft: int,
|
||||||
@ -452,7 +453,7 @@ and due <= ? limit ?)""",
|
|||||||
def _deckRevLimit(self, did: int) -> int:
|
def _deckRevLimit(self, did: int) -> int:
|
||||||
return self._deckNewLimit(did, self._deckRevLimitSingle)
|
return self._deckNewLimit(did, self._deckRevLimitSingle)
|
||||||
|
|
||||||
def _deckRevLimitSingle(self, d: Dict[str, Any]) -> int: # type: ignore[override]
|
def _deckRevLimitSingle(self, d: Deck) -> int: # type: ignore[override]
|
||||||
if d["dyn"]:
|
if d["dyn"]:
|
||||||
return self.reportLimit
|
return self.reportLimit
|
||||||
c = self.col.decks.confForDid(d["id"])
|
c = self.col.decks.confForDid(d["id"])
|
||||||
@ -567,7 +568,7 @@ did = ? and queue = {QUEUE_TYPE_REV} and due <= ? limit ?""",
|
|||||||
card.queue = QUEUE_TYPE_DAY_LEARN_RELEARN
|
card.queue = QUEUE_TYPE_DAY_LEARN_RELEARN
|
||||||
return delay
|
return delay
|
||||||
|
|
||||||
def _nextLapseIvl(self, card: Card, conf: Dict[str, Any]) -> int:
|
def _nextLapseIvl(self, card: Card, conf: QueueConfig) -> int:
|
||||||
return max(conf["minInt"], int(card.ivl * conf["mult"]))
|
return max(conf["minInt"], int(card.ivl * conf["mult"]))
|
||||||
|
|
||||||
def _rescheduleRev(self, card: Card, ease: int) -> None: # type: ignore[override]
|
def _rescheduleRev(self, card: Card, ease: int) -> None: # type: ignore[override]
|
||||||
@ -607,7 +608,7 @@ did = ? and queue = {QUEUE_TYPE_REV} and due <= ? limit ?""",
|
|||||||
# interval capped?
|
# interval capped?
|
||||||
return min(interval, conf["maxIvl"])
|
return min(interval, conf["maxIvl"])
|
||||||
|
|
||||||
def _constrainedIvl(self, ivl: float, conf: Dict[str, Any], prev: int) -> int: # type: ignore[override]
|
def _constrainedIvl(self, ivl: float, conf: QueueConfig, prev: int) -> int: # type: ignore[override]
|
||||||
"Integer interval after interval factor and prev+1 constraints applied."
|
"Integer interval after interval factor and prev+1 constraints applied."
|
||||||
new = ivl * conf.get("ivlFct", 1)
|
new = ivl * conf.get("ivlFct", 1)
|
||||||
return int(max(new, prev + 1))
|
return int(max(new, prev + 1))
|
||||||
@ -641,7 +642,7 @@ did = ? and queue = {QUEUE_TYPE_REV} and due <= ? limit ?""",
|
|||||||
self.col.decks.select(did)
|
self.col.decks.select(did)
|
||||||
return ids
|
return ids
|
||||||
|
|
||||||
def _fillDyn(self, deck: Dict[str, Any]) -> Sequence[int]: # type: ignore[override]
|
def _fillDyn(self, deck: Deck) -> Sequence[int]: # type: ignore[override]
|
||||||
search, limit, order = deck["terms"][0]
|
search, limit, order = deck["terms"][0]
|
||||||
orderlimit = self._dynOrder(order, limit)
|
orderlimit = self._dynOrder(order, limit)
|
||||||
if search.strip():
|
if search.strip():
|
||||||
@ -707,7 +708,7 @@ did = ?, queue = %s, due = ?, usn = ? where id = ?"""
|
|||||||
# Leeches
|
# Leeches
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def _checkLeech(self, card: Card, conf: Dict[str, Any]) -> bool:
|
def _checkLeech(self, card: Card, conf: QueueConfig) -> bool:
|
||||||
"Leech handler. True if card was a leech."
|
"Leech handler. True if card was a leech."
|
||||||
lf = conf["leechFails"]
|
lf = conf["leechFails"]
|
||||||
if not lf:
|
if not lf:
|
||||||
@ -737,7 +738,7 @@ did = ?, queue = %s, due = ?, usn = ? where id = ?"""
|
|||||||
# Tools
|
# Tools
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def _newConf(self, card: Card) -> Dict[str, Any]:
|
def _newConf(self, card: Card) -> QueueConfig:
|
||||||
conf = self._cardConf(card)
|
conf = self._cardConf(card)
|
||||||
# normal deck
|
# normal deck
|
||||||
if not card.odid:
|
if not card.odid:
|
||||||
@ -756,7 +757,7 @@ did = ?, queue = %s, due = ?, usn = ? where id = ?"""
|
|||||||
perDay=self.reportLimit,
|
perDay=self.reportLimit,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _lapseConf(self, card: Card) -> Dict[str, Any]:
|
def _lapseConf(self, card: Card) -> QueueConfig:
|
||||||
conf = self._cardConf(card)
|
conf = self._cardConf(card)
|
||||||
# normal deck
|
# normal deck
|
||||||
if not card.odid:
|
if not card.odid:
|
||||||
|
@ -13,6 +13,7 @@ import anki # pylint: disable=unused-import
|
|||||||
from anki import hooks
|
from anki import hooks
|
||||||
from anki.cards import Card
|
from anki.cards import Card
|
||||||
from anki.consts import *
|
from anki.consts import *
|
||||||
|
from anki.decks import Deck, DeckConfig, DeckManager, FilteredDeck, QueueConfig
|
||||||
from anki.lang import _
|
from anki.lang import _
|
||||||
from anki.rsbackend import (
|
from anki.rsbackend import (
|
||||||
CountsForDeckToday,
|
CountsForDeckToday,
|
||||||
@ -355,7 +356,7 @@ order by due"""
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def _deckNewLimit(
|
def _deckNewLimit(
|
||||||
self, did: int, fn: Optional[Callable[[Dict[str, Any]], int]] = None
|
self, did: int, fn: Optional[Callable[[Deck], int]] = None
|
||||||
) -> int:
|
) -> int:
|
||||||
if not fn:
|
if not fn:
|
||||||
fn = self._deckNewLimitSingle
|
fn = self._deckNewLimitSingle
|
||||||
@ -383,7 +384,7 @@ select count() from
|
|||||||
lim,
|
lim,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _deckNewLimitSingle(self, g: Dict[str, Any]) -> int:
|
def _deckNewLimitSingle(self, g: DeckConfig) -> int:
|
||||||
"Limit for deck without parent limits."
|
"Limit for deck without parent limits."
|
||||||
if g["dyn"]:
|
if g["dyn"]:
|
||||||
return self.dynReportLimit
|
return self.dynReportLimit
|
||||||
@ -552,11 +553,11 @@ did = ? and queue = {QUEUE_TYPE_DAY_LEARN_RELEARN} and due <= ? limit ?""",
|
|||||||
|
|
||||||
self._logLrn(card, ease, conf, leaving, type, lastLeft)
|
self._logLrn(card, ease, conf, leaving, type, lastLeft)
|
||||||
|
|
||||||
def _updateRevIvlOnFail(self, card: Card, conf: Dict[str, Any]) -> None:
|
def _updateRevIvlOnFail(self, card: Card, conf: QueueConfig) -> None:
|
||||||
card.lastIvl = card.ivl
|
card.lastIvl = card.ivl
|
||||||
card.ivl = self._lapseIvl(card, conf)
|
card.ivl = self._lapseIvl(card, conf)
|
||||||
|
|
||||||
def _moveToFirstStep(self, card: Card, conf: Dict[str, Any]) -> Any:
|
def _moveToFirstStep(self, card: Card, conf: QueueConfig) -> Any:
|
||||||
card.left = self._startingLeft(card)
|
card.left = self._startingLeft(card)
|
||||||
|
|
||||||
# relearning card?
|
# relearning card?
|
||||||
@ -565,19 +566,19 @@ did = ? and queue = {QUEUE_TYPE_DAY_LEARN_RELEARN} and due <= ? limit ?""",
|
|||||||
|
|
||||||
return self._rescheduleLrnCard(card, conf)
|
return self._rescheduleLrnCard(card, conf)
|
||||||
|
|
||||||
def _moveToNextStep(self, card: Card, conf: Dict[str, Any]) -> None:
|
def _moveToNextStep(self, card: Card, conf: QueueConfig) -> None:
|
||||||
# decrement real left count and recalculate left today
|
# decrement real left count and recalculate left today
|
||||||
left = (card.left % 1000) - 1
|
left = (card.left % 1000) - 1
|
||||||
card.left = self._leftToday(conf["delays"], left) * 1000 + left
|
card.left = self._leftToday(conf["delays"], left) * 1000 + left
|
||||||
|
|
||||||
self._rescheduleLrnCard(card, conf)
|
self._rescheduleLrnCard(card, conf)
|
||||||
|
|
||||||
def _repeatStep(self, card: Card, conf: Dict[str, Any]) -> None:
|
def _repeatStep(self, card: Card, conf: QueueConfig) -> None:
|
||||||
delay = self._delayForRepeatingGrade(conf, card.left)
|
delay = self._delayForRepeatingGrade(conf, card.left)
|
||||||
self._rescheduleLrnCard(card, conf, delay=delay)
|
self._rescheduleLrnCard(card, conf, delay=delay)
|
||||||
|
|
||||||
def _rescheduleLrnCard(
|
def _rescheduleLrnCard(
|
||||||
self, card: Card, conf: Dict[str, Any], delay: Optional[int] = None
|
self, card: Card, conf: QueueConfig, delay: Optional[int] = None
|
||||||
) -> Any:
|
) -> Any:
|
||||||
# normal delay for the current step?
|
# normal delay for the current step?
|
||||||
if delay is None:
|
if delay is None:
|
||||||
@ -608,7 +609,7 @@ did = ? and queue = {QUEUE_TYPE_DAY_LEARN_RELEARN} and due <= ? limit ?""",
|
|||||||
card.queue = QUEUE_TYPE_DAY_LEARN_RELEARN
|
card.queue = QUEUE_TYPE_DAY_LEARN_RELEARN
|
||||||
return delay
|
return delay
|
||||||
|
|
||||||
def _delayForGrade(self, conf: Dict[str, Any], left: int) -> int:
|
def _delayForGrade(self, conf: QueueConfig, left: int) -> int:
|
||||||
left = left % 1000
|
left = left % 1000
|
||||||
try:
|
try:
|
||||||
delay = conf["delays"][-left]
|
delay = conf["delays"][-left]
|
||||||
@ -620,7 +621,7 @@ did = ? and queue = {QUEUE_TYPE_DAY_LEARN_RELEARN} and due <= ? limit ?""",
|
|||||||
delay = 1
|
delay = 1
|
||||||
return delay * 60
|
return delay * 60
|
||||||
|
|
||||||
def _delayForRepeatingGrade(self, conf: Dict[str, Any], left: int) -> Any:
|
def _delayForRepeatingGrade(self, conf: QueueConfig, left: int) -> Any:
|
||||||
# halfway between last and next
|
# halfway between last and next
|
||||||
delay1 = self._delayForGrade(conf, left)
|
delay1 = self._delayForGrade(conf, left)
|
||||||
if len(conf["delays"]) > 1:
|
if len(conf["delays"]) > 1:
|
||||||
@ -636,7 +637,7 @@ did = ? and queue = {QUEUE_TYPE_DAY_LEARN_RELEARN} and due <= ? limit ?""",
|
|||||||
else:
|
else:
|
||||||
return self._newConf(card)
|
return self._newConf(card)
|
||||||
|
|
||||||
def _rescheduleAsRev(self, card: Card, conf: Dict[str, Any], early: bool) -> None:
|
def _rescheduleAsRev(self, card: Card, conf: QueueConfig, early: bool) -> None:
|
||||||
lapse = card.type in (CARD_TYPE_REV, CARD_TYPE_RELEARNING)
|
lapse = card.type in (CARD_TYPE_REV, CARD_TYPE_RELEARNING)
|
||||||
|
|
||||||
if lapse:
|
if lapse:
|
||||||
@ -680,7 +681,7 @@ did = ? and queue = {QUEUE_TYPE_DAY_LEARN_RELEARN} and due <= ? limit ?""",
|
|||||||
return ok + 1
|
return ok + 1
|
||||||
|
|
||||||
def _graduatingIvl(
|
def _graduatingIvl(
|
||||||
self, card: Card, conf: Dict[str, Any], early: bool, fuzz: bool = True
|
self, card: Card, conf: QueueConfig, early: bool, fuzz: bool = True
|
||||||
) -> Any:
|
) -> Any:
|
||||||
if card.type in (CARD_TYPE_REV, CARD_TYPE_RELEARNING):
|
if card.type in (CARD_TYPE_REV, CARD_TYPE_RELEARNING):
|
||||||
bonus = early and 1 or 0
|
bonus = early and 1 or 0
|
||||||
@ -695,7 +696,7 @@ did = ? and queue = {QUEUE_TYPE_DAY_LEARN_RELEARN} and due <= ? limit ?""",
|
|||||||
ideal = self._fuzzedIvl(ideal)
|
ideal = self._fuzzedIvl(ideal)
|
||||||
return ideal
|
return ideal
|
||||||
|
|
||||||
def _rescheduleNew(self, card: Card, conf: Dict[str, Any], early: bool) -> None:
|
def _rescheduleNew(self, card: Card, conf: QueueConfig, early: bool) -> None:
|
||||||
"Reschedule a new card that's graduated for the first time."
|
"Reschedule a new card that's graduated for the first time."
|
||||||
card.ivl = self._graduatingIvl(card, conf, early)
|
card.ivl = self._graduatingIvl(card, conf, early)
|
||||||
card.due = self.today + card.ivl
|
card.due = self.today + card.ivl
|
||||||
@ -706,7 +707,7 @@ did = ? and queue = {QUEUE_TYPE_DAY_LEARN_RELEARN} and due <= ? limit ?""",
|
|||||||
self,
|
self,
|
||||||
card: Card,
|
card: Card,
|
||||||
ease: int,
|
ease: int,
|
||||||
conf: Dict[str, Any],
|
conf: QueueConfig,
|
||||||
leaving: bool,
|
leaving: bool,
|
||||||
type: int,
|
type: int,
|
||||||
lastLeft: int,
|
lastLeft: int,
|
||||||
@ -791,7 +792,9 @@ and due <= ? limit ?)""",
|
|||||||
lim = min(lim, self._deckRevLimitSingle(parent, parentLimit=lim))
|
lim = min(lim, self._deckRevLimitSingle(parent, parentLimit=lim))
|
||||||
return hooks.scheduler_review_limit_for_single_deck(lim, d)
|
return hooks.scheduler_review_limit_for_single_deck(lim, d)
|
||||||
|
|
||||||
def _revForDeck(self, did: int, lim: int, childMap: Dict[int, Any]) -> Any:
|
def _revForDeck(
|
||||||
|
self, did: int, lim: int, childMap: DeckManager.childMapNode
|
||||||
|
) -> Any:
|
||||||
dids = [did] + self.col.decks.childDids(did, childMap)
|
dids = [did] + self.col.decks.childDids(did, childMap)
|
||||||
lim = min(lim, self.reportLimit)
|
lim = min(lim, self.reportLimit)
|
||||||
return self.col.db.scalar(
|
return self.col.db.scalar(
|
||||||
@ -888,7 +891,7 @@ select id from cards where did in %s and queue = {QUEUE_TYPE_REV} and due <= ? l
|
|||||||
|
|
||||||
return delay
|
return delay
|
||||||
|
|
||||||
def _lapseIvl(self, card: Card, conf: Dict[str, Any]) -> Any:
|
def _lapseIvl(self, card: Card, conf: QueueConfig) -> Any:
|
||||||
ivl = max(1, conf["minInt"], int(card.ivl * conf["mult"]))
|
ivl = max(1, conf["minInt"], int(card.ivl * conf["mult"]))
|
||||||
return ivl
|
return ivl
|
||||||
|
|
||||||
@ -975,7 +978,7 @@ select id from cards where did in %s and queue = {QUEUE_TYPE_REV} and due <= ? l
|
|||||||
return [ivl - fuzz, ivl + fuzz]
|
return [ivl - fuzz, ivl + fuzz]
|
||||||
|
|
||||||
def _constrainedIvl(
|
def _constrainedIvl(
|
||||||
self, ivl: float, conf: Dict[str, Any], prev: int, fuzz: bool
|
self, ivl: float, conf: QueueConfig, prev: int, fuzz: bool
|
||||||
) -> int:
|
) -> int:
|
||||||
ivl = int(ivl * conf.get("ivlFct", 1))
|
ivl = int(ivl * conf.get("ivlFct", 1))
|
||||||
if fuzz:
|
if fuzz:
|
||||||
@ -1058,7 +1061,7 @@ end)
|
|||||||
self.col.decks.select(did)
|
self.col.decks.select(did)
|
||||||
return cnt
|
return cnt
|
||||||
|
|
||||||
def _fillDyn(self, deck: Dict[str, Any]) -> int:
|
def _fillDyn(self, deck: FilteredDeck) -> int:
|
||||||
start = -100000
|
start = -100000
|
||||||
total = 0
|
total = 0
|
||||||
for search, limit, order in deck["terms"]:
|
for search, limit, order in deck["terms"]:
|
||||||
@ -1167,7 +1170,7 @@ where id = ?
|
|||||||
# Leeches
|
# Leeches
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def _checkLeech(self, card: Card, conf: Dict[str, Any]) -> bool:
|
def _checkLeech(self, card: Card, conf: QueueConfig) -> bool:
|
||||||
"Leech handler. True if card was a leech."
|
"Leech handler. True if card was a leech."
|
||||||
lf = conf["leechFails"]
|
lf = conf["leechFails"]
|
||||||
if not lf:
|
if not lf:
|
||||||
@ -1190,7 +1193,7 @@ where id = ?
|
|||||||
# Tools
|
# Tools
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def _cardConf(self, card: Card) -> Dict[str, Any]:
|
def _cardConf(self, card: Card) -> DeckConfig:
|
||||||
return self.col.decks.confForDid(card.did)
|
return self.col.decks.confForDid(card.did)
|
||||||
|
|
||||||
def _newConf(self, card: Card) -> Any:
|
def _newConf(self, card: Card) -> Any:
|
||||||
@ -1229,7 +1232,7 @@ where id = ?
|
|||||||
resched=conf["resched"],
|
resched=conf["resched"],
|
||||||
)
|
)
|
||||||
|
|
||||||
def _revConf(self, card: Card) -> Dict[str, Any]:
|
def _revConf(self, card: Card) -> QueueConfig:
|
||||||
conf = self._cardConf(card)
|
conf = self._cardConf(card)
|
||||||
# normal deck
|
# normal deck
|
||||||
if not card.odid:
|
if not card.odid:
|
||||||
|
@ -71,23 +71,25 @@ hooks = [
|
|||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="scheduler_new_limit_for_single_deck",
|
name="scheduler_new_limit_for_single_deck",
|
||||||
args=["count: int", "deck: Dict[str, Any]"],
|
args=["count: int", "deck: anki.decks.Deck"],
|
||||||
return_type="int",
|
return_type="int",
|
||||||
doc="""Allows changing the number of new card for this deck (without
|
doc="""Allows changing the number of new card for this deck (without
|
||||||
considering descendants).""",
|
considering descendants).""",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="scheduler_review_limit_for_single_deck",
|
name="scheduler_review_limit_for_single_deck",
|
||||||
args=["count: int", "deck: Dict[str, Any]"],
|
args=["count: int", "deck: anki.decks.Deck"],
|
||||||
return_type="int",
|
return_type="int",
|
||||||
doc="""Allows changing the number of rev card for this deck (without
|
doc="""Allows changing the number of rev card for this deck (without
|
||||||
considering descendants).""",
|
considering descendants).""",
|
||||||
),
|
),
|
||||||
# obsolete
|
# obsolete
|
||||||
Hook(name="deck_added", args=["deck: Dict[str, Any]"], doc="Obsolete, do not use."),
|
Hook(
|
||||||
|
name="deck_added", args=["deck: anki.decks.Deck"], doc="Obsolete, do not use."
|
||||||
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="note_type_added",
|
name="note_type_added",
|
||||||
args=["notetype: Dict[str, Any]"],
|
args=["notetype: anki.models.NoteType"],
|
||||||
doc="Obsolete, do not use.",
|
doc="Obsolete, do not use.",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
|
@ -254,7 +254,7 @@ class Editor:
|
|||||||
id: Optional[str] = None,
|
id: Optional[str] = None,
|
||||||
toggleable: bool = False,
|
toggleable: bool = False,
|
||||||
disables: bool = True,
|
disables: bool = True,
|
||||||
):
|
) -> str:
|
||||||
if icon:
|
if icon:
|
||||||
if icon.startswith("qrc:/"):
|
if icon.startswith("qrc:/"):
|
||||||
iconstr = icon
|
iconstr = icon
|
||||||
|
@ -119,8 +119,8 @@ class FieldDialog(QDialog):
|
|||||||
def onDelete(self):
|
def onDelete(self):
|
||||||
if len(self.model["flds"]) < 2:
|
if len(self.model["flds"]) < 2:
|
||||||
return showWarning(_("Notes require at least one field."))
|
return showWarning(_("Notes require at least one field."))
|
||||||
c = self.mm.useCount(self.model)
|
count = self.mm.useCount(self.model)
|
||||||
c = ngettext("%d note", "%d notes", c) % c
|
c = ngettext("%d note", "%d notes", count) % count
|
||||||
if not askUser(_("Delete field from %s?") % c):
|
if not askUser(_("Delete field from %s?") % c):
|
||||||
return
|
return
|
||||||
if not self.change_tracker.mark_schema():
|
if not self.change_tracker.mark_schema():
|
||||||
|
@ -7,12 +7,14 @@ See pylib/anki/hooks.py
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Any, Callable, Dict, List, Optional, Tuple
|
from typing import Any, Callable, List, Optional, Tuple
|
||||||
|
|
||||||
import anki
|
import anki
|
||||||
import aqt
|
import aqt
|
||||||
from anki.cards import Card
|
from anki.cards import Card
|
||||||
|
from anki.decks import Deck, DeckConfig
|
||||||
from anki.hooks import runFilter, runHook
|
from anki.hooks import runFilter, runHook
|
||||||
|
from anki.models import NoteType
|
||||||
from aqt.qt import QDialog, QEvent, QMenu
|
from aqt.qt import QDialog, QEvent, QMenu
|
||||||
from aqt.tagedit import TagEdit
|
from aqt.tagedit import TagEdit
|
||||||
|
|
||||||
@ -827,20 +829,20 @@ collection_did_load = _CollectionDidLoadHook()
|
|||||||
|
|
||||||
|
|
||||||
class _CurrentNoteTypeDidChangeHook:
|
class _CurrentNoteTypeDidChangeHook:
|
||||||
_hooks: List[Callable[[Dict[str, Any]], None]] = []
|
_hooks: List[Callable[[NoteType], None]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[[Dict[str, Any]], None]) -> None:
|
def append(self, cb: Callable[[NoteType], None]) -> None:
|
||||||
"""(notetype: Dict[str, Any])"""
|
"""(notetype: NoteType)"""
|
||||||
self._hooks.append(cb)
|
self._hooks.append(cb)
|
||||||
|
|
||||||
def remove(self, cb: Callable[[Dict[str, Any]], None]) -> None:
|
def remove(self, cb: Callable[[NoteType], None]) -> None:
|
||||||
if cb in self._hooks:
|
if cb in self._hooks:
|
||||||
self._hooks.remove(cb)
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
def count(self) -> int:
|
def count(self) -> int:
|
||||||
return len(self._hooks)
|
return len(self._hooks)
|
||||||
|
|
||||||
def __call__(self, notetype: Dict[str, Any]) -> None:
|
def __call__(self, notetype: NoteType) -> None:
|
||||||
for hook in self._hooks:
|
for hook in self._hooks:
|
||||||
try:
|
try:
|
||||||
hook(notetype)
|
hook(notetype)
|
||||||
@ -1046,16 +1048,18 @@ class _DeckConfDidAddConfigHook:
|
|||||||
Config groups are created as clones of the current one.
|
Config groups are created as clones of the current one.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_hooks: List[Callable[["aqt.deckconf.DeckConf", Any, Any, str, int], None]] = []
|
_hooks: List[
|
||||||
|
Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig, str, int], None]
|
||||||
|
] = []
|
||||||
|
|
||||||
def append(
|
def append(
|
||||||
self, cb: Callable[["aqt.deckconf.DeckConf", Any, Any, str, int], None]
|
self, cb: Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig, str, int], None]
|
||||||
) -> None:
|
) -> None:
|
||||||
"""(deck_conf: aqt.deckconf.DeckConf, deck: Any, config: Any, new_name: str, new_conf_id: int)"""
|
"""(deck_conf: aqt.deckconf.DeckConf, deck: Deck, config: DeckConfig, new_name: str, new_conf_id: int)"""
|
||||||
self._hooks.append(cb)
|
self._hooks.append(cb)
|
||||||
|
|
||||||
def remove(
|
def remove(
|
||||||
self, cb: Callable[["aqt.deckconf.DeckConf", Any, Any, str, int], None]
|
self, cb: Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig, str, int], None]
|
||||||
) -> None:
|
) -> None:
|
||||||
if cb in self._hooks:
|
if cb in self._hooks:
|
||||||
self._hooks.remove(cb)
|
self._hooks.remove(cb)
|
||||||
@ -1066,8 +1070,8 @@ class _DeckConfDidAddConfigHook:
|
|||||||
def __call__(
|
def __call__(
|
||||||
self,
|
self,
|
||||||
deck_conf: aqt.deckconf.DeckConf,
|
deck_conf: aqt.deckconf.DeckConf,
|
||||||
deck: Any,
|
deck: Deck,
|
||||||
config: Any,
|
config: DeckConfig,
|
||||||
new_name: str,
|
new_name: str,
|
||||||
new_conf_id: int,
|
new_conf_id: int,
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -1086,13 +1090,17 @@ deck_conf_did_add_config = _DeckConfDidAddConfigHook()
|
|||||||
class _DeckConfDidLoadConfigHook:
|
class _DeckConfDidLoadConfigHook:
|
||||||
"""Called once widget state has been set from deck config"""
|
"""Called once widget state has been set from deck config"""
|
||||||
|
|
||||||
_hooks: List[Callable[["aqt.deckconf.DeckConf", Any, Any], None]] = []
|
_hooks: List[Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig], None]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[["aqt.deckconf.DeckConf", Any, Any], None]) -> None:
|
def append(
|
||||||
"""(deck_conf: aqt.deckconf.DeckConf, deck: Any, config: Any)"""
|
self, cb: Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig], None]
|
||||||
|
) -> None:
|
||||||
|
"""(deck_conf: aqt.deckconf.DeckConf, deck: Deck, config: DeckConfig)"""
|
||||||
self._hooks.append(cb)
|
self._hooks.append(cb)
|
||||||
|
|
||||||
def remove(self, cb: Callable[["aqt.deckconf.DeckConf", Any, Any], None]) -> None:
|
def remove(
|
||||||
|
self, cb: Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig], None]
|
||||||
|
) -> None:
|
||||||
if cb in self._hooks:
|
if cb in self._hooks:
|
||||||
self._hooks.remove(cb)
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
@ -1100,7 +1108,7 @@ class _DeckConfDidLoadConfigHook:
|
|||||||
return len(self._hooks)
|
return len(self._hooks)
|
||||||
|
|
||||||
def __call__(
|
def __call__(
|
||||||
self, deck_conf: aqt.deckconf.DeckConf, deck: Any, config: Any
|
self, deck_conf: aqt.deckconf.DeckConf, deck: Deck, config: DeckConfig
|
||||||
) -> None:
|
) -> None:
|
||||||
for hook in self._hooks:
|
for hook in self._hooks:
|
||||||
try:
|
try:
|
||||||
@ -1146,13 +1154,17 @@ deck_conf_did_setup_ui_form = _DeckConfDidSetupUiFormHook()
|
|||||||
class _DeckConfWillRemoveConfigHook:
|
class _DeckConfWillRemoveConfigHook:
|
||||||
"""Called before current config group is removed"""
|
"""Called before current config group is removed"""
|
||||||
|
|
||||||
_hooks: List[Callable[["aqt.deckconf.DeckConf", Any, Any], None]] = []
|
_hooks: List[Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig], None]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[["aqt.deckconf.DeckConf", Any, Any], None]) -> None:
|
def append(
|
||||||
"""(deck_conf: aqt.deckconf.DeckConf, deck: Any, config: Any)"""
|
self, cb: Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig], None]
|
||||||
|
) -> None:
|
||||||
|
"""(deck_conf: aqt.deckconf.DeckConf, deck: Deck, config: DeckConfig)"""
|
||||||
self._hooks.append(cb)
|
self._hooks.append(cb)
|
||||||
|
|
||||||
def remove(self, cb: Callable[["aqt.deckconf.DeckConf", Any, Any], None]) -> None:
|
def remove(
|
||||||
|
self, cb: Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig], None]
|
||||||
|
) -> None:
|
||||||
if cb in self._hooks:
|
if cb in self._hooks:
|
||||||
self._hooks.remove(cb)
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
@ -1160,7 +1172,7 @@ class _DeckConfWillRemoveConfigHook:
|
|||||||
return len(self._hooks)
|
return len(self._hooks)
|
||||||
|
|
||||||
def __call__(
|
def __call__(
|
||||||
self, deck_conf: aqt.deckconf.DeckConf, deck: Any, config: Any
|
self, deck_conf: aqt.deckconf.DeckConf, deck: Deck, config: DeckConfig
|
||||||
) -> None:
|
) -> None:
|
||||||
for hook in self._hooks:
|
for hook in self._hooks:
|
||||||
try:
|
try:
|
||||||
@ -1177,16 +1189,16 @@ deck_conf_will_remove_config = _DeckConfWillRemoveConfigHook()
|
|||||||
class _DeckConfWillRenameConfigHook:
|
class _DeckConfWillRenameConfigHook:
|
||||||
"""Called before config group is renamed"""
|
"""Called before config group is renamed"""
|
||||||
|
|
||||||
_hooks: List[Callable[["aqt.deckconf.DeckConf", Any, Any, str], None]] = []
|
_hooks: List[Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig, str], None]] = []
|
||||||
|
|
||||||
def append(
|
def append(
|
||||||
self, cb: Callable[["aqt.deckconf.DeckConf", Any, Any, str], None]
|
self, cb: Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig, str], None]
|
||||||
) -> None:
|
) -> None:
|
||||||
"""(deck_conf: aqt.deckconf.DeckConf, deck: Any, config: Any, new_name: str)"""
|
"""(deck_conf: aqt.deckconf.DeckConf, deck: Deck, config: DeckConfig, new_name: str)"""
|
||||||
self._hooks.append(cb)
|
self._hooks.append(cb)
|
||||||
|
|
||||||
def remove(
|
def remove(
|
||||||
self, cb: Callable[["aqt.deckconf.DeckConf", Any, Any, str], None]
|
self, cb: Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig, str], None]
|
||||||
) -> None:
|
) -> None:
|
||||||
if cb in self._hooks:
|
if cb in self._hooks:
|
||||||
self._hooks.remove(cb)
|
self._hooks.remove(cb)
|
||||||
@ -1195,7 +1207,11 @@ class _DeckConfWillRenameConfigHook:
|
|||||||
return len(self._hooks)
|
return len(self._hooks)
|
||||||
|
|
||||||
def __call__(
|
def __call__(
|
||||||
self, deck_conf: aqt.deckconf.DeckConf, deck: Any, config: Any, new_name: str
|
self,
|
||||||
|
deck_conf: aqt.deckconf.DeckConf,
|
||||||
|
deck: Deck,
|
||||||
|
config: DeckConfig,
|
||||||
|
new_name: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
for hook in self._hooks:
|
for hook in self._hooks:
|
||||||
try:
|
try:
|
||||||
@ -1212,13 +1228,17 @@ deck_conf_will_rename_config = _DeckConfWillRenameConfigHook()
|
|||||||
class _DeckConfWillSaveConfigHook:
|
class _DeckConfWillSaveConfigHook:
|
||||||
"""Called before widget state is saved to config"""
|
"""Called before widget state is saved to config"""
|
||||||
|
|
||||||
_hooks: List[Callable[["aqt.deckconf.DeckConf", Any, Any], None]] = []
|
_hooks: List[Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig], None]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[["aqt.deckconf.DeckConf", Any, Any], None]) -> None:
|
def append(
|
||||||
"""(deck_conf: aqt.deckconf.DeckConf, deck: Any, config: Any)"""
|
self, cb: Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig], None]
|
||||||
|
) -> None:
|
||||||
|
"""(deck_conf: aqt.deckconf.DeckConf, deck: Deck, config: DeckConfig)"""
|
||||||
self._hooks.append(cb)
|
self._hooks.append(cb)
|
||||||
|
|
||||||
def remove(self, cb: Callable[["aqt.deckconf.DeckConf", Any, Any], None]) -> None:
|
def remove(
|
||||||
|
self, cb: Callable[["aqt.deckconf.DeckConf", Deck, DeckConfig], None]
|
||||||
|
) -> None:
|
||||||
if cb in self._hooks:
|
if cb in self._hooks:
|
||||||
self._hooks.remove(cb)
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
@ -1226,7 +1246,7 @@ class _DeckConfWillSaveConfigHook:
|
|||||||
return len(self._hooks)
|
return len(self._hooks)
|
||||||
|
|
||||||
def __call__(
|
def __call__(
|
||||||
self, deck_conf: aqt.deckconf.DeckConf, deck: Any, config: Any
|
self, deck_conf: aqt.deckconf.DeckConf, deck: Deck, config: DeckConfig
|
||||||
) -> None:
|
) -> None:
|
||||||
for hook in self._hooks:
|
for hook in self._hooks:
|
||||||
try:
|
try:
|
||||||
@ -1355,20 +1375,20 @@ editor_did_init = _EditorDidInitHook()
|
|||||||
|
|
||||||
|
|
||||||
class _EditorDidInitButtonsHook:
|
class _EditorDidInitButtonsHook:
|
||||||
_hooks: List[Callable[[List, "aqt.editor.Editor"], None]] = []
|
_hooks: List[Callable[[List[str], "aqt.editor.Editor"], None]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[[List, "aqt.editor.Editor"], None]) -> None:
|
def append(self, cb: Callable[[List[str], "aqt.editor.Editor"], None]) -> None:
|
||||||
"""(buttons: List, editor: aqt.editor.Editor)"""
|
"""(buttons: List[str], editor: aqt.editor.Editor)"""
|
||||||
self._hooks.append(cb)
|
self._hooks.append(cb)
|
||||||
|
|
||||||
def remove(self, cb: Callable[[List, "aqt.editor.Editor"], None]) -> None:
|
def remove(self, cb: Callable[[List[str], "aqt.editor.Editor"], None]) -> None:
|
||||||
if cb in self._hooks:
|
if cb in self._hooks:
|
||||||
self._hooks.remove(cb)
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
def count(self) -> int:
|
def count(self) -> int:
|
||||||
return len(self._hooks)
|
return len(self._hooks)
|
||||||
|
|
||||||
def __call__(self, buttons: List, editor: aqt.editor.Editor) -> None:
|
def __call__(self, buttons: List[str], editor: aqt.editor.Editor) -> None:
|
||||||
for hook in self._hooks:
|
for hook in self._hooks:
|
||||||
try:
|
try:
|
||||||
hook(buttons, editor)
|
hook(buttons, editor)
|
||||||
|
@ -14,7 +14,7 @@ import weakref
|
|||||||
import zipfile
|
import zipfile
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from typing import Any, Callable, Dict, List, Optional, Sequence, TextIO, Tuple, cast
|
from typing import Any, Callable, List, Optional, Sequence, TextIO, Tuple, cast
|
||||||
|
|
||||||
import anki
|
import anki
|
||||||
import aqt
|
import aqt
|
||||||
@ -27,6 +27,7 @@ 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.decks import Deck
|
||||||
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
|
||||||
@ -652,7 +653,7 @@ from the profile screen."
|
|||||||
self.maybe_check_for_addon_updates()
|
self.maybe_check_for_addon_updates()
|
||||||
self.deckBrowser.show()
|
self.deckBrowser.show()
|
||||||
|
|
||||||
def _selectedDeck(self) -> Optional[Dict[str, Any]]:
|
def _selectedDeck(self) -> Optional[Deck]:
|
||||||
did = self.col.decks.selected()
|
did = self.col.decks.selected()
|
||||||
if not self.col.decks.nameOrNone(did):
|
if not self.col.decks.nameOrNone(did):
|
||||||
showInfo(_("Please select a deck."))
|
showInfo(_("Please select a deck."))
|
||||||
|
@ -185,6 +185,8 @@ class Models(QDialog):
|
|||||||
|
|
||||||
|
|
||||||
class AddModel(QDialog):
|
class AddModel(QDialog):
|
||||||
|
model: Optional[NoteType]
|
||||||
|
|
||||||
def __init__(self, mw: AnkiQt, parent: Optional[QWidget] = None):
|
def __init__(self, mw: AnkiQt, parent: Optional[QWidget] = None):
|
||||||
self.parent_ = parent or mw
|
self.parent_ = parent or mw
|
||||||
self.mw = mw
|
self.mw = mw
|
||||||
|
@ -194,20 +194,20 @@ hooks = [
|
|||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="deck_conf_did_load_config",
|
name="deck_conf_did_load_config",
|
||||||
args=["deck_conf: aqt.deckconf.DeckConf", "deck: Any", "config: Any"],
|
args=["deck_conf: aqt.deckconf.DeckConf", "deck: Deck", "config: DeckConfig"],
|
||||||
doc="Called once widget state has been set from deck config",
|
doc="Called once widget state has been set from deck config",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="deck_conf_will_save_config",
|
name="deck_conf_will_save_config",
|
||||||
args=["deck_conf: aqt.deckconf.DeckConf", "deck: Any", "config: Any"],
|
args=["deck_conf: aqt.deckconf.DeckConf", "deck: Deck", "config: DeckConfig"],
|
||||||
doc="Called before widget state is saved to config",
|
doc="Called before widget state is saved to config",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="deck_conf_did_add_config",
|
name="deck_conf_did_add_config",
|
||||||
args=[
|
args=[
|
||||||
"deck_conf: aqt.deckconf.DeckConf",
|
"deck_conf: aqt.deckconf.DeckConf",
|
||||||
"deck: Any",
|
"deck: Deck",
|
||||||
"config: Any",
|
"config: DeckConfig",
|
||||||
"new_name: str",
|
"new_name: str",
|
||||||
"new_conf_id: int",
|
"new_conf_id: int",
|
||||||
],
|
],
|
||||||
@ -224,15 +224,15 @@ hooks = [
|
|||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="deck_conf_will_remove_config",
|
name="deck_conf_will_remove_config",
|
||||||
args=["deck_conf: aqt.deckconf.DeckConf", "deck: Any", "config: Any"],
|
args=["deck_conf: aqt.deckconf.DeckConf", "deck: Deck", "config: DeckConfig"],
|
||||||
doc="Called before current config group is removed",
|
doc="Called before current config group is removed",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="deck_conf_will_rename_config",
|
name="deck_conf_will_rename_config",
|
||||||
args=[
|
args=[
|
||||||
"deck_conf: aqt.deckconf.DeckConf",
|
"deck_conf: aqt.deckconf.DeckConf",
|
||||||
"deck: Any",
|
"deck: Deck",
|
||||||
"config: Any",
|
"config: DeckConfig",
|
||||||
"new_name: str",
|
"new_name: str",
|
||||||
],
|
],
|
||||||
doc="Called before config group is renamed",
|
doc="Called before config group is renamed",
|
||||||
@ -530,7 +530,7 @@ hooks = [
|
|||||||
###################
|
###################
|
||||||
Hook(
|
Hook(
|
||||||
name="editor_did_init_buttons",
|
name="editor_did_init_buttons",
|
||||||
args=["buttons: List", "editor: aqt.editor.Editor"],
|
args=["buttons: List[str]", "editor: aqt.editor.Editor"],
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="editor_did_init_shortcuts",
|
name="editor_did_init_shortcuts",
|
||||||
@ -653,7 +653,7 @@ hooks = [
|
|||||||
###################
|
###################
|
||||||
Hook(
|
Hook(
|
||||||
name="current_note_type_did_change",
|
name="current_note_type_did_change",
|
||||||
args=["notetype: Dict[str, Any]"],
|
args=["notetype: NoteType"],
|
||||||
legacy_hook="currentModelChanged",
|
legacy_hook="currentModelChanged",
|
||||||
legacy_no_args=True,
|
legacy_no_args=True,
|
||||||
),
|
),
|
||||||
|
Loading…
Reference in New Issue
Block a user