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