Make apkg exporting on backend abortable

This commit is contained in:
RumovZ 2022-04-25 08:28:26 +02:00
parent e6dbe5b7f8
commit e4d36e71f3
5 changed files with 17 additions and 12 deletions

View file

@ -97,10 +97,14 @@ impl Backend {
} }
} }
fn export_progress_fn(&self) -> impl FnMut(usize) { fn export_progress_fn(&self) -> impl FnMut(usize) -> Result<()> {
let mut handler = self.new_progress_handler(); let mut handler = self.new_progress_handler();
move |media_files| { move |media_files| {
handler.update(Progress::Export(media_files), true); if handler.update(Progress::Export(media_files), true) {
Ok(())
} else {
Err(AnkiError::Interrupted)
}
} }
} }
} }

View file

@ -30,6 +30,7 @@ impl Collection {
with_scheduling: bool, with_scheduling: bool,
with_media: bool, with_media: bool,
media_fn: Option<Box<dyn FnOnce(HashSet<PathBuf>) -> MediaIter>>, media_fn: Option<Box<dyn FnOnce(HashSet<PathBuf>) -> MediaIter>>,
progress_fn: impl FnMut(usize) -> Result<()>,
progress_fn: impl FnMut(usize), progress_fn: impl FnMut(usize),
) -> Result<()> { ) -> Result<()> {
let temp_apkg = tempfile_in_parent_of(out_path.as_ref())?; let temp_apkg = tempfile_in_parent_of(out_path.as_ref())?;

View file

@ -36,7 +36,7 @@ fn roundtrip() {
true, true,
true, true,
None, None,
|_| (), |_| Ok(()),
) )
.unwrap(); .unwrap();
target_col.import_apkg(&apkg_path, &mut |_| Ok(())).unwrap(); target_col.import_apkg(&apkg_path, &mut |_| Ok(())).unwrap();

View file

@ -39,7 +39,7 @@ impl Collection {
out_path: impl AsRef<Path>, out_path: impl AsRef<Path>,
include_media: bool, include_media: bool,
legacy: bool, legacy: bool,
progress_fn: impl FnMut(usize), progress_fn: impl FnMut(usize) -> Result<()>,
) -> Result<()> { ) -> Result<()> {
let colpkg_name = out_path.as_ref(); let colpkg_name = out_path.as_ref();
let temp_colpkg = tempfile_in_parent_of(colpkg_name)?; let temp_colpkg = tempfile_in_parent_of(colpkg_name)?;
@ -103,7 +103,7 @@ fn export_collection_file(
media_dir: Option<PathBuf>, media_dir: Option<PathBuf>,
legacy: bool, legacy: bool,
tr: &I18n, tr: &I18n,
progress_fn: impl FnMut(usize), progress_fn: impl FnMut(usize) -> Result<()>,
) -> Result<()> { ) -> Result<()> {
let meta = if legacy { let meta = if legacy {
Meta::new_legacy() Meta::new_legacy()
@ -143,7 +143,7 @@ pub(crate) fn export_colpkg_from_data(
col_size, col_size,
MediaIter::empty(), MediaIter::empty(),
tr, tr,
|_| (), |_| Ok(()),
) )
} }
@ -154,7 +154,7 @@ pub(crate) fn export_collection(
col_size: usize, col_size: usize,
media: MediaIter, media: MediaIter,
tr: &I18n, tr: &I18n,
progress_fn: impl FnMut(usize), progress_fn: impl FnMut(usize) -> Result<()>,
) -> Result<()> { ) -> Result<()> {
let out_file = File::create(&out_path)?; let out_file = File::create(&out_path)?;
let mut zip = ZipWriter::new(out_file); let mut zip = ZipWriter::new(out_file);
@ -240,7 +240,7 @@ fn write_media(
meta: &Meta, meta: &Meta,
zip: &mut ZipWriter<File>, zip: &mut ZipWriter<File>,
media: MediaIter, media: MediaIter,
progress_fn: impl FnMut(usize), progress_fn: impl FnMut(usize) -> Result<()>,
) -> Result<()> { ) -> Result<()> {
let mut media_entries = vec![]; let mut media_entries = vec![];
write_media_files(meta, zip, media, &mut media_entries, progress_fn)?; write_media_files(meta, zip, media, &mut media_entries, progress_fn)?;
@ -284,12 +284,12 @@ fn write_media_files(
zip: &mut ZipWriter<File>, zip: &mut ZipWriter<File>,
media: MediaIter, media: MediaIter,
media_entries: &mut Vec<MediaEntry>, media_entries: &mut Vec<MediaEntry>,
mut progress_fn: impl FnMut(usize), mut progress_fn: impl FnMut(usize) -> Result<()>,
) -> Result<()> { ) -> Result<()> {
let mut copier = MediaCopier::new(meta); let mut copier = MediaCopier::new(meta);
for (index, res) in media.0.enumerate() { for (index, res) in media.0.enumerate() {
let path = res?; let path = res?;
progress_fn(index); progress_fn(index)?;
zip.start_file(index.to_string(), file_options_stored())?; zip.start_file(index.to_string(), file_options_stored())?;

View file

@ -41,7 +41,7 @@ fn roundtrip() -> Result<()> {
// export to a file // export to a file
let col = collection_with_media(dir, name)?; let col = collection_with_media(dir, name)?;
let colpkg_name = dir.join(format!("{name}.colpkg")); let colpkg_name = dir.join(format!("{name}.colpkg"));
col.export_colpkg(&colpkg_name, true, legacy, |_| ())?; col.export_colpkg(&colpkg_name, true, legacy, |_| Ok(()))?;
// import into a new collection // import into a new collection
let anki2_name = dir let anki2_name = dir
.join(format!("{name}.anki2")) .join(format!("{name}.anki2"))
@ -82,7 +82,7 @@ fn normalization_check_on_export() -> Result<()> {
// manually write a file in the wrong encoding. // manually write a file in the wrong encoding.
std::fs::write(col.media_folder.join("ぱぱ.jpg"), "nfd encoding")?; std::fs::write(col.media_folder.join("ぱぱ.jpg"), "nfd encoding")?;
assert_eq!( assert_eq!(
col.export_colpkg(&colpkg_name, true, false, |_| ()) col.export_colpkg(&colpkg_name, true, false, |_| Ok(()))
.unwrap_err(), .unwrap_err(),
AnkiError::MediaCheckRequired AnkiError::MediaCheckRequired
); );