Fix daily counts being included in apkg import

Fixes https://github.com/ankidroid/Anki-Android/issues/12477
This commit is contained in:
Damien Elmes 2022-09-24 08:40:26 +10:00
parent 66178edd5a
commit b97a8bfa26
2 changed files with 34 additions and 9 deletions

View File

@ -30,10 +30,15 @@ impl Context<'_> {
pub(super) fn import_decks_and_configs(
&mut self,
keep_filtered: bool,
contains_scheduling: bool,
) -> Result<HashMap<DeckId, DeckId>> {
let mut ctx = DeckContext::new(self.target_col, self.usn);
ctx.import_deck_configs(mem::take(&mut self.data.deck_configs))?;
ctx.import_decks(mem::take(&mut self.data.decks), keep_filtered)?;
ctx.import_decks(
mem::take(&mut self.data.decks),
keep_filtered,
contains_scheduling,
)?;
Ok(ctx.imported_decks)
}
}
@ -47,23 +52,39 @@ impl DeckContext<'_> {
Ok(())
}
fn import_decks(&mut self, mut decks: Vec<Deck>, keep_filtered: bool) -> Result<()> {
fn import_decks(
&mut self,
mut decks: Vec<Deck>,
keep_filtered: bool,
contains_scheduling: bool,
) -> Result<()> {
// ensure parents are seen before children
decks.sort_unstable_by_key(|deck| deck.level());
for deck in &mut decks {
self.prepare_deck(deck, keep_filtered);
self.prepare_deck(deck, keep_filtered, contains_scheduling);
self.import_deck(deck)?;
}
Ok(())
}
fn prepare_deck(&self, deck: &mut Deck, keep_filtered: bool) {
fn prepare_deck(&self, deck: &mut Deck, keep_filtered: bool, contains_scheduling: bool) {
self.maybe_reparent(deck);
if !keep_filtered && deck.is_filtered() {
deck.kind = DeckKind::Normal(NormalDeck {
config_id: 1,
..Default::default()
});
} else if !contains_scheduling {
// reset things like today's study count and collapse state
deck.common = Default::default();
deck.kind = match &mut deck.kind {
DeckKind::Normal(normal) => DeckKind::Normal(NormalDeck {
config_id: 1,
description: mem::take(&mut normal.description),
..Default::default()
}),
DeckKind::Filtered(_) => unreachable!(),
}
}
}
@ -205,7 +226,7 @@ mod test {
new_deck_with_machine_name("NEW PARENT\x1fchild", false),
new_deck_with_machine_name("new parent", false),
];
ctx.import_decks(imports, false).unwrap();
ctx.import_decks(imports, false, false).unwrap();
let existing_decks: HashSet<_> = ctx
.target_col
.get_all_deck_names(true)

View File

@ -83,7 +83,8 @@ impl<'a> Context<'a> {
let mut media_map = self.prepare_media()?;
let note_imports = self.import_notes_and_notetypes(&mut media_map)?;
let keep_filtered = self.data.enables_filtered_decks();
let imported_decks = self.import_decks_and_configs(keep_filtered)?;
let contains_scheduling = self.data.contains_scheduling();
let imported_decks = self.import_decks_and_configs(keep_filtered, contains_scheduling)?;
self.import_cards_and_revlog(&note_imports.id_map, &imported_decks, keep_filtered)?;
self.copy_media(&mut media_map)?;
Ok(note_imports.log)
@ -112,12 +113,15 @@ impl ExchangeData {
fn enables_filtered_decks(&self) -> bool {
// Earlier versions relied on the importer handling filtered decks by converting
// them into regular ones, so there is no guarantee that all original decks
// are included.
self.contains_scheduling() && self.contains_all_original_decks()
// are included. And the legacy exporter included the default deck config, so we
// can't use it to determine if scheduling is included.
self.contains_scheduling()
&& self.contains_all_original_decks()
&& !self.deck_configs.is_empty()
}
fn contains_scheduling(&self) -> bool {
!(self.revlog.is_empty() && self.deck_configs.is_empty())
!self.revlog.is_empty()
}
fn contains_all_original_decks(&self) -> bool {