diff --git a/rslib/src/media/files.rs b/rslib/src/media/files.rs index c5523f5f1..b6bd4d192 100644 --- a/rslib/src/media/files.rs +++ b/rslib/src/media/files.rs @@ -267,24 +267,26 @@ pub(super) fn add_file_from_ankiweb( fname: &str, data: &[u8], ) -> Result { + let sha1 = sha1_of_data(data); let normalized = normalize_filename(fname); - let path = media_folder.join(normalized.as_ref()); - fs::write(&path, data)?; - - let sha1 = sha1_of_data(data); + // if the filename is already valid, we can write the file directly + let (renamed_from, path) = if let Cow::Borrowed(_) = normalized { + let path = media_folder.join(normalized.as_ref()); + fs::write(&path, data)?; + (None, path) + } else { + debug!("non-normalized filename received {}", fname); + // ankiweb sent us a non-normalized filename, so we'll rename it + let new_name = add_data_to_folder_uniquely(media_folder, fname, data, sha1)?; + ( + Some(new_name.to_string()), + media_folder.join(new_name.as_ref()), + ) + }; let mtime = mtime_as_i64(path)?; - // fixme: could we use the info sent from the server for the hash instead - // of hashing it here and returning hash? - - let renamed_from = if let Cow::Borrowed(_) = normalized { - None - } else { - Some(fname.to_string()) - }; - Ok(AddedFile { fname: normalized.to_string(), sha1, diff --git a/rslib/src/media/sync.rs b/rslib/src/media/sync.rs index 2bbdb58a1..94cfdb362 100644 --- a/rslib/src/media/sync.rs +++ b/rslib/src/media/sync.rs @@ -24,7 +24,7 @@ static SYNC_MAX_FILES: usize = 25; static SYNC_MAX_BYTES: usize = (2.5 * 1024.0 * 1024.0) as usize; static SYNC_SINGLE_FILE_MAX_BYTES: usize = 100 * 1024 * 1024; -// fixme: non-normalized filenames on ankiweb +// fixme: dir mod handling when downloading files in a sync // fixme: concurrent modifications during upload step /// The counts are not cumulative - the progress hook should accumulate them. @@ -507,18 +507,41 @@ fn record_removals(ctx: &mut MediaDatabaseContext, removals: &[&String]) -> Resu fn record_additions(ctx: &mut MediaDatabaseContext, additions: Vec) -> Result<()> { for file in additions { - let entry = MediaEntry { - fname: file.fname.to_string(), - sha1: Some(file.sha1), - mtime: file.mtime, - sync_required: false, - }; - debug!( - "marking added: {} {}", - entry.fname, - hex::encode(entry.sha1.as_ref().unwrap()) - ); - ctx.set_entry(&entry)?; + if let Some(renamed) = file.renamed_from { + // the file AnkiWeb sent us wasn't normalized, so we need to record + // the old file name as a deletion + debug!("marking non-normalized file as deleted: {}", renamed); + let mut entry = MediaEntry { + fname: renamed, + sha1: None, + mtime: 0, + sync_required: true, + }; + ctx.set_entry(&entry)?; + // and upload the new filename to ankiweb + debug!("marking renamed file as needing upload: {}", file.fname); + entry = MediaEntry { + fname: file.fname.to_string(), + sha1: Some(file.sha1), + mtime: file.mtime, + sync_required: true, + }; + ctx.set_entry(&entry)?; + } else { + // a normal addition + let entry = MediaEntry { + fname: file.fname.to_string(), + sha1: Some(file.sha1), + mtime: file.mtime, + sync_required: false, + }; + debug!( + "marking added: {} {}", + entry.fname, + hex::encode(entry.sha1.as_ref().unwrap()) + ); + ctx.set_entry(&entry)?; + } } Ok(())