use keyword args for calls with more than one argument

This commit is contained in:
Damien Elmes 2020-05-24 09:05:48 +10:00
parent 89dde3aeb0
commit 38508c3ad7
21 changed files with 89 additions and 90 deletions

View file

@ -723,7 +723,7 @@ message GetChangedTagsOut {
message SetConfigJsonIn { message SetConfigJsonIn {
string key = 1; string key = 1;
bytes val = 2; bytes value_json = 2;
} }
enum StockNoteType { enum StockNoteType {

View file

@ -46,12 +46,12 @@ PROTODEPS := ../proto/backend.proto ../proto/fluent.proto
perl -i'' -pe 's/from fluent_pb2/from anki.fluent_pb2/' anki/backend_pb2.pyi perl -i'' -pe 's/from fluent_pb2/from anki.fluent_pb2/' anki/backend_pb2.pyi
perl -i'' -pe 's/import fluent_pb2/import anki.fluent_pb2/' anki/backend_pb2.py perl -i'' -pe 's/import fluent_pb2/import anki.fluent_pb2/' anki/backend_pb2.py
python tools/genbackend.py python tools/genbackend.py
python -m black anki/rsbackend.py python -m black -t py36 anki/rsbackend.py
@touch $@ @touch $@
.build/hooks: tools/genhooks.py tools/hookslib.py .build/hooks: tools/genhooks.py tools/hookslib.py
python tools/genhooks.py python tools/genhooks.py
python -m black anki/hooks.py python -m black -t py36 anki/hooks.py
@touch $@ @touch $@
BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps anki/buildinfo.py .build/py-proto .build/hooks BUILD_STEPS := .build/vernum .build/run-deps .build/dev-deps anki/buildinfo.py .build/py-proto .build/hooks

View file

@ -26,13 +26,7 @@ from anki.lang import _
from anki.media import MediaManager, media_paths_from_col_path from anki.media import MediaManager, media_paths_from_col_path
from anki.models import ModelManager from anki.models import ModelManager
from anki.notes import Note from anki.notes import Note
from anki.rsbackend import ( from anki.rsbackend import TR, DBError, FormatTimeSpanContext, RustBackend, pb
TR,
DBError,
FormatTimeSpanContext,
RustBackend,
pb,
)
from anki.sched import Scheduler as V1Scheduler from anki.sched import Scheduler as V1Scheduler
from anki.schedv2 import Scheduler as V2Scheduler from anki.schedv2 import Scheduler as V2Scheduler
from anki.tags import TagManager from anki.tags import TagManager
@ -86,7 +80,7 @@ class Collection:
seconds: float, seconds: float,
context: FormatTimeSpanContext = FormatTimeSpanContext.INTERVALS, context: FormatTimeSpanContext = FormatTimeSpanContext.INTERVALS,
) -> str: ) -> str:
return self.backend.format_timespan(seconds, context) return self.backend.format_timespan(seconds=seconds, context=context)
# Scheduler # Scheduler
########################################################################## ##########################################################################
@ -246,7 +240,12 @@ class Collection:
log_path = self.path.replace(".anki2", "2.log") log_path = self.path.replace(".anki2", "2.log")
# connect # connect
self.backend.open_collection(self.path, media_dir, media_db, log_path) self.backend.open_collection(
collection_path=self.path,
media_folder_path=media_dir,
media_db_path=media_db,
log_path=log_path,
)
self.db = DBProxy(weakref.proxy(self.backend)) self.db = DBProxy(weakref.proxy(self.backend))
self.db.begin() self.db.begin()
@ -317,7 +316,7 @@ class Collection:
return Note(self, self.models.current(forDeck)) return Note(self, self.models.current(forDeck))
def add_note(self, note: Note, deck_id: int) -> None: def add_note(self, note: Note, deck_id: int) -> None:
note.id = self.backend.add_note(note.to_backend_note(), deck_id) note.id = self.backend.add_note(note=note.to_backend_note(), deck_id=deck_id)
def addNote(self, note: Note) -> int: def addNote(self, note: Note) -> int:
self.add_note(note, note.model()["did"]) self.add_note(note, note.model()["did"])
@ -423,7 +422,7 @@ select id from notes where id in %s and id not in (select nid from cards)"""
mode = pb.SortOrder( mode = pb.SortOrder(
builtin=pb.BuiltinSearchOrder(kind=kind, reverse=reverse) builtin=pb.BuiltinSearchOrder(kind=kind, reverse=reverse)
) )
return self.backend.search_cards(query, mode) return self.backend.search_cards(search=query, order=mode)
def find_notes(self, query: str) -> Sequence[int]: def find_notes(self, query: str) -> Sequence[int]:
return self.backend.search_notes(query) return self.backend.search_notes(query)

View file

@ -37,7 +37,7 @@ class ConfigManager:
raise KeyError raise KeyError
def set(self, key: str, val: Any) -> None: def set(self, key: str, val: Any) -> None:
self.col.backend.set_config_json(key, to_json_bytes(val)) self.col.backend.set_config_json(key=key, value_json=to_json_bytes(val))
def remove(self, key: str) -> None: def remove(self, key: str) -> None:
self.col.backend.remove_config(key) self.col.backend.remove_config(key)

View file

@ -205,7 +205,7 @@ class DeckManager:
"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(
to_json_bytes(g), preserve_usn deck=to_json_bytes(g), preserve_usn_and_mtime=preserve_usn
) )
except anki.rsbackend.DeckIsFilteredError: except anki.rsbackend.DeckIsFilteredError:
raise DeckRenameError("deck was filtered") raise DeckRenameError("deck was filtered")
@ -284,7 +284,7 @@ class DeckManager:
def update_config(self, conf: Dict[str, Any], preserve_usn=False) -> None: def update_config(self, conf: Dict[str, Any], 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(
to_json_bytes(conf), preserve_usn config=to_json_bytes(conf), preserve_usn_and_mtime=preserve_usn
) )
def add_config( def add_config(

View file

@ -38,7 +38,14 @@ def findReplace(
fold: bool = True, fold: bool = True,
) -> int: ) -> int:
"Find and replace fields in a note. Returns changed note count." "Find and replace fields in a note. Returns changed note count."
return col.backend.find_and_replace(nids, src, dst, regex, not fold, field) return col.backend.find_and_replace(
nids=nids,
search=src,
replacement=dst,
regex=regex,
match_case=not fold,
field_name=field,
)
def fieldNamesForNotes(col: Collection, nids: List[int]) -> List[str]: def fieldNamesForNotes(col: Collection, nids: List[int]) -> List[str]:

View file

@ -86,7 +86,7 @@ def render_latex_returning_errors(
header = model["latexPre"] header = model["latexPre"]
footer = model["latexPost"] footer = model["latexPost"]
proto = col.backend.extract_latex(html, svg, expand_clozes) proto = col.backend.extract_latex(text=html, svg=svg, expand_clozes=expand_clozes)
out = ExtractedLatexOutput.from_proto(proto) out = ExtractedLatexOutput.from_proto(proto)
errors = [] errors = []
html = out.html html = out.html

View file

@ -96,7 +96,7 @@ class MediaManager:
"""Write the file to the media folder, renaming if not unique. """Write the file to the media folder, renaming if not unique.
Returns possibly-renamed filename.""" Returns possibly-renamed filename."""
return self.col.backend.add_media_file(desired_fname, data) return self.col.backend.add_media_file(desired_name=desired_fname, data=data)
def add_extension_based_on_mime(self, fname: str, content_type: str) -> str: def add_extension_based_on_mime(self, fname: str, content_type: str) -> str:
"If jpg or png mime, add .png/.jpg if missing extension." "If jpg or png mime, add .png/.jpg if missing extension."

View file

@ -223,7 +223,7 @@ class ModelManager:
self._remove_from_cache(m["id"]) self._remove_from_cache(m["id"])
self.ensureNameUnique(m) self.ensureNameUnique(m)
m["id"] = self.col.backend.add_or_update_notetype( m["id"] = self.col.backend.add_or_update_notetype(
to_json_bytes(m), preserve_usn_and_mtime=preserve_usn json=to_json_bytes(m), preserve_usn_and_mtime=preserve_usn
) )
self.setCurrent(m) self.setCurrent(m)
self._mutate_after_write(m) self._mutate_after_write(m)

View file

@ -15,19 +15,7 @@ import enum
import json import json
import os import os
from dataclasses import dataclass from dataclasses import dataclass
from typing import ( from typing import Any, Dict, List, Optional, Sequence, Union
Any,
Callable,
Dict,
Iterable,
List,
NewType,
NoReturn,
Optional,
Sequence,
Tuple,
Union,
)
import ankirspy # pytype: disable=import-error import ankirspy # pytype: disable=import-error
@ -37,9 +25,7 @@ from anki import hooks
from anki.dbproxy import Row as DBRow from anki.dbproxy import Row as DBRow
from anki.dbproxy import ValueForDB from anki.dbproxy import ValueForDB
from anki.fluent_pb2 import FluentString as TR from anki.fluent_pb2 import FluentString as TR
from anki.sound import AVTag, SoundOrVideoTag, TTSTag
from anki.types import assert_impossible_literal from anki.types import assert_impossible_literal
from anki.utils import intTime
assert ankirspy.buildhash() == anki.buildinfo.buildhash assert ankirspy.buildhash() == anki.buildinfo.buildhash
@ -54,19 +40,13 @@ StockNoteType = pb.StockNoteType
try: try:
import orjson import orjson
to_json_bytes = orjson.dumps
from_json_bytes = orjson.loads
except: except:
# add compat layer for 32 bit builds that can't use orjson # add compat layer for 32 bit builds that can't use orjson
print("reverting to stock json") to_json_bytes = lambda obj: json.dumps(obj).encode("utf8") # type: ignore
from_json_bytes = json.loads
class orjson: # type: ignore
def dumps(obj: Any) -> bytes:
return json.dumps(obj).encode("utf8")
loads = json.loads
to_json_bytes = orjson.dumps
from_json_bytes = orjson.loads
class Interrupted(Exception): class Interrupted(Exception):
@ -223,7 +203,7 @@ class RustBackend:
return self._db_command(dict(kind="rollback")) return self._db_command(dict(kind="rollback"))
def _db_command(self, input: Dict[str, Any]) -> Any: def _db_command(self, input: Dict[str, Any]) -> Any:
return orjson.loads(self._backend.db_command(orjson.dumps(input))) return from_json_bytes(self._backend.db_command(to_json_bytes(input)))
def translate(self, key: TR, **kwargs: Union[str, int, float]) -> str: def translate(self, key: TR, **kwargs: Union[str, int, float]) -> str:
return self.translate_string(translate_string_in(key, **kwargs)) return self.translate_string(translate_string_in(key, **kwargs))
@ -236,7 +216,7 @@ class RustBackend:
print( print(
"please use col.format_timespan() instead of col.backend.format_time_span()" "please use col.format_timespan() instead of col.backend.format_time_span()"
) )
return self.format_timespan(seconds, context) return self.format_timespan(seconds=seconds, context=context)
def _run_command(self, method: int, input: Any) -> bytes: def _run_command(self, method: int, input: Any) -> bytes:
input_bytes = input.SerializeToString() input_bytes = input.SerializeToString()
@ -253,14 +233,14 @@ class RustBackend:
# @@AUTOGEN@@ # @@AUTOGEN@@
def extract_av_tags(self, text: str, question_side: bool) -> pb.ExtractAVTagsOut: def extract_av_tags(self, *, text: str, question_side: bool) -> pb.ExtractAVTagsOut:
input = pb.ExtractAVTagsIn(text=text, question_side=question_side) input = pb.ExtractAVTagsIn(text=text, question_side=question_side)
output = pb.ExtractAVTagsOut() output = pb.ExtractAVTagsOut()
output.ParseFromString(self._run_command(1, input)) output.ParseFromString(self._run_command(1, input))
return output return output
def extract_latex( def extract_latex(
self, text: str, svg: bool, expand_clozes: bool self, *, text: str, svg: bool, expand_clozes: bool
) -> pb.ExtractLatexOut: ) -> pb.ExtractLatexOut:
input = pb.ExtractLatexIn(text=text, svg=svg, expand_clozes=expand_clozes) input = pb.ExtractLatexIn(text=text, svg=svg, expand_clozes=expand_clozes)
output = pb.ExtractLatexOut() output = pb.ExtractLatexOut()
@ -273,14 +253,14 @@ class RustBackend:
output.ParseFromString(self._run_command(3, input)) output.ParseFromString(self._run_command(3, input))
return output return output
def render_existing_card(self, card_id: int, browser: bool) -> pb.RenderCardOut: def render_existing_card(self, *, card_id: int, browser: bool) -> pb.RenderCardOut:
input = pb.RenderExistingCardIn(card_id=card_id, browser=browser) input = pb.RenderExistingCardIn(card_id=card_id, browser=browser)
output = pb.RenderCardOut() output = pb.RenderCardOut()
output.ParseFromString(self._run_command(4, input)) output.ParseFromString(self._run_command(4, input))
return output return output
def render_uncommitted_card( def render_uncommitted_card(
self, note: pb.Note, card_ord: int, template: bytes, fill_empty: bool self, *, note: pb.Note, card_ord: int, template: bytes, fill_empty: bool
) -> pb.RenderCardOut: ) -> pb.RenderCardOut:
input = pb.RenderUncommittedCardIn( input = pb.RenderUncommittedCardIn(
note=note, card_ord=card_ord, template=template, fill_empty=fill_empty note=note, card_ord=card_ord, template=template, fill_empty=fill_empty
@ -295,7 +275,7 @@ class RustBackend:
output.ParseFromString(self._run_command(6, input)) output.ParseFromString(self._run_command(6, input))
return output.val return output.val
def search_cards(self, search: str, order: pb.SortOrder) -> Sequence[int]: def search_cards(self, *, search: str, order: pb.SortOrder) -> Sequence[int]:
input = pb.SearchCardsIn(search=search, order=order) input = pb.SearchCardsIn(search=search, order=order)
output = pb.SearchCardsOut() output = pb.SearchCardsOut()
output.ParseFromString(self._run_command(7, input)) output.ParseFromString(self._run_command(7, input))
@ -309,6 +289,7 @@ class RustBackend:
def find_and_replace( def find_and_replace(
self, self,
*,
nids: Sequence[int], nids: Sequence[int],
search: str, search: str,
replacement: str, replacement: str,
@ -346,13 +327,13 @@ class RustBackend:
output.ParseFromString(self._run_command(12, input)) output.ParseFromString(self._run_command(12, input))
return output return output
def studied_today(self, cards: int, seconds: float) -> str: def studied_today(self, *, cards: int, seconds: float) -> str:
input = pb.StudiedTodayIn(cards=cards, seconds=seconds) input = pb.StudiedTodayIn(cards=cards, seconds=seconds)
output = pb.String() output = pb.String()
output.ParseFromString(self._run_command(13, input)) output.ParseFromString(self._run_command(13, input))
return output.val return output.val
def congrats_learn_message(self, next_due: float, remaining: int) -> str: def congrats_learn_message(self, *, next_due: float, remaining: int) -> str:
input = pb.CongratsLearnMessageIn(next_due=next_due, remaining=remaining) input = pb.CongratsLearnMessageIn(next_due=next_due, remaining=remaining)
output = pb.String() output = pb.String()
output.ParseFromString(self._run_command(14, input)) output.ParseFromString(self._run_command(14, input))
@ -370,7 +351,7 @@ class RustBackend:
output.ParseFromString(self._run_command(16, input)) output.ParseFromString(self._run_command(16, input))
return output return output
def add_media_file(self, desired_name: str, data: bytes) -> str: def add_media_file(self, *, desired_name: str, data: bytes) -> str:
input = pb.AddMediaFileIn(desired_name=desired_name, data=data) input = pb.AddMediaFileIn(desired_name=desired_name, data=data)
output = pb.String() output = pb.String()
output.ParseFromString(self._run_command(17, input)) output.ParseFromString(self._run_command(17, input))
@ -389,7 +370,7 @@ class RustBackend:
return output return output
def add_or_update_deck_legacy( def add_or_update_deck_legacy(
self, deck: bytes, preserve_usn_and_mtime: bool self, *, deck: bytes, preserve_usn_and_mtime: bool
) -> int: ) -> int:
input = pb.AddOrUpdateDeckLegacyIn( input = pb.AddOrUpdateDeckLegacyIn(
deck=deck, preserve_usn_and_mtime=preserve_usn_and_mtime deck=deck, preserve_usn_and_mtime=preserve_usn_and_mtime
@ -398,7 +379,7 @@ class RustBackend:
output.ParseFromString(self._run_command(20, input)) output.ParseFromString(self._run_command(20, input))
return output.did return output.did
def deck_tree(self, include_counts: bool, top_deck_id: int) -> pb.DeckTreeNode: def deck_tree(self, *, include_counts: bool, top_deck_id: int) -> pb.DeckTreeNode:
input = pb.DeckTreeIn(include_counts=include_counts, top_deck_id=top_deck_id) input = pb.DeckTreeIn(include_counts=include_counts, top_deck_id=top_deck_id)
output = pb.DeckTreeNode() output = pb.DeckTreeNode()
output.ParseFromString(self._run_command(21, input)) output.ParseFromString(self._run_command(21, input))
@ -429,7 +410,7 @@ class RustBackend:
return output.json return output.json
def get_deck_names( def get_deck_names(
self, skip_empty_default: bool, include_filtered: bool self, *, skip_empty_default: bool, include_filtered: bool
) -> Sequence[pb.DeckNameID]: ) -> Sequence[pb.DeckNameID]:
input = pb.GetDeckNamesIn( input = pb.GetDeckNamesIn(
skip_empty_default=skip_empty_default, include_filtered=include_filtered skip_empty_default=skip_empty_default, include_filtered=include_filtered
@ -451,7 +432,7 @@ class RustBackend:
return output return output
def add_or_update_deck_config_legacy( def add_or_update_deck_config_legacy(
self, config: bytes, preserve_usn_and_mtime: bool self, *, config: bytes, preserve_usn_and_mtime: bool
) -> int: ) -> int:
input = pb.AddOrUpdateDeckConfigLegacyIn( input = pb.AddOrUpdateDeckConfigLegacyIn(
config=config, preserve_usn_and_mtime=preserve_usn_and_mtime config=config, preserve_usn_and_mtime=preserve_usn_and_mtime
@ -506,7 +487,7 @@ class RustBackend:
output.ParseFromString(self._run_command(37, input)) output.ParseFromString(self._run_command(37, input))
return output return output
def add_note(self, note: pb.Note, deck_id: int) -> int: def add_note(self, *, note: pb.Note, deck_id: int) -> int:
input = pb.AddNoteIn(note=note, deck_id=deck_id) input = pb.AddNoteIn(note=note, deck_id=deck_id)
output = pb.NoteID() output = pb.NoteID()
output.ParseFromString(self._run_command(38, input)) output.ParseFromString(self._run_command(38, input))
@ -523,14 +504,14 @@ class RustBackend:
output.ParseFromString(self._run_command(40, input)) output.ParseFromString(self._run_command(40, input))
return output return output
def add_note_tags(self, nids: Sequence[int], tags: str) -> int: def add_note_tags(self, *, nids: Sequence[int], tags: str) -> int:
input = pb.AddNoteTagsIn(nids=nids, tags=tags) input = pb.AddNoteTagsIn(nids=nids, tags=tags)
output = pb.UInt32() output = pb.UInt32()
output.ParseFromString(self._run_command(41, input)) output.ParseFromString(self._run_command(41, input))
return output.val return output.val
def update_note_tags( def update_note_tags(
self, nids: Sequence[int], tags: str, replacement: str, regex: bool self, *, nids: Sequence[int], tags: str, replacement: str, regex: bool
) -> int: ) -> int:
input = pb.UpdateNoteTagsIn( input = pb.UpdateNoteTagsIn(
nids=nids, tags=tags, replacement=replacement, regex=regex nids=nids, tags=tags, replacement=replacement, regex=regex
@ -545,7 +526,7 @@ class RustBackend:
return output.numbers return output.numbers
def after_note_updates( def after_note_updates(
self, nids: Sequence[int], mark_notes_modified: bool, generate_cards: bool self, *, nids: Sequence[int], mark_notes_modified: bool, generate_cards: bool
) -> pb.Empty: ) -> pb.Empty:
input = pb.AfterNoteUpdatesIn( input = pb.AfterNoteUpdatesIn(
nids=nids, nids=nids,
@ -562,7 +543,9 @@ class RustBackend:
output.ParseFromString(self._run_command(45, input)) output.ParseFromString(self._run_command(45, input))
return output.fields return output.fields
def add_or_update_notetype(self, json: bytes, preserve_usn_and_mtime: bool) -> int: def add_or_update_notetype(
self, *, json: bytes, preserve_usn_and_mtime: bool
) -> int:
input = pb.AddOrUpdateNotetypeIn( input = pb.AddOrUpdateNotetypeIn(
json=json, preserve_usn_and_mtime=preserve_usn_and_mtime json=json, preserve_usn_and_mtime=preserve_usn_and_mtime
) )
@ -608,6 +591,7 @@ class RustBackend:
def open_collection( def open_collection(
self, self,
*,
collection_path: str, collection_path: str,
media_folder_path: str, media_folder_path: str,
media_db_path: str, media_db_path: str,
@ -635,7 +619,7 @@ class RustBackend:
output.ParseFromString(self._run_command(55, input)) output.ParseFromString(self._run_command(55, input))
return output.problems return output.problems
def sync_media(self, hkey: str, endpoint: str) -> pb.Empty: def sync_media(self, *, hkey: str, endpoint: str) -> pb.Empty:
input = pb.SyncMediaIn(hkey=hkey, endpoint=endpoint) input = pb.SyncMediaIn(hkey=hkey, endpoint=endpoint)
output = pb.Empty() output = pb.Empty()
output.ParseFromString(self._run_command(56, input)) output.ParseFromString(self._run_command(56, input))
@ -659,7 +643,7 @@ class RustBackend:
return output.val return output.val
def format_timespan( def format_timespan(
self, seconds: float, context: pb.FormatTimespanIn.Context self, *, seconds: float, context: pb.FormatTimespanIn.Context
) -> str: ) -> str:
input = pb.FormatTimespanIn(seconds=seconds, context=context) input = pb.FormatTimespanIn(seconds=seconds, context=context)
output = pb.String() output = pb.String()
@ -667,7 +651,7 @@ class RustBackend:
return output.val return output.val
def register_tags( def register_tags(
self, tags: str, preserve_usn: bool, usn: int, clear_first: bool self, *, tags: str, preserve_usn: bool, usn: int, clear_first: bool
) -> bool: ) -> bool:
input = pb.RegisterTagsIn( input = pb.RegisterTagsIn(
tags=tags, preserve_usn=preserve_usn, usn=usn, clear_first=clear_first tags=tags, preserve_usn=preserve_usn, usn=usn, clear_first=clear_first
@ -694,8 +678,8 @@ class RustBackend:
output.ParseFromString(self._run_command(64, input)) output.ParseFromString(self._run_command(64, input))
return output.json return output.json
def set_config_json(self, key: str, val: bytes) -> pb.Empty: def set_config_json(self, *, key: str, value_json: bytes) -> pb.Empty:
input = pb.SetConfigJsonIn(key=key, val=val) input = pb.SetConfigJsonIn(key=key, value_json=value_json)
output = pb.Empty() output = pb.Empty()
output.ParseFromString(self._run_command(65, input)) output.ParseFromString(self._run_command(65, input))
return output return output

View file

@ -1270,7 +1270,9 @@ from cards where did in {dids} and queue = {QUEUE_TYPE_LRN}
remaining = remaining or 0 remaining = remaining or 0
if next and next < self.dayCutoff: if next and next < self.dayCutoff:
next -= intTime() - self.col.conf["collapseTime"] next -= intTime() - self.col.conf["collapseTime"]
return self.col.backend.congrats_learn_message(abs(next), remaining) return self.col.backend.congrats_learn_message(
next_due=abs(next), remaining=remaining
)
else: else:
return "" return ""

View file

@ -177,7 +177,7 @@ from revlog where id > ? """
return "<b>" + str(s) + "</b>" return "<b>" + str(s) + "</b>"
if cards: if cards:
b += self.col.backend.studied_today(cards, float(thetime)) b += self.col.backend.studied_today(cards=cards, seconds=float(thetime))
# again/pass count # again/pass count
b += "<br>" + _("Again count: %s") % bold(failed) b += "<br>" + _("Again count: %s") % bold(failed)
if cards: if cards:

View file

@ -83,14 +83,16 @@ class TagManager:
def bulk_add(self, nids: List[int], tags: str) -> int: def bulk_add(self, nids: List[int], tags: str) -> int:
"""Add space-separate tags to provided notes, returning changed count.""" """Add space-separate tags to provided notes, returning changed count."""
return self.col.backend.add_note_tags(nids, tags) return self.col.backend.add_note_tags(nids=nids, tags=tags)
def bulk_update( def bulk_update(
self, nids: List[int], tags: str, replacement: str, regex: bool self, nids: List[int], tags: str, replacement: str, regex: bool
) -> int: ) -> int:
"""Replace space-separated tags, returning changed count. """Replace space-separated tags, returning changed count.
Tags replaced with an empty string will be removed.""" Tags replaced with an empty string will be removed."""
return self.col.backend.update_note_tags(nids, tags, replacement, regex) return self.col.backend.update_note_tags(
nids=nids, tags=tags, replacement=replacement, regex=regex
)
# legacy routines # legacy routines

View file

@ -215,10 +215,10 @@ class TemplateRenderContext:
) )
qtext = apply_custom_filters(partial.qnodes, self, front_side=None) qtext = apply_custom_filters(partial.qnodes, self, front_side=None)
qout = self.col().backend.extract_av_tags(qtext, True) qout = self.col().backend.extract_av_tags(text=qtext, question_side=True)
atext = apply_custom_filters(partial.anodes, self, front_side=qtext) atext = apply_custom_filters(partial.anodes, self, front_side=qtext)
aout = self.col().backend.extract_av_tags(atext, False) aout = self.col().backend.extract_av_tags(text=atext, question_side=False)
output = TemplateRenderOutput( output = TemplateRenderOutput(
question_text=qout.text, question_text=qout.text,
@ -237,14 +237,16 @@ class TemplateRenderContext:
if self._template: if self._template:
# card layout screen # card layout screen
out = self._col.backend.render_uncommitted_card( out = self._col.backend.render_uncommitted_card(
self._note.to_backend_note(), note=self._note.to_backend_note(),
self._card.ord, card_ord=self._card.ord,
to_json_bytes(self._template), template=to_json_bytes(self._template),
self._fill_empty, fill_empty=self._fill_empty,
) )
else: else:
# existing card (eg study mode) # existing card (eg study mode)
out = self._col.backend.render_existing_card(self._card.id, self._browser) out = self._col.backend.render_existing_card(
card_id=self._card.id, browser=self._browser
)
return PartiallyRenderedCard.from_proto(out) return PartiallyRenderedCard.from_proto(out)

View file

@ -80,7 +80,10 @@ def fix_snakecase(name):
def get_input_args(msg): def get_input_args(msg):
fields = sorted(msg.fields, key=lambda x: x.number) fields = sorted(msg.fields, key=lambda x: x.number)
return ", ".join(["self"] + [f"{f.name}: {python_type(f)}" for f in fields]) self_star = ["self"]
if len(fields) >= 2:
self_star.append("*")
return ", ".join(self_star + [f"{f.name}: {python_type(f)}" for f in fields])
def get_input_assign(msg): def get_input_assign(msg):

View file

@ -304,7 +304,7 @@ class CardLayout(QDialog):
self.preview_web.set_bridge_command(self._on_bridge_cmd, self) self.preview_web.set_bridge_command(self._on_bridge_cmd, self)
if self._isCloze(): if self._isCloze():
nums = self.note.cloze_numbers_in_fields() nums = list(self.note.cloze_numbers_in_fields())
if self.ord + 1 not in nums: if self.ord + 1 not in nums:
# current card is empty # current card is empty
nums.append(self.ord + 1) nums.append(self.ord + 1)

View file

@ -145,7 +145,7 @@ where id > ?""",
) )
cards = cards or 0 cards = cards or 0
thetime = thetime or 0 thetime = thetime or 0
buf = self.mw.col.backend.studied_today(cards, float(thetime)) buf = self.mw.col.backend.studied_today(cards=cards, seconds=float(thetime))
return buf return buf
def _renderDeckTree(self, top: DeckTreeNode) -> str: def _renderDeckTree(self, top: DeckTreeNode) -> str:

View file

@ -25,7 +25,7 @@ def bodyClass(col, card) -> str:
def allSounds(text) -> List: def allSounds(text) -> List:
print("allSounds() deprecated") print("allSounds() deprecated")
out = aqt.mw.col.backend.extract_av_tags(text, True) out = aqt.mw.col.backend.extract_av_tags(text=text, question_side=True)
return [ return [
x.filename x.filename
for x in av_tags_to_native(out.av_tags) for x in av_tags_to_native(out.av_tags)

View file

@ -74,7 +74,7 @@ class MediaSyncer:
gui_hooks.media_sync_did_start_or_stop(True) gui_hooks.media_sync_did_start_or_stop(True)
def run() -> None: def run() -> None:
self.mw.col.backend.sync_media(hkey, self._endpoint()) self.mw.col.backend.sync_media(hkey=hkey, endpoint=self._endpoint())
self.mw.taskman.run_in_background(run, self._on_finished) self.mw.taskman.run_in_background(run, self._on_finished)

View file

@ -89,7 +89,7 @@ class Preferences(QDialog):
f.useCurrent.setCurrentIndex(int(not qc.get("addToCur", True))) f.useCurrent.setCurrentIndex(int(not qc.get("addToCur", True)))
s = self.prefs.sched s = self.prefs
f.lrnCutoff.setValue(s.learn_ahead_secs / 60.0) f.lrnCutoff.setValue(s.learn_ahead_secs / 60.0)
f.timeLimit.setValue(s.time_limit_secs / 60.0) f.timeLimit.setValue(s.time_limit_secs / 60.0)
f.showEstimates.setChecked(s.show_intervals_on_buttons) f.showEstimates.setChecked(s.show_intervals_on_buttons)
@ -122,7 +122,7 @@ class Preferences(QDialog):
qc = d.conf qc = d.conf
qc["addToCur"] = not f.useCurrent.currentIndex() qc["addToCur"] = not f.useCurrent.currentIndex()
s = self.prefs.sched s = self.prefs
s.show_remaining_due_counts = f.showProgress.isChecked() s.show_remaining_due_counts = f.showProgress.isChecked()
s.show_intervals_on_buttons = f.showEstimates.isChecked() s.show_intervals_on_buttons = f.showEstimates.isChecked()
s.new_review_mix = f.newSpread.currentIndex() s.new_review_mix = f.newSpread.currentIndex()

View file

@ -1028,7 +1028,7 @@ impl BackendService for Backend {
self.with_col(|col| { self.with_col(|col| {
col.transact(None, |col| { col.transact(None, |col| {
// ensure it's a well-formed object // ensure it's a well-formed object
let val: JsonValue = serde_json::from_slice(&input.val)?; let val: JsonValue = serde_json::from_slice(&input.value_json)?;
col.set_config(input.key.as_str(), &val) col.set_config(input.key.as_str(), &val)
}) })
}) })