mirror of
https://github.com/ankitects/anki.git
synced 2025-09-21 15:32: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<()> {
|
fn import_notes(&mut self, notes: Vec<Note>, progress_fn: &mut ProgressFn) -> Result<()> {
|
||||||
let mut progress = IncrementalProgress::new(|u| progress_fn(ImportProgress::Notes(u)));
|
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()?;
|
progress.increment()?;
|
||||||
if let Some(notetype_id) = self.remapped_notetypes.get(¬e.notetype_id) {
|
if let Some(notetype_id) = self.remapped_notetypes.get(¬e.notetype_id) {
|
||||||
if self.target_guids.contains_key(¬e.guid) {
|
if self.target_guids.contains_key(¬e.guid) {
|
||||||
|
|
|
@ -48,7 +48,7 @@ pub fn import_colpkg(
|
||||||
|
|
||||||
restore_media(
|
restore_media(
|
||||||
&meta,
|
&meta,
|
||||||
progress_fn,
|
&mut progress_fn,
|
||||||
&mut archive,
|
&mut archive,
|
||||||
target_media_folder,
|
target_media_folder,
|
||||||
media_db,
|
media_db,
|
||||||
|
@ -88,17 +88,13 @@ fn restore_media(
|
||||||
}
|
}
|
||||||
|
|
||||||
std::fs::create_dir_all(media_folder)?;
|
std::fs::create_dir_all(media_folder)?;
|
||||||
|
|
||||||
let media_manager = MediaManager::new(media_folder, media_db)?;
|
let media_manager = MediaManager::new(media_folder, media_db)?;
|
||||||
let mut db_progress_fn = |u| progress_fn(ImportProgress::MediaCheck(u)).is_ok();
|
let mut media_comparer = MediaComparer::new(meta, &mut progress_fn, &media_manager, log)?;
|
||||||
media_manager.register_changes(&mut db_progress_fn, log)?;
|
|
||||||
|
|
||||||
let mut get_checksum = media_manager.checksum_getter();
|
|
||||||
let mut progress = IncrementalProgress::new(|u| progress_fn(ImportProgress::Media(u)));
|
let mut progress = IncrementalProgress::new(|u| progress_fn(ImportProgress::Media(u)));
|
||||||
|
for mut entry in media_entries {
|
||||||
for entry in &media_entries {
|
|
||||||
progress.increment()?;
|
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(())
|
Ok(())
|
||||||
|
@ -108,12 +104,16 @@ fn maybe_restore_media_file(
|
||||||
meta: &Meta,
|
meta: &Meta,
|
||||||
media_folder: &Path,
|
media_folder: &Path,
|
||||||
archive: &mut ZipArchive<File>,
|
archive: &mut ZipArchive<File>,
|
||||||
entry: &SafeMediaEntry,
|
entry: &mut SafeMediaEntry,
|
||||||
get_checksum: &mut impl FnMut(&str) -> Result<Option<Sha1Hash>>,
|
media_comparer: &mut MediaComparer,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let file_path = entry.file_path(media_folder);
|
let file_path = entry.file_path(media_folder);
|
||||||
let mut zip_file = entry.fetch_file(archive)?;
|
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 {
|
if !already_exists {
|
||||||
restore_media_file(meta, &mut zip_file, &file_path)?;
|
restore_media_file(meta, &mut zip_file, &file_path)?;
|
||||||
};
|
};
|
||||||
|
@ -150,3 +150,31 @@ fn copy_collection(
|
||||||
|
|
||||||
Ok(())
|
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.
|
/// Like [MediaEntry], but with a safe filename and set zip filename.
|
||||||
pub(super) struct SafeMediaEntry {
|
pub(super) struct SafeMediaEntry {
|
||||||
pub(super) name: String,
|
pub(super) name: String,
|
||||||
#[allow(dead_code)]
|
|
||||||
pub(super) size: u32,
|
pub(super) size: u32,
|
||||||
pub(super) sha1: Sha1Hash,
|
pub(super) sha1: Sha1Hash,
|
||||||
pub(super) index: usize,
|
pub(super) index: usize,
|
||||||
|
@ -86,19 +85,15 @@ impl SafeMediaEntry {
|
||||||
.map_err(|_| AnkiError::invalid_input(&format!("{} missing from archive", self.index)))
|
.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,
|
&self,
|
||||||
meta: &Meta,
|
|
||||||
self_zipped: &ZipFile,
|
|
||||||
other_path: &Path,
|
|
||||||
get_checksum: &mut impl FnMut(&str) -> Result<Option<Sha1Hash>>,
|
get_checksum: &mut impl FnMut(&str) -> Result<Option<Sha1Hash>>,
|
||||||
) -> Result<bool> {
|
) -> 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))
|
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(
|
pub(super) fn copy_from_archive(
|
||||||
|
|
Loading…
Reference in a new issue