diff --git a/proto/backend.proto b/proto/backend.proto index 4f631e917..d8b12e3d7 100644 --- a/proto/backend.proto +++ b/proto/backend.proto @@ -29,7 +29,6 @@ message I18nBackendInit { message BackendInput { oneof value { - TemplateRequirementsIn template_requirements = 16; SchedTimingTodayIn sched_timing_today = 17; Empty deck_tree = 18; SearchCardsIn search_cards = 19; @@ -103,7 +102,6 @@ message BackendOutput { AllStockNotetypesOut all_stock_notetypes = 60; // fallible commands - TemplateRequirementsOut template_requirements = 16; DeckTreeOut deck_tree = 18; SearchCardsOut search_cards = 19; SearchNotesOut search_notes = 20; @@ -213,31 +211,6 @@ message MediaSyncUploadProgress { uint32 deletions = 2; } -message TemplateRequirementsIn { - repeated string template_front = 1; - map field_names_to_ordinals = 2; -} - -message TemplateRequirementsOut { - repeated TemplateRequirement requirements = 1; -} - -message TemplateRequirement { - oneof value { - TemplateRequirementAll all = 1; - TemplateRequirementAny any = 2; - Empty none = 3; - } -} - -message TemplateRequirementAll { - repeated uint32 ords = 1; -} - -message TemplateRequirementAny { - repeated uint32 ords = 1; -} - message SchedTimingTodayIn { int64 created_secs = 1; int64 now_secs = 2; diff --git a/pylib/anki/collection.py b/pylib/anki/collection.py index d2375c041..8afbd45a8 100644 --- a/pylib/anki/collection.py +++ b/pylib/anki/collection.py @@ -456,6 +456,9 @@ insert into cards values (?,?,?,?,?,?,0,0,?,0,0,0,0,0,0,0,0,"")""", return all_cards + # fixme: make sure we enforce deck!=dyn requirement when generating cards + # fixme: make sure we enforce random due number when adding into random sorted deck + def _newCard( self, note: Note, @@ -796,10 +799,6 @@ select id from notes where mid not in """ problems.append(_("Fixed AnkiDroid deck override bug.")) self.models.save(m, updateReqs=False) if m["type"] == MODEL_STD: - # model with missing req specification - if "req" not in m: - self.models._updateRequired(m) - problems.append(_("Fixed note type: %s") % m["name"]) # cards with invalid ordinal ids = self.db.list( """ diff --git a/pylib/anki/models.py b/pylib/anki/models.py index 47c2aeb2b..6a1de1d6d 100644 --- a/pylib/anki/models.py +++ b/pylib/anki/models.py @@ -19,10 +19,6 @@ from anki.utils import checksum, ids2str, intTime, joinFields, splitFields NoteType = Dict[str, Any] Field = Dict[str, Any] Template = Dict[str, Union[str, int, None]] -TemplateRequirementType = str # Union["all", "any", "none"] -# template ordinal, type, list of field ordinals -TemplateRequiredFieldOrds = Tuple[int, TemplateRequirementType, List[int]] -AllTemplateReqs = List[TemplateRequiredFieldOrds] # fixme: memory leaks # fixme: syncing, beforeUpload @@ -520,14 +516,7 @@ class ModelManager: # Required field/text cache ########################################################################## - def _updateRequired(self, m: NoteType) -> None: - fronts = [t["qfmt"] for t in m["tmpls"]] - field_map = {} - for (idx, fld) in enumerate(m["flds"]): - field_map[fld["name"]] = idx - reqs = self.col.backend.template_requirements(fronts, field_map) - m["req"] = [list(l) for l in reqs] - + # fixme: genCards(), clayout, importing, cards.isEmpty def availOrds(self, m: NoteType, flds: str) -> List: "Given a joined field string, return available template ordinals." if m["type"] == MODEL_CLOZE: diff --git a/pylib/anki/rsbackend.py b/pylib/anki/rsbackend.py index 6b52b3fc3..34e7cb957 100644 --- a/pylib/anki/rsbackend.py +++ b/pylib/anki/rsbackend.py @@ -37,7 +37,6 @@ from anki import hooks from anki.dbproxy import Row as DBRow from anki.dbproxy import ValueForDB from anki.fluent_pb2 import FluentString as TR -from anki.models import AllTemplateReqs from anki.sound import AVTag, SoundOrVideoTag, TTSTag from anki.types import assert_impossible_literal from anki.utils import intTime @@ -127,24 +126,6 @@ def proto_exception_to_native(err: pb.BackendError) -> Exception: assert_impossible_literal(val) -def proto_template_reqs_to_legacy( - reqs: List[pb.TemplateRequirement], -) -> AllTemplateReqs: - legacy_reqs = [] - for (idx, req) in enumerate(reqs): - kind = req.WhichOneof("value") - # fixme: sorting is for the unit tests - should check if any - # code depends on the order - if kind == "any": - legacy_reqs.append((idx, "any", sorted(req.any.ords))) - elif kind == "all": - legacy_reqs.append((idx, "all", sorted(req.all.ords))) - else: - l: List[int] = [] - legacy_reqs.append((idx, "none", l)) - return legacy_reqs - - def av_tag_to_native(tag: pb.AVTag) -> AVTag: val = tag.WhichOneof("value") if val == "sound_or_video": @@ -289,18 +270,6 @@ class RustBackend: release_gil=True, ) - def template_requirements( - self, template_fronts: List[str], field_map: Dict[str, int] - ) -> AllTemplateReqs: - input = pb.BackendInput( - template_requirements=pb.TemplateRequirementsIn( - template_front=template_fronts, field_names_to_ordinals=field_map - ) - ) - output = self._run_command(input).template_requirements - reqs: List[pb.TemplateRequirement] = output.requirements # type: ignore - return proto_template_reqs_to_legacy(reqs) - def sched_timing_today( self, created_secs: int, diff --git a/rslib/src/backend/mod.rs b/rslib/src/backend/mod.rs index 82844c7a6..1d862c3da 100644 --- a/rslib/src/backend/mod.rs +++ b/rslib/src/backend/mod.rs @@ -25,7 +25,7 @@ use crate::{ sched::cutoff::{local_minutes_west_for_stamp, sched_timing_today}, sched::timespan::{answer_button_time, learning_congrats, studied_today, time_span}, search::SortMode, - template::{render_card, FieldMap, FieldRequirements, ParsedTemplate, RenderedNode}, + template::{render_card, RenderedNode}, text::{extract_av_tags, strip_av_tags, AVTag}, timestamp::TimestampSecs, types::Usn, @@ -36,7 +36,7 @@ use log::error; use pb::backend_input::Value; use prost::Message; use serde_json::Value as JsonValue; -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use std::convert::TryFrom; use std::path::PathBuf; use std::sync::{Arc, Mutex}; @@ -212,9 +212,6 @@ impl Backend { ) -> Result { use pb::backend_output::Value as OValue; Ok(match ival { - Value::TemplateRequirements(input) => { - OValue::TemplateRequirements(self.template_requirements(input)?) - } Value::SchedTimingToday(input) => { OValue::SchedTimingToday(self.sched_timing_today(input)) } @@ -411,46 +408,6 @@ impl Backend { self.progress_callback = progress_cb; } - fn template_requirements( - &self, - input: pb::TemplateRequirementsIn, - ) -> Result { - let map: FieldMap = input - .field_names_to_ordinals - .iter() - .map(|(name, ord)| (name.as_str(), *ord as u16)) - .collect(); - // map each provided template into a requirements list - use crate::backend_proto::template_requirement::Value; - let all_reqs = input - .template_front - .into_iter() - .map(|template| { - if let Ok(tmpl) = ParsedTemplate::from_text(&template) { - // convert the rust structure into a protobuf one - let val = match tmpl.requirements(&map) { - FieldRequirements::Any(ords) => Value::Any(pb::TemplateRequirementAny { - ords: ords_hash_to_set(ords), - }), - FieldRequirements::All(ords) => Value::All(pb::TemplateRequirementAll { - ords: ords_hash_to_set(ords), - }), - FieldRequirements::None => Value::None(pb::Empty {}), - }; - Ok(pb::TemplateRequirement { value: Some(val) }) - } else { - // template parsing failures make card unsatisfiable - Ok(pb::TemplateRequirement { - value: Some(Value::None(pb::Empty {})), - }) - } - }) - .collect::>>()?; - Ok(pb::TemplateRequirementsOut { - requirements: all_reqs, - }) - } - fn sched_timing_today(&self, input: pb::SchedTimingTodayIn) -> pb::SchedTimingTodayOut { let today = sched_timing_today( TimestampSecs(input.created_secs), @@ -1030,10 +987,6 @@ fn translate_arg_to_fluent_val(arg: &pb::TranslateArgValue) -> FluentValue { } } -fn ords_hash_to_set(ords: HashSet) -> Vec { - ords.iter().map(|ord| *ord as u32).collect() -} - fn rendered_nodes_to_proto(nodes: Vec) -> Vec { nodes .into_iter()