mirror of
https://github.com/ankitects/anki.git
synced 2025-09-21 07:22:23 -04:00
Add import_cards(), import_revlog()
This commit is contained in:
parent
ffdd8b741e
commit
08791e24fc
2 changed files with 66 additions and 8 deletions
|
@ -5,8 +5,7 @@ use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{self},
|
io, mem,
|
||||||
mem,
|
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -40,6 +39,7 @@ struct Context<'a> {
|
||||||
remapped_notes: HashMap<NoteId, NoteId>,
|
remapped_notes: HashMap<NoteId, NoteId>,
|
||||||
remapped_decks: HashMap<DeckId, DeckId>,
|
remapped_decks: HashMap<DeckId, DeckId>,
|
||||||
remapped_deck_configs: HashMap<DeckConfigId, DeckConfigId>,
|
remapped_deck_configs: HashMap<DeckConfigId, DeckConfigId>,
|
||||||
|
remapped_cards: HashMap<CardId, CardId>,
|
||||||
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,12 +97,7 @@ impl Collection {
|
||||||
let archive = ZipArchive::new(file)?;
|
let archive = ZipArchive::new(file)?;
|
||||||
|
|
||||||
let mut ctx = Context::new(archive, self, search, with_scheduling)?;
|
let mut ctx = Context::new(archive, self, search, with_scheduling)?;
|
||||||
ctx.prepare_media()?;
|
ctx.import()?;
|
||||||
ctx.import_notetypes()?;
|
|
||||||
ctx.import_notes()?;
|
|
||||||
ctx.import_deck_configs()?;
|
|
||||||
ctx.import_decks()?;
|
|
||||||
ctx.copy_media()?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,11 +147,23 @@ impl<'a> Context<'a> {
|
||||||
remapped_notes: HashMap::new(),
|
remapped_notes: HashMap::new(),
|
||||||
remapped_decks: HashMap::new(),
|
remapped_decks: HashMap::new(),
|
||||||
remapped_deck_configs: HashMap::new(),
|
remapped_deck_configs: HashMap::new(),
|
||||||
|
remapped_cards: HashMap::new(),
|
||||||
used_media_entries: HashMap::new(),
|
used_media_entries: HashMap::new(),
|
||||||
normalize_notes,
|
normalize_notes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn import(&mut self) -> Result<()> {
|
||||||
|
self.prepare_media()?;
|
||||||
|
self.import_notetypes()?;
|
||||||
|
self.import_notes()?;
|
||||||
|
self.import_deck_configs()?;
|
||||||
|
self.import_decks()?;
|
||||||
|
self.import_cards()?;
|
||||||
|
self.import_revlog()?;
|
||||||
|
self.copy_media()
|
||||||
|
}
|
||||||
|
|
||||||
fn prepare_media(&mut self) -> Result<()> {
|
fn prepare_media(&mut self) -> Result<()> {
|
||||||
let existing_sha1s = self.target_col.all_existing_sha1s()?;
|
let existing_sha1s = self.target_col.all_existing_sha1s()?;
|
||||||
for mut entry in extract_media_entries(&Meta::new_legacy(), &mut self.archive)? {
|
for mut entry in extract_media_entries(&Meta::new_legacy(), &mut self.archive)? {
|
||||||
|
@ -392,6 +399,50 @@ impl<'a> Context<'a> {
|
||||||
.get_deck_by_name(deck.name.as_native_str())
|
.get_deck_by_name(deck.name.as_native_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn import_cards(&mut self) -> Result<()> {
|
||||||
|
let existing = self.target_col.storage.all_cards_as_nid_and_ord()?;
|
||||||
|
for mut card in mem::take(&mut self.data.cards) {
|
||||||
|
if self.conflicting_notes.contains(&card.note_id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
self.remap_note_id(&mut card);
|
||||||
|
if existing.contains(&(card.note_id, card.template_idx)) {
|
||||||
|
// TODO: maybe update
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
self.remap_deck_id(&mut card);
|
||||||
|
// TODO: adjust collection-relative due times
|
||||||
|
// TODO: remove cards from filtered decks
|
||||||
|
let old_id = mem::take(&mut card.id);
|
||||||
|
self.target_col.add_card(&mut card)?;
|
||||||
|
self.remapped_cards.insert(old_id, card.id);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remap_note_id(&self, card: &mut Card) {
|
||||||
|
if let Some(nid) = self.remapped_notes.get(&card.note_id) {
|
||||||
|
card.note_id = *nid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remap_deck_id(&self, card: &mut Card) {
|
||||||
|
if let Some(did) = self.remapped_decks.get(&card.deck_id) {
|
||||||
|
card.deck_id = *did;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn import_revlog(&mut self) -> Result<()> {
|
||||||
|
for mut entry in mem::take(&mut self.data.revlog) {
|
||||||
|
if let Some(cid) = self.remapped_cards.get(&entry.cid) {
|
||||||
|
entry.cid = *cid;
|
||||||
|
entry.usn = self.usn;
|
||||||
|
self.target_col.add_revlog_entry_undoable(entry)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
|
|
@ -400,6 +400,13 @@ impl super::SqliteStorage {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn all_cards_as_nid_and_ord(&self) -> Result<HashSet<(NoteId, u16)>> {
|
||||||
|
self.db
|
||||||
|
.prepare("SELECT nid, ord FROM cards")?
|
||||||
|
.query_and_then([], |r| Ok((NoteId(r.get(0)?), r.get(1)?)))?
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn card_ids_of_notes(&self, nids: &[NoteId]) -> Result<Vec<CardId>> {
|
pub(crate) fn card_ids_of_notes(&self, nids: &[NoteId]) -> Result<Vec<CardId>> {
|
||||||
let mut stmt = self
|
let mut stmt = self
|
||||||
.db
|
.db
|
||||||
|
|
Loading…
Reference in a new issue