Use rayon for memories endpoint
This commit is contained in:
@@ -5,6 +5,7 @@ use chrono::{DateTime, Datelike, FixedOffset, Local, LocalResult, NaiveDate, Tim
|
|||||||
use log::{debug, trace, warn};
|
use log::{debug, trace, warn};
|
||||||
use opentelemetry::trace::{Span, Status, Tracer};
|
use opentelemetry::trace::{Span, Status, Tracer};
|
||||||
use opentelemetry::KeyValue;
|
use opentelemetry::KeyValue;
|
||||||
|
use rayon::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
@@ -133,8 +134,7 @@ fn extract_date_from_filename(filename: &str) -> Option<DateTime<FixedOffset>> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 1. Screenshot format: Screenshot_2014-06-01-20-44-50.png
|
// 1. Screenshot format: Screenshot_2014-06-01-20-44-50.png
|
||||||
if let Some(captures) =
|
if let Some(captures) = regex::Regex::new(r"Screenshot_(\d{4})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(\d{2})")
|
||||||
regex::Regex::new(r"Screenshot_(\d{4})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(\d{2})")
|
|
||||||
.ok()?
|
.ok()?
|
||||||
.captures(filename)
|
.captures(filename)
|
||||||
.and_then(|c| build_date_from_ymd_capture(&c))
|
.and_then(|c| build_date_from_ymd_capture(&c))
|
||||||
@@ -169,19 +169,25 @@ fn extract_date_from_filename(filename: &str) -> Option<DateTime<FixedOffset>> {
|
|||||||
|
|
||||||
// Millisecond timestamp (13 digits)
|
// Millisecond timestamp (13 digits)
|
||||||
if timestamp_str.len() >= 13 {
|
if timestamp_str.len() >= 13 {
|
||||||
if let Ok(ts_millis) = timestamp_str[0..13].parse::<i64>() {
|
if let Some(date_time) = timestamp_str[0..13]
|
||||||
if let Some(naive_dt) = DateTime::from_timestamp_millis(ts_millis) {
|
.parse::<i64>()
|
||||||
return Some(naive_dt.fixed_offset());
|
.ok()
|
||||||
}
|
.and_then(|timestamp_millis| DateTime::from_timestamp_millis(timestamp_millis))
|
||||||
|
.map(|naive_dt| naive_dt.fixed_offset())
|
||||||
|
{
|
||||||
|
return Some(date_time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second timestamp (10 digits)
|
// Second timestamp (10 digits)
|
||||||
if timestamp_str.len() >= 10 {
|
if timestamp_str.len() >= 10 {
|
||||||
if let Ok(ts_secs) = timestamp_str[0..10].parse::<i64>() {
|
if let Some(date_time) = timestamp_str[0..10]
|
||||||
if let Some(naive_dt) = DateTime::from_timestamp(ts_secs, 0) {
|
.parse::<i64>()
|
||||||
return Some(naive_dt.fixed_offset());
|
.ok()
|
||||||
}
|
.and_then(|timestamp_secs| DateTime::from_timestamp(timestamp_secs, 0))
|
||||||
|
.map(|naive_dt| naive_dt.fixed_offset())
|
||||||
|
{
|
||||||
|
return Some(date_time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,43 +232,46 @@ pub async fn list_memories(
|
|||||||
|
|
||||||
let base = Path::new(&app_state.base_path);
|
let base = Path::new(&app_state.base_path);
|
||||||
|
|
||||||
let mut memories_with_dates: Vec<(MemoryItem, NaiveDate)> = Vec::new();
|
let entries: Vec<_> = WalkDir::new(base)
|
||||||
|
|
||||||
for entry in WalkDir::new(base)
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|e| e.ok())
|
.filter_map(|e| e.ok())
|
||||||
.filter(|e| e.file_type().is_file())
|
.filter(|e| e.file_type().is_file())
|
||||||
{
|
.filter(|e| is_image_or_video(e.path()))
|
||||||
let path = entry.path();
|
.collect();
|
||||||
|
|
||||||
if !is_image_or_video(path) {
|
let mut memories_with_dates: Vec<(MemoryItem, NaiveDate)> = entries
|
||||||
continue;
|
.par_iter()
|
||||||
}
|
.filter_map(|entry| {
|
||||||
|
let path = entry.path();
|
||||||
|
|
||||||
// Get file date and timestamps in one operation
|
// Get file date and timestamps in one operation
|
||||||
let (file_date, created, modified) = match get_file_date_info(path, &client_timezone) {
|
let (file_date, created, modified) = match get_file_date_info(path, &client_timezone) {
|
||||||
Some(info) => info,
|
Some(info) => info,
|
||||||
None => {
|
None => {
|
||||||
warn!("No date info found for file: {:?}", path);
|
warn!("No date info found for file: {:?}", path);
|
||||||
continue;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_memories_match(file_date, now, span_mode, years_back) {
|
if is_memories_match(file_date, now, span_mode, years_back) {
|
||||||
if let Ok(rel) = path.strip_prefix(base) {
|
return if let Ok(rel) = path.strip_prefix(base) {
|
||||||
memories_with_dates.push((
|
Some((
|
||||||
MemoryItem {
|
MemoryItem {
|
||||||
path: rel.to_string_lossy().to_string(),
|
path: rel.to_string_lossy().to_string(),
|
||||||
created,
|
created,
|
||||||
modified,
|
modified,
|
||||||
},
|
},
|
||||||
file_date,
|
file_date,
|
||||||
));
|
))
|
||||||
} else {
|
} else {
|
||||||
warn!("Failed to strip prefix from path: {:?}", path);
|
warn!("Failed to strip prefix from path: {:?}", path);
|
||||||
|
None
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
None
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
match span_mode {
|
match span_mode {
|
||||||
// Sort by absolute time for a more 'overview'
|
// Sort by absolute time for a more 'overview'
|
||||||
|
|||||||
Reference in New Issue
Block a user