First working POC

This commit is contained in:
2026-01-26 22:21:54 +01:00
commit cfddc1edea
255 changed files with 77606 additions and 0 deletions
+173
View File
@@ -0,0 +1,173 @@
pub mod types;
pub mod online;
pub mod offline;
pub mod hybrid;
pub use types::*;
pub use online::OnlineRepository;
pub use offline::OfflineRepository;
pub use hybrid::HybridRepository;
use async_trait::async_trait;
/// Repository trait for media access (online, offline, or hybrid)
///
/// @req: UR-002 - Access media when online or offline
/// @req: UR-007 - Navigate media in library
/// @req: UR-008 - Search media across libraries
/// @req: IR-010 - Jellyfin API client for library browsing
/// @req: DR-012 - Local database for media metadata cache
/// @req: DR-013 - Repository pattern for online/offline data access
#[async_trait]
pub trait MediaRepository: Send + Sync {
/// Get all libraries
///
/// @req: UR-007 - Navigate media in library
/// @req: JA-003 - Get user library views
async fn get_libraries(&self) -> Result<Vec<Library>, RepoError>;
/// Get items in a library or parent
///
/// @req: UR-007 - Navigate media in library
/// @req: JA-004 - Get library items (paginated)
async fn get_items(
&self,
parent_id: &str,
options: Option<GetItemsOptions>,
) -> Result<SearchResult, RepoError>;
/// Get a single item by ID
///
/// @req: UR-007 - Navigate media in library
/// @req: JA-005 - Get item details and metadata
async fn get_item(&self, item_id: &str) -> Result<MediaItem, RepoError>;
/// Get latest items in a library
///
/// @req: UR-024 - View recently added content on server
/// @req: JA-016 - Get recently added items
async fn get_latest_items(
&self,
parent_id: &str,
limit: Option<usize>,
) -> Result<Vec<MediaItem>, RepoError>;
/// Get resume items (continue watching/listening)
///
/// @req: UR-019 - Resume playback from where you left off
/// @req: UR-023 - View "Next Up" / Continue Watching on home screen
/// @req: JA-015 - Get "Continue Watching" items
async fn get_resume_items(
&self,
parent_id: Option<&str>,
limit: Option<usize>,
) -> Result<Vec<MediaItem>, RepoError>;
/// Get next up episodes
///
/// @req: UR-023 - View "Next Up" / Continue Watching; auto-play next episode
/// @req: JA-014 - Get "Next Up" items
async fn get_next_up_episodes(
&self,
series_id: Option<&str>,
limit: Option<usize>,
) -> Result<Vec<MediaItem>, RepoError>;
/// Get recently played audio
async fn get_recently_played_audio(
&self,
limit: Option<usize>,
) -> Result<Vec<MediaItem>, RepoError>;
/// Get resume movies
async fn get_resume_movies(&self, limit: Option<usize>) -> Result<Vec<MediaItem>, RepoError>;
/// Get genres
async fn get_genres(&self, parent_id: Option<&str>) -> Result<Vec<Genre>, RepoError>;
/// Search for items
///
/// @req: UR-008 - Search media across libraries
/// @req: JA-006 - Search across libraries
async fn search(
&self,
query: &str,
options: Option<SearchOptions>,
) -> Result<SearchResult, RepoError>;
/// Get playback info for streaming
///
/// @req: UR-003 - Play videos
/// @req: UR-004 - Play audio uninterrupted
/// @req: JA-007 - Get playback info and stream URL
async fn get_playback_info(&self, item_id: &str) -> Result<PlaybackInfo, RepoError>;
/// Get audio stream URL for a track
///
/// @req: UR-004 - Play audio uninterrupted
/// @req: JA-007 - Get playback info and stream URL
async fn get_audio_stream_url(&self, item_id: &str) -> Result<String, RepoError>;
/// Report playback start
///
/// @req: UR-025 - Sync watch history and progress back to Jellyfin
/// @req: JA-010 - Report playback start
async fn report_playback_start(
&self,
item_id: &str,
position_ticks: i64,
) -> Result<(), RepoError>;
/// Report playback progress
///
/// @req: UR-025 - Sync watch history and progress back to Jellyfin
/// @req: JA-011 - Report playback progress (periodic)
async fn report_playback_progress(
&self,
item_id: &str,
position_ticks: i64,
) -> Result<(), RepoError>;
/// Report playback stopped
///
/// @req: UR-025 - Sync watch history and progress back to Jellyfin
/// @req: JA-012 - Report playback stopped
async fn report_playback_stopped(
&self,
item_id: &str,
position_ticks: i64,
) -> Result<(), RepoError>;
/// Get image URL (synchronous - just constructs URL)
fn get_image_url(
&self,
item_id: &str,
image_type: ImageType,
options: Option<ImageOptions>,
) -> String;
/// Mark item as favorite
async fn mark_favorite(&self, item_id: &str) -> Result<(), RepoError>;
/// Unmark item as favorite
async fn unmark_favorite(&self, item_id: &str) -> Result<(), RepoError>;
/// Get person details
async fn get_person(&self, person_id: &str) -> Result<MediaItem, RepoError>;
/// Get items by person (filmography)
async fn get_items_by_person(
&self,
person_id: &str,
options: Option<GetItemsOptions>,
) -> Result<SearchResult, RepoError>;
/// Get similar/related items for a movie or show
///
/// @req: UR-009 - Discover similar content based on current item
async fn get_similar_items(
&self,
item_id: &str,
limit: Option<usize>,
) -> Result<SearchResult, RepoError>;
}