mirror of
https://github.com/ankitects/anki.git
synced 2025-09-21 07:22:23 -04:00
Avoid registering changes if hashes are not needed
This commit is contained in:
parent
146fd2a6b6
commit
76f4bf26ea
3 changed files with 46 additions and 23 deletions
|
@ -187,7 +187,7 @@ impl<'n> NoteContext<'n> {
|
|||
fn import_notes(&mut self, notes: Vec<Note>, progress_fn: &mut ProgressFn) -> Result<()> {
|
||||
let mut progress = IncrementalProgress::new(|u| progress_fn(ImportProgress::Notes(u)));
|
||||
|
||||
for mut note in notes.into_iter() {
|
||||
for mut note in notes {
|
||||
progress.increment()?;
|
||||
if let Some(notetype_id) = self.remapped_notetypes.get(¬e.notetype_id) {
|
||||
if self.target_guids.contains_key(¬e.guid) {
|
||||
|
|
|
@ -48,7 +48,7 @@ pub fn import_colpkg(
|
|||
|
||||
restore_media(
|
||||
&meta,
|
||||
progress_fn,
|
||||
&mut progress_fn,
|
||||
&mut archive,
|
||||
target_media_folder,
|
||||
media_db,
|
||||
|
@ -88,17 +88,13 @@ fn restore_media(
|
|||
}
|
||||
|
||||
std::fs::create_dir_all(media_folder)?;
|
||||
|
||||
let media_manager = MediaManager::new(media_folder, media_db)?;
|
||||
let mut db_progress_fn = |u| progress_fn(ImportProgress::MediaCheck(u)).is_ok();
|
||||
media_manager.register_changes(&mut db_progress_fn, log)?;
|
||||
let mut media_comparer = MediaComparer::new(meta, &mut progress_fn, &media_manager, log)?;
|
||||
|
||||
let mut get_checksum = media_manager.checksum_getter();
|
||||
let mut progress = IncrementalProgress::new(|u| progress_fn(ImportProgress::Media(u)));
|
||||
|
||||
for entry in &media_entries {
|
||||
for mut entry in media_entries {
|
||||
progress.increment()?;
|
||||
maybe_restore_media_file(meta, media_folder, archive, entry, &mut get_checksum)?;
|
||||
maybe_restore_media_file(meta, media_folder, archive, &mut entry, &mut media_comparer)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -108,12 +104,16 @@ fn maybe_restore_media_file(
|
|||
meta: &Meta,
|
||||
media_folder: &Path,
|
||||
archive: &mut ZipArchive<File>,
|
||||
entry: &SafeMediaEntry,
|
||||
get_checksum: &mut impl FnMut(&str) -> Result<Option<Sha1Hash>>,
|
||||
entry: &mut SafeMediaEntry,
|
||||
media_comparer: &mut MediaComparer,
|
||||
) -> Result<()> {
|
||||
let file_path = entry.file_path(media_folder);
|
||||
let mut zip_file = entry.fetch_file(archive)?;
|
||||
let already_exists = entry.is_equal_to(meta, &zip_file, &file_path, get_checksum)?;
|
||||
if meta.media_list_is_hashmap() {
|
||||
entry.size = zip_file.size() as u32;
|
||||
}
|
||||
|
||||
let already_exists = media_comparer.entry_is_equal_to(entry, &file_path)?;
|
||||
if !already_exists {
|
||||
restore_media_file(meta, &mut zip_file, &file_path)?;
|
||||
};
|
||||
|
@ -150,3 +150,31 @@ fn copy_collection(
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
struct MediaComparer<'a>(Option<Box<dyn FnMut(&str) -> Result<Option<Sha1Hash>> + 'a>>);
|
||||
|
||||
impl<'a> MediaComparer<'a> {
|
||||
fn new(
|
||||
meta: &Meta,
|
||||
mut progress_fn: impl FnMut(ImportProgress) -> Result<()>,
|
||||
media_manager: &'a MediaManager,
|
||||
log: &Logger,
|
||||
) -> Result<Self> {
|
||||
Ok(Self(if meta.media_list_is_hashmap() {
|
||||
None
|
||||
} else {
|
||||
let mut db_progress_fn = |u| progress_fn(ImportProgress::MediaCheck(u)).is_ok();
|
||||
media_manager.register_changes(&mut db_progress_fn, log)?;
|
||||
Some(Box::new(media_manager.checksum_getter()))
|
||||
}))
|
||||
}
|
||||
|
||||
fn entry_is_equal_to(&mut self, entry: &SafeMediaEntry, other_path: &Path) -> Result<bool> {
|
||||
if let Some(ref mut get_checksum) = self.0 {
|
||||
Ok(entry.has_checksum_equal_to(get_checksum)?)
|
||||
} else {
|
||||
Ok(entry.has_size_equal_to(other_path))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ use crate::{
|
|||
/// Like [MediaEntry], but with a safe filename and set zip filename.
|
||||
pub(super) struct SafeMediaEntry {
|
||||
pub(super) name: String,
|
||||
#[allow(dead_code)]
|
||||
pub(super) size: u32,
|
||||
pub(super) sha1: Sha1Hash,
|
||||
pub(super) index: usize,
|
||||
|
@ -86,19 +85,15 @@ impl SafeMediaEntry {
|
|||
.map_err(|_| AnkiError::invalid_input(&format!("{} missing from archive", self.index)))
|
||||
}
|
||||
|
||||
pub(super) fn is_equal_to(
|
||||
pub(super) fn has_checksum_equal_to(
|
||||
&self,
|
||||
meta: &Meta,
|
||||
self_zipped: &ZipFile,
|
||||
other_path: &Path,
|
||||
get_checksum: &mut impl FnMut(&str) -> Result<Option<Sha1Hash>>,
|
||||
) -> Result<bool> {
|
||||
if meta.media_list_is_hashmap() {
|
||||
Ok(fs::metadata(other_path)
|
||||
.map_or(false, |metadata| metadata.len() == self_zipped.size()))
|
||||
} else {
|
||||
get_checksum(&self.name).map(|opt| opt.map_or(false, |sha1| sha1 == self.sha1))
|
||||
}
|
||||
|
||||
pub(super) fn has_size_equal_to(&self, other_path: &Path) -> bool {
|
||||
fs::metadata(other_path).map_or(false, |metadata| metadata.len() == self.size as u64)
|
||||
}
|
||||
|
||||
pub(super) fn copy_from_archive(
|
||||
|
|
Loading…
Reference in a new issue