mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
migrate decks and dconf methods
This commit is contained in:
parent
081a61a438
commit
7550e6241c
4 changed files with 415 additions and 380 deletions
|
@ -33,28 +33,63 @@ message Bytes {
|
||||||
bytes val = 1;
|
bytes val = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message Bool {
|
||||||
|
bool val = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// New style RPC definitions
|
// New style RPC definitions
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
service BackendService {
|
service BackendService {
|
||||||
rpc RenderExistingCard (RenderExistingCardIn) returns (RenderCardOut);
|
// card rendering
|
||||||
rpc RenderUncommittedCard (RenderUncommittedCardIn) returns (RenderCardOut);
|
|
||||||
rpc SchedTimingToday (Empty) returns (SchedTimingTodayOut);
|
|
||||||
rpc DeckTree (DeckTreeIn) returns (DeckTreeNode);
|
|
||||||
rpc SearchCards (SearchCardsIn) returns (SearchCardsOut);
|
|
||||||
rpc SearchNotes (SearchNotesIn) returns (SearchNotesOut);
|
|
||||||
rpc CheckMedia (Empty) returns (CheckMediaOut);
|
|
||||||
rpc LocalMinutesWest (Int64) returns (Int32);
|
|
||||||
rpc StripAVTags (String) returns (String);
|
|
||||||
rpc ExtractAVTags (ExtractAVTagsIn) returns (ExtractAVTagsOut);
|
rpc ExtractAVTags (ExtractAVTagsIn) returns (ExtractAVTagsOut);
|
||||||
rpc ExtractLatex (ExtractLatexIn) returns (ExtractLatexOut);
|
rpc ExtractLatex (ExtractLatexIn) returns (ExtractLatexOut);
|
||||||
rpc DeckTreeLegacy (Empty) returns (Bytes);
|
|
||||||
rpc CheckDatabase (Empty) returns (CheckDatabaseOut);
|
|
||||||
rpc GetEmptyCards (Empty) returns (EmptyCardsReport);
|
rpc GetEmptyCards (Empty) returns (EmptyCardsReport);
|
||||||
|
rpc RenderExistingCard (RenderExistingCardIn) returns (RenderCardOut);
|
||||||
|
rpc RenderUncommittedCard (RenderUncommittedCardIn) returns (RenderCardOut);
|
||||||
|
rpc StripAVTags (String) returns (String);
|
||||||
|
|
||||||
|
// searching
|
||||||
|
|
||||||
|
rpc SearchCards (SearchCardsIn) returns (SearchCardsOut);
|
||||||
|
rpc SearchNotes (SearchNotesIn) returns (SearchNotesOut);
|
||||||
|
|
||||||
|
// scheduling
|
||||||
|
|
||||||
|
rpc LocalMinutesWest (Int64) returns (Int32);
|
||||||
|
rpc SchedTimingToday (Empty) returns (SchedTimingTodayOut);
|
||||||
|
|
||||||
|
// media
|
||||||
|
|
||||||
|
rpc CheckMedia (Empty) returns (CheckMediaOut);
|
||||||
rpc SyncMedia (SyncMediaIn) returns (Empty);
|
rpc SyncMedia (SyncMediaIn) returns (Empty);
|
||||||
rpc TrashMediaFiles (TrashMediaFilesIn) returns (Empty);
|
rpc TrashMediaFiles (TrashMediaFilesIn) returns (Empty);
|
||||||
rpc GetDeckLegacy (Int64) returns (Bytes);
|
|
||||||
|
// decks
|
||||||
|
|
||||||
|
rpc AddOrUpdateDeckLegacy (AddOrUpdateDeckLegacyIn) returns (Int64);
|
||||||
|
rpc DeckTree (DeckTreeIn) returns (DeckTreeNode);
|
||||||
|
rpc DeckTreeLegacy (Empty) returns (Bytes);
|
||||||
|
rpc GetAllDecksLegacy (Empty) returns (Bytes);
|
||||||
rpc GetDeckIDByName (String) returns (Int64);
|
rpc GetDeckIDByName (String) returns (Int64);
|
||||||
|
rpc GetDeckLegacy (Int64) returns (Bytes);
|
||||||
|
rpc GetDeckNames (GetDeckNamesIn) returns (DeckNames);
|
||||||
|
rpc NewDeckLegacy (Bool) returns (Bytes);
|
||||||
|
rpc RemoveDeck (Int64) returns (Empty);
|
||||||
|
|
||||||
|
// deck config
|
||||||
|
|
||||||
|
rpc AddOrUpdateDeckConfigLegacy (AddOrUpdateDeckConfigLegacyIn) returns (Int64);
|
||||||
|
rpc AllDeckConfigLegacy (Empty) returns (Bytes);
|
||||||
|
rpc GetDeckConfigLegacy (Int64) returns (Bytes);
|
||||||
|
rpc NewDeckConfigLegacy (Empty) returns (Bytes);
|
||||||
|
rpc RemoveDeckConfig (Int64) returns (Empty);
|
||||||
|
|
||||||
|
// misc
|
||||||
|
|
||||||
|
rpc CheckDatabase (Empty) returns (CheckDatabaseOut);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protobuf stored in .anki2 files
|
// Protobuf stored in .anki2 files
|
||||||
|
@ -312,11 +347,6 @@ message BackendInput {
|
||||||
int64 get_card = 38;
|
int64 get_card = 38;
|
||||||
Card update_card = 39;
|
Card update_card = 39;
|
||||||
Card add_card = 40;
|
Card add_card = 40;
|
||||||
int64 get_deck_config = 41;
|
|
||||||
AddOrUpdateDeckConfigIn add_or_update_deck_config = 42;
|
|
||||||
Empty all_deck_config = 43;
|
|
||||||
Empty new_deck_config = 44;
|
|
||||||
int64 remove_deck_config = 45;
|
|
||||||
Empty abort_media_sync = 46;
|
Empty abort_media_sync = 46;
|
||||||
Empty before_upload = 47;
|
Empty before_upload = 47;
|
||||||
RegisterTagsIn register_tags = 48;
|
RegisterTagsIn register_tags = 48;
|
||||||
|
@ -328,7 +358,6 @@ message BackendInput {
|
||||||
Empty get_all_config = 55;
|
Empty get_all_config = 55;
|
||||||
int32 get_changed_notetypes = 56;
|
int32 get_changed_notetypes = 56;
|
||||||
AddOrUpdateNotetypeIn add_or_update_notetype = 57;
|
AddOrUpdateNotetypeIn add_or_update_notetype = 57;
|
||||||
Empty get_all_decks = 58;
|
|
||||||
StockNoteType get_stock_notetype_legacy = 60;
|
StockNoteType get_stock_notetype_legacy = 60;
|
||||||
int64 get_notetype_legacy = 61;
|
int64 get_notetype_legacy = 61;
|
||||||
Empty get_notetype_names = 62;
|
Empty get_notetype_names = 62;
|
||||||
|
@ -339,10 +368,6 @@ message BackendInput {
|
||||||
AddNoteIn add_note = 67;
|
AddNoteIn add_note = 67;
|
||||||
Note update_note = 68;
|
Note update_note = 68;
|
||||||
int64 get_note = 69;
|
int64 get_note = 69;
|
||||||
GetDeckNamesIn get_deck_names = 73;
|
|
||||||
AddOrUpdateDeckLegacyIn add_or_update_deck_legacy = 74;
|
|
||||||
bool new_deck_legacy = 75;
|
|
||||||
int64 remove_deck = 76;
|
|
||||||
FieldNamesForNotesIn field_names_for_notes = 78;
|
FieldNamesForNotesIn field_names_for_notes = 78;
|
||||||
FindAndReplaceIn find_and_replace = 79;
|
FindAndReplaceIn find_and_replace = 79;
|
||||||
AfterNoteUpdatesIn after_note_updates = 80;
|
AfterNoteUpdatesIn after_note_updates = 80;
|
||||||
|
@ -374,11 +399,6 @@ message BackendOutput {
|
||||||
GetCardOut get_card = 38;
|
GetCardOut get_card = 38;
|
||||||
Empty update_card = 39;
|
Empty update_card = 39;
|
||||||
int64 add_card = 40;
|
int64 add_card = 40;
|
||||||
bytes get_deck_config = 41;
|
|
||||||
int64 add_or_update_deck_config = 42;
|
|
||||||
bytes all_deck_config = 43;
|
|
||||||
bytes new_deck_config = 44;
|
|
||||||
Empty remove_deck_config = 45;
|
|
||||||
Empty before_upload = 47;
|
Empty before_upload = 47;
|
||||||
bool register_tags = 48;
|
bool register_tags = 48;
|
||||||
AllTagsOut all_tags = 50;
|
AllTagsOut all_tags = 50;
|
||||||
|
@ -389,7 +409,6 @@ message BackendOutput {
|
||||||
bytes get_all_config = 55;
|
bytes get_all_config = 55;
|
||||||
bytes get_changed_notetypes = 56;
|
bytes get_changed_notetypes = 56;
|
||||||
int64 add_or_update_notetype = 57;
|
int64 add_or_update_notetype = 57;
|
||||||
bytes get_all_decks = 58;
|
|
||||||
bytes get_notetype_legacy = 61;
|
bytes get_notetype_legacy = 61;
|
||||||
NoteTypeNames get_notetype_names = 62;
|
NoteTypeNames get_notetype_names = 62;
|
||||||
NoteTypeUseCounts get_notetype_names_and_counts = 63;
|
NoteTypeUseCounts get_notetype_names_and_counts = 63;
|
||||||
|
@ -399,10 +418,6 @@ message BackendOutput {
|
||||||
int64 add_note = 67;
|
int64 add_note = 67;
|
||||||
Empty update_note = 68;
|
Empty update_note = 68;
|
||||||
Note get_note = 69;
|
Note get_note = 69;
|
||||||
DeckNames get_deck_names = 73;
|
|
||||||
int64 add_or_update_deck_legacy = 74;
|
|
||||||
bytes new_deck_legacy = 75;
|
|
||||||
Empty remove_deck = 76;
|
|
||||||
FieldNamesForNotesOut field_names_for_notes = 78;
|
FieldNamesForNotesOut field_names_for_notes = 78;
|
||||||
uint32 find_and_replace = 79;
|
uint32 find_and_replace = 79;
|
||||||
Empty after_note_updates = 80;
|
Empty after_note_updates = 80;
|
||||||
|
@ -692,7 +707,7 @@ message CloseCollectionIn {
|
||||||
bool downgrade_to_schema11 = 1;
|
bool downgrade_to_schema11 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AddOrUpdateDeckConfigIn {
|
message AddOrUpdateDeckConfigLegacyIn {
|
||||||
bytes config = 1;
|
bytes config = 1;
|
||||||
bool preserve_usn_and_mtime = 2;
|
bool preserve_usn_and_mtime = 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import anki.backend_pb2 as pb
|
||||||
from anki.consts import *
|
from anki.consts import *
|
||||||
from anki.errors import DeckRenameError
|
from anki.errors import DeckRenameError
|
||||||
from anki.lang import _
|
from anki.lang import _
|
||||||
from anki.rsbackend import DeckTreeNode, NotFoundError, from_json_bytes
|
from anki.rsbackend import DeckTreeNode, NotFoundError, from_json_bytes, to_json_bytes
|
||||||
from anki.utils import ids2str, intTime
|
from anki.utils import ids2str, intTime
|
||||||
|
|
||||||
# legacy code may pass this in as the type argument to .id()
|
# legacy code may pass this in as the type argument to .id()
|
||||||
|
@ -108,8 +108,8 @@ class DeckManager:
|
||||||
self, skip_empty_default=False, include_filtered=True
|
self, skip_empty_default=False, include_filtered=True
|
||||||
) -> Sequence[pb.DeckNameID]:
|
) -> Sequence[pb.DeckNameID]:
|
||||||
"A sorted sequence of deck names and IDs."
|
"A sorted sequence of deck names and IDs."
|
||||||
return self.col.backend.get_deck_names_and_ids(
|
return self.col.backend.get_deck_names(
|
||||||
skip_empty_default, include_filtered
|
skip_empty_default=skip_empty_default, include_filtered=include_filtered
|
||||||
)
|
)
|
||||||
|
|
||||||
def id_for_name(self, name: str) -> Optional[int]:
|
def id_for_name(self, name: str) -> Optional[int]:
|
||||||
|
@ -125,10 +125,10 @@ class DeckManager:
|
||||||
return not self.get_legacy(int(id))
|
return not self.get_legacy(int(id))
|
||||||
|
|
||||||
def get_all_legacy(self) -> List[Dict]:
|
def get_all_legacy(self) -> List[Dict]:
|
||||||
return list(self.col.backend.get_all_decks().values())
|
return list(from_json_bytes(self.col.backend.get_all_decks_legacy()).values())
|
||||||
|
|
||||||
def new_deck_legacy(self, filtered: bool) -> Dict:
|
def new_deck_legacy(self, filtered: bool) -> Dict:
|
||||||
return self.col.backend.new_deck_legacy(filtered)
|
return from_json_bytes(self.col.backend.new_deck_legacy(filtered))
|
||||||
|
|
||||||
def deck_tree(self) -> pb.DeckTreeNode:
|
def deck_tree(self) -> pb.DeckTreeNode:
|
||||||
return self.col.backend.deck_tree(include_counts=False, top_deck_id=0)
|
return self.col.backend.deck_tree(include_counts=False, top_deck_id=0)
|
||||||
|
@ -201,11 +201,11 @@ class DeckManager:
|
||||||
def update(self, g: Dict[str, Any], preserve_usn=True) -> None:
|
def update(self, g: Dict[str, Any], preserve_usn=True) -> None:
|
||||||
"Add or update an existing deck. Used for syncing and merging."
|
"Add or update an existing deck. Used for syncing and merging."
|
||||||
try:
|
try:
|
||||||
self.col.backend.add_or_update_deck_legacy(g, preserve_usn)
|
g["id"] = self.col.backend.add_or_update_deck_legacy(
|
||||||
|
to_json_bytes(g), preserve_usn
|
||||||
|
)
|
||||||
except anki.rsbackend.DeckIsFilteredError:
|
except anki.rsbackend.DeckIsFilteredError:
|
||||||
raise DeckRenameError("deck was filtered")
|
raise DeckRenameError("deck was filtered")
|
||||||
except anki.rsbackend.ExistsError:
|
|
||||||
raise DeckRenameError("deck already exists")
|
|
||||||
|
|
||||||
def rename(self, g: Dict[str, Any], newName: str) -> None:
|
def rename(self, g: Dict[str, Any], newName: str) -> None:
|
||||||
"Rename deck prefix to NAME if not exists. Updates children."
|
"Rename deck prefix to NAME if not exists. Updates children."
|
||||||
|
@ -257,7 +257,7 @@ class DeckManager:
|
||||||
|
|
||||||
def all_config(self) -> List:
|
def all_config(self) -> List:
|
||||||
"A list of all deck config."
|
"A list of all deck config."
|
||||||
return list(self.col.backend.all_deck_config())
|
return list(from_json_bytes(self.col.backend.all_deck_config_legacy()))
|
||||||
|
|
||||||
def confForDid(self, did: int) -> Any:
|
def confForDid(self, did: int) -> Any:
|
||||||
deck = self.get(did, default=False)
|
deck = self.get(did, default=False)
|
||||||
|
@ -274,10 +274,15 @@ class DeckManager:
|
||||||
return deck
|
return deck
|
||||||
|
|
||||||
def get_config(self, conf_id: int) -> Any:
|
def get_config(self, conf_id: int) -> Any:
|
||||||
return self.col.backend.get_deck_config(conf_id)
|
try:
|
||||||
|
return from_json_bytes(self.col.backend.get_deck_config_legacy(conf_id))
|
||||||
|
except NotFoundError:
|
||||||
|
return None
|
||||||
|
|
||||||
def update_config(self, conf: Dict[str, Any], preserve_usn=False) -> None:
|
def update_config(self, conf: Dict[str, Any], preserve_usn=False) -> None:
|
||||||
self.col.backend.add_or_update_deck_config(conf, preserve_usn)
|
conf["id"] = self.col.backend.add_or_update_deck_config_legacy(
|
||||||
|
to_json_bytes(conf), preserve_usn
|
||||||
|
)
|
||||||
|
|
||||||
def add_config(
|
def add_config(
|
||||||
self, name: str, clone_from: Optional[Dict[str, Any]] = None
|
self, name: str, clone_from: Optional[Dict[str, Any]] = None
|
||||||
|
@ -286,7 +291,7 @@ class DeckManager:
|
||||||
conf = copy.deepcopy(clone_from)
|
conf = copy.deepcopy(clone_from)
|
||||||
conf["id"] = 0
|
conf["id"] = 0
|
||||||
else:
|
else:
|
||||||
conf = self.col.backend.new_deck_config()
|
conf = from_json_bytes(self.col.backend.new_deck_config_legacy())
|
||||||
conf["name"] = name
|
conf["name"] = name
|
||||||
self.update_config(conf)
|
self.update_config(conf)
|
||||||
return conf
|
return conf
|
||||||
|
@ -321,7 +326,7 @@ class DeckManager:
|
||||||
|
|
||||||
def restoreToDefault(self, conf) -> None:
|
def restoreToDefault(self, conf) -> None:
|
||||||
oldOrder = conf["new"]["order"]
|
oldOrder = conf["new"]["order"]
|
||||||
new = self.col.backend.new_deck_config()
|
new = from_json_bytes(self.col.backend.new_deck_config_legacy())
|
||||||
new["id"] = conf["id"]
|
new["id"] = conf["id"]
|
||||||
new["name"] = conf["name"]
|
new["name"] = conf["name"]
|
||||||
self.update_config(new)
|
self.update_config(new)
|
||||||
|
|
|
@ -320,36 +320,6 @@ class RustBackend:
|
||||||
def add_card(self, card: BackendCard) -> int:
|
def add_card(self, card: BackendCard) -> int:
|
||||||
return self._run_command(pb.BackendInput(add_card=card)).add_card
|
return self._run_command(pb.BackendInput(add_card=card)).add_card
|
||||||
|
|
||||||
def get_deck_config(self, dcid: int) -> Dict[str, Any]:
|
|
||||||
jstr = self._run_command(pb.BackendInput(get_deck_config=dcid)).get_deck_config
|
|
||||||
return orjson.loads(jstr)
|
|
||||||
|
|
||||||
def add_or_update_deck_config(self, conf: Dict[str, Any], preserve_usn) -> None:
|
|
||||||
conf_json = orjson.dumps(conf)
|
|
||||||
id = self._run_command(
|
|
||||||
pb.BackendInput(
|
|
||||||
add_or_update_deck_config=pb.AddOrUpdateDeckConfigIn(
|
|
||||||
config=conf_json, preserve_usn_and_mtime=preserve_usn
|
|
||||||
)
|
|
||||||
)
|
|
||||||
).add_or_update_deck_config
|
|
||||||
conf["id"] = id
|
|
||||||
|
|
||||||
def all_deck_config(self) -> Sequence[Dict[str, Any]]:
|
|
||||||
jstr = self._run_command(
|
|
||||||
pb.BackendInput(all_deck_config=pb.Empty())
|
|
||||||
).all_deck_config
|
|
||||||
return orjson.loads(jstr)
|
|
||||||
|
|
||||||
def new_deck_config(self) -> Dict[str, Any]:
|
|
||||||
jstr = self._run_command(
|
|
||||||
pb.BackendInput(new_deck_config=pb.Empty())
|
|
||||||
).new_deck_config
|
|
||||||
return orjson.loads(jstr)
|
|
||||||
|
|
||||||
def remove_deck_config(self, dcid: int) -> None:
|
|
||||||
self._run_command(pb.BackendInput(remove_deck_config=dcid))
|
|
||||||
|
|
||||||
def abort_media_sync(self):
|
def abort_media_sync(self):
|
||||||
self._run_command(pb.BackendInput(abort_media_sync=pb.Empty()))
|
self._run_command(pb.BackendInput(abort_media_sync=pb.Empty()))
|
||||||
|
|
||||||
|
@ -420,12 +390,6 @@ class RustBackend:
|
||||||
).get_changed_notetypes
|
).get_changed_notetypes
|
||||||
return orjson.loads(jstr)
|
return orjson.loads(jstr)
|
||||||
|
|
||||||
def get_all_decks(self) -> Dict[str, Dict[str, Any]]:
|
|
||||||
jstr = self._run_command(
|
|
||||||
pb.BackendInput(get_all_decks=pb.Empty())
|
|
||||||
).get_all_decks
|
|
||||||
return orjson.loads(jstr)
|
|
||||||
|
|
||||||
def get_stock_notetype_legacy(self, kind: StockNoteType) -> Dict[str, Any]:
|
def get_stock_notetype_legacy(self, kind: StockNoteType) -> Dict[str, Any]:
|
||||||
bytes = self._run_command(
|
bytes = self._run_command(
|
||||||
pb.BackendInput(get_stock_notetype_legacy=kind)
|
pb.BackendInput(get_stock_notetype_legacy=kind)
|
||||||
|
@ -495,40 +459,6 @@ class RustBackend:
|
||||||
except NotFoundError:
|
except NotFoundError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_deck_names_and_ids(
|
|
||||||
self, skip_empty_default: bool, include_filtered: bool = True
|
|
||||||
) -> Sequence[pb.DeckNameID]:
|
|
||||||
return self._run_command(
|
|
||||||
pb.BackendInput(
|
|
||||||
get_deck_names=pb.GetDeckNamesIn(
|
|
||||||
skip_empty_default=skip_empty_default,
|
|
||||||
include_filtered=include_filtered,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
).get_deck_names.entries
|
|
||||||
|
|
||||||
def add_or_update_deck_legacy(
|
|
||||||
self, deck: Dict[str, Any], preserve_usn: bool
|
|
||||||
) -> None:
|
|
||||||
deck_json = orjson.dumps(deck)
|
|
||||||
id = self._run_command(
|
|
||||||
pb.BackendInput(
|
|
||||||
add_or_update_deck_legacy=pb.AddOrUpdateDeckLegacyIn(
|
|
||||||
deck=deck_json, preserve_usn_and_mtime=preserve_usn
|
|
||||||
)
|
|
||||||
)
|
|
||||||
).add_or_update_deck_legacy
|
|
||||||
deck["id"] = id
|
|
||||||
|
|
||||||
def new_deck_legacy(self, filtered: bool) -> Dict[str, Any]:
|
|
||||||
jstr = self._run_command(
|
|
||||||
pb.BackendInput(new_deck_legacy=filtered)
|
|
||||||
).new_deck_legacy
|
|
||||||
return orjson.loads(jstr)
|
|
||||||
|
|
||||||
def remove_deck(self, did: int) -> None:
|
|
||||||
self._run_command(pb.BackendInput(remove_deck=did))
|
|
||||||
|
|
||||||
def field_names_for_note_ids(self, nids: List[int]) -> Sequence[str]:
|
def field_names_for_note_ids(self, nids: List[int]) -> Sequence[str]:
|
||||||
return self._run_command(
|
return self._run_command(
|
||||||
pb.BackendInput(field_names_for_notes=pb.FieldNamesForNotesIn(nids=nids)),
|
pb.BackendInput(field_names_for_notes=pb.FieldNamesForNotesIn(nids=nids)),
|
||||||
|
@ -621,10 +551,30 @@ class RustBackend:
|
||||||
|
|
||||||
# @@AUTOGEN@@
|
# @@AUTOGEN@@
|
||||||
|
|
||||||
|
def extract_av_tags(self, text: str, question_side: bool) -> pb.ExtractAVTagsOut:
|
||||||
|
input = pb.ExtractAVTagsIn(text=text, question_side=question_side)
|
||||||
|
output = pb.ExtractAVTagsOut()
|
||||||
|
output.ParseFromString(self._run_command2(1, input))
|
||||||
|
return output
|
||||||
|
|
||||||
|
def extract_latex(
|
||||||
|
self, text: str, svg: bool, expand_clozes: bool
|
||||||
|
) -> pb.ExtractLatexOut:
|
||||||
|
input = pb.ExtractLatexIn(text=text, svg=svg, expand_clozes=expand_clozes)
|
||||||
|
output = pb.ExtractLatexOut()
|
||||||
|
output.ParseFromString(self._run_command2(2, input))
|
||||||
|
return output
|
||||||
|
|
||||||
|
def get_empty_cards(self) -> pb.EmptyCardsReport:
|
||||||
|
input = pb.Empty()
|
||||||
|
output = pb.EmptyCardsReport()
|
||||||
|
output.ParseFromString(self._run_command2(3, input))
|
||||||
|
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_command2(1, input))
|
output.ParseFromString(self._run_command2(4, input))
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def render_uncommitted_card(
|
def render_uncommitted_card(
|
||||||
|
@ -634,97 +584,81 @@ class RustBackend:
|
||||||
note=note, card_ord=card_ord, template=template, fill_empty=fill_empty
|
note=note, card_ord=card_ord, template=template, fill_empty=fill_empty
|
||||||
)
|
)
|
||||||
output = pb.RenderCardOut()
|
output = pb.RenderCardOut()
|
||||||
output.ParseFromString(self._run_command2(2, input))
|
output.ParseFromString(self._run_command2(5, input))
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def sched_timing_today(self) -> pb.SchedTimingTodayOut:
|
def strip_av_tags(self, val: str) -> str:
|
||||||
input = pb.Empty()
|
input = pb.String(val=val)
|
||||||
output = pb.SchedTimingTodayOut()
|
output = pb.String()
|
||||||
output.ParseFromString(self._run_command2(3, input))
|
output.ParseFromString(self._run_command2(6, input))
|
||||||
return output
|
return output.val
|
||||||
|
|
||||||
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)
|
|
||||||
output = pb.DeckTreeNode()
|
|
||||||
output.ParseFromString(self._run_command2(4, input))
|
|
||||||
return output
|
|
||||||
|
|
||||||
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_command2(5, input))
|
output.ParseFromString(self._run_command2(7, input))
|
||||||
return output.card_ids
|
return output.card_ids
|
||||||
|
|
||||||
def search_notes(self, search: str) -> Sequence[int]:
|
def search_notes(self, search: str) -> Sequence[int]:
|
||||||
input = pb.SearchNotesIn(search=search)
|
input = pb.SearchNotesIn(search=search)
|
||||||
output = pb.SearchNotesOut()
|
output = pb.SearchNotesOut()
|
||||||
output.ParseFromString(self._run_command2(6, input))
|
output.ParseFromString(self._run_command2(8, input))
|
||||||
return output.note_ids
|
return output.note_ids
|
||||||
|
|
||||||
def check_media(self) -> pb.CheckMediaOut:
|
|
||||||
input = pb.Empty()
|
|
||||||
output = pb.CheckMediaOut()
|
|
||||||
output.ParseFromString(self._run_command2(7, input))
|
|
||||||
return output
|
|
||||||
|
|
||||||
def local_minutes_west(self, val: int) -> int:
|
def local_minutes_west(self, val: int) -> int:
|
||||||
input = pb.Int64(val=val)
|
input = pb.Int64(val=val)
|
||||||
output = pb.Int32()
|
output = pb.Int32()
|
||||||
output.ParseFromString(self._run_command2(8, input))
|
|
||||||
return output.val
|
|
||||||
|
|
||||||
def strip_av_tags(self, val: str) -> str:
|
|
||||||
input = pb.String(val=val)
|
|
||||||
output = pb.String()
|
|
||||||
output.ParseFromString(self._run_command2(9, input))
|
output.ParseFromString(self._run_command2(9, input))
|
||||||
return output.val
|
return output.val
|
||||||
|
|
||||||
def extract_av_tags(self, text: str, question_side: bool) -> pb.ExtractAVTagsOut:
|
def sched_timing_today(self) -> pb.SchedTimingTodayOut:
|
||||||
input = pb.ExtractAVTagsIn(text=text, question_side=question_side)
|
input = pb.Empty()
|
||||||
output = pb.ExtractAVTagsOut()
|
output = pb.SchedTimingTodayOut()
|
||||||
output.ParseFromString(self._run_command2(10, input))
|
output.ParseFromString(self._run_command2(10, input))
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def extract_latex(
|
def check_media(self) -> pb.CheckMediaOut:
|
||||||
self, text: str, svg: bool, expand_clozes: bool
|
input = pb.Empty()
|
||||||
) -> pb.ExtractLatexOut:
|
output = pb.CheckMediaOut()
|
||||||
input = pb.ExtractLatexIn(text=text, svg=svg, expand_clozes=expand_clozes)
|
|
||||||
output = pb.ExtractLatexOut()
|
|
||||||
output.ParseFromString(self._run_command2(11, input))
|
output.ParseFromString(self._run_command2(11, input))
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def deck_tree_legacy(self) -> bytes:
|
|
||||||
input = pb.Empty()
|
|
||||||
output = pb.Bytes()
|
|
||||||
output.ParseFromString(self._run_command2(12, input))
|
|
||||||
return output.val
|
|
||||||
|
|
||||||
def check_database(self) -> Sequence[str]:
|
|
||||||
input = pb.Empty()
|
|
||||||
output = pb.CheckDatabaseOut()
|
|
||||||
output.ParseFromString(self._run_command2(13, input))
|
|
||||||
return output.problems
|
|
||||||
|
|
||||||
def get_empty_cards(self) -> pb.EmptyCardsReport:
|
|
||||||
input = pb.Empty()
|
|
||||||
output = pb.EmptyCardsReport()
|
|
||||||
output.ParseFromString(self._run_command2(14, input))
|
|
||||||
return output
|
|
||||||
|
|
||||||
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_command2(15, input))
|
output.ParseFromString(self._run_command2(12, input))
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def trash_media_files(self, fnames: Sequence[str]) -> pb.Empty:
|
def trash_media_files(self, fnames: Sequence[str]) -> pb.Empty:
|
||||||
input = pb.TrashMediaFilesIn(fnames=fnames)
|
input = pb.TrashMediaFilesIn(fnames=fnames)
|
||||||
output = pb.Empty()
|
output = pb.Empty()
|
||||||
output.ParseFromString(self._run_command2(16, input))
|
output.ParseFromString(self._run_command2(13, input))
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def get_deck_legacy(self, val: int) -> bytes:
|
def add_or_update_deck_legacy(
|
||||||
input = pb.Int64(val=val)
|
self, deck: bytes, preserve_usn_and_mtime: bool
|
||||||
|
) -> int:
|
||||||
|
input = pb.AddOrUpdateDeckLegacyIn(
|
||||||
|
deck=deck, preserve_usn_and_mtime=preserve_usn_and_mtime
|
||||||
|
)
|
||||||
|
output = pb.Int64()
|
||||||
|
output.ParseFromString(self._run_command2(14, input))
|
||||||
|
return output.val
|
||||||
|
|
||||||
|
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)
|
||||||
|
output = pb.DeckTreeNode()
|
||||||
|
output.ParseFromString(self._run_command2(15, input))
|
||||||
|
return output
|
||||||
|
|
||||||
|
def deck_tree_legacy(self) -> bytes:
|
||||||
|
input = pb.Empty()
|
||||||
|
output = pb.Bytes()
|
||||||
|
output.ParseFromString(self._run_command2(16, input))
|
||||||
|
return output.val
|
||||||
|
|
||||||
|
def get_all_decks_legacy(self) -> bytes:
|
||||||
|
input = pb.Empty()
|
||||||
output = pb.Bytes()
|
output = pb.Bytes()
|
||||||
output.ParseFromString(self._run_command2(17, input))
|
output.ParseFromString(self._run_command2(17, input))
|
||||||
return output.val
|
return output.val
|
||||||
|
@ -735,6 +669,74 @@ class RustBackend:
|
||||||
output.ParseFromString(self._run_command2(18, input))
|
output.ParseFromString(self._run_command2(18, input))
|
||||||
return output.val
|
return output.val
|
||||||
|
|
||||||
|
def get_deck_legacy(self, val: int) -> bytes:
|
||||||
|
input = pb.Int64(val=val)
|
||||||
|
output = pb.Bytes()
|
||||||
|
output.ParseFromString(self._run_command2(19, input))
|
||||||
|
return output.val
|
||||||
|
|
||||||
|
def get_deck_names(
|
||||||
|
self, skip_empty_default: bool, include_filtered: bool
|
||||||
|
) -> Sequence[pb.DeckNameID]:
|
||||||
|
input = pb.GetDeckNamesIn(
|
||||||
|
skip_empty_default=skip_empty_default, include_filtered=include_filtered
|
||||||
|
)
|
||||||
|
output = pb.DeckNames()
|
||||||
|
output.ParseFromString(self._run_command2(20, input))
|
||||||
|
return output.entries
|
||||||
|
|
||||||
|
def new_deck_legacy(self, val: bool) -> bytes:
|
||||||
|
input = pb.Bool(val=val)
|
||||||
|
output = pb.Bytes()
|
||||||
|
output.ParseFromString(self._run_command2(21, input))
|
||||||
|
return output.val
|
||||||
|
|
||||||
|
def remove_deck(self, val: int) -> pb.Empty:
|
||||||
|
input = pb.Int64(val=val)
|
||||||
|
output = pb.Empty()
|
||||||
|
output.ParseFromString(self._run_command2(22, input))
|
||||||
|
return output
|
||||||
|
|
||||||
|
def add_or_update_deck_config_legacy(
|
||||||
|
self, config: bytes, preserve_usn_and_mtime: bool
|
||||||
|
) -> int:
|
||||||
|
input = pb.AddOrUpdateDeckConfigLegacyIn(
|
||||||
|
config=config, preserve_usn_and_mtime=preserve_usn_and_mtime
|
||||||
|
)
|
||||||
|
output = pb.Int64()
|
||||||
|
output.ParseFromString(self._run_command2(23, input))
|
||||||
|
return output.val
|
||||||
|
|
||||||
|
def all_deck_config_legacy(self) -> bytes:
|
||||||
|
input = pb.Empty()
|
||||||
|
output = pb.Bytes()
|
||||||
|
output.ParseFromString(self._run_command2(24, input))
|
||||||
|
return output.val
|
||||||
|
|
||||||
|
def get_deck_config_legacy(self, val: int) -> bytes:
|
||||||
|
input = pb.Int64(val=val)
|
||||||
|
output = pb.Bytes()
|
||||||
|
output.ParseFromString(self._run_command2(25, input))
|
||||||
|
return output.val
|
||||||
|
|
||||||
|
def new_deck_config_legacy(self) -> bytes:
|
||||||
|
input = pb.Empty()
|
||||||
|
output = pb.Bytes()
|
||||||
|
output.ParseFromString(self._run_command2(26, input))
|
||||||
|
return output.val
|
||||||
|
|
||||||
|
def remove_deck_config(self, val: int) -> pb.Empty:
|
||||||
|
input = pb.Int64(val=val)
|
||||||
|
output = pb.Empty()
|
||||||
|
output.ParseFromString(self._run_command2(27, input))
|
||||||
|
return output
|
||||||
|
|
||||||
|
def check_database(self) -> Sequence[str]:
|
||||||
|
input = pb.Empty()
|
||||||
|
output = pb.CheckDatabaseOut()
|
||||||
|
output.ParseFromString(self._run_command2(28, input))
|
||||||
|
return output.problems
|
||||||
|
|
||||||
# @@AUTOGEN@@
|
# @@AUTOGEN@@
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@ use crate::{
|
||||||
backend_proto as pb,
|
backend_proto as pb,
|
||||||
backend_proto::builtin_search_order::BuiltinSortKind,
|
backend_proto::builtin_search_order::BuiltinSortKind,
|
||||||
backend_proto::{
|
backend_proto::{
|
||||||
AddOrUpdateDeckConfigIn, BackendResult, Empty, RenderedTemplateReplacement, SyncMediaIn,
|
AddOrUpdateDeckConfigLegacyIn, BackendResult, Empty, RenderedTemplateReplacement,
|
||||||
|
SyncMediaIn,
|
||||||
},
|
},
|
||||||
card::{Card, CardID},
|
card::{Card, CardID},
|
||||||
card::{CardQueue, CardType},
|
card::{CardQueue, CardType},
|
||||||
|
@ -172,6 +173,8 @@ impl From<()> for pb::Empty {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BackendService for Backend {
|
impl BackendService for Backend {
|
||||||
|
// card rendering
|
||||||
|
|
||||||
fn render_existing_card(
|
fn render_existing_card(
|
||||||
&mut self,
|
&mut self,
|
||||||
input: pb::RenderExistingCardIn,
|
input: pb::RenderExistingCardIn,
|
||||||
|
@ -200,80 +203,26 @@ impl BackendService for Backend {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sched_timing_today(&mut self, _input: pb::Empty) -> Result<pb::SchedTimingTodayOut> {
|
fn get_empty_cards(&mut self, _input: pb::Empty) -> Result<pb::EmptyCardsReport> {
|
||||||
self.with_col(|col| col.timing_today().map(Into::into))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deck_tree(&mut self, input: pb::DeckTreeIn) -> Result<pb::DeckTreeNode> {
|
|
||||||
let lim = if input.top_deck_id > 0 {
|
|
||||||
Some(DeckID(input.top_deck_id))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
self.with_col(|col| col.deck_tree(input.include_counts, lim))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_media(&mut self, _input: pb::Empty) -> Result<pb::CheckMediaOut> {
|
|
||||||
let callback =
|
|
||||||
|progress: usize| self.fire_progress_callback(Progress::MediaCheck(progress as u32));
|
|
||||||
|
|
||||||
self.with_col(|col| {
|
self.with_col(|col| {
|
||||||
let mgr = MediaManager::new(&col.media_folder, &col.media_db)?;
|
let mut empty = col.empty_cards()?;
|
||||||
col.transact(None, |ctx| {
|
let report = col.empty_cards_report(&mut empty)?;
|
||||||
let mut checker = MediaChecker::new(ctx, &mgr, callback);
|
|
||||||
let mut output = checker.check()?;
|
|
||||||
|
|
||||||
let report = checker.summarize_output(&mut output);
|
let mut outnotes = vec![];
|
||||||
|
for (_ntid, notes) in empty {
|
||||||
Ok(pb::CheckMediaOut {
|
outnotes.extend(notes.into_iter().map(|e| pb::NoteWithEmptyCards {
|
||||||
unused: output.unused,
|
note_id: e.nid.0,
|
||||||
missing: output.missing,
|
will_delete_note: e.empty.len() == e.current_count,
|
||||||
report,
|
card_ids: e.empty.into_iter().map(|(_ord, id)| id.0).collect(),
|
||||||
have_trash: output.trash_count > 0,
|
}))
|
||||||
})
|
}
|
||||||
|
Ok(pb::EmptyCardsReport {
|
||||||
|
report,
|
||||||
|
notes: outnotes,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn search_cards(&mut self, input: pb::SearchCardsIn) -> Result<pb::SearchCardsOut> {
|
|
||||||
self.with_col(|col| {
|
|
||||||
let order = if let Some(order) = input.order {
|
|
||||||
use pb::sort_order::Value as V;
|
|
||||||
match order.value {
|
|
||||||
Some(V::None(_)) => SortMode::NoOrder,
|
|
||||||
Some(V::Custom(s)) => SortMode::Custom(s),
|
|
||||||
Some(V::FromConfig(_)) => SortMode::FromConfig,
|
|
||||||
Some(V::Builtin(b)) => SortMode::Builtin {
|
|
||||||
kind: sort_kind_from_pb(b.kind),
|
|
||||||
reverse: b.reverse,
|
|
||||||
},
|
|
||||||
None => SortMode::FromConfig,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SortMode::FromConfig
|
|
||||||
};
|
|
||||||
let cids = col.search_cards(&input.search, order)?;
|
|
||||||
Ok(pb::SearchCardsOut {
|
|
||||||
card_ids: cids.into_iter().map(|v| v.0).collect(),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn search_notes(&mut self, input: pb::SearchNotesIn) -> Result<pb::SearchNotesOut> {
|
|
||||||
self.with_col(|col| {
|
|
||||||
let nids = col.search_notes(&input.search)?;
|
|
||||||
Ok(pb::SearchNotesOut {
|
|
||||||
note_ids: nids.into_iter().map(|v| v.0).collect(),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_minutes_west(&mut self, input: pb::Int64) -> BackendResult<pb::Int32> {
|
|
||||||
Ok(pb::Int32 {
|
|
||||||
val: local_minutes_west_for_stamp(input.val),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn strip_av_tags(&mut self, input: pb::String) -> BackendResult<pb::String> {
|
fn strip_av_tags(&mut self, input: pb::String) -> BackendResult<pb::String> {
|
||||||
Ok(pb::String {
|
Ok(pb::String {
|
||||||
val: strip_av_tags(&input.val).into(),
|
val: strip_av_tags(&input.val).into(),
|
||||||
|
@ -335,14 +284,67 @@ impl BackendService for Backend {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_database(&mut self, _input: pb::Empty) -> BackendResult<pb::CheckDatabaseOut> {
|
// searching
|
||||||
|
//-----------------------------------------------
|
||||||
|
|
||||||
|
fn search_cards(&mut self, input: pb::SearchCardsIn) -> Result<pb::SearchCardsOut> {
|
||||||
self.with_col(|col| {
|
self.with_col(|col| {
|
||||||
col.check_database().map(|problems| pb::CheckDatabaseOut {
|
let order = if let Some(order) = input.order {
|
||||||
problems: problems.to_i18n_strings(&col.i18n),
|
use pb::sort_order::Value as V;
|
||||||
|
match order.value {
|
||||||
|
Some(V::None(_)) => SortMode::NoOrder,
|
||||||
|
Some(V::Custom(s)) => SortMode::Custom(s),
|
||||||
|
Some(V::FromConfig(_)) => SortMode::FromConfig,
|
||||||
|
Some(V::Builtin(b)) => SortMode::Builtin {
|
||||||
|
kind: sort_kind_from_pb(b.kind),
|
||||||
|
reverse: b.reverse,
|
||||||
|
},
|
||||||
|
None => SortMode::FromConfig,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SortMode::FromConfig
|
||||||
|
};
|
||||||
|
let cids = col.search_cards(&input.search, order)?;
|
||||||
|
Ok(pb::SearchCardsOut {
|
||||||
|
card_ids: cids.into_iter().map(|v| v.0).collect(),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn search_notes(&mut self, input: pb::SearchNotesIn) -> Result<pb::SearchNotesOut> {
|
||||||
|
self.with_col(|col| {
|
||||||
|
let nids = col.search_notes(&input.search)?;
|
||||||
|
Ok(pb::SearchNotesOut {
|
||||||
|
note_ids: nids.into_iter().map(|v| v.0).collect(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// scheduling
|
||||||
|
//-----------------------------------------------
|
||||||
|
|
||||||
|
fn sched_timing_today(&mut self, _input: pb::Empty) -> Result<pb::SchedTimingTodayOut> {
|
||||||
|
self.with_col(|col| col.timing_today().map(Into::into))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn local_minutes_west(&mut self, input: pb::Int64) -> BackendResult<pb::Int32> {
|
||||||
|
Ok(pb::Int32 {
|
||||||
|
val: local_minutes_west_for_stamp(input.val),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// decks
|
||||||
|
//-----------------------------------------------
|
||||||
|
|
||||||
|
fn deck_tree(&mut self, input: pb::DeckTreeIn) -> Result<pb::DeckTreeNode> {
|
||||||
|
let lim = if input.top_deck_id > 0 {
|
||||||
|
Some(DeckID(input.top_deck_id))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
self.with_col(|col| col.deck_tree(input.include_counts, lim))
|
||||||
|
}
|
||||||
|
|
||||||
fn deck_tree_legacy(&mut self, _input: pb::Empty) -> BackendResult<pb::Bytes> {
|
fn deck_tree_legacy(&mut self, _input: pb::Empty) -> BackendResult<pb::Bytes> {
|
||||||
self.with_col(|col| {
|
self.with_col(|col| {
|
||||||
let tree = col.legacy_deck_tree()?;
|
let tree = col.legacy_deck_tree()?;
|
||||||
|
@ -352,26 +354,6 @@ impl BackendService for Backend {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_empty_cards(&mut self, _input: pb::Empty) -> Result<pb::EmptyCardsReport> {
|
|
||||||
self.with_col(|col| {
|
|
||||||
let mut empty = col.empty_cards()?;
|
|
||||||
let report = col.empty_cards_report(&mut empty)?;
|
|
||||||
|
|
||||||
let mut outnotes = vec![];
|
|
||||||
for (_ntid, notes) in empty {
|
|
||||||
outnotes.extend(notes.into_iter().map(|e| pb::NoteWithEmptyCards {
|
|
||||||
note_id: e.nid.0,
|
|
||||||
will_delete_note: e.empty.len() == e.current_count,
|
|
||||||
card_ids: e.empty.into_iter().map(|(_ord, id)| id.0).collect(),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
Ok(pb::EmptyCardsReport {
|
|
||||||
report,
|
|
||||||
notes: outnotes,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_deck_legacy(&mut self, input: pb::Int64) -> Result<pb::Bytes> {
|
fn get_deck_legacy(&mut self, input: pb::Int64) -> Result<pb::Bytes> {
|
||||||
self.with_col(|col| {
|
self.with_col(|col| {
|
||||||
let deck: DeckSchema11 = col
|
let deck: DeckSchema11 = col
|
||||||
|
@ -393,6 +375,120 @@ impl BackendService for Backend {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_all_decks_legacy(&mut self, _input: Empty) -> BackendResult<pb::Bytes> {
|
||||||
|
self.with_col(|col| {
|
||||||
|
let decks = col.storage.get_all_decks_as_schema11()?;
|
||||||
|
serde_json::to_vec(&decks).map_err(Into::into)
|
||||||
|
})
|
||||||
|
.map(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_deck_names(&mut self, input: pb::GetDeckNamesIn) -> Result<pb::DeckNames> {
|
||||||
|
self.with_col(|col| {
|
||||||
|
let names = if input.include_filtered {
|
||||||
|
col.get_all_deck_names(input.skip_empty_default)?
|
||||||
|
} else {
|
||||||
|
col.get_all_normal_deck_names()?
|
||||||
|
};
|
||||||
|
Ok(pb::DeckNames {
|
||||||
|
entries: names
|
||||||
|
.into_iter()
|
||||||
|
.map(|(id, name)| pb::DeckNameId { id: id.0, name })
|
||||||
|
.collect(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_or_update_deck_legacy(
|
||||||
|
&mut self,
|
||||||
|
input: pb::AddOrUpdateDeckLegacyIn,
|
||||||
|
) -> Result<pb::Int64> {
|
||||||
|
self.with_col(|col| {
|
||||||
|
let schema11: DeckSchema11 = serde_json::from_slice(&input.deck)?;
|
||||||
|
let mut deck: Deck = schema11.into();
|
||||||
|
if input.preserve_usn_and_mtime {
|
||||||
|
col.transact(None, |col| {
|
||||||
|
let usn = col.usn()?;
|
||||||
|
col.add_or_update_single_deck(&mut deck, usn)
|
||||||
|
})?;
|
||||||
|
} else {
|
||||||
|
col.add_or_update_deck(&mut deck)?;
|
||||||
|
}
|
||||||
|
Ok(deck.id.0.into())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_deck_legacy(&mut self, input: pb::Bool) -> BackendResult<pb::Bytes> {
|
||||||
|
let deck = if input.val {
|
||||||
|
Deck::new_filtered()
|
||||||
|
} else {
|
||||||
|
Deck::new_normal()
|
||||||
|
};
|
||||||
|
let schema11: DeckSchema11 = deck.into();
|
||||||
|
serde_json::to_vec(&schema11)
|
||||||
|
.map_err(Into::into)
|
||||||
|
.map(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_deck(&mut self, input: pb::Int64) -> BackendResult<Empty> {
|
||||||
|
self.with_col(|col| col.remove_deck_and_child_decks(DeckID(input.val)))
|
||||||
|
.map(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
// deck config
|
||||||
|
//----------------------------------------------------
|
||||||
|
|
||||||
|
fn add_or_update_deck_config_legacy(
|
||||||
|
&mut self,
|
||||||
|
input: AddOrUpdateDeckConfigLegacyIn,
|
||||||
|
) -> BackendResult<pb::Int64> {
|
||||||
|
let conf: DeckConfSchema11 = serde_json::from_slice(&input.config)?;
|
||||||
|
let mut conf: DeckConf = conf.into();
|
||||||
|
self.with_col(|col| {
|
||||||
|
col.transact(None, |col| {
|
||||||
|
col.add_or_update_deck_config(&mut conf, input.preserve_usn_and_mtime)?;
|
||||||
|
Ok(conf.id.0)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.map(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn all_deck_config_legacy(&mut self, _input: Empty) -> BackendResult<pb::Bytes> {
|
||||||
|
self.with_col(|col| {
|
||||||
|
let conf: Vec<DeckConfSchema11> = col
|
||||||
|
.storage
|
||||||
|
.all_deck_config()?
|
||||||
|
.into_iter()
|
||||||
|
.map(Into::into)
|
||||||
|
.collect();
|
||||||
|
serde_json::to_vec(&conf).map_err(Into::into)
|
||||||
|
})
|
||||||
|
.map(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_deck_config_legacy(&mut self, _input: Empty) -> BackendResult<pb::Bytes> {
|
||||||
|
serde_json::to_vec(&DeckConfSchema11::default())
|
||||||
|
.map_err(Into::into)
|
||||||
|
.map(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_deck_config(&mut self, input: pb::Int64) -> BackendResult<Empty> {
|
||||||
|
self.with_col(|col| col.transact(None, |col| col.remove_deck_config(DeckConfID(input.val))))
|
||||||
|
.map(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_deck_config_legacy(&mut self, input: pb::Int64) -> BackendResult<pb::Bytes> {
|
||||||
|
self.with_col(|col| {
|
||||||
|
let conf = col.get_deck_config(DeckConfID(input.val), true)?.unwrap();
|
||||||
|
let conf: DeckConfSchema11 = conf.into();
|
||||||
|
Ok(serde_json::to_vec(&conf)?)
|
||||||
|
})
|
||||||
|
.map(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
// media
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
|
||||||
fn sync_media(&mut self, input: SyncMediaIn) -> BackendResult<Empty> {
|
fn sync_media(&mut self, input: SyncMediaIn) -> BackendResult<Empty> {
|
||||||
let mut guard = self.col.lock().unwrap();
|
let mut guard = self.col.lock().unwrap();
|
||||||
|
|
||||||
|
@ -420,6 +516,38 @@ impl BackendService for Backend {
|
||||||
})
|
})
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_media(&mut self, _input: pb::Empty) -> Result<pb::CheckMediaOut> {
|
||||||
|
let callback =
|
||||||
|
|progress: usize| self.fire_progress_callback(Progress::MediaCheck(progress as u32));
|
||||||
|
|
||||||
|
self.with_col(|col| {
|
||||||
|
let mgr = MediaManager::new(&col.media_folder, &col.media_db)?;
|
||||||
|
col.transact(None, |ctx| {
|
||||||
|
let mut checker = MediaChecker::new(ctx, &mgr, callback);
|
||||||
|
let mut output = checker.check()?;
|
||||||
|
|
||||||
|
let report = checker.summarize_output(&mut output);
|
||||||
|
|
||||||
|
Ok(pb::CheckMediaOut {
|
||||||
|
unused: output.unused,
|
||||||
|
missing: output.missing,
|
||||||
|
report,
|
||||||
|
have_trash: output.trash_count > 0,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// misc
|
||||||
|
|
||||||
|
fn check_database(&mut self, _input: pb::Empty) -> BackendResult<pb::CheckDatabaseOut> {
|
||||||
|
self.with_col(|col| {
|
||||||
|
col.check_database().map(|problems| pb::CheckDatabaseOut {
|
||||||
|
problems: problems.to_i18n_strings(&col.i18n),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Backend {
|
impl Backend {
|
||||||
|
@ -547,16 +675,6 @@ impl Backend {
|
||||||
OValue::UpdateCard(pb::Empty {})
|
OValue::UpdateCard(pb::Empty {})
|
||||||
}
|
}
|
||||||
Value::AddCard(card) => OValue::AddCard(self.add_card(card)?),
|
Value::AddCard(card) => OValue::AddCard(self.add_card(card)?),
|
||||||
Value::GetDeckConfig(dcid) => OValue::GetDeckConfig(self.get_deck_config(dcid)?),
|
|
||||||
Value::AddOrUpdateDeckConfig(input) => {
|
|
||||||
OValue::AddOrUpdateDeckConfig(self.add_or_update_deck_config(input)?)
|
|
||||||
}
|
|
||||||
Value::AllDeckConfig(_) => OValue::AllDeckConfig(self.all_deck_config()?),
|
|
||||||
Value::NewDeckConfig(_) => OValue::NewDeckConfig(self.new_deck_config()?),
|
|
||||||
Value::RemoveDeckConfig(dcid) => {
|
|
||||||
self.remove_deck_config(dcid)?;
|
|
||||||
OValue::RemoveDeckConfig(pb::Empty {})
|
|
||||||
}
|
|
||||||
Value::AbortMediaSync(_) => {
|
Value::AbortMediaSync(_) => {
|
||||||
self.abort_media_sync();
|
self.abort_media_sync();
|
||||||
OValue::AbortMediaSync(pb::Empty {})
|
OValue::AbortMediaSync(pb::Empty {})
|
||||||
|
@ -582,7 +700,6 @@ impl Backend {
|
||||||
Value::GetChangedNotetypes(_) => {
|
Value::GetChangedNotetypes(_) => {
|
||||||
OValue::GetChangedNotetypes(self.get_changed_notetypes()?)
|
OValue::GetChangedNotetypes(self.get_changed_notetypes()?)
|
||||||
}
|
}
|
||||||
Value::GetAllDecks(_) => OValue::GetAllDecks(self.get_all_decks()?),
|
|
||||||
Value::GetStockNotetypeLegacy(kind) => {
|
Value::GetStockNotetypeLegacy(kind) => {
|
||||||
OValue::GetStockNotetypeLegacy(self.get_stock_notetype_legacy(kind)?)
|
OValue::GetStockNotetypeLegacy(self.get_stock_notetype_legacy(kind)?)
|
||||||
}
|
}
|
||||||
|
@ -611,18 +728,6 @@ impl Backend {
|
||||||
OValue::UpdateNote(pb::Empty {})
|
OValue::UpdateNote(pb::Empty {})
|
||||||
}
|
}
|
||||||
Value::GetNote(nid) => OValue::GetNote(self.get_note(nid)?),
|
Value::GetNote(nid) => OValue::GetNote(self.get_note(nid)?),
|
||||||
Value::GetDeckNames(input) => OValue::GetDeckNames(self.get_deck_names(input)?),
|
|
||||||
Value::AddOrUpdateDeckLegacy(input) => {
|
|
||||||
OValue::AddOrUpdateDeckLegacy(self.add_or_update_deck_legacy(input)?)
|
|
||||||
}
|
|
||||||
Value::NewDeckLegacy(filtered) => {
|
|
||||||
OValue::NewDeckLegacy(self.new_deck_legacy(filtered)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
Value::RemoveDeck(did) => OValue::RemoveDeck({
|
|
||||||
self.remove_deck(did)?;
|
|
||||||
pb::Empty {}
|
|
||||||
}),
|
|
||||||
Value::FieldNamesForNotes(input) => {
|
Value::FieldNamesForNotes(input) => {
|
||||||
OValue::FieldNamesForNotes(self.field_names_for_notes(input)?)
|
OValue::FieldNamesForNotes(self.field_names_for_notes(input)?)
|
||||||
}
|
}
|
||||||
|
@ -845,45 +950,6 @@ impl Backend {
|
||||||
Ok(card.id.0)
|
Ok(card.id.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_deck_config(&self, dcid: i64) -> Result<Vec<u8>> {
|
|
||||||
self.with_col(|col| {
|
|
||||||
let conf = col.get_deck_config(DeckConfID(dcid), true)?.unwrap();
|
|
||||||
let conf: DeckConfSchema11 = conf.into();
|
|
||||||
Ok(serde_json::to_vec(&conf)?)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_or_update_deck_config(&self, input: AddOrUpdateDeckConfigIn) -> Result<i64> {
|
|
||||||
let conf: DeckConfSchema11 = serde_json::from_slice(&input.config)?;
|
|
||||||
let mut conf: DeckConf = conf.into();
|
|
||||||
self.with_col(|col| {
|
|
||||||
col.transact(None, |col| {
|
|
||||||
col.add_or_update_deck_config(&mut conf, input.preserve_usn_and_mtime)?;
|
|
||||||
Ok(conf.id.0)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn all_deck_config(&self) -> Result<Vec<u8>> {
|
|
||||||
self.with_col(|col| {
|
|
||||||
let conf: Vec<DeckConfSchema11> = col
|
|
||||||
.storage
|
|
||||||
.all_deck_config()?
|
|
||||||
.into_iter()
|
|
||||||
.map(Into::into)
|
|
||||||
.collect();
|
|
||||||
serde_json::to_vec(&conf).map_err(Into::into)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_deck_config(&self) -> Result<Vec<u8>> {
|
|
||||||
serde_json::to_vec(&DeckConfSchema11::default()).map_err(Into::into)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_deck_config(&self, dcid: i64) -> Result<()> {
|
|
||||||
self.with_col(|col| col.transact(None, |col| col.remove_deck_config(DeckConfID(dcid))))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn before_upload(&self) -> Result<()> {
|
fn before_upload(&self) -> Result<()> {
|
||||||
self.with_col(|col| col.before_upload())
|
self.with_col(|col| col.before_upload())
|
||||||
}
|
}
|
||||||
|
@ -974,13 +1040,6 @@ impl Backend {
|
||||||
// })
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_all_decks(&self) -> Result<Vec<u8>> {
|
|
||||||
self.with_col(|col| {
|
|
||||||
let decks = col.storage.get_all_decks_as_schema11()?;
|
|
||||||
serde_json::to_vec(&decks).map_err(Into::into)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_notetype_names(&self) -> Result<pb::NoteTypeNames> {
|
fn get_notetype_names(&self) -> Result<pb::NoteTypeNames> {
|
||||||
self.with_col(|col| {
|
self.with_col(|col| {
|
||||||
let entries: Vec<_> = col
|
let entries: Vec<_> = col
|
||||||
|
@ -1078,52 +1137,6 @@ impl Backend {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_deck_names(&self, input: pb::GetDeckNamesIn) -> Result<pb::DeckNames> {
|
|
||||||
self.with_col(|col| {
|
|
||||||
let names = if input.include_filtered {
|
|
||||||
col.get_all_deck_names(input.skip_empty_default)?
|
|
||||||
} else {
|
|
||||||
col.get_all_normal_deck_names()?
|
|
||||||
};
|
|
||||||
Ok(pb::DeckNames {
|
|
||||||
entries: names
|
|
||||||
.into_iter()
|
|
||||||
.map(|(id, name)| pb::DeckNameId { id: id.0, name })
|
|
||||||
.collect(),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_or_update_deck_legacy(&self, input: pb::AddOrUpdateDeckLegacyIn) -> Result<i64> {
|
|
||||||
self.with_col(|col| {
|
|
||||||
let schema11: DeckSchema11 = serde_json::from_slice(&input.deck)?;
|
|
||||||
let mut deck: Deck = schema11.into();
|
|
||||||
if input.preserve_usn_and_mtime {
|
|
||||||
col.transact(None, |col| {
|
|
||||||
let usn = col.usn()?;
|
|
||||||
col.add_or_update_single_deck(&mut deck, usn)
|
|
||||||
})?;
|
|
||||||
} else {
|
|
||||||
col.add_or_update_deck(&mut deck)?;
|
|
||||||
}
|
|
||||||
Ok(deck.id.0)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_deck_legacy(&self, filtered: bool) -> Result<Vec<u8>> {
|
|
||||||
let deck = if filtered {
|
|
||||||
Deck::new_filtered()
|
|
||||||
} else {
|
|
||||||
Deck::new_normal()
|
|
||||||
};
|
|
||||||
let schema11: DeckSchema11 = deck.into();
|
|
||||||
serde_json::to_vec(&schema11).map_err(Into::into)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_deck(&self, did: i64) -> Result<()> {
|
|
||||||
self.with_col(|col| col.remove_deck_and_child_decks(DeckID(did)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn field_names_for_notes(
|
fn field_names_for_notes(
|
||||||
&self,
|
&self,
|
||||||
input: pb::FieldNamesForNotesIn,
|
input: pb::FieldNamesForNotesIn,
|
||||||
|
|
Loading…
Reference in a new issue