mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
embed deck config and expose to frontend
This commit is contained in:
parent
037df9522b
commit
42a4d11416
6 changed files with 103 additions and 74 deletions
|
@ -39,7 +39,7 @@ from anki.cards import Card, CardId
|
|||
from anki.config import Config, ConfigManager
|
||||
from anki.consts import *
|
||||
from anki.dbproxy import DBProxy
|
||||
from anki.decks import Deck, DeckId, DeckManager
|
||||
from anki.decks import Deck, DeckConfig, DeckConfigId, DeckId, DeckManager
|
||||
from anki.errors import AbortSchemaModification, DBError
|
||||
from anki.lang import FormatTimeSpan
|
||||
from anki.media import MediaManager, media_paths_from_col_path
|
||||
|
@ -335,6 +335,10 @@ class Collection:
|
|||
"Get a new-style deck object. Currently read-only."
|
||||
return self._backend.get_deck(id)
|
||||
|
||||
def get_deck_config(self, id: DeckConfigId) -> DeckConfig:
|
||||
"Get a new-style deck config object. Currently read-only."
|
||||
return self._backend.get_deck_config(id)
|
||||
|
||||
def get_notetype(self, id: NotetypeId) -> Notetype:
|
||||
"""Get a new-style notetype object. This is not cached; avoid calling frequently."""
|
||||
return self._backend.get_notetype(id)
|
||||
|
|
|
@ -32,12 +32,13 @@ DeckConfigDict = Dict[str, Any]
|
|||
|
||||
# currently only supports read-only access
|
||||
Deck = _pb.Deck
|
||||
DeckConfig = _pb.DeckConfig
|
||||
|
||||
DeckId = NewType("DeckId", int)
|
||||
DeckConfId = NewType("DeckConfId", int)
|
||||
DeckConfigId = NewType("DeckConfigId", int)
|
||||
|
||||
DEFAULT_DECK_ID = DeckId(1)
|
||||
DEFAULT_DECK_CONF_ID = DeckConfId(1)
|
||||
DEFAULT_DECK_CONF_ID = DeckConfigId(1)
|
||||
|
||||
|
||||
class DecksDictProxy:
|
||||
|
@ -128,7 +129,7 @@ class DeckManager:
|
|||
self,
|
||||
name: str,
|
||||
create: bool = True,
|
||||
type: DeckConfId = DeckConfId(0),
|
||||
type: DeckConfigId = DeckConfigId(0),
|
||||
) -> Optional[DeckId]:
|
||||
"Add a deck with NAME. Reuse deck if already exists. Return id as int."
|
||||
id = self.id_for_name(name)
|
||||
|
@ -323,7 +324,7 @@ class DeckManager:
|
|||
deck = self.get(did, default=False)
|
||||
assert deck
|
||||
if "conf" in deck:
|
||||
dcid = DeckConfId(int(deck["conf"])) # may be a string
|
||||
dcid = DeckConfigId(int(deck["conf"])) # may be a string
|
||||
conf = self.get_config(dcid)
|
||||
if not conf:
|
||||
# fall back on default
|
||||
|
@ -333,7 +334,7 @@ class DeckManager:
|
|||
# dynamic decks have embedded conf
|
||||
return deck
|
||||
|
||||
def get_config(self, conf_id: DeckConfId) -> Optional[DeckConfigDict]:
|
||||
def get_config(self, conf_id: DeckConfigId) -> Optional[DeckConfigDict]:
|
||||
try:
|
||||
return from_json_bytes(self.col._backend.get_deck_config_legacy(conf_id))
|
||||
except NotFoundError:
|
||||
|
@ -358,10 +359,10 @@ class DeckManager:
|
|||
|
||||
def add_config_returning_id(
|
||||
self, name: str, clone_from: Optional[DeckConfigDict] = None
|
||||
) -> DeckConfId:
|
||||
) -> DeckConfigId:
|
||||
return self.add_config(name, clone_from)["id"]
|
||||
|
||||
def remove_config(self, id: DeckConfId) -> None:
|
||||
def remove_config(self, id: DeckConfigId) -> None:
|
||||
"Remove a configuration and update all decks using it."
|
||||
self.col.modSchema(check=True)
|
||||
for g in self.all():
|
||||
|
@ -373,7 +374,7 @@ class DeckManager:
|
|||
self.save(g)
|
||||
self.col._backend.remove_deck_config(id)
|
||||
|
||||
def setConf(self, grp: DeckConfigDict, id: DeckConfId) -> None:
|
||||
def setConf(self, grp: DeckConfigDict, id: DeckConfigId) -> None:
|
||||
grp["conf"] = id
|
||||
self.save(grp)
|
||||
|
||||
|
|
|
@ -219,6 +219,7 @@ service CardRenderingService {
|
|||
service DeckConfigService {
|
||||
rpc AddOrUpdateDeckConfigLegacy(AddOrUpdateDeckConfigLegacyIn)
|
||||
returns (DeckConfigId);
|
||||
rpc GetDeckConfig(DeckConfigId) returns (DeckConfig);
|
||||
rpc AllDeckConfigLegacy(Empty) returns (Json);
|
||||
rpc GetDeckConfigLegacy(DeckConfigId) returns (Json);
|
||||
rpc NewDeckConfigLegacy(Empty) returns (Json);
|
||||
|
@ -294,7 +295,8 @@ service CardsService {
|
|||
// These should be moved to a separate file in the future
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
message DeckConfigInner {
|
||||
message DeckConfig {
|
||||
message Config {
|
||||
enum NewCardOrder {
|
||||
NEW_CARD_ORDER_DUE = 0;
|
||||
NEW_CARD_ORDER_RANDOM = 1;
|
||||
|
@ -354,10 +356,14 @@ message DeckConfigInner {
|
|||
bool bury_reviews = 28;
|
||||
|
||||
bytes other = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// Containers for passing around database objects
|
||||
///////////////////////////////////////////////////////////
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
int64 mtime_secs = 3;
|
||||
int32 usn = 4;
|
||||
Config config = 5;
|
||||
}
|
||||
|
||||
message Deck {
|
||||
message Common {
|
||||
|
@ -504,6 +510,9 @@ message Notetype {
|
|||
repeated Template templates = 9;
|
||||
}
|
||||
|
||||
// Database objects
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
message Note {
|
||||
int64 id = 1;
|
||||
string guid = 2;
|
||||
|
|
|
@ -38,6 +38,10 @@ impl DeckConfigService for Backend {
|
|||
.map(Into::into)
|
||||
}
|
||||
|
||||
fn get_deck_config(&self, input: pb::DeckConfigId) -> Result<pb::DeckConfig> {
|
||||
self.with_col(|col| Ok(col.get_deck_config(input.into(), true)?.unwrap().into()))
|
||||
}
|
||||
|
||||
fn get_deck_config_legacy(&self, input: pb::DeckConfigId) -> Result<pb::Json> {
|
||||
self.with_col(|col| {
|
||||
let conf = col.get_deck_config(input.into(), true)?.unwrap();
|
||||
|
@ -58,3 +62,15 @@ impl DeckConfigService for Backend {
|
|||
.map(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DeckConf> for pb::DeckConfig {
|
||||
fn from(c: DeckConf) -> Self {
|
||||
pb::DeckConfig {
|
||||
id: c.id.0,
|
||||
name: c.name,
|
||||
mtime_secs: c.mtime_secs.0,
|
||||
usn: c.usn.0,
|
||||
config: Some(c.inner),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ use crate::{
|
|||
};
|
||||
|
||||
pub use crate::backend_proto::{
|
||||
deck_config_inner::{LeechAction, NewCardOrder, ReviewCardOrder, ReviewMix},
|
||||
DeckConfigInner,
|
||||
deck_config::config::{LeechAction, NewCardOrder, ReviewCardOrder, ReviewMix},
|
||||
deck_config::Config as DeckConfigInner,
|
||||
};
|
||||
pub use schema11::{DeckConfSchema11, NewCardOrderSchema11};
|
||||
/// Old deck config and cards table store 250% as 2500.
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use super::{DeckConf, DeckConfId, INITIAL_EASE_FACTOR_THOUSANDS};
|
||||
use crate::backend_proto::deck_config_inner::NewCardOrder;
|
||||
use crate::backend_proto::DeckConfigInner;
|
||||
use super::{DeckConfigInner, NewCardOrder};
|
||||
use crate::{serde::default_on_invalid, timestamp::TimestampSecs, types::Usn};
|
||||
use serde_aux::field_attributes::deserialize_number_from_string;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
|
Loading…
Reference in a new issue