mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
Add import_decks()
This commit is contained in:
parent
48bc6627b1
commit
5cf1705784
1 changed files with 79 additions and 2 deletions
|
@ -16,6 +16,7 @@ use zip::ZipArchive;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
collection::CollectionBuilder,
|
collection::CollectionBuilder,
|
||||||
|
decks::NormalDeck,
|
||||||
import_export::{
|
import_export::{
|
||||||
gather::ExchangeData,
|
gather::ExchangeData,
|
||||||
package::{
|
package::{
|
||||||
|
@ -37,6 +38,7 @@ struct Context<'a> {
|
||||||
guid_map: HashMap<String, NoteMeta>,
|
guid_map: HashMap<String, NoteMeta>,
|
||||||
remapped_notetypes: HashMap<NotetypeId, NotetypeId>,
|
remapped_notetypes: HashMap<NotetypeId, NotetypeId>,
|
||||||
remapped_notes: HashMap<NoteId, NoteId>,
|
remapped_notes: HashMap<NoteId, NoteId>,
|
||||||
|
remapped_decks: HashMap<DeckId, DeckId>,
|
||||||
data: ExchangeData,
|
data: ExchangeData,
|
||||||
usn: Usn,
|
usn: Usn,
|
||||||
/// Map of source media files, that do not already exist in the target.
|
/// Map of source media files, that do not already exist in the target.
|
||||||
|
@ -97,8 +99,7 @@ impl Collection {
|
||||||
ctx.prepare_media()?;
|
ctx.prepare_media()?;
|
||||||
ctx.import_notetypes()?;
|
ctx.import_notetypes()?;
|
||||||
ctx.import_notes()?;
|
ctx.import_notes()?;
|
||||||
|
ctx.import_decks()?;
|
||||||
ctx.target_col.insert_data(&ctx.data)?;
|
|
||||||
ctx.copy_media()?;
|
ctx.copy_media()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -147,6 +148,7 @@ impl<'a> Context<'a> {
|
||||||
conflicting_notes: HashSet::new(),
|
conflicting_notes: HashSet::new(),
|
||||||
remapped_notetypes: HashMap::new(),
|
remapped_notetypes: HashMap::new(),
|
||||||
remapped_notes: HashMap::new(),
|
remapped_notes: HashMap::new(),
|
||||||
|
remapped_decks: HashMap::new(),
|
||||||
used_media_entries: HashMap::new(),
|
used_media_entries: HashMap::new(),
|
||||||
normalize_notes,
|
normalize_notes,
|
||||||
})
|
})
|
||||||
|
@ -322,6 +324,49 @@ impl<'a> Context<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn import_decks(&mut self) -> Result<()> {
|
||||||
|
// TODO: ensure alphabetical order, so parents are seen first
|
||||||
|
let mut renamed_parents = Vec::new();
|
||||||
|
|
||||||
|
for mut deck in mem::take(&mut self.data.decks) {
|
||||||
|
deck.maybe_reparent(&renamed_parents);
|
||||||
|
if let Some(original) = self.get_deck_by_name(&deck)? {
|
||||||
|
if original.is_filtered() {
|
||||||
|
deck.uniquify_name(&mut renamed_parents);
|
||||||
|
self.add_deck(&mut deck)?;
|
||||||
|
} else {
|
||||||
|
self.update_deck(&deck, original)?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.add_deck(&mut deck)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_deck(&mut self, deck: &mut Deck) -> Result<()> {
|
||||||
|
let old_id = mem::take(&mut deck.id);
|
||||||
|
self.target_col.add_deck_inner(deck, self.usn)?;
|
||||||
|
self.remapped_decks.insert(old_id, deck.id);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Caller must ensure decks are normal.
|
||||||
|
fn update_deck(&mut self, deck: &Deck, original: Deck) -> Result<()> {
|
||||||
|
let mut new_deck = original.clone();
|
||||||
|
new_deck.normal_mut()?.update_with_other(deck.normal()?);
|
||||||
|
self.remapped_decks.insert(deck.id, new_deck.id);
|
||||||
|
self.target_col
|
||||||
|
.update_deck_inner(&mut new_deck, original, self.usn)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_deck_by_name(&mut self, deck: &Deck) -> Result<Option<Deck>> {
|
||||||
|
self.target_col
|
||||||
|
.storage
|
||||||
|
.get_deck_by_name(deck.name.as_native_str())
|
||||||
|
}
|
||||||
|
|
||||||
fn copy_media(&mut self) -> Result<()> {
|
fn copy_media(&mut self) -> Result<()> {
|
||||||
for (used, entry) in self.used_media_entries.values() {
|
for (used, entry) in self.used_media_entries.values() {
|
||||||
if *used {
|
if *used {
|
||||||
|
@ -332,6 +377,38 @@ impl<'a> Context<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Deck {
|
||||||
|
fn maybe_reparent(&mut self, renamed_parents: &[(String, String)]) {
|
||||||
|
if let Some(new_name) = reparented_name(self.name.as_native_str(), renamed_parents) {
|
||||||
|
self.name = NativeDeckName::from_native_str(new_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn uniquify_name(&mut self, renamed_parents: &mut Vec<(String, String)>) {
|
||||||
|
let name = self.name.as_native_str();
|
||||||
|
let new_name = format!("{name} {}", TimestampSecs::now());
|
||||||
|
renamed_parents.push((format!("{name}\x1f"), format!("{new_name}\x1f")));
|
||||||
|
self.name = NativeDeckName::from_native_str(new_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NormalDeck {
|
||||||
|
fn update_with_other(&mut self, other: &Self) {
|
||||||
|
self.markdown_description = other.markdown_description;
|
||||||
|
self.description = other.description.clone();
|
||||||
|
if other.config_id != 1 {
|
||||||
|
self.config_id = other.config_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reparented_name(name: &str, renamed_parents: &[(String, String)]) -> Option<String> {
|
||||||
|
renamed_parents.iter().find_map(|(old_parent, new_parent)| {
|
||||||
|
name.starts_with(old_parent)
|
||||||
|
.then(|| name.replacen(old_parent, new_parent, 1))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
impl Notetype {
|
impl Notetype {
|
||||||
fn schema_hash(&self) -> [u8; 20] {
|
fn schema_hash(&self) -> [u8; 20] {
|
||||||
let mut hasher = Sha1::new();
|
let mut hasher = Sha1::new();
|
||||||
|
|
Loading…
Reference in a new issue