feat: enhance media management with EXIF data extraction, metadata filtering, and storage path generation

refactor: update configuration handling to use environment variables and improve code organization
This commit is contained in:
2025-11-14 11:22:51 +01:00
parent 70dc0a7131
commit 3c3b51a2a7
24 changed files with 393 additions and 181 deletions

View File

@@ -1,25 +1 @@
use libertas_core::{
config::{Config, DatabaseConfig, DatabaseType},
error::CoreResult,
};
pub fn load_config() -> CoreResult<Config> {
Ok(Config {
database: DatabaseConfig {
db_type: DatabaseType::Postgres,
url: "postgres://postgres:postgres@localhost:5432/libertas_db".to_string(),
},
server_address: "127.0.0.1:8080".to_string(),
jwt_secret: "super_secret_jwt_key".to_string(),
media_library_path: "media_library".to_string(),
broker_url: "nats://localhost:4222".to_string(),
max_upload_size_mb: Some(100),
default_storage_quota_gb: Some(10),
allowed_sort_columns: Some(vec![
"date_taken".to_string(),
"created_at".to_string(),
"original_filename".to_string(),
]),
thumbnail_config: None,
})
}
pub use libertas_core::config::load_config;

View File

@@ -4,10 +4,9 @@ use std::{
sync::Arc,
};
use chrono::Datelike;
use clap::Parser;
use libertas_core::{
config::Config, error::{CoreError, CoreResult}, media_utils::{extract_exif_data, parse_exif_datetime}, models::{Media, MediaMetadata, MediaMetadataSource, User}, repositories::{MediaMetadataRepository, MediaRepository, UserRepository}
config::AppConfig, error::{CoreError, CoreResult}, media_utils::{extract_exif_data, get_storage_path_and_date}, models::{Media, MediaMetadata, User}, repositories::{MediaMetadataRepository, MediaRepository, UserRepository}
};
use libertas_infra::factory::{build_database_pool, build_media_metadata_repository, build_media_repository, build_user_repository};
use serde_json;
@@ -30,7 +29,7 @@ struct Cli {
}
struct ImporterState {
config: Config,
config: AppConfig,
media_repo: Arc<dyn MediaRepository>,
user_repo: Arc<dyn UserRepository>,
metadata_repo: Arc<dyn MediaMetadataRepository>,
@@ -132,31 +131,22 @@ async fn process_file(file_path: &Path, user: &User, state: &ImporterState) -> C
}
};
let date_taken_str = extracted_data.all_tags.iter()
.find(|(source, tag_name, _)| {
*source == MediaMetadataSource::Exif &&
(tag_name == "DateTimeOriginal" || tag_name == "ModifyDate")
})
.map(|(_, _, tag_value)| tag_value);
let (storage_path_buf, _date_taken) =
get_storage_path_and_date(&extracted_data, &filename);
let date_taken = date_taken_str.and_then(|s| parse_exif_datetime(s));
let file_date = date_taken.unwrap_or_else(chrono::Utc::now);
let year = file_date.year().to_string();
let month = format!("{:02}", file_date.month());
let mut dest_path_buf = PathBuf::from(&state.config.media_library_path);
dest_path_buf.push(&year);
dest_path_buf.push(&month);
dest_path_buf.push(&storage_path_buf);
fs::create_dir_all(&dest_path_buf).await?;
println!(" -> Storing file at: {}", dest_path_buf.display());
dest_path_buf.push(&filename);
if let Some(parent) = dest_path_buf.parent() {
fs::create_dir_all(parent).await?;
}
fs::copy(file_path, &dest_path_buf).await?;
let storage_path_str = PathBuf::from(&year)
.join(&month)
.join(&filename)
.to_string_lossy()
.to_string();
let storage_path_str = storage_path_buf.to_string_lossy().to_string();
let mime_type = mime_guess::from_path(file_path)
.first_or_octet_stream()
.to_string();