fix(rust): Match Go CLI's album-based export directory structure
Switch from date-based (YYYY/MM-Month) to album-based directory structure to ensure compatibility with Go CLI. Files now export to AlbumName/ folders with "Uncategorized" for files without albums. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -440,43 +440,23 @@ fn generate_export_path(
|
||||
metadata: Option<&FileMetadata>,
|
||||
pub_magic_metadata: Option<&serde_json::Value>,
|
||||
) -> Result<PathBuf> {
|
||||
use chrono::{TimeZone, Utc};
|
||||
|
||||
// Start with export directory
|
||||
let mut path = export_dir.to_path_buf();
|
||||
|
||||
// Add date-based directory structure (YYYY/MM-MonthName)
|
||||
// Use updation_time as creation time proxy
|
||||
let datetime = Utc
|
||||
.timestamp_micros(file.updation_time)
|
||||
.single()
|
||||
.ok_or_else(|| crate::Error::Generic("Invalid timestamp".into()))?;
|
||||
|
||||
let year = datetime.format("%Y").to_string();
|
||||
let month = datetime.format("%m-%B").to_string(); // e.g., "01-January"
|
||||
|
||||
path.push(year);
|
||||
path.push(month);
|
||||
|
||||
// Add collection name if available
|
||||
if let Some(col) = collection
|
||||
// Match Go CLI structure: export_dir/AlbumName/filename
|
||||
// Use collection/album name as folder, or "Uncategorized" if none
|
||||
let album_folder = if let Some(col) = collection
|
||||
&& let Some(ref name) = col.name
|
||||
&& !name.is_empty()
|
||||
&& name != "Uncategorized"
|
||||
{
|
||||
// Sanitize collection name for filesystem
|
||||
let safe_name: String = name
|
||||
.chars()
|
||||
.map(|c| match c {
|
||||
'/' | '\\' | ':' | '*' | '?' | '"' | '<' | '>' | '|' => '_',
|
||||
c if c.is_control() => '_',
|
||||
c => c,
|
||||
})
|
||||
.collect::<String>()
|
||||
.trim()
|
||||
.to_string();
|
||||
path.push(safe_name);
|
||||
}
|
||||
// Sanitize collection name for filesystem (matching Go's approach)
|
||||
sanitize_album_name(name)
|
||||
} else {
|
||||
// Files without a collection go to "Uncategorized" (matching Go CLI)
|
||||
"Uncategorized".to_string()
|
||||
};
|
||||
|
||||
path.push(album_folder);
|
||||
|
||||
// Use filename from public magic metadata (edited name) or regular metadata
|
||||
let filename = {
|
||||
@@ -565,6 +545,19 @@ fn sanitize_filename(name: &str) -> String {
|
||||
.to_string()
|
||||
}
|
||||
|
||||
/// Sanitize an album/collection name for filesystem (matching Go CLI's logic)
|
||||
fn sanitize_album_name(name: &str) -> String {
|
||||
// Go CLI replaces : and / with _ in album names
|
||||
name.chars()
|
||||
.map(|c| match c {
|
||||
':' | '/' => '_',
|
||||
c => c,
|
||||
})
|
||||
.collect::<String>()
|
||||
.trim()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
/// Decrypt file metadata
|
||||
fn decrypt_file_metadata(
|
||||
file: &crate::api::models::File,
|
||||
|
||||
Reference in New Issue
Block a user