Allow for excluding directories from Memories endpoint #37
@@ -14,4 +14,4 @@ You must have `ffmpeg` installed for streaming video and generating video thumbn
|
|||||||
- `BIND_URL` is the url and port to bind to (typically your own IP address)
|
- `BIND_URL` is the url and port to bind to (typically your own IP address)
|
||||||
- `SECRET_KEY` is the *hopefully* random string to sign Tokens with
|
- `SECRET_KEY` is the *hopefully* random string to sign Tokens with
|
||||||
- `RUST_LOG` is one of `off, error, warn, info, debug, trace`, from least to most noisy [error is default]
|
- `RUST_LOG` is one of `off, error, warn, info, debug, trace`, from least to most noisy [error is default]
|
||||||
|
- `EXCLUDED_DIRS` is a comma separated list of directories to exclude from the Memories API
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use opentelemetry::KeyValue;
|
|||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::path::PathBuf;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
use crate::data::Claims;
|
use crate::data::Claims;
|
||||||
@@ -134,10 +135,11 @@ 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) = regex::Regex::new(r"Screenshot_(\d{4})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(\d{2})")
|
if let Some(captures) =
|
||||||
.ok()?
|
regex::Regex::new(r"Screenshot_(\d{4})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(\d{2})")
|
||||||
.captures(filename)
|
.ok()?
|
||||||
.and_then(|c| build_date_from_ymd_capture(&c))
|
.captures(filename)
|
||||||
|
.and_then(|c| build_date_from_ymd_capture(&c))
|
||||||
{
|
{
|
||||||
return Some(captures);
|
return Some(captures);
|
||||||
}
|
}
|
||||||
@@ -232,11 +234,33 @@ pub async fn list_memories(
|
|||||||
|
|
||||||
let base = Path::new(&app_state.base_path);
|
let base = Path::new(&app_state.base_path);
|
||||||
|
|
||||||
|
// Build a list of excluded directories with full paths
|
||||||
|
let excluded_paths: Vec<PathBuf> = app_state
|
||||||
|
.excluded_dirs
|
||||||
|
.iter()
|
||||||
|
.map(|dir| base.join(dir))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
debug!("Excluded directories: {:?}", excluded_paths);
|
||||||
|
|
||||||
let entries: Vec<_> = WalkDir::new(base)
|
let entries: Vec<_> = 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| {
|
||||||
.filter(|e| is_image_or_video(e.path()))
|
// Skip excluded directories
|
||||||
|
if !excluded_paths.is_empty() {
|
||||||
|
let path = e.path();
|
||||||
|
for excluded in &excluded_paths {
|
||||||
|
if path.starts_with(excluded) {
|
||||||
|
debug!("Skipping excluded path: {:?}", path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
})
|
||||||
|
.filter(|e| e.file_type().is_file() && is_image_or_video(e.path()))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut memories_with_dates: Vec<(MemoryItem, NaiveDate)> = entries
|
let mut memories_with_dates: Vec<(MemoryItem, NaiveDate)> = entries
|
||||||
@@ -310,6 +334,7 @@ pub async fn list_memories(
|
|||||||
client_timezone.unwrap_or_else(|| FixedOffset::east_opt(0).unwrap())
|
client_timezone.unwrap_or_else(|| FixedOffset::east_opt(0).unwrap())
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
KeyValue::new("excluded_dirs", format!("{:?}", app_state.excluded_dirs)),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
span.set_status(Status::Ok);
|
span.set_status(Status::Ok);
|
||||||
|
|||||||
15
src/state.rs
15
src/state.rs
@@ -9,6 +9,7 @@ pub struct AppState {
|
|||||||
pub thumbnail_path: String,
|
pub thumbnail_path: String,
|
||||||
pub video_path: String,
|
pub video_path: String,
|
||||||
pub gif_path: String,
|
pub gif_path: String,
|
||||||
|
pub excluded_dirs: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppState {
|
impl AppState {
|
||||||
@@ -18,6 +19,7 @@ impl AppState {
|
|||||||
thumbnail_path: String,
|
thumbnail_path: String,
|
||||||
video_path: String,
|
video_path: String,
|
||||||
gif_path: String,
|
gif_path: String,
|
||||||
|
excluded_dirs: Vec<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let playlist_generator = PlaylistGenerator::new();
|
let playlist_generator = PlaylistGenerator::new();
|
||||||
let video_playlist_manager =
|
let video_playlist_manager =
|
||||||
@@ -30,8 +32,19 @@ impl AppState {
|
|||||||
thumbnail_path,
|
thumbnail_path,
|
||||||
video_path,
|
video_path,
|
||||||
gif_path,
|
gif_path,
|
||||||
|
excluded_dirs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse excluded directories from environment variable
|
||||||
|
fn parse_excluded_dirs() -> Vec<String> {
|
||||||
|
env::var("EXCLUDED_DIRS")
|
||||||
|
.unwrap_or_default()
|
||||||
|
.split(',')
|
||||||
|
.filter(|dir| !dir.trim().is_empty())
|
||||||
|
.map(|dir| dir.trim().to_string())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AppState {
|
impl Default for AppState {
|
||||||
@@ -42,6 +55,7 @@ impl Default for AppState {
|
|||||||
env::var("THUMBNAILS").expect("THUMBNAILS was not set in the env"),
|
env::var("THUMBNAILS").expect("THUMBNAILS was not set in the env"),
|
||||||
env::var("VIDEO_PATH").expect("VIDEO_PATH was not set in the env"),
|
env::var("VIDEO_PATH").expect("VIDEO_PATH was not set in the env"),
|
||||||
env::var("GIFS_DIRECTORY").expect("GIFS_DIRECTORY was not set in the env"),
|
env::var("GIFS_DIRECTORY").expect("GIFS_DIRECTORY was not set in the env"),
|
||||||
|
Self::parse_excluded_dirs(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,6 +81,7 @@ impl AppState {
|
|||||||
thumbnail_path.to_string_lossy().to_string(),
|
thumbnail_path.to_string_lossy().to_string(),
|
||||||
video_path.to_string_lossy().to_string(),
|
video_path.to_string_lossy().to_string(),
|
||||||
gif_path.to_string_lossy().to_string(),
|
gif_path.to_string_lossy().to_string(),
|
||||||
|
Vec::new(), // No excluded directories for test state
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user