From 50023bad402bc3bb3a4c78089b9bf7617685dbaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Gro=C3=9Fe?= Date: Wed, 1 Feb 2023 19:06:00 +0000 Subject: [PATCH] Append suffix to download filenames to avoid overwrites (#35) --- src/windows/room/chat.rs | 60 +++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/src/windows/room/chat.rs b/src/windows/room/chat.rs index 1e06453..d6307a3 100644 --- a/src/windows/room/chat.rs +++ b/src/windows/room/chat.rs @@ -178,44 +178,42 @@ impl ChatState { None => settings.dirs.downloads.clone(), }; - let source = match &ev.content.msgtype { - MessageType::Audio(c) => { - if filename.is_dir() { - filename.push(c.body.as_str()); - } - - c.source.clone() - }, + let (source, msg_filename) = match &ev.content.msgtype { + MessageType::Audio(c) => (c.source.clone(), c.body.as_str()), MessageType::File(c) => { - if filename.is_dir() { - if let Some(name) = &c.filename { - filename.push(name); - } else { - filename.push(c.body.as_str()); - } - } - - c.source.clone() - }, - MessageType::Image(c) => { - if filename.is_dir() { - filename.push(c.body.as_str()); - } - - c.source.clone() - }, - MessageType::Video(c) => { - if filename.is_dir() { - filename.push(c.body.as_str()); - } - - c.source.clone() + (c.source.clone(), c.filename.as_deref().unwrap_or(c.body.as_str())) }, + MessageType::Image(c) => (c.source.clone(), c.body.as_str()), + MessageType::Video(c) => (c.source.clone(), c.body.as_str()), _ => { return Err(IambError::NoAttachment.into()); }, }; + if filename.is_dir() { + filename.push(msg_filename); + } + + if filename.exists() && !flags.contains(DownloadFlags::FORCE) { + // Find an incrementally suffixed filename, e.g. image-2.jpg -> image-3.jpg + if let Some(stem) = filename.file_stem().and_then(OsStr::to_str) { + let ext = filename.extension(); + let mut filename_incr = filename.clone(); + for n in 1..=1000 { + if let Some(ext) = ext.and_then(OsStr::to_str) { + filename_incr.set_file_name(format!("{}-{}.{}", stem, n, ext)); + } else { + filename_incr.set_file_name(format!("{}-{}", stem, n)); + } + + if !filename_incr.exists() { + filename = filename_incr; + break; + } + } + } + } + if !filename.exists() || flags.contains(DownloadFlags::FORCE) { let req = MediaRequest { source, format: MediaFormat::File };