MediaRole auto-detection + manual role API + sync wiring (#7)
role_detector: classify items as Interstitial by collection name/tag patterns.
Wire chapter extraction + role detection into sync adapter (worker + presentation).
SQLite: persist/read role column, migration.
PUT /library/items/{id}/role endpoint for manual override.
This commit is contained in:
@@ -5,7 +5,7 @@ use crate::models::{
|
||||
LibraryCollection, LibrarySyncLogEntry, LibrarySyncResult, MediaItem,
|
||||
SeasonSummary, ShowSummary,
|
||||
};
|
||||
use crate::value_objects::{ContentType, LibrarySearchFilter};
|
||||
use crate::value_objects::{ContentType, LibrarySearchFilter, MediaRole};
|
||||
|
||||
use super::media::IMediaProvider;
|
||||
|
||||
@@ -18,6 +18,8 @@ pub trait LibraryCommand: Send + Sync {
|
||||
async fn log_sync_start(&self, provider_id: &str) -> DomainResult<i64>;
|
||||
|
||||
async fn log_sync_finish(&self, log_id: i64, result: &LibrarySyncResult) -> DomainResult<()>;
|
||||
|
||||
async fn update_role(&self, item_id: &str, role: MediaRole) -> DomainResult<()>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
||||
@@ -418,6 +418,18 @@ impl LibraryCommand for InMemoryLibraryRepository {
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
async fn update_role(&self, item_id: &str, role: crate::value_objects::MediaRole) -> DomainResult<()> {
|
||||
let mut store = self.items.lock().unwrap();
|
||||
if let Some(item) = store.get_mut(item_id) {
|
||||
item.set_role(role);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(crate::errors::DomainError::NotFound(format!(
|
||||
"Library item {item_id} not found"
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
async fn log_sync_finish(&self, log_id: i64, result: &LibrarySyncResult) -> DomainResult<()> {
|
||||
let mut logs = self.sync_logs.lock().unwrap();
|
||||
if let Some(entry) = logs.iter_mut().find(|e| e.id() == log_id) {
|
||||
|
||||
Reference in New Issue
Block a user