mirror of
https://github.com/ankitects/anki.git
synced 2025-09-20 15:02:21 -04:00
Let import_apkg() take a progress func
This commit is contained in:
parent
a78d101c53
commit
bb27eb3f08
7 changed files with 40 additions and 16 deletions
|
@ -110,6 +110,7 @@ pub(super) fn progress_to_proto(progress: Option<Progress>, tr: &I18n) -> pb::Pr
|
||||||
match progress {
|
match progress {
|
||||||
ImportProgress::Collection => tr.importing_importing_collection(),
|
ImportProgress::Collection => tr.importing_importing_collection(),
|
||||||
ImportProgress::Media(n) => tr.importing_processed_media_file(n),
|
ImportProgress::Media(n) => tr.importing_processed_media_file(n),
|
||||||
|
ImportProgress::MediaCheck(n) => tr.media_check_checked(n),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
|
|
|
@ -9,4 +9,5 @@ pub mod package;
|
||||||
pub enum ImportProgress {
|
pub enum ImportProgress {
|
||||||
Collection,
|
Collection,
|
||||||
Media(usize),
|
Media(usize),
|
||||||
|
MediaCheck(usize),
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl Collection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Context<'a> {
|
impl<F> Context<'_, F> {
|
||||||
pub(super) fn import_cards_and_revlog(
|
pub(super) fn import_cards_and_revlog(
|
||||||
&mut self,
|
&mut self,
|
||||||
imported_notes: &HashMap<NoteId, NoteId>,
|
imported_notes: &HashMap<NoteId, NoteId>,
|
||||||
|
|
|
@ -26,7 +26,7 @@ impl<'d> DeckContext<'d> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context<'_> {
|
impl<F> Context<'_, F> {
|
||||||
pub(super) fn import_decks_and_configs(&mut self) -> Result<HashMap<DeckId, DeckId>> {
|
pub(super) fn import_decks_and_configs(&mut self) -> Result<HashMap<DeckId, DeckId>> {
|
||||||
let mut ctx = DeckContext::new(self.target_col, self.usn);
|
let mut ctx = DeckContext::new(self.target_col, self.usn);
|
||||||
ctx.import_deck_configs(mem::take(&mut self.data.deck_configs))?;
|
ctx.import_deck_configs(mem::take(&mut self.data.deck_configs))?;
|
||||||
|
|
|
@ -7,9 +7,12 @@ use zip::ZipArchive;
|
||||||
|
|
||||||
use super::Context;
|
use super::Context;
|
||||||
use crate::{
|
use crate::{
|
||||||
import_export::package::{
|
import_export::{
|
||||||
media::{extract_media_entries, SafeMediaEntry},
|
package::{
|
||||||
Meta,
|
media::{extract_media_entries, SafeMediaEntry},
|
||||||
|
Meta,
|
||||||
|
},
|
||||||
|
ImportProgress,
|
||||||
},
|
},
|
||||||
media::{
|
media::{
|
||||||
files::{add_hash_suffix_to_file_stem, sha1_of_reader},
|
files::{add_hash_suffix_to_file_stem, sha1_of_reader},
|
||||||
|
@ -29,14 +32,20 @@ pub(super) struct MediaUseMap {
|
||||||
unchecked: Vec<SafeMediaEntry>,
|
unchecked: Vec<SafeMediaEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Context<'a> {
|
impl<F: FnMut(ImportProgress) -> Result<()>> Context<'_, F> {
|
||||||
pub(super) fn prepare_media(&mut self) -> Result<MediaUseMap> {
|
pub(super) fn prepare_media(&mut self) -> Result<MediaUseMap> {
|
||||||
let existing_sha1s = self.target_col.all_existing_sha1s()?;
|
let progress_fn = |u| (&mut self.progress_fn)(ImportProgress::MediaCheck(u)).is_ok();
|
||||||
|
let existing_sha1s = self.target_col.all_existing_sha1s(progress_fn)?;
|
||||||
prepare_media(&mut self.archive, &existing_sha1s)
|
prepare_media(&mut self.archive, &existing_sha1s)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn copy_media(&mut self, media_map: &mut MediaUseMap) -> Result<()> {
|
pub(super) fn copy_media(&mut self, media_map: &mut MediaUseMap) -> Result<()> {
|
||||||
|
let mut counter = 0;
|
||||||
for entry in media_map.used_entries() {
|
for entry in media_map.used_entries() {
|
||||||
|
counter += 1;
|
||||||
|
if counter % 10 == 0 {
|
||||||
|
(self.progress_fn)(ImportProgress::Media(counter))?;
|
||||||
|
}
|
||||||
entry.copy_from_archive(&mut self.archive, &self.target_col.media_folder)?;
|
entry.copy_from_archive(&mut self.archive, &self.target_col.media_folder)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -44,9 +53,12 @@ impl<'a> Context<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Collection {
|
impl Collection {
|
||||||
fn all_existing_sha1s(&mut self) -> Result<HashMap<String, [u8; 20]>> {
|
fn all_existing_sha1s(
|
||||||
|
&mut self,
|
||||||
|
progress_fn: impl FnMut(usize) -> bool,
|
||||||
|
) -> Result<HashMap<String, [u8; 20]>> {
|
||||||
let mgr = MediaManager::new(&self.media_folder, &self.media_db)?;
|
let mgr = MediaManager::new(&self.media_folder, &self.media_db)?;
|
||||||
mgr.all_checksums(|_| true, &self.log)
|
mgr.all_checksums(progress_fn, &self.log)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,32 +15,41 @@ use zip::ZipArchive;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
collection::CollectionBuilder,
|
collection::CollectionBuilder,
|
||||||
import_export::{gather::ExchangeData, package::Meta},
|
import_export::{gather::ExchangeData, package::Meta, ImportProgress},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
search::SearchNode,
|
search::SearchNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Context<'a> {
|
struct Context<'a, F> {
|
||||||
target_col: &'a mut Collection,
|
target_col: &'a mut Collection,
|
||||||
archive: ZipArchive<File>,
|
archive: ZipArchive<File>,
|
||||||
data: ExchangeData,
|
data: ExchangeData,
|
||||||
usn: Usn,
|
usn: Usn,
|
||||||
|
progress_fn: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Collection {
|
impl Collection {
|
||||||
pub fn import_apkg(&mut self, path: impl AsRef<Path>) -> Result<OpOutput<()>> {
|
pub fn import_apkg(
|
||||||
|
&mut self,
|
||||||
|
path: impl AsRef<Path>,
|
||||||
|
progress_fn: impl FnMut(ImportProgress) -> Result<()>,
|
||||||
|
) -> Result<OpOutput<()>> {
|
||||||
let file = File::open(path)?;
|
let file = File::open(path)?;
|
||||||
let archive = ZipArchive::new(file)?;
|
let archive = ZipArchive::new(file)?;
|
||||||
|
|
||||||
self.transact(Op::Import, |col| {
|
self.transact(Op::Import, |col| {
|
||||||
let mut ctx = Context::new(archive, col)?;
|
let mut ctx = Context::new(archive, col, progress_fn)?;
|
||||||
ctx.import()
|
ctx.import()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Context<'a> {
|
impl<'a, F: FnMut(ImportProgress) -> Result<()>> Context<'a, F> {
|
||||||
fn new(mut archive: ZipArchive<File>, target_col: &'a mut Collection) -> Result<Self> {
|
fn new(
|
||||||
|
mut archive: ZipArchive<File>,
|
||||||
|
target_col: &'a mut Collection,
|
||||||
|
progress_fn: F,
|
||||||
|
) -> Result<Self> {
|
||||||
let data =
|
let data =
|
||||||
ExchangeData::gather_from_archive(&mut archive, SearchNode::WholeCollection, true)?;
|
ExchangeData::gather_from_archive(&mut archive, SearchNode::WholeCollection, true)?;
|
||||||
let usn = target_col.usn()?;
|
let usn = target_col.usn()?;
|
||||||
|
@ -49,6 +58,7 @@ impl<'a> Context<'a> {
|
||||||
archive,
|
archive,
|
||||||
data,
|
data,
|
||||||
usn,
|
usn,
|
||||||
|
progress_fn,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ impl NoteMeta {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context<'_> {
|
impl<F> Context<'_, F> {
|
||||||
pub(super) fn import_notes_and_notetypes(
|
pub(super) fn import_notes_and_notetypes(
|
||||||
&mut self,
|
&mut self,
|
||||||
media_map: &mut MediaUseMap,
|
media_map: &mut MediaUseMap,
|
||||||
|
|
Loading…
Reference in a new issue