mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
PEP8 models.py
This commit is contained in:
parent
62c23c6816
commit
17533e6a78
25 changed files with 318 additions and 280 deletions
|
@ -45,4 +45,7 @@ disable=
|
||||||
arguments-differ,
|
arguments-differ,
|
||||||
|
|
||||||
[BASIC]
|
[BASIC]
|
||||||
good-names = id
|
good-names =
|
||||||
|
id,
|
||||||
|
tr,
|
||||||
|
db,
|
|
@ -28,7 +28,7 @@ def partial_path(full_path: str, components: int) -> str:
|
||||||
|
|
||||||
|
|
||||||
def print_deprecation_warning(msg: str, frame: int = 2) -> None:
|
def print_deprecation_warning(msg: str, frame: int = 2) -> None:
|
||||||
path, linenum, fn, y = traceback.extract_stack(limit=5)[frame]
|
path, linenum, _, _ = traceback.extract_stack(limit=5)[frame]
|
||||||
path = partial_path(path, components=3)
|
path = partial_path(path, components=3)
|
||||||
print(f"{path}:{linenum}:{msg}")
|
print(f"{path}:{linenum}:{msg}")
|
||||||
|
|
||||||
|
|
|
@ -1,6 +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
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
|
@ -1,6 +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
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from typing import Any, Dict, List, Optional, Tuple
|
from typing import Any, Dict, List, Optional, Tuple
|
||||||
|
|
|
@ -1,6 +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
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
|
|
@ -1,6 +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
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
@ -134,7 +136,7 @@ acq_reps+ret_reps, lapses, card_type_id from cards"""
|
||||||
model["name"] = "Mnemosyne-FrontOnly"
|
model["name"] = "Mnemosyne-FrontOnly"
|
||||||
mm = self.col.models
|
mm = self.col.models
|
||||||
mm.save(model)
|
mm.save(model)
|
||||||
mm.setCurrent(model)
|
mm.set_current(model)
|
||||||
self.model = model
|
self.model = model
|
||||||
self._fields = len(model["flds"])
|
self._fields = len(model["flds"])
|
||||||
self.initMapping()
|
self.initMapping()
|
||||||
|
@ -145,34 +147,34 @@ acq_reps+ret_reps, lapses, card_type_id from cards"""
|
||||||
m = addBasicModel(self.col)
|
m = addBasicModel(self.col)
|
||||||
m["name"] = "Mnemosyne-FrontBack"
|
m["name"] = "Mnemosyne-FrontBack"
|
||||||
mm = self.col.models
|
mm = self.col.models
|
||||||
t = mm.newTemplate("Back")
|
t = mm.new_template("Back")
|
||||||
t["qfmt"] = "{{Back}}"
|
t["qfmt"] = "{{Back}}"
|
||||||
t["afmt"] = t["qfmt"] + "\n\n<hr id=answer>\n\n{{Front}}" # type: ignore
|
t["afmt"] = t["qfmt"] + "\n\n<hr id=answer>\n\n{{Front}}" # type: ignore
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
self._addFronts(notes, m)
|
self._addFronts(notes, m)
|
||||||
|
|
||||||
def _addVocabulary(self, notes):
|
def _addVocabulary(self, notes):
|
||||||
mm = self.col.models
|
mm = self.col.models
|
||||||
m = mm.new("Mnemosyne-Vocabulary")
|
m = mm.new("Mnemosyne-Vocabulary")
|
||||||
for f in "Expression", "Pronunciation", "Meaning", "Notes":
|
for f in "Expression", "Pronunciation", "Meaning", "Notes":
|
||||||
fm = mm.newField(f)
|
fm = mm.new_field(f)
|
||||||
mm.addField(m, fm)
|
mm.addField(m, fm)
|
||||||
t = mm.newTemplate("Recognition")
|
t = mm.new_template("Recognition")
|
||||||
t["qfmt"] = "{{Expression}}"
|
t["qfmt"] = "{{Expression}}"
|
||||||
t["afmt"] = (
|
t["afmt"] = (
|
||||||
cast(str, t["qfmt"])
|
cast(str, t["qfmt"])
|
||||||
+ """\n\n<hr id=answer>\n\n\
|
+ """\n\n<hr id=answer>\n\n\
|
||||||
{{Pronunciation}}<br>\n{{Meaning}}<br>\n{{Notes}}"""
|
{{Pronunciation}}<br>\n{{Meaning}}<br>\n{{Notes}}"""
|
||||||
)
|
)
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
t = mm.newTemplate("Production")
|
t = mm.new_template("Production")
|
||||||
t["qfmt"] = "{{Meaning}}"
|
t["qfmt"] = "{{Meaning}}"
|
||||||
t["afmt"] = (
|
t["afmt"] = (
|
||||||
cast(str, t["qfmt"])
|
cast(str, t["qfmt"])
|
||||||
+ """\n\n<hr id=answer>\n\n\
|
+ """\n\n<hr id=answer>\n\n\
|
||||||
{{Expression}}<br>\n{{Pronunciation}}<br>\n{{Notes}}"""
|
{{Expression}}<br>\n{{Pronunciation}}<br>\n{{Notes}}"""
|
||||||
)
|
)
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
mm.add(m)
|
mm.add(m)
|
||||||
self._addFronts(notes, m, fields=("f", "p_1", "m_1", "n"))
|
self._addFronts(notes, m, fields=("f", "p_1", "m_1", "n"))
|
||||||
|
|
||||||
|
@ -206,7 +208,7 @@ acq_reps+ret_reps, lapses, card_type_id from cards"""
|
||||||
model["name"] = "Mnemosyne-Cloze"
|
model["name"] = "Mnemosyne-Cloze"
|
||||||
mm = self.col.models
|
mm = self.col.models
|
||||||
mm.save(model)
|
mm.save(model)
|
||||||
mm.setCurrent(model)
|
mm.set_current(model)
|
||||||
self.model = model
|
self.model = model
|
||||||
self._fields = len(model["flds"])
|
self._fields = len(model["flds"])
|
||||||
self.initMapping()
|
self.initMapping()
|
||||||
|
|
|
@ -1,6 +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
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
import html
|
import html
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from typing import Dict, List, Optional, Tuple, Union
|
from typing import Dict, List, Optional, Tuple, Union
|
||||||
|
@ -130,7 +132,7 @@ class NoteImporter(Importer):
|
||||||
csums[csum] = [id]
|
csums[csum] = [id]
|
||||||
firsts: Dict[str, bool] = {}
|
firsts: Dict[str, bool] = {}
|
||||||
fld0idx = self.mapping.index(self.model["flds"][0]["name"])
|
fld0idx = self.mapping.index(self.model["flds"][0]["name"])
|
||||||
self._fmap = self.col.models.fieldMap(self.model)
|
self._fmap = self.col.models.field_map(self.model)
|
||||||
self._nextID = NoteId(timestampID(self.col.db, "notes"))
|
self._nextID = NoteId(timestampID(self.col.db, "notes"))
|
||||||
# loop through the notes
|
# loop through the notes
|
||||||
updates: List[Updates] = []
|
updates: List[Updates] = []
|
||||||
|
|
|
@ -24,7 +24,7 @@ class PaukerImporter(NoteImporter):
|
||||||
model = addForwardReverse(self.col)
|
model = addForwardReverse(self.col)
|
||||||
model["name"] = "Pauker"
|
model["name"] = "Pauker"
|
||||||
self.col.models.save(model, updateReqs=False)
|
self.col.models.save(model, updateReqs=False)
|
||||||
self.col.models.setCurrent(model)
|
self.col.models.set_current(model)
|
||||||
self.model = model
|
self.model = model
|
||||||
self.initMapping()
|
self.initMapping()
|
||||||
NoteImporter.run(self)
|
NoteImporter.run(self)
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
# 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
|
||||||
|
|
||||||
|
# pylint: enable=invalid-name
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import pprint
|
import pprint
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import traceback
|
|
||||||
from typing import Any, Dict, List, NewType, Optional, Sequence, Tuple, Union
|
from typing import Any, Dict, List, NewType, Optional, Sequence, Tuple, Union
|
||||||
|
|
||||||
import anki # pylint: disable=unused-import
|
import anki # pylint: disable=unused-import
|
||||||
import anki._backend.backend_pb2 as _pb
|
import anki._backend.backend_pb2 as _pb
|
||||||
|
from anki._legacy import DeprecatedNamesMixin, deprecated, print_deprecation_warning
|
||||||
from anki.collection import OpChanges, OpChangesWithId
|
from anki.collection import OpChanges, OpChangesWithId
|
||||||
from anki.consts import *
|
from anki.consts import *
|
||||||
from anki.errors import NotFoundError
|
from anki.errors import NotFoundError
|
||||||
|
@ -40,8 +42,9 @@ class ModelsDictProxy:
|
||||||
self._col = col.weakref()
|
self._col = col.weakref()
|
||||||
|
|
||||||
def _warn(self) -> None:
|
def _warn(self) -> None:
|
||||||
traceback.print_stack(file=sys.stdout)
|
print_deprecation_warning(
|
||||||
print("add-on should use methods on col.models, not col.models.models dict")
|
"add-on should use methods on col.decks, not col.decks.decks dict"
|
||||||
|
)
|
||||||
|
|
||||||
def __getitem__(self, item: Any) -> Any:
|
def __getitem__(self, item: Any) -> Any:
|
||||||
self._warn()
|
self._warn()
|
||||||
|
@ -72,7 +75,7 @@ class ModelsDictProxy:
|
||||||
return self._col.models.have(item)
|
return self._col.models.have(item)
|
||||||
|
|
||||||
|
|
||||||
class ModelManager:
|
class ModelManager(DeprecatedNamesMixin):
|
||||||
# Saving/loading registry
|
# Saving/loading registry
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
|
@ -83,27 +86,9 @@ class ModelManager:
|
||||||
self._cache = {}
|
self._cache = {}
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
d = dict(self.__dict__)
|
attrs = dict(self.__dict__)
|
||||||
del d["col"]
|
del attrs["col"]
|
||||||
return f"{super().__repr__()} {pprint.pformat(d, width=300)}"
|
return f"{super().__repr__()} {pprint.pformat(attrs, width=300)}"
|
||||||
|
|
||||||
def save(
|
|
||||||
self,
|
|
||||||
m: NotetypeDict = None,
|
|
||||||
# no longer used
|
|
||||||
templates: bool = False,
|
|
||||||
updateReqs: bool = True,
|
|
||||||
) -> None:
|
|
||||||
"Save changes made to provided note type."
|
|
||||||
if not m:
|
|
||||||
print("col.models.save() should be passed the changed notetype")
|
|
||||||
return
|
|
||||||
|
|
||||||
self.update(m, preserve_usn=False)
|
|
||||||
|
|
||||||
# legacy
|
|
||||||
def flush(self) -> None:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Caching
|
# Caching
|
||||||
#############################################################
|
#############################################################
|
||||||
|
@ -114,8 +99,8 @@ class ModelManager:
|
||||||
|
|
||||||
_cache: Dict[NotetypeId, NotetypeDict] = {}
|
_cache: Dict[NotetypeId, NotetypeDict] = {}
|
||||||
|
|
||||||
def _update_cache(self, nt: NotetypeDict) -> None:
|
def _update_cache(self, notetype: NotetypeDict) -> None:
|
||||||
self._cache[nt["id"]] = nt
|
self._cache[notetype["id"]] = notetype
|
||||||
|
|
||||||
def _remove_from_cache(self, ntid: NotetypeId) -> None:
|
def _remove_from_cache(self, ntid: NotetypeId) -> None:
|
||||||
if ntid in self._cache:
|
if ntid in self._cache:
|
||||||
|
@ -136,14 +121,6 @@ class ModelManager:
|
||||||
def all_use_counts(self) -> Sequence[NotetypeNameIdUseCount]:
|
def all_use_counts(self) -> Sequence[NotetypeNameIdUseCount]:
|
||||||
return self.col._backend.get_notetype_names_and_counts()
|
return self.col._backend.get_notetype_names_and_counts()
|
||||||
|
|
||||||
# legacy
|
|
||||||
|
|
||||||
def allNames(self) -> List[str]:
|
|
||||||
return [n.name for n in self.all_names_and_ids()]
|
|
||||||
|
|
||||||
def ids(self) -> List[NotetypeId]:
|
|
||||||
return [NotetypeId(n.id) for n in self.all_names_and_ids()]
|
|
||||||
|
|
||||||
# only used by importing code
|
# only used by importing code
|
||||||
def have(self, id: NotetypeId) -> bool:
|
def have(self, id: NotetypeId) -> bool:
|
||||||
if isinstance(id, str):
|
if isinstance(id, str):
|
||||||
|
@ -153,19 +130,15 @@ class ModelManager:
|
||||||
# Current note type
|
# Current note type
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
def current(self, forDeck: bool = True) -> NotetypeDict:
|
def current(self, for_deck: bool = True) -> NotetypeDict:
|
||||||
"Get current model."
|
"Get current model. In new code, prefer col.defaults_for_adding()"
|
||||||
m = self.get(self.col.decks.current().get("mid"))
|
notetype = self.get(self.col.decks.current().get("mid"))
|
||||||
if not forDeck or not m:
|
if not for_deck or not notetype:
|
||||||
m = self.get(self.col.conf["curModel"])
|
notetype = self.get(self.col.conf["curModel"])
|
||||||
if m:
|
if notetype:
|
||||||
return m
|
return notetype
|
||||||
return self.get(NotetypeId(self.all_names_and_ids()[0].id))
|
return self.get(NotetypeId(self.all_names_and_ids()[0].id))
|
||||||
|
|
||||||
def setCurrent(self, m: NotetypeDict) -> None:
|
|
||||||
"""Legacy. The current notetype is now updated on note add."""
|
|
||||||
self.col.set_config("curModel", m["id"])
|
|
||||||
|
|
||||||
# Retrieving and creating models
|
# Retrieving and creating models
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
|
@ -183,20 +156,20 @@ class ModelManager:
|
||||||
elif isinstance(id, str):
|
elif isinstance(id, str):
|
||||||
id = int(id)
|
id = int(id)
|
||||||
|
|
||||||
nt = self._get_cached(id)
|
notetype = self._get_cached(id)
|
||||||
if not nt:
|
if not notetype:
|
||||||
try:
|
try:
|
||||||
nt = from_json_bytes(self.col._backend.get_notetype_legacy(id))
|
notetype = from_json_bytes(self.col._backend.get_notetype_legacy(id))
|
||||||
self._update_cache(nt)
|
self._update_cache(notetype)
|
||||||
except NotFoundError:
|
except NotFoundError:
|
||||||
return None
|
return None
|
||||||
return nt
|
return notetype
|
||||||
|
|
||||||
def all(self) -> List[NotetypeDict]:
|
def all(self) -> List[NotetypeDict]:
|
||||||
"Get all models."
|
"Get all models."
|
||||||
return [self.get(NotetypeId(nt.id)) for nt in self.all_names_and_ids()]
|
return [self.get(NotetypeId(nt.id)) for nt in self.all_names_and_ids()]
|
||||||
|
|
||||||
def byName(self, name: str) -> Optional[NotetypeDict]:
|
def by_name(self, name: str) -> Optional[NotetypeDict]:
|
||||||
"Get model with NAME."
|
"Get model with NAME."
|
||||||
id = self.id_for_name(name)
|
id = self.id_for_name(name)
|
||||||
if id:
|
if id:
|
||||||
|
@ -207,67 +180,53 @@ class ModelManager:
|
||||||
def new(self, name: str) -> NotetypeDict:
|
def new(self, name: str) -> NotetypeDict:
|
||||||
"Create a new model, and return it."
|
"Create a new model, and return it."
|
||||||
# caller should call save() after modifying
|
# caller should call save() after modifying
|
||||||
nt = from_json_bytes(
|
notetype = from_json_bytes(
|
||||||
self.col._backend.get_stock_notetype_legacy(StockNotetypeKind.BASIC)
|
self.col._backend.get_stock_notetype_legacy(StockNotetypeKind.BASIC)
|
||||||
)
|
)
|
||||||
nt["flds"] = []
|
notetype["flds"] = []
|
||||||
nt["tmpls"] = []
|
notetype["tmpls"] = []
|
||||||
nt["name"] = name
|
notetype["name"] = name
|
||||||
return nt
|
return notetype
|
||||||
|
|
||||||
def rem(self, m: NotetypeDict) -> None:
|
|
||||||
"Delete model, and all its cards/notes."
|
|
||||||
self.remove(m["id"])
|
|
||||||
|
|
||||||
def remove_all_notetypes(self) -> None:
|
def remove_all_notetypes(self) -> None:
|
||||||
for nt in self.all_names_and_ids():
|
for notetype in self.all_names_and_ids():
|
||||||
self._remove_from_cache(NotetypeId(nt.id))
|
self._remove_from_cache(NotetypeId(notetype.id))
|
||||||
self.col._backend.remove_notetype(nt.id)
|
self.col._backend.remove_notetype(notetype.id)
|
||||||
|
|
||||||
def remove(self, id: NotetypeId) -> OpChanges:
|
def remove(self, id: NotetypeId) -> OpChanges:
|
||||||
"Modifies schema."
|
"Modifies schema."
|
||||||
self._remove_from_cache(id)
|
self._remove_from_cache(id)
|
||||||
return self.col._backend.remove_notetype(id)
|
return self.col._backend.remove_notetype(id)
|
||||||
|
|
||||||
def add(self, m: NotetypeDict) -> OpChangesWithId:
|
def add(self, notetype: NotetypeDict) -> OpChangesWithId:
|
||||||
"Replaced with add_dict()"
|
"Replaced with add_dict()"
|
||||||
self.ensureNameUnique(m)
|
self.ensure_name_unique(notetype)
|
||||||
out = self.col._backend.add_notetype_legacy(to_json_bytes(m))
|
out = self.col._backend.add_notetype_legacy(to_json_bytes(notetype))
|
||||||
m["id"] = out.id
|
notetype["id"] = out.id
|
||||||
self._mutate_after_write(m)
|
self._mutate_after_write(notetype)
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def add_dict(self, m: NotetypeDict) -> OpChangesWithId:
|
def add_dict(self, notetype: NotetypeDict) -> OpChangesWithId:
|
||||||
"Notetype needs to be fetched from DB after adding."
|
"Notetype needs to be fetched from DB after adding."
|
||||||
self.ensureNameUnique(m)
|
self.ensure_name_unique(notetype)
|
||||||
return self.col._backend.add_notetype_legacy(to_json_bytes(m))
|
return self.col._backend.add_notetype_legacy(to_json_bytes(notetype))
|
||||||
|
|
||||||
def ensureNameUnique(self, m: NotetypeDict) -> None:
|
def ensure_name_unique(self, notetype: NotetypeDict) -> None:
|
||||||
existing_id = self.id_for_name(m["name"])
|
existing_id = self.id_for_name(notetype["name"])
|
||||||
if existing_id is not None and existing_id != m["id"]:
|
if existing_id is not None and existing_id != notetype["id"]:
|
||||||
m["name"] += "-" + checksum(str(time.time()))[:5]
|
notetype["name"] += "-" + checksum(str(time.time()))[:5]
|
||||||
|
|
||||||
def update(self, m: NotetypeDict, preserve_usn: bool = True) -> None:
|
def update_dict(self, notetype: NotetypeDict) -> OpChanges:
|
||||||
"Add or update an existing model. Use .update_dict() instead."
|
|
||||||
self._remove_from_cache(m["id"])
|
|
||||||
self.ensureNameUnique(m)
|
|
||||||
m["id"] = self.col._backend.add_or_update_notetype(
|
|
||||||
json=to_json_bytes(m), preserve_usn_and_mtime=preserve_usn
|
|
||||||
)
|
|
||||||
self.setCurrent(m)
|
|
||||||
self._mutate_after_write(m)
|
|
||||||
|
|
||||||
def update_dict(self, m: NotetypeDict) -> OpChanges:
|
|
||||||
"Update a NotetypeDict. Caller will need to re-load notetype if new fields/cards added."
|
"Update a NotetypeDict. Caller will need to re-load notetype if new fields/cards added."
|
||||||
self._remove_from_cache(m["id"])
|
self._remove_from_cache(notetype["id"])
|
||||||
self.ensureNameUnique(m)
|
self.ensure_name_unique(notetype)
|
||||||
return self.col._backend.update_notetype_legacy(to_json_bytes(m))
|
return self.col._backend.update_notetype_legacy(to_json_bytes(notetype))
|
||||||
|
|
||||||
def _mutate_after_write(self, nt: NotetypeDict) -> None:
|
def _mutate_after_write(self, notetype: NotetypeDict) -> None:
|
||||||
# existing code expects the note type to be mutated to reflect
|
# existing code expects the note type to be mutated to reflect
|
||||||
# the changes made when adding, such as ordinal assignment :-(
|
# the changes made when adding, such as ordinal assignment :-(
|
||||||
updated = self.get(nt["id"])
|
updated = self.get(notetype["id"])
|
||||||
nt.update(updated)
|
notetype.update(updated)
|
||||||
|
|
||||||
# Tools
|
# Tools
|
||||||
##################################################
|
##################################################
|
||||||
|
@ -279,147 +238,115 @@ class ModelManager:
|
||||||
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: NotetypeDict) -> int:
|
def use_count(self, notetype: NotetypeDict) -> 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 = ?", notetype["id"]
|
||||||
|
)
|
||||||
|
|
||||||
# Copying
|
# Copying
|
||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
def copy(self, m: NotetypeDict, add: bool = True) -> NotetypeDict:
|
def copy(self, notetype: NotetypeDict, add: bool = True) -> NotetypeDict:
|
||||||
"Copy, save and return."
|
"Copy, save and return."
|
||||||
m2 = copy.deepcopy(m)
|
cloned = copy.deepcopy(notetype)
|
||||||
m2["name"] = without_unicode_isolation(
|
cloned["name"] = without_unicode_isolation(
|
||||||
self.col.tr.notetypes_copy(val=m2["name"])
|
self.col.tr.notetypes_copy(val=cloned["name"])
|
||||||
)
|
)
|
||||||
m2["id"] = 0
|
cloned["id"] = 0
|
||||||
if add:
|
if add:
|
||||||
self.add(m2)
|
self.add(cloned)
|
||||||
return m2
|
return cloned
|
||||||
|
|
||||||
# Fields
|
# Fields
|
||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
def fieldMap(self, m: NotetypeDict) -> Dict[str, Tuple[int, FieldDict]]:
|
def field_map(self, notetype: NotetypeDict) -> Dict[str, Tuple[int, FieldDict]]:
|
||||||
"Mapping of field name -> (ord, field)."
|
"Mapping of field name -> (ord, field)."
|
||||||
return {f["name"]: (f["ord"], f) for f in m["flds"]}
|
return {f["name"]: (f["ord"], f) for f in notetype["flds"]}
|
||||||
|
|
||||||
def fieldNames(self, m: NotetypeDict) -> List[str]:
|
def field_names(self, notetype: NotetypeDict) -> List[str]:
|
||||||
return [f["name"] for f in m["flds"]]
|
return [f["name"] for f in notetype["flds"]]
|
||||||
|
|
||||||
def sortIdx(self, m: NotetypeDict) -> int:
|
def sort_idx(self, notetype: NotetypeDict) -> int:
|
||||||
return m["sortf"]
|
return notetype["sortf"]
|
||||||
|
|
||||||
# Adding & changing fields
|
# Adding & changing fields
|
||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
def new_field(self, name: str) -> FieldDict:
|
def new_field(self, name: str) -> FieldDict:
|
||||||
assert isinstance(name, str)
|
assert isinstance(name, str)
|
||||||
nt = from_json_bytes(
|
notetype = from_json_bytes(
|
||||||
self.col._backend.get_stock_notetype_legacy(StockNotetypeKind.BASIC)
|
self.col._backend.get_stock_notetype_legacy(StockNotetypeKind.BASIC)
|
||||||
)
|
)
|
||||||
field = nt["flds"][0]
|
field = notetype["flds"][0]
|
||||||
field["name"] = name
|
field["name"] = name
|
||||||
field["ord"] = None
|
field["ord"] = None
|
||||||
return field
|
return field
|
||||||
|
|
||||||
def add_field(self, m: NotetypeDict, field: FieldDict) -> None:
|
def add_field(self, notetype: NotetypeDict, field: FieldDict) -> None:
|
||||||
"Modifies schema."
|
"Modifies schema."
|
||||||
m["flds"].append(field)
|
notetype["flds"].append(field)
|
||||||
|
|
||||||
def remove_field(self, m: NotetypeDict, field: FieldDict) -> None:
|
def remove_field(self, notetype: NotetypeDict, field: FieldDict) -> None:
|
||||||
"Modifies schema."
|
"Modifies schema."
|
||||||
m["flds"].remove(field)
|
notetype["flds"].remove(field)
|
||||||
|
|
||||||
def reposition_field(self, m: NotetypeDict, field: FieldDict, idx: int) -> None:
|
def reposition_field(
|
||||||
|
self, notetype: NotetypeDict, field: FieldDict, idx: int
|
||||||
|
) -> None:
|
||||||
"Modifies schema."
|
"Modifies schema."
|
||||||
oldidx = m["flds"].index(field)
|
oldidx = notetype["flds"].index(field)
|
||||||
if oldidx == idx:
|
if oldidx == idx:
|
||||||
return
|
return
|
||||||
|
|
||||||
m["flds"].remove(field)
|
notetype["flds"].remove(field)
|
||||||
m["flds"].insert(idx, field)
|
notetype["flds"].insert(idx, field)
|
||||||
|
|
||||||
def rename_field(self, m: NotetypeDict, field: FieldDict, new_name: str) -> None:
|
def rename_field(
|
||||||
assert field in m["flds"]
|
self, notetype: NotetypeDict, field: FieldDict, new_name: str
|
||||||
|
) -> None:
|
||||||
|
assert field in notetype["flds"]
|
||||||
field["name"] = new_name
|
field["name"] = new_name
|
||||||
|
|
||||||
def set_sort_index(self, nt: NotetypeDict, idx: int) -> None:
|
def set_sort_index(self, notetype: NotetypeDict, idx: int) -> None:
|
||||||
"Modifies schema."
|
"Modifies schema."
|
||||||
assert 0 <= idx < len(nt["flds"])
|
assert 0 <= idx < len(notetype["flds"])
|
||||||
nt["sortf"] = idx
|
notetype["sortf"] = idx
|
||||||
|
|
||||||
# legacy
|
|
||||||
|
|
||||||
newField = new_field
|
|
||||||
|
|
||||||
def addField(self, m: NotetypeDict, field: FieldDict) -> None:
|
|
||||||
self.add_field(m, field)
|
|
||||||
if m["id"]:
|
|
||||||
self.save(m)
|
|
||||||
|
|
||||||
def remField(self, m: NotetypeDict, field: FieldDict) -> None:
|
|
||||||
self.remove_field(m, field)
|
|
||||||
self.save(m)
|
|
||||||
|
|
||||||
def moveField(self, m: NotetypeDict, field: FieldDict, idx: int) -> None:
|
|
||||||
self.reposition_field(m, field, idx)
|
|
||||||
self.save(m)
|
|
||||||
|
|
||||||
def renameField(self, m: NotetypeDict, field: FieldDict, newName: str) -> None:
|
|
||||||
self.rename_field(m, field, newName)
|
|
||||||
self.save(m)
|
|
||||||
|
|
||||||
# Adding & changing templates
|
# Adding & changing templates
|
||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
def new_template(self, name: str) -> TemplateDict:
|
def new_template(self, name: str) -> TemplateDict:
|
||||||
nt = from_json_bytes(
|
notetype = from_json_bytes(
|
||||||
self.col._backend.get_stock_notetype_legacy(StockNotetypeKind.BASIC)
|
self.col._backend.get_stock_notetype_legacy(StockNotetypeKind.BASIC)
|
||||||
)
|
)
|
||||||
template = nt["tmpls"][0]
|
template = notetype["tmpls"][0]
|
||||||
template["name"] = name
|
template["name"] = name
|
||||||
template["qfmt"] = ""
|
template["qfmt"] = ""
|
||||||
template["afmt"] = ""
|
template["afmt"] = ""
|
||||||
template["ord"] = None
|
template["ord"] = None
|
||||||
return template
|
return template
|
||||||
|
|
||||||
def add_template(self, m: NotetypeDict, template: TemplateDict) -> None:
|
def add_template(self, notetype: NotetypeDict, template: TemplateDict) -> None:
|
||||||
"Modifies schema."
|
"Modifies schema."
|
||||||
m["tmpls"].append(template)
|
notetype["tmpls"].append(template)
|
||||||
|
|
||||||
def remove_template(self, m: NotetypeDict, template: TemplateDict) -> None:
|
def remove_template(self, notetype: NotetypeDict, template: TemplateDict) -> None:
|
||||||
"Modifies schema."
|
"Modifies schema."
|
||||||
assert len(m["tmpls"]) > 1
|
assert len(notetype["tmpls"]) > 1
|
||||||
m["tmpls"].remove(template)
|
notetype["tmpls"].remove(template)
|
||||||
|
|
||||||
def reposition_template(
|
def reposition_template(
|
||||||
self, m: NotetypeDict, template: TemplateDict, idx: int
|
self, notetype: NotetypeDict, template: TemplateDict, idx: int
|
||||||
) -> None:
|
) -> None:
|
||||||
"Modifies schema."
|
"Modifies schema."
|
||||||
oldidx = m["tmpls"].index(template)
|
oldidx = notetype["tmpls"].index(template)
|
||||||
if oldidx == idx:
|
if oldidx == idx:
|
||||||
return
|
return
|
||||||
|
|
||||||
m["tmpls"].remove(template)
|
notetype["tmpls"].remove(template)
|
||||||
m["tmpls"].insert(idx, template)
|
notetype["tmpls"].insert(idx, template)
|
||||||
|
|
||||||
# legacy
|
|
||||||
|
|
||||||
newTemplate = new_template
|
|
||||||
|
|
||||||
def addTemplate(self, m: NotetypeDict, template: TemplateDict) -> None:
|
|
||||||
self.add_template(m, template)
|
|
||||||
if m["id"]:
|
|
||||||
self.save(m)
|
|
||||||
|
|
||||||
def remTemplate(self, m: NotetypeDict, template: TemplateDict) -> None:
|
|
||||||
self.remove_template(m, template)
|
|
||||||
self.save(m)
|
|
||||||
|
|
||||||
def moveTemplate(self, m: NotetypeDict, template: TemplateDict, idx: int) -> None:
|
|
||||||
self.reposition_template(m, template, idx)
|
|
||||||
self.save(m)
|
|
||||||
|
|
||||||
def template_use_count(self, ntid: NotetypeId, ord: int) -> int:
|
def template_use_count(self, ntid: NotetypeId, ord: int) -> int:
|
||||||
return self.col.db.scalar(
|
return self.col.db.scalar(
|
||||||
|
@ -464,9 +391,9 @@ and notes.mid = ? and cards.ord = ?""",
|
||||||
|
|
||||||
# legacy API - used by unit tests and add-ons
|
# legacy API - used by unit tests and add-ons
|
||||||
|
|
||||||
def change(
|
def change( # pylint: disable=invalid-name
|
||||||
self,
|
self,
|
||||||
m: NotetypeDict,
|
notetype: NotetypeDict,
|
||||||
nids: List[anki.notes.NoteId],
|
nids: List[anki.notes.NoteId],
|
||||||
newModel: NotetypeDict,
|
newModel: NotetypeDict,
|
||||||
fmap: Dict[int, Optional[int]],
|
fmap: Dict[int, Optional[int]],
|
||||||
|
@ -476,7 +403,11 @@ and notes.mid = ? and cards.ord = ?""",
|
||||||
self.col.modSchema(check=True)
|
self.col.modSchema(check=True)
|
||||||
assert fmap
|
assert fmap
|
||||||
field_map = self._convert_legacy_map(fmap, len(newModel["flds"]))
|
field_map = self._convert_legacy_map(fmap, len(newModel["flds"]))
|
||||||
if not cmap or newModel["type"] == MODEL_CLOZE or m["type"] == MODEL_CLOZE:
|
if (
|
||||||
|
not cmap
|
||||||
|
or newModel["type"] == MODEL_CLOZE
|
||||||
|
or notetype["type"] == MODEL_CLOZE
|
||||||
|
):
|
||||||
template_map = []
|
template_map = []
|
||||||
else:
|
else:
|
||||||
template_map = self._convert_legacy_map(cmap, len(newModel["tmpls"]))
|
template_map = self._convert_legacy_map(cmap, len(newModel["tmpls"]))
|
||||||
|
@ -486,7 +417,7 @@ and notes.mid = ? and cards.ord = ?""",
|
||||||
note_ids=nids,
|
note_ids=nids,
|
||||||
new_fields=field_map,
|
new_fields=field_map,
|
||||||
new_templates=template_map,
|
new_templates=template_map,
|
||||||
old_notetype_id=m["id"],
|
old_notetype_id=notetype["id"],
|
||||||
new_notetype_id=newModel["id"],
|
new_notetype_id=newModel["id"],
|
||||||
current_schema=self.col.db.scalar("select scm from col"),
|
current_schema=self.col.db.scalar("select scm from col"),
|
||||||
)
|
)
|
||||||
|
@ -510,21 +441,107 @@ and notes.mid = ? and cards.ord = ?""",
|
||||||
# Schema hash
|
# Schema hash
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def scmhash(self, m: NotetypeDict) -> str:
|
def scmhash(self, notetype: NotetypeDict) -> str:
|
||||||
"Return a hash of the schema, to see if models are compatible."
|
"Return a hash of the schema, to see if models are compatible."
|
||||||
s = ""
|
buf = ""
|
||||||
for f in m["flds"]:
|
for field in notetype["flds"]:
|
||||||
s += f["name"]
|
buf += field["name"]
|
||||||
for t in m["tmpls"]:
|
for template in notetype["tmpls"]:
|
||||||
s += t["name"]
|
buf += template["name"]
|
||||||
return checksum(s)
|
return checksum(buf)
|
||||||
|
|
||||||
# Cloze
|
# Legacy
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
|
@deprecated(info="use note.cloze_numbers_in_fields()")
|
||||||
def _availClozeOrds(
|
def _availClozeOrds(
|
||||||
self, m: NotetypeDict, flds: str, allowEmpty: bool = True
|
self, notetype: NotetypeDict, flds: str, allow_empty: bool = True
|
||||||
) -> List[int]:
|
) -> List[int]:
|
||||||
print("_availClozeOrds() is deprecated; use note.cloze_numbers_in_fields()")
|
|
||||||
note = _pb.Note(fields=[flds])
|
note = _pb.Note(fields=[flds])
|
||||||
return list(self.col._backend.cloze_numbers_in_note(note))
|
return list(self.col._backend.cloze_numbers_in_note(note))
|
||||||
|
|
||||||
|
# @deprecated(replaced_by=add_template)
|
||||||
|
def addTemplate(self, notetype: NotetypeDict, template: TemplateDict) -> None:
|
||||||
|
self.add_template(notetype, template)
|
||||||
|
if notetype["id"]:
|
||||||
|
self.update(notetype)
|
||||||
|
|
||||||
|
# @deprecated(replaced_by=remove_template)
|
||||||
|
def remTemplate(self, notetype: NotetypeDict, template: TemplateDict) -> None:
|
||||||
|
self.remove_template(notetype, template)
|
||||||
|
self.update(notetype)
|
||||||
|
|
||||||
|
# @deprecated(replaced_by=reposition_template)
|
||||||
|
def move_template(
|
||||||
|
self, notetype: NotetypeDict, template: TemplateDict, idx: int
|
||||||
|
) -> None:
|
||||||
|
self.reposition_template(notetype, template, idx)
|
||||||
|
self.update(notetype)
|
||||||
|
|
||||||
|
# @deprecated(replaced_by=add_field)
|
||||||
|
def addField(self, notetype: NotetypeDict, field: FieldDict) -> None:
|
||||||
|
self.add_field(notetype, field)
|
||||||
|
if notetype["id"]:
|
||||||
|
self.update(notetype)
|
||||||
|
|
||||||
|
# @deprecated(replaced_by=remove_field)
|
||||||
|
def remField(self, notetype: NotetypeDict, field: FieldDict) -> None:
|
||||||
|
self.remove_field(notetype, field)
|
||||||
|
self.update(notetype)
|
||||||
|
|
||||||
|
# @deprecated(replaced_by=reposition_field)
|
||||||
|
def moveField(self, notetype: NotetypeDict, field: FieldDict, idx: int) -> None:
|
||||||
|
self.reposition_field(notetype, field, idx)
|
||||||
|
self.update(notetype)
|
||||||
|
|
||||||
|
# @deprecated(replaced_by=rename_field)
|
||||||
|
def renameField(
|
||||||
|
self, notetype: NotetypeDict, field: FieldDict, new_name: str
|
||||||
|
) -> None:
|
||||||
|
self.rename_field(notetype, field, new_name)
|
||||||
|
self.update(notetype)
|
||||||
|
|
||||||
|
@deprecated(replaced_by=remove)
|
||||||
|
def rem(self, m: NotetypeDict) -> None:
|
||||||
|
"Delete model, and all its cards/notes."
|
||||||
|
self.remove(m["id"])
|
||||||
|
|
||||||
|
# @deprecated(info="not needed; is updated on note add")
|
||||||
|
def set_current(self, m: NotetypeDict) -> None:
|
||||||
|
self.col.set_config("curModel", m["id"])
|
||||||
|
|
||||||
|
@deprecated(replaced_by=all_names_and_ids)
|
||||||
|
def all_names(self) -> List[str]:
|
||||||
|
return [n.name for n in self.all_names_and_ids()]
|
||||||
|
|
||||||
|
@deprecated(replaced_by=all_names_and_ids)
|
||||||
|
def ids(self) -> List[NotetypeId]:
|
||||||
|
return [NotetypeId(n.id) for n in self.all_names_and_ids()]
|
||||||
|
|
||||||
|
@deprecated(info="no longer required")
|
||||||
|
def flush(self) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# @deprecated(replaced_by=update_dict)
|
||||||
|
def update(self, notetype: NotetypeDict, preserve_usn: bool = True) -> None:
|
||||||
|
"Add or update an existing model. Use .update_dict() instead."
|
||||||
|
self._remove_from_cache(notetype["id"])
|
||||||
|
self.ensure_name_unique(notetype)
|
||||||
|
notetype["id"] = self.col._backend.add_or_update_notetype(
|
||||||
|
json=to_json_bytes(notetype), preserve_usn_and_mtime=preserve_usn
|
||||||
|
)
|
||||||
|
self.set_current(notetype)
|
||||||
|
self._mutate_after_write(notetype)
|
||||||
|
|
||||||
|
# @deprecated(replaced_by=update_dict)
|
||||||
|
def save(self, notetype: NotetypeDict = None, **legacy_kwargs: bool) -> None:
|
||||||
|
"Save changes made to provided note type."
|
||||||
|
if not notetype:
|
||||||
|
print_deprecation_warning(
|
||||||
|
"col.models.save() should be passed the changed notetype"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
self.update(notetype, preserve_usn=False)
|
||||||
|
|
|
@ -61,7 +61,7 @@ class Note(DeprecatedNamesMixin):
|
||||||
self.usn = note.usn
|
self.usn = note.usn
|
||||||
self.tags = list(note.tags)
|
self.tags = list(note.tags)
|
||||||
self.fields = list(note.fields)
|
self.fields = list(note.fields)
|
||||||
self._fmap = self.col.models.fieldMap(self.note_type())
|
self._fmap = self.col.models.field_map(self.note_type())
|
||||||
|
|
||||||
def _to_backend_note(self) -> _pb.Note:
|
def _to_backend_note(self) -> _pb.Note:
|
||||||
hooks.note_will_flush(self)
|
hooks.note_will_flush(self)
|
||||||
|
|
|
@ -1,6 +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
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
from typing import List, Optional, Tuple
|
from typing import List, Optional, Tuple
|
||||||
|
|
||||||
from anki.cards import Card, CardId
|
from anki.cards import Card, CardId
|
||||||
|
|
|
@ -1,6 +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
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import random
|
import random
|
||||||
|
|
|
@ -1,6 +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
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import random
|
import random
|
||||||
|
|
|
@ -44,10 +44,10 @@ def test_genrem():
|
||||||
m = col.models.current()
|
m = col.models.current()
|
||||||
mm = col.models
|
mm = col.models
|
||||||
# adding a new template should automatically create cards
|
# adding a new template should automatically create cards
|
||||||
t = mm.newTemplate("rev")
|
t = mm.new_template("rev")
|
||||||
t["qfmt"] = "{{Front}}2"
|
t["qfmt"] = "{{Front}}2"
|
||||||
t["afmt"] = ""
|
t["afmt"] = ""
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
mm.save(m, templates=True)
|
mm.save(m, templates=True)
|
||||||
assert len(note.cards()) == 2
|
assert len(note.cards()) == 2
|
||||||
# if the template is changed to remove cards, they'll be removed
|
# if the template is changed to remove cards, they'll be removed
|
||||||
|
@ -68,9 +68,8 @@ def test_genrem():
|
||||||
|
|
||||||
def test_gendeck():
|
def test_gendeck():
|
||||||
col = getEmptyCol()
|
col = getEmptyCol()
|
||||||
cloze = col.models.byName("Cloze")
|
cloze = col.models.by_name("Cloze")
|
||||||
col.models.setCurrent(cloze)
|
note = col.new_note(cloze)
|
||||||
note = col.newNote()
|
|
||||||
note["Text"] = "{{c1::one}}"
|
note["Text"] = "{{c1::one}}"
|
||||||
col.addNote(note)
|
col.addNote(note)
|
||||||
assert col.cardCount() == 1
|
assert col.cardCount() == 1
|
||||||
|
|
|
@ -57,10 +57,10 @@ def test_noteAddDelete():
|
||||||
# test multiple cards - add another template
|
# test multiple cards - add another template
|
||||||
m = col.models.current()
|
m = col.models.current()
|
||||||
mm = col.models
|
mm = col.models
|
||||||
t = mm.newTemplate("Reverse")
|
t = mm.new_template("Reverse")
|
||||||
t["qfmt"] = "{{Back}}"
|
t["qfmt"] = "{{Back}}"
|
||||||
t["afmt"] = "{{Front}}"
|
t["afmt"] = "{{Front}}"
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
mm.save(m)
|
mm.save(m)
|
||||||
assert col.cardCount() == 2
|
assert col.cardCount() == 2
|
||||||
# creating new notes should use both cards
|
# creating new notes should use both cards
|
||||||
|
|
|
@ -37,10 +37,10 @@ def test_findCards():
|
||||||
m = col.models.current()
|
m = col.models.current()
|
||||||
m = col.models.copy(m)
|
m = col.models.copy(m)
|
||||||
mm = col.models
|
mm = col.models
|
||||||
t = mm.newTemplate("Reverse")
|
t = mm.new_template("Reverse")
|
||||||
t["qfmt"] = "{{Back}}"
|
t["qfmt"] = "{{Back}}"
|
||||||
t["afmt"] = "{{Front}}"
|
t["afmt"] = "{{Front}}"
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
mm.save(m)
|
mm.save(m)
|
||||||
note = col.newNote()
|
note = col.newNote()
|
||||||
note["Front"] = "test"
|
note["Front"] = "test"
|
||||||
|
|
|
@ -189,7 +189,7 @@ def test_csv2():
|
||||||
col = getEmptyCol()
|
col = getEmptyCol()
|
||||||
mm = col.models
|
mm = col.models
|
||||||
m = mm.current()
|
m = mm.current()
|
||||||
note = mm.newField("Three")
|
note = mm.new_field("Three")
|
||||||
mm.addField(m, note)
|
mm.addField(m, note)
|
||||||
mm.save(m)
|
mm.save(m)
|
||||||
n = col.newNote()
|
n = col.newNote()
|
||||||
|
@ -213,7 +213,7 @@ def test_tsv_tag_modified():
|
||||||
col = getEmptyCol()
|
col = getEmptyCol()
|
||||||
mm = col.models
|
mm = col.models
|
||||||
m = mm.current()
|
m = mm.current()
|
||||||
note = mm.newField("Top")
|
note = mm.new_field("Top")
|
||||||
mm.addField(m, note)
|
mm.addField(m, note)
|
||||||
mm.save(m)
|
mm.save(m)
|
||||||
n = col.newNote()
|
n = col.newNote()
|
||||||
|
@ -249,7 +249,7 @@ def test_tsv_tag_multiple_tags():
|
||||||
col = getEmptyCol()
|
col = getEmptyCol()
|
||||||
mm = col.models
|
mm = col.models
|
||||||
m = mm.current()
|
m = mm.current()
|
||||||
note = mm.newField("Top")
|
note = mm.new_field("Top")
|
||||||
mm.addField(m, note)
|
mm.addField(m, note)
|
||||||
mm.save(m)
|
mm.save(m)
|
||||||
n = col.newNote()
|
n = col.newNote()
|
||||||
|
@ -283,7 +283,7 @@ def test_csv_tag_only_if_modified():
|
||||||
col = getEmptyCol()
|
col = getEmptyCol()
|
||||||
mm = col.models
|
mm = col.models
|
||||||
m = mm.current()
|
m = mm.current()
|
||||||
note = mm.newField("Left")
|
note = mm.new_field("Left")
|
||||||
mm.addField(m, note)
|
mm.addField(m, note)
|
||||||
mm.save(m)
|
mm.save(m)
|
||||||
n = col.newNote()
|
n = col.newNote()
|
||||||
|
|
|
@ -17,7 +17,7 @@ def test_modelDelete():
|
||||||
note["Back"] = "2"
|
note["Back"] = "2"
|
||||||
col.addNote(note)
|
col.addNote(note)
|
||||||
assert col.cardCount() == 1
|
assert col.cardCount() == 1
|
||||||
col.models.rem(col.models.current())
|
col.models.remove(col.models.current()["id"])
|
||||||
assert col.cardCount() == 0
|
assert col.cardCount() == 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ def test_fields():
|
||||||
assert "{{NewFront}}" in m["tmpls"][0]["qfmt"]
|
assert "{{NewFront}}" in m["tmpls"][0]["qfmt"]
|
||||||
h = col.models.scmhash(m)
|
h = col.models.scmhash(m)
|
||||||
# add a field
|
# add a field
|
||||||
field = col.models.newField("foo")
|
field = col.models.new_field("foo")
|
||||||
col.models.addField(m, field)
|
col.models.addField(m, field)
|
||||||
assert col.get_note(col.models.nids(m)[0]).fields == ["1", "2", ""]
|
assert col.get_note(col.models.nids(m)[0]).fields == ["1", "2", ""]
|
||||||
assert col.models.scmhash(m) != h
|
assert col.models.scmhash(m) != h
|
||||||
|
@ -65,7 +65,7 @@ def test_fields():
|
||||||
col.models.moveField(m, m["flds"][1], 0)
|
col.models.moveField(m, m["flds"][1], 0)
|
||||||
assert col.get_note(col.models.nids(m)[0]).fields == ["1", ""]
|
assert col.get_note(col.models.nids(m)[0]).fields == ["1", ""]
|
||||||
# add another and put in middle
|
# add another and put in middle
|
||||||
field = col.models.newField("baz")
|
field = col.models.new_field("baz")
|
||||||
col.models.addField(m, field)
|
col.models.addField(m, field)
|
||||||
note = col.get_note(col.models.nids(m)[0])
|
note = col.get_note(col.models.nids(m)[0])
|
||||||
note["baz"] = "2"
|
note["baz"] = "2"
|
||||||
|
@ -86,10 +86,10 @@ def test_templates():
|
||||||
col = getEmptyCol()
|
col = getEmptyCol()
|
||||||
m = col.models.current()
|
m = col.models.current()
|
||||||
mm = col.models
|
mm = col.models
|
||||||
t = mm.newTemplate("Reverse")
|
t = mm.new_template("Reverse")
|
||||||
t["qfmt"] = "{{Back}}"
|
t["qfmt"] = "{{Back}}"
|
||||||
t["afmt"] = "{{Front}}"
|
t["afmt"] = "{{Front}}"
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
mm.save(m)
|
mm.save(m)
|
||||||
note = col.newNote()
|
note = col.newNote()
|
||||||
note["Front"] = "1"
|
note["Front"] = "1"
|
||||||
|
@ -101,23 +101,26 @@ def test_templates():
|
||||||
assert c.ord == 0
|
assert c.ord == 0
|
||||||
assert c2.ord == 1
|
assert c2.ord == 1
|
||||||
# switch templates
|
# switch templates
|
||||||
col.models.moveTemplate(m, c.template(), 1)
|
col.models.reposition_template(m, c.template(), 1)
|
||||||
|
col.models.update(m)
|
||||||
c.load()
|
c.load()
|
||||||
c2.load()
|
c2.load()
|
||||||
assert c.ord == 1
|
assert c.ord == 1
|
||||||
assert c2.ord == 0
|
assert c2.ord == 0
|
||||||
# removing a template should delete its cards
|
# removing a template should delete its cards
|
||||||
col.models.remTemplate(m, m["tmpls"][0])
|
col.models.remove_template(m, m["tmpls"][0])
|
||||||
|
col.models.update(m)
|
||||||
assert col.cardCount() == 1
|
assert col.cardCount() == 1
|
||||||
# and should have updated the other cards' ordinals
|
# and should have updated the other cards' ordinals
|
||||||
c = note.cards()[0]
|
c = note.cards()[0]
|
||||||
assert c.ord == 0
|
assert c.ord == 0
|
||||||
assert stripHTML(c.question()) == "1"
|
assert stripHTML(c.question()) == "1"
|
||||||
# it shouldn't be possible to orphan notes by removing templates
|
# it shouldn't be possible to orphan notes by removing templates
|
||||||
t = mm.newTemplate("template name")
|
t = mm.new_template("template name")
|
||||||
t["qfmt"] = "{{Front}}2"
|
t["qfmt"] = "{{Front}}2"
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
col.models.remTemplate(m, m["tmpls"][0])
|
col.models.remove_template(m, m["tmpls"][0])
|
||||||
|
col.models.update(m)
|
||||||
assert (
|
assert (
|
||||||
col.db.scalar(
|
col.db.scalar(
|
||||||
"select count() from cards where nid not in (select id from notes)"
|
"select count() from cards where nid not in (select id from notes)"
|
||||||
|
@ -128,17 +131,17 @@ def test_templates():
|
||||||
|
|
||||||
def test_cloze_ordinals():
|
def test_cloze_ordinals():
|
||||||
col = getEmptyCol()
|
col = getEmptyCol()
|
||||||
col.models.setCurrent(col.models.byName("Cloze"))
|
m = col.models.by_name("Cloze")
|
||||||
m = col.models.current()
|
|
||||||
mm = col.models
|
mm = col.models
|
||||||
|
|
||||||
# We replace the default Cloze template
|
# We replace the default Cloze template
|
||||||
t = mm.newTemplate("ChainedCloze")
|
t = mm.new_template("ChainedCloze")
|
||||||
t["qfmt"] = "{{text:cloze:Text}}"
|
t["qfmt"] = "{{text:cloze:Text}}"
|
||||||
t["afmt"] = "{{text:cloze:Text}}"
|
t["afmt"] = "{{text:cloze:Text}}"
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
mm.save(m)
|
mm.save(m)
|
||||||
col.models.remTemplate(m, m["tmpls"][0])
|
col.models.remove_template(m, m["tmpls"][0])
|
||||||
|
col.models.update(m)
|
||||||
|
|
||||||
note = col.newNote()
|
note = col.newNote()
|
||||||
note["Text"] = "{{c1::firstQ::firstA}}{{c2::secondQ::secondA}}"
|
note["Text"] = "{{c1::firstQ::firstA}}{{c2::secondQ::secondA}}"
|
||||||
|
@ -163,26 +166,26 @@ def test_text():
|
||||||
|
|
||||||
def test_cloze():
|
def test_cloze():
|
||||||
col = getEmptyCol()
|
col = getEmptyCol()
|
||||||
col.models.setCurrent(col.models.byName("Cloze"))
|
m = col.models.by_name("Cloze")
|
||||||
note = col.newNote()
|
note = col.new_note(m)
|
||||||
assert note.note_type()["name"] == "Cloze"
|
assert note.note_type()["name"] == "Cloze"
|
||||||
# a cloze model with no clozes is not empty
|
# a cloze model with no clozes is not empty
|
||||||
note["Text"] = "nothing"
|
note["Text"] = "nothing"
|
||||||
assert col.addNote(note)
|
assert col.addNote(note)
|
||||||
# try with one cloze
|
# try with one cloze
|
||||||
note = col.newNote()
|
note = col.new_note(m)
|
||||||
note["Text"] = "hello {{c1::world}}"
|
note["Text"] = "hello {{c1::world}}"
|
||||||
assert col.addNote(note) == 1
|
assert col.addNote(note) == 1
|
||||||
assert "hello <span class=cloze>[...]</span>" in note.cards()[0].question()
|
assert "hello <span class=cloze>[...]</span>" in note.cards()[0].question()
|
||||||
assert "hello <span class=cloze>world</span>" in note.cards()[0].answer()
|
assert "hello <span class=cloze>world</span>" in note.cards()[0].answer()
|
||||||
# and with a comment
|
# and with a comment
|
||||||
note = col.newNote()
|
note = col.new_note(m)
|
||||||
note["Text"] = "hello {{c1::world::typical}}"
|
note["Text"] = "hello {{c1::world::typical}}"
|
||||||
assert col.addNote(note) == 1
|
assert col.addNote(note) == 1
|
||||||
assert "<span class=cloze>[typical]</span>" in note.cards()[0].question()
|
assert "<span class=cloze>[typical]</span>" in note.cards()[0].question()
|
||||||
assert "<span class=cloze>world</span>" in note.cards()[0].answer()
|
assert "<span class=cloze>world</span>" in note.cards()[0].answer()
|
||||||
# and with 2 clozes
|
# and with 2 clozes
|
||||||
note = col.newNote()
|
note = col.new_note(m)
|
||||||
note["Text"] = "hello {{c1::world}} {{c2::bar}}"
|
note["Text"] = "hello {{c1::world}} {{c2::bar}}"
|
||||||
assert col.addNote(note) == 2
|
assert col.addNote(note) == 2
|
||||||
(c1, c2) = note.cards()
|
(c1, c2) = note.cards()
|
||||||
|
@ -192,7 +195,7 @@ def test_cloze():
|
||||||
assert "world <span class=cloze>bar</span>" in c2.answer()
|
assert "world <span class=cloze>bar</span>" in c2.answer()
|
||||||
# if there are multiple answers for a single cloze, they are given in a
|
# if there are multiple answers for a single cloze, they are given in a
|
||||||
# list
|
# list
|
||||||
note = col.newNote()
|
note = col.new_note(m)
|
||||||
note["Text"] = "a {{c1::b}} {{c1::c}}"
|
note["Text"] = "a {{c1::b}} {{c1::c}}"
|
||||||
assert col.addNote(note) == 1
|
assert col.addNote(note) == 1
|
||||||
assert "<span class=cloze>b</span> <span class=cloze>c</span>" in (
|
assert "<span class=cloze>b</span> <span class=cloze>c</span>" in (
|
||||||
|
@ -211,8 +214,8 @@ def test_cloze():
|
||||||
|
|
||||||
def test_cloze_mathjax():
|
def test_cloze_mathjax():
|
||||||
col = getEmptyCol()
|
col = getEmptyCol()
|
||||||
col.models.setCurrent(col.models.byName("Cloze"))
|
m = col.models.by_name("Cloze")
|
||||||
note = col.newNote()
|
note = col.new_note(m)
|
||||||
note[
|
note[
|
||||||
"Text"
|
"Text"
|
||||||
] = r"{{c1::ok}} \(2^2\) {{c2::not ok}} \(2^{{c3::2}}\) \(x^3\) {{c4::blah}} {{c5::text with \(x^2\) jax}}"
|
] = r"{{c1::ok}} \(2^2\) {{c2::not ok}} \(2^{{c3::2}}\) \(x^3\) {{c4::blah}} {{c5::text with \(x^2\) jax}}"
|
||||||
|
@ -224,7 +227,7 @@ def test_cloze_mathjax():
|
||||||
assert "class=cloze" in note.cards()[3].question()
|
assert "class=cloze" in note.cards()[3].question()
|
||||||
assert "class=cloze" in note.cards()[4].question()
|
assert "class=cloze" in note.cards()[4].question()
|
||||||
|
|
||||||
note = col.newNote()
|
note = col.new_note(m)
|
||||||
note["Text"] = r"\(a\) {{c1::b}} \[ {{c1::c}} \]"
|
note["Text"] = r"\(a\) {{c1::b}} \[ {{c1::c}} \]"
|
||||||
assert col.addNote(note)
|
assert col.addNote(note)
|
||||||
assert len(note.cards()) == 1
|
assert len(note.cards()) == 1
|
||||||
|
@ -237,11 +240,10 @@ def test_cloze_mathjax():
|
||||||
|
|
||||||
def test_typecloze():
|
def test_typecloze():
|
||||||
col = getEmptyCol()
|
col = getEmptyCol()
|
||||||
m = col.models.byName("Cloze")
|
m = col.models.by_name("Cloze")
|
||||||
col.models.setCurrent(m)
|
|
||||||
m["tmpls"][0]["qfmt"] = "{{cloze:Text}}{{type:cloze:Text}}"
|
m["tmpls"][0]["qfmt"] = "{{cloze:Text}}{{type:cloze:Text}}"
|
||||||
col.models.save(m)
|
col.models.save(m)
|
||||||
note = col.newNote()
|
note = col.new_note(m)
|
||||||
note["Text"] = "hello {{c1::world}}"
|
note["Text"] = "hello {{c1::world}}"
|
||||||
col.addNote(note)
|
col.addNote(note)
|
||||||
assert "[[type:cloze:Text]]" in note.cards()[0].question()
|
assert "[[type:cloze:Text]]" in note.cards()[0].question()
|
||||||
|
@ -249,17 +251,17 @@ def test_typecloze():
|
||||||
|
|
||||||
def test_chained_mods():
|
def test_chained_mods():
|
||||||
col = getEmptyCol()
|
col = getEmptyCol()
|
||||||
col.models.setCurrent(col.models.byName("Cloze"))
|
m = col.models.by_name("Cloze")
|
||||||
m = col.models.current()
|
|
||||||
mm = col.models
|
mm = col.models
|
||||||
|
|
||||||
# We replace the default Cloze template
|
# We replace the default Cloze template
|
||||||
t = mm.newTemplate("ChainedCloze")
|
t = mm.new_template("ChainedCloze")
|
||||||
t["qfmt"] = "{{cloze:text:Text}}"
|
t["qfmt"] = "{{cloze:text:Text}}"
|
||||||
t["afmt"] = "{{cloze:text:Text}}"
|
t["afmt"] = "{{cloze:text:Text}}"
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
mm.save(m)
|
mm.save(m)
|
||||||
col.models.remTemplate(m, m["tmpls"][0])
|
col.models.remove_template(m, m["tmpls"][0])
|
||||||
|
col.models.update(m)
|
||||||
|
|
||||||
note = col.newNote()
|
note = col.newNote()
|
||||||
q1 = '<span style="color:red">phrase</span>'
|
q1 = '<span style="color:red">phrase</span>'
|
||||||
|
@ -285,14 +287,14 @@ def test_chained_mods():
|
||||||
|
|
||||||
def test_modelChange():
|
def test_modelChange():
|
||||||
col = getEmptyCol()
|
col = getEmptyCol()
|
||||||
cloze = col.models.byName("Cloze")
|
cloze = col.models.by_name("Cloze")
|
||||||
# enable second template and add a note
|
# enable second template and add a note
|
||||||
m = col.models.current()
|
m = col.models.current()
|
||||||
mm = col.models
|
mm = col.models
|
||||||
t = mm.newTemplate("Reverse")
|
t = mm.new_template("Reverse")
|
||||||
t["qfmt"] = "{{Back}}"
|
t["qfmt"] = "{{Back}}"
|
||||||
t["afmt"] = "{{Front}}"
|
t["afmt"] = "{{Front}}"
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
mm.save(m)
|
mm.save(m)
|
||||||
basic = m
|
basic = m
|
||||||
note = col.newNote()
|
note = col.newNote()
|
||||||
|
@ -360,7 +362,8 @@ def test_modelChange():
|
||||||
assert note["Text"] == "f2"
|
assert note["Text"] == "f2"
|
||||||
assert len(note.cards()) == 2
|
assert len(note.cards()) == 2
|
||||||
# back the other way, with deletion of second ord
|
# back the other way, with deletion of second ord
|
||||||
col.models.remTemplate(basic, basic["tmpls"][1])
|
col.models.remove_template(basic, basic["tmpls"][1])
|
||||||
|
col.models.update(basic)
|
||||||
assert col.db.scalar("select count() from cards where nid = ?", note.id) == 2
|
assert col.db.scalar("select count() from cards where nid = ?", note.id) == 2
|
||||||
map = {0: 0}
|
map = {0: 0}
|
||||||
col.models.change(cloze, [note.id], basic, map, map)
|
col.models.change(cloze, [note.id], basic, map, map)
|
||||||
|
@ -375,14 +378,14 @@ def test_req():
|
||||||
|
|
||||||
col = getEmptyCol()
|
col = getEmptyCol()
|
||||||
mm = col.models
|
mm = col.models
|
||||||
basic = mm.byName("Basic")
|
basic = mm.by_name("Basic")
|
||||||
assert "req" in basic
|
assert "req" in basic
|
||||||
reqSize(basic)
|
reqSize(basic)
|
||||||
r = basic["req"][0]
|
r = basic["req"][0]
|
||||||
assert r[0] == 0
|
assert r[0] == 0
|
||||||
assert r[1] in ("any", "all")
|
assert r[1] in ("any", "all")
|
||||||
assert r[2] == [0]
|
assert r[2] == [0]
|
||||||
opt = mm.byName("Basic (optional reversed card)")
|
opt = mm.by_name("Basic (optional reversed card)")
|
||||||
reqSize(opt)
|
reqSize(opt)
|
||||||
r = opt["req"][0]
|
r = opt["req"][0]
|
||||||
assert r[1] in ("any", "all")
|
assert r[1] in ("any", "all")
|
||||||
|
@ -397,7 +400,7 @@ def test_req():
|
||||||
mm.save(opt, templates=True)
|
mm.save(opt, templates=True)
|
||||||
assert opt["req"][1] == [1, "none", []]
|
assert opt["req"][1] == [1, "none", []]
|
||||||
|
|
||||||
opt = mm.byName("Basic (type in the answer)")
|
opt = mm.by_name("Basic (type in the answer)")
|
||||||
reqSize(opt)
|
reqSize(opt)
|
||||||
r = opt["req"][0]
|
r = opt["req"][0]
|
||||||
assert r[1] in ("any", "all")
|
assert r[1] in ("any", "all")
|
||||||
|
|
|
@ -63,10 +63,10 @@ def test_new():
|
||||||
# # the default order should ensure siblings are not seen together, and
|
# # the default order should ensure siblings are not seen together, and
|
||||||
# # should show all cards
|
# # should show all cards
|
||||||
# m = col.models.current(); mm = col.models
|
# m = col.models.current(); mm = col.models
|
||||||
# t = mm.newTemplate("Reverse")
|
# t = mm.new_template("Reverse")
|
||||||
# t['qfmt'] = "{{Back}}"
|
# t['qfmt'] = "{{Back}}"
|
||||||
# t['afmt'] = "{{Front}}"
|
# t['afmt'] = "{{Front}}"
|
||||||
# mm.addTemplate(m, t)
|
# mm.add_template(m, t)
|
||||||
# mm.save(m)
|
# mm.save(m)
|
||||||
# note = col.newNote()
|
# note = col.newNote()
|
||||||
# note['Front'] = u"2"; note['Back'] = u"2"
|
# note['Front'] = u"2"; note['Back'] = u"2"
|
||||||
|
@ -562,8 +562,8 @@ def test_suspend():
|
||||||
|
|
||||||
def test_cram():
|
def test_cram():
|
||||||
col = getEmptyCol()
|
col = getEmptyCol()
|
||||||
opt = col.models.byName("Basic (and reversed card)")
|
opt = col.models.by_name("Basic (and reversed card)")
|
||||||
col.models.setCurrent(opt)
|
col.models.set_current(opt)
|
||||||
note = col.newNote()
|
note = col.newNote()
|
||||||
note["Front"] = "one"
|
note["Front"] = "one"
|
||||||
col.addNote(note)
|
col.addNote(note)
|
||||||
|
@ -806,14 +806,14 @@ def test_ordcycle():
|
||||||
# add two more templates and set second active
|
# add two more templates and set second active
|
||||||
m = col.models.current()
|
m = col.models.current()
|
||||||
mm = col.models
|
mm = col.models
|
||||||
t = mm.newTemplate("Reverse")
|
t = mm.new_template("Reverse")
|
||||||
t["qfmt"] = "{{Back}}"
|
t["qfmt"] = "{{Back}}"
|
||||||
t["afmt"] = "{{Front}}"
|
t["afmt"] = "{{Front}}"
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
t = mm.newTemplate("f2")
|
t = mm.new_template("f2")
|
||||||
t["qfmt"] = "{{Front}}2"
|
t["qfmt"] = "{{Front}}2"
|
||||||
t["afmt"] = "{{Back}}"
|
t["afmt"] = "{{Back}}"
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
mm.save(m)
|
mm.save(m)
|
||||||
# create a new note; it should have 3 cards
|
# create a new note; it should have 3 cards
|
||||||
note = col.newNote()
|
note = col.newNote()
|
||||||
|
|
|
@ -75,10 +75,10 @@ def test_new():
|
||||||
# # the default order should ensure siblings are not seen together, and
|
# # the default order should ensure siblings are not seen together, and
|
||||||
# # should show all cards
|
# # should show all cards
|
||||||
# m = col.models.current(); mm = col.models
|
# m = col.models.current(); mm = col.models
|
||||||
# t = mm.newTemplate("Reverse")
|
# t = mm.new_template("Reverse")
|
||||||
# t['qfmt'] = "{{Back}}"
|
# t['qfmt'] = "{{Back}}"
|
||||||
# t['afmt'] = "{{Front}}"
|
# t['afmt'] = "{{Front}}"
|
||||||
# mm.addTemplate(m, t)
|
# mm.add_template(m, t)
|
||||||
# mm.save(m)
|
# mm.save(m)
|
||||||
# note = col.newNote()
|
# note = col.newNote()
|
||||||
# note['Front'] = u"2"; note['Back'] = u"2"
|
# note['Front'] = u"2"; note['Back'] = u"2"
|
||||||
|
@ -880,14 +880,14 @@ def test_ordcycle():
|
||||||
# add two more templates and set second active
|
# add two more templates and set second active
|
||||||
m = col.models.current()
|
m = col.models.current()
|
||||||
mm = col.models
|
mm = col.models
|
||||||
t = mm.newTemplate("Reverse")
|
t = mm.new_template("Reverse")
|
||||||
t["qfmt"] = "{{Back}}"
|
t["qfmt"] = "{{Back}}"
|
||||||
t["afmt"] = "{{Front}}"
|
t["afmt"] = "{{Front}}"
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
t = mm.newTemplate("f2")
|
t = mm.new_template("f2")
|
||||||
t["qfmt"] = "{{Front}}2"
|
t["qfmt"] = "{{Front}}2"
|
||||||
t["afmt"] = "{{Back}}"
|
t["afmt"] = "{{Back}}"
|
||||||
mm.addTemplate(m, t)
|
mm.add_template(m, t)
|
||||||
mm.save(m)
|
mm.save(m)
|
||||||
# create a new note; it should have 3 cards
|
# create a new note; it should have 3 cards
|
||||||
note = col.newNote()
|
note = col.newNote()
|
||||||
|
|
|
@ -77,13 +77,13 @@ class Hook:
|
||||||
class {self.classname()}:
|
class {self.classname()}:
|
||||||
{classdoc}{self.list_code()}
|
{classdoc}{self.list_code()}
|
||||||
|
|
||||||
def append(self, cb: {self.callable()}) -> None:
|
def append(self, callback: {self.callable()}) -> None:
|
||||||
'''{appenddoc}'''
|
'''{appenddoc}'''
|
||||||
self._hooks.append(cb)
|
self._hooks.append(callback)
|
||||||
|
|
||||||
def remove(self, cb: {self.callable()}) -> None:
|
def remove(self, callback: {self.callable()}) -> None:
|
||||||
if cb in self._hooks:
|
if callback in self._hooks:
|
||||||
self._hooks.remove(cb)
|
self._hooks.remove(callback)
|
||||||
|
|
||||||
def count(self) -> int:
|
def count(self) -> int:
|
||||||
return len(self._hooks)
|
return len(self._hooks)
|
||||||
|
|
|
@ -226,7 +226,7 @@ class CardLayout(QDialog):
|
||||||
tform.style_button.setText(tr.card_templates_template_styling())
|
tform.style_button.setText(tr.card_templates_template_styling())
|
||||||
tform.groupBox.setTitle(tr.card_templates_template_box())
|
tform.groupBox.setTitle(tr.card_templates_template_box())
|
||||||
|
|
||||||
cnt = self.mw.col.models.useCount(self.model)
|
cnt = self.mw.col.models.use_count(self.model)
|
||||||
self.tform.changes_affect_label.setText(
|
self.tform.changes_affect_label.setText(
|
||||||
self.col.tr.card_templates_changes_will_affect_notes(count=cnt)
|
self.col.tr.card_templates_changes_will_affect_notes(count=cnt)
|
||||||
)
|
)
|
||||||
|
@ -633,14 +633,14 @@ class CardLayout(QDialog):
|
||||||
return name
|
return name
|
||||||
|
|
||||||
def onAddCard(self) -> None:
|
def onAddCard(self) -> None:
|
||||||
cnt = self.mw.col.models.useCount(self.model)
|
cnt = self.mw.col.models.use_count(self.model)
|
||||||
txt = tr.card_templates_this_will_create_card_proceed(count=cnt)
|
txt = tr.card_templates_this_will_create_card_proceed(count=cnt)
|
||||||
if not askUser(txt):
|
if not askUser(txt):
|
||||||
return
|
return
|
||||||
if not self.change_tracker.mark_schema():
|
if not self.change_tracker.mark_schema():
|
||||||
return
|
return
|
||||||
name = self._newCardName()
|
name = self._newCardName()
|
||||||
t = self.mm.newTemplate(name)
|
t = self.mm.new_template(name)
|
||||||
old = self.current_template()
|
old = self.current_template()
|
||||||
t["qfmt"] = old["qfmt"]
|
t["qfmt"] = old["qfmt"]
|
||||||
t["afmt"] = old["afmt"]
|
t["afmt"] = old["afmt"]
|
||||||
|
|
|
@ -136,7 +136,7 @@ class FieldDialog(QDialog):
|
||||||
if not self.change_tracker.mark_schema():
|
if not self.change_tracker.mark_schema():
|
||||||
return
|
return
|
||||||
self.saveField()
|
self.saveField()
|
||||||
f = self.mm.newField(name)
|
f = self.mm.new_field(name)
|
||||||
self.mm.add_field(self.model, f)
|
self.mm.add_field(self.model, f)
|
||||||
self.fillFields()
|
self.fillFields()
|
||||||
self.form.fieldList.setCurrentRow(len(self.model["flds"]) - 1)
|
self.form.fieldList.setCurrentRow(len(self.model["flds"]) - 1)
|
||||||
|
@ -145,7 +145,7 @@ class FieldDialog(QDialog):
|
||||||
if len(self.model["flds"]) < 2:
|
if len(self.model["flds"]) < 2:
|
||||||
showWarning(tr.fields_notes_require_at_least_one_field())
|
showWarning(tr.fields_notes_require_at_least_one_field())
|
||||||
return
|
return
|
||||||
count = self.mm.useCount(self.model)
|
count = self.mm.use_count(self.model)
|
||||||
c = tr.browsing_note_count(count=count)
|
c = tr.browsing_note_count(count=count)
|
||||||
if not askUser(tr.fields_delete_field_from(val=c)):
|
if not askUser(tr.fields_delete_field_from(val=c)):
|
||||||
return
|
return
|
||||||
|
|
|
@ -76,7 +76,7 @@ class ModelChooser(QHBoxLayout):
|
||||||
edit = QPushButton(tr.qt_misc_manage(), clicked=self.onEdit) # type: ignore
|
edit = QPushButton(tr.qt_misc_manage(), clicked=self.onEdit) # type: ignore
|
||||||
|
|
||||||
def nameFunc() -> List[str]:
|
def nameFunc() -> List[str]:
|
||||||
return sorted(self.deck.models.allNames())
|
return sorted(self.deck.models.all_names())
|
||||||
|
|
||||||
ret = StudyDeck(
|
ret = StudyDeck(
|
||||||
self.mw,
|
self.mw,
|
||||||
|
@ -92,7 +92,7 @@ class ModelChooser(QHBoxLayout):
|
||||||
)
|
)
|
||||||
if not ret.name:
|
if not ret.name:
|
||||||
return
|
return
|
||||||
m = self.deck.models.byName(ret.name)
|
m = self.deck.models.by_name(ret.name)
|
||||||
self.deck.conf["curModel"] = m["id"]
|
self.deck.conf["curModel"] = m["id"]
|
||||||
cdeck = self.deck.decks.current()
|
cdeck = self.deck.decks.current()
|
||||||
cdeck["mid"] = m["id"]
|
cdeck["mid"] = m["id"]
|
||||||
|
|
|
@ -99,7 +99,7 @@ class NotetypeChooser(QHBoxLayout):
|
||||||
qconnect(edit.clicked, self.onEdit)
|
qconnect(edit.clicked, self.onEdit)
|
||||||
|
|
||||||
def nameFunc() -> List[str]:
|
def nameFunc() -> List[str]:
|
||||||
return sorted(self.mw.col.models.allNames())
|
return sorted(self.mw.col.models.all_names())
|
||||||
|
|
||||||
ret = StudyDeck(
|
ret = StudyDeck(
|
||||||
self.mw,
|
self.mw,
|
||||||
|
@ -116,7 +116,7 @@ class NotetypeChooser(QHBoxLayout):
|
||||||
if not ret.name:
|
if not ret.name:
|
||||||
return
|
return
|
||||||
|
|
||||||
notetype = self.mw.col.models.byName(ret.name)
|
notetype = self.mw.col.models.by_name(ret.name)
|
||||||
if (id := notetype["id"]) != self._selected_notetype_id:
|
if (id := notetype["id"]) != self._selected_notetype_id:
|
||||||
self.selected_notetype_id = id
|
self.selected_notetype_id = id
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue