diff --git a/pylib/anki/collection.py b/pylib/anki/collection.py index c81deaa6e..910d8b9d6 100644 --- a/pylib/anki/collection.py +++ b/pylib/anki/collection.py @@ -824,6 +824,40 @@ class Collection: ) -> OpChanges: return self._backend.set_config_string(key=key, value=value, undoable=undoable) + def get_aux_notetype_config( + self, id: NotetypeId, key: str, default: Any = None + ) -> Any: + key = self._backend.get_aux_notetype_config_key(id=id, key=key) + return self.get_config(key, default=default) + + def set_aux_notetype_config( + self, id: NotetypeId, key: str, value: Any, *, undoable: bool = False + ) -> OpChanges: + key = self._backend.get_aux_notetype_config_key(id=id, key=key) + return self.set_config(key, value, undoable=undoable) + + def get_aux_template_config( + self, id: NotetypeId, card_ordinal: int, key: str, default: Any = None + ) -> Any: + key = self._backend.get_aux_template_config_key( + notetype_id=id, card_ordinal=card_ordinal, key=key + ) + return self.get_config(key, default=default) + + def set_aux_template_config( + self, + id: NotetypeId, + card_ordinal: int, + key: str, + value: Any, + *, + undoable: bool = False, + ) -> OpChanges: + key = self._backend.get_aux_template_config_key( + notetype_id=id, card_ordinal=card_ordinal, key=key + ) + return self.set_config(key, value, undoable=undoable) + # Stats ########################################################################## diff --git a/pylib/tests/test_cards.py b/pylib/tests/test_cards.py index e7a1ba830..5728cf7e1 100644 --- a/pylib/tests/test_cards.py +++ b/pylib/tests/test_cards.py @@ -77,8 +77,7 @@ def test_gendeck(): assert note.cards()[0].did == 1 # set the model to a new default col newId = col.decks.id("new") - # fixme: dedicated API for this - col.set_config(f"_nt_{cloze['id']}_lastDeck", newId) + col.set_aux_notetype_config(cloze["id"], "lastDeck", newId) col.models.save(cloze, updateReqs=False) # a newly generated card should share the first card's col note["Text"] += "{{c2::two}}" diff --git a/rslib/backend.proto b/rslib/backend.proto index 234228213..7247c4397 100644 --- a/rslib/backend.proto +++ b/rslib/backend.proto @@ -213,6 +213,8 @@ service NotetypesService { rpc GetNotetypeNamesAndCounts(Empty) returns (NotetypeUseCounts); rpc GetNotetypeIdByName(String) returns (NotetypeId); rpc RemoveNotetype(NotetypeId) returns (OpChanges); + rpc GetAuxNotetypeConfigKey(GetAuxConfigKeyIn) returns (String); + rpc GetAuxTemplateConfigKey(GetAuxTemplateConfigKeyIn) returns (String); } service CardRenderingService { @@ -1621,3 +1623,14 @@ message SetFlagIn { repeated int64 card_ids = 1; uint32 flag = 2; } + +message GetAuxConfigKeyIn { + int64 id = 1; + string key = 2; +} + +message GetAuxTemplateConfigKeyIn { + int64 notetype_id = 1; + uint32 card_ordinal = 2; + string key = 3; +} diff --git a/rslib/src/backend/notetypes.rs b/rslib/src/backend/notetypes.rs index c60aa34d7..02d2c23d0 100644 --- a/rslib/src/backend/notetypes.rs +++ b/rslib/src/backend/notetypes.rs @@ -5,6 +5,7 @@ use super::Backend; pub(super) use crate::backend_proto::notetypes_service::Service as NotetypesService; use crate::{ backend_proto as pb, + config::get_aux_notetype_config_key, notetype::{all_stock_notetypes, Notetype, NotetypeSchema11}, prelude::*, }; @@ -134,6 +135,24 @@ impl NotetypesService for Backend { self.with_col(|col| col.remove_notetype(input.into())) .map(Into::into) } + + fn get_aux_notetype_config_key(&self, input: pb::GetAuxConfigKeyIn) -> Result { + Ok(get_aux_notetype_config_key(input.id.into(), &input.key).into()) + } + + fn get_aux_template_config_key( + &self, + input: pb::GetAuxTemplateConfigKeyIn, + ) -> Result { + self.with_col(|col| { + col.get_aux_template_config_key( + input.notetype_id.into(), + input.card_ordinal as usize, + &input.key, + ) + .map(Into::into) + }) + } } impl From for Notetype { diff --git a/rslib/src/config/mod.rs b/rslib/src/config/mod.rs index 3ac207965..93d660e6d 100644 --- a/rslib/src/config/mod.rs +++ b/rslib/src/config/mod.rs @@ -13,7 +13,7 @@ use serde_repr::{Deserialize_repr, Serialize_repr}; use slog::warn; use strum::IntoStaticStr; -pub use self::{bool::BoolKey, string::StringKey}; +pub use self::{bool::BoolKey, notetype::get_aux_notetype_config_key, string::StringKey}; use crate::prelude::*; /// Only used when updating/undoing. diff --git a/rslib/src/config/notetype.rs b/rslib/src/config/notetype.rs index 2d289beb4..ae21a4830 100644 --- a/rslib/src/config/notetype.rs +++ b/rslib/src/config/notetype.rs @@ -4,7 +4,7 @@ use strum::IntoStaticStr; use super::ConfigKey; -use crate::prelude::*; +use crate::{notetype::NotetypeKind, prelude::*}; /// Notetype config packed into a collection config key. This may change /// frequently, and we want to avoid the potentially expensive notetype @@ -16,9 +16,29 @@ enum NotetypeConfigKey { LastDeckAddedTo, } +impl Collection { + pub fn get_aux_template_config_key( + &mut self, + ntid: NotetypeId, + card_ordinal: usize, + key: &str, + ) -> Result { + let nt = self.get_notetype(ntid)?.ok_or(AnkiError::NotFound)?; + let ordinal = if matches!(nt.config.kind(), NotetypeKind::Cloze) { + 0 + } else { + card_ordinal + }; + Ok(get_aux_notetype_config_key( + ntid, + &format!("{}_{}", key, ordinal), + )) + } +} + impl NotetypeConfigKey { fn for_notetype(self, ntid: NotetypeId) -> String { - build_aux_notetype_key(ntid, <&'static str>::from(self)) + get_aux_notetype_config_key(ntid, <&'static str>::from(self)) } } @@ -34,7 +54,7 @@ impl Collection { } pub(crate) fn clear_aux_config_for_notetype(&mut self, ntid: NotetypeId) -> Result<()> { - self.remove_config_prefix(&build_aux_notetype_key(ntid, "")) + self.remove_config_prefix(&get_aux_notetype_config_key(ntid, "")) } pub(crate) fn get_last_deck_added_to_for_notetype(&self, id: NotetypeId) -> Option { @@ -48,6 +68,6 @@ impl Collection { } } -fn build_aux_notetype_key(ntid: NotetypeId, key: &str) -> String { +pub fn get_aux_notetype_config_key(ntid: NotetypeId, key: &str) -> String { format!("_nt_{ntid}_{key}", ntid = ntid, key = key) }