feature/exif-endpoint #44
@@ -130,8 +130,12 @@ fn get_file_date_info(
|
|||||||
// Read file metadata once
|
// Read file metadata once
|
||||||
let meta = std::fs::metadata(path).ok()?;
|
let meta = std::fs::metadata(path).ok()?;
|
||||||
|
|
||||||
// Extract metadata timestamps
|
// Get created timestamp (tries filename first, then metadata)
|
||||||
let metadata_created = meta.created().ok().map(|t| {
|
let path_str = path.to_str()?;
|
||||||
|
let created = get_created_timestamp_with_fallback(path_str, &meta, client_timezone);
|
||||||
|
|
||||||
|
// Get modified timestamp from metadata
|
||||||
|
let modified = meta.modified().ok().map(|t| {
|
||||||
let utc: DateTime<Utc> = t.into();
|
let utc: DateTime<Utc> = t.into();
|
||||||
if let Some(tz) = client_timezone {
|
if let Some(tz) = client_timezone {
|
||||||
utc.with_timezone(tz).timestamp()
|
utc.with_timezone(tz).timestamp()
|
||||||
@@ -140,16 +144,7 @@ fn get_file_date_info(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let metadata_modified = meta.modified().ok().map(|t| {
|
// Try to get date from filename for the NaiveDate
|
||||||
let utc: DateTime<Utc> = t.into();
|
|
||||||
if let Some(tz) = client_timezone {
|
|
||||||
utc.with_timezone(tz).timestamp()
|
|
||||||
} else {
|
|
||||||
utc.timestamp()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Try to get date from filename
|
|
||||||
if let Some(date_time) = path
|
if let Some(date_time) = path
|
||||||
.file_name()
|
.file_name()
|
||||||
.and_then(|filename| filename.to_str())
|
.and_then(|filename| filename.to_str())
|
||||||
@@ -162,20 +157,13 @@ fn get_file_date_info(
|
|||||||
date_time.with_timezone(&Local).fixed_offset()
|
date_time.with_timezone(&Local).fixed_offset()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use the timestamp from the filename date
|
|
||||||
let created_ts = date_in_timezone.timestamp();
|
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"File date from file {:?} > {:?} = {:?}",
|
"File date from file {:?} > {:?} = {:?}",
|
||||||
path.file_name(),
|
path.file_name(),
|
||||||
date_time,
|
date_time,
|
||||||
date_in_timezone
|
date_in_timezone
|
||||||
);
|
);
|
||||||
return Some((
|
return Some((date_in_timezone.date_naive(), created, modified));
|
||||||
date_in_timezone.date_naive(),
|
|
||||||
Some(created_ts),
|
|
||||||
metadata_modified,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall back to metadata if no date in filename
|
// Fall back to metadata if no date in filename
|
||||||
@@ -189,7 +177,7 @@ fn get_file_date_info(
|
|||||||
};
|
};
|
||||||
|
|
||||||
trace!("Fallback metadata create date = {:?}", date_in_timezone);
|
trace!("Fallback metadata create date = {:?}", date_in_timezone);
|
||||||
Some((date_in_timezone, metadata_created, metadata_modified))
|
Some((date_in_timezone, created, modified))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert Unix timestamp to NaiveDate in client timezone
|
/// Convert Unix timestamp to NaiveDate in client timezone
|
||||||
@@ -208,30 +196,35 @@ fn timestamp_to_naive_date(
|
|||||||
Some(date)
|
Some(date)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract created/modified timestamps from file metadata
|
/// Get created timestamp, trying filename parsing first, then falling back to metadata
|
||||||
fn extract_metadata_timestamps(
|
fn get_created_timestamp_with_fallback(
|
||||||
|
file_path: &str,
|
||||||
metadata: &std::fs::Metadata,
|
metadata: &std::fs::Metadata,
|
||||||
client_timezone: &Option<FixedOffset>,
|
client_timezone: &Option<FixedOffset>,
|
||||||
) -> (Option<i64>, Option<i64>) {
|
) -> Option<i64> {
|
||||||
let created = metadata.created().ok().map(|t| {
|
// Try to extract date from filename first
|
||||||
|
if let Some(filename_date) = Path::new(file_path)
|
||||||
|
.file_name()
|
||||||
|
.and_then(|f| f.to_str())
|
||||||
|
.and_then(extract_date_from_filename)
|
||||||
|
{
|
||||||
|
let timestamp = if let Some(tz) = client_timezone {
|
||||||
|
filename_date.with_timezone(tz).timestamp()
|
||||||
|
} else {
|
||||||
|
filename_date.timestamp()
|
||||||
|
};
|
||||||
|
return Some(timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to metadata
|
||||||
|
metadata.created().ok().map(|t| {
|
||||||
let utc: DateTime<Utc> = t.into();
|
let utc: DateTime<Utc> = t.into();
|
||||||
if let Some(tz) = client_timezone {
|
if let Some(tz) = client_timezone {
|
||||||
utc.with_timezone(tz).timestamp()
|
utc.with_timezone(tz).timestamp()
|
||||||
} else {
|
} else {
|
||||||
utc.timestamp()
|
utc.timestamp()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
let modified = metadata.modified().ok().map(|t| {
|
|
||||||
let utc: DateTime<Utc> = t.into();
|
|
||||||
if let Some(tz) = client_timezone {
|
|
||||||
utc.with_timezone(tz).timestamp()
|
|
||||||
} else {
|
|
||||||
utc.timestamp()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
(created, modified)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extract_date_from_filename(filename: &str) -> Option<DateTime<FixedOffset>> {
|
pub fn extract_date_from_filename(filename: &str) -> Option<DateTime<FixedOffset>> {
|
||||||
@@ -388,7 +381,16 @@ fn collect_exif_memories(
|
|||||||
|
|
||||||
// Get file metadata for created/modified timestamps
|
// Get file metadata for created/modified timestamps
|
||||||
let metadata = std::fs::metadata(&full_path).ok()?;
|
let metadata = std::fs::metadata(&full_path).ok()?;
|
||||||
let (created, modified) = extract_metadata_timestamps(&metadata, client_timezone);
|
let created =
|
||||||
|
get_created_timestamp_with_fallback(file_path, &metadata, client_timezone);
|
||||||
|
let modified = metadata.modified().ok().map(|t| {
|
||||||
|
let utc: DateTime<Utc> = t.into();
|
||||||
|
if let Some(tz) = client_timezone {
|
||||||
|
utc.with_timezone(tz).timestamp()
|
||||||
|
} else {
|
||||||
|
utc.timestamp()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Some((
|
Some((
|
||||||
MemoryItem {
|
MemoryItem {
|
||||||
|
|||||||
Reference in New Issue
Block a user