Implement the video adapter to retrieve the root folder content.

This commit is contained in:
Florian THIERRY
2026-07-14 21:35:55 +02:00
parent fc7eeb1d57
commit beb0134dfc
11 changed files with 90 additions and 29 deletions
+2 -2
View File
@@ -18,12 +18,12 @@ impl VideoService {
Self { video_port }
}
pub fn list_root_folder(self) -> Result<Vec<LibraryItem>, VideoError> {
pub fn list_root_folder(&self) -> Result<Vec<LibraryItem>, VideoError> {
let read_items_with_possibly_no_id = self.video_port.list_root_folder()?;
let items_with_id = read_items_with_possibly_no_id.iter()
.map(LibraryRawItem::map_to_library_item)
.collect();
self.video_port.save_all(items_with_id);
self.video_port.save_all(&items_with_id)?;
Ok(items_with_id)
}
}
@@ -1,17 +1,20 @@
use std::io::Read;
use uuid::Uuid;
#[derive(Clone, Copy)]
pub enum LibraryItemType {
VIDEO,
FOLDER
}
#[derive(Clone)]
pub struct LibraryItem {
pub id: Uuid,
pub name: String,
pub r#type: LibraryItemType,
}
#[derive(Clone)]
pub struct LibraryRawItem {
pub id: Option<Uuid>,
pub name: String,
@@ -21,7 +24,7 @@ impl LibraryRawItem {
pub fn map_to_library_item(&self) -> LibraryItem {
LibraryItem {
id: self.id.unwrap_or(Uuid::new_v4()),
name: self.name,
name: self.name.clone(),
r#type: self.r#type,
}
}
+1
View File
@@ -8,6 +8,7 @@ pub trait VideoPort: Send + Sync {
fn list_folder(&self, folder_id: Uuid) -> Result<Vec<LibraryRawItem>, VideoError>;
fn get_video_stream(&self, video_id: Uuid) -> Result<Video, VideoError>;
fn save(&self, library_item: &LibraryItem) -> Result<(), VideoError>;
fn save_all(&self, library_items: &Vec<LibraryItem>) -> Result<(), VideoError>;
fn clone_box(&self) -> Box<dyn VideoPort>;
}
+3 -2
View File
@@ -2,7 +2,7 @@ extern crate core;
use actix_web::web::ServiceConfig;
use actix_web::{get, web, HttpResponse, Responder};
use crate::video::handler::download_file;
use crate::video::handler::{download_file, get_root_folder_content};
pub mod user;
pub mod video;
@@ -13,7 +13,8 @@ async fn health() -> impl Responder {
}
pub fn init(cfg: &mut ServiceConfig) {
cfg.service(download_file);
cfg.service(download_file)
.service(get_root_folder_content);
cfg.default_service(web::to(not_found));
}
+21 -1
View File
@@ -1,7 +1,12 @@
use actix_web::{get, HttpResponse, Responder};
use std::sync::Arc;
use actix_web::{get, web, HttpResponse, Responder};
use tokio::fs::File;
use tokio_util::codec::{BytesCodec, FramedRead};
use futures_util::stream::StreamExt;
use lumiere_application::video::service::VideoService;
use lumiere_domain::video::error::VideoError;
use lumiere_domain::video::model::library_item::LibraryItem;
use crate::video::model::LibraryItemDto;
#[get("/download")]
pub async fn download_file() -> impl Responder {
@@ -15,3 +20,18 @@ pub async fn download_file() -> impl Responder {
}
})
}
#[get("/library")]
pub async fn get_root_folder_content(
video_service: web::Data<Arc<VideoService>>
) -> impl Responder {
match video_service.list_root_folder() {
Ok(library_items) => {
let result: Vec<LibraryItemDto> = library_items.iter()
.map(LibraryItemDto::new)
.collect();
HttpResponse::Ok().json(result)
}
Err(_) => HttpResponse::InternalServerError().finish()
}
}
+1
View File
@@ -1,2 +1,3 @@
pub mod handler;
pub mod model;
pub mod video_format_content_type_mapper;
+27
View File
@@ -0,0 +1,27 @@
use lumiere_domain::video::model::library_item::{LibraryItem, LibraryItemType};
use serde::Serialize;
use uuid::Uuid;
#[derive(Serialize)]
pub struct LibraryItemDto {
pub id: Uuid,
pub name: String,
pub r#type: String
}
impl LibraryItemDto {
pub fn new(library_item: &LibraryItem) -> Self {
Self {
id: library_item.id.clone(),
name: library_item.name.clone(),
r#type: Self::map_type_to_string(library_item.r#type)
}
}
fn map_type_to_string(r#type: LibraryItemType) -> String {
match r#type {
LibraryItemType::VIDEO => String::from("VIDEO"),
LibraryItemType::FOLDER => String::from("FOLDER")
}
}
}
@@ -1,11 +1,11 @@
use lumiere_domain::video::library_item::VideoFormat;
pub fn map_to_content_type(video_format: &VideoFormat) -> &'static str {
match video_format {
VideoFormat::AVI => "video/x-msvideo",
VideoFormat::MKV => "video/x-matroska",
VideoFormat::MP4 => "video/mp4",
VideoFormat::WEBM => "video/webm",
VideoFormat::UNKNOWN => "application/octet-stream"
}
}
// use lumiere_domain::video::library_item::VideoFormat;
//
// pub fn map_to_content_type(video_format: &VideoFormat) -> &'static str {
// match video_format {
// VideoFormat::AVI => "video/x-msvideo",
// VideoFormat::MKV => "video/x-matroska",
// VideoFormat::MP4 => "video/mp4",
// VideoFormat::WEBM => "video/webm",
// VideoFormat::UNKNOWN => "application/octet-stream"
// }
// }
+12 -11
View File
@@ -6,6 +6,7 @@ use uuid::Uuid;
use std::env;
use std::fs;
#[derive(Clone)]
pub struct VideoAdapter {
}
@@ -50,20 +51,16 @@ impl VideoAdapter {
Ok(items)
}
pub fn get_all_library_items_from_db(&self) -> Result<Vec<LibraryRawItem>, VideoError> {
fn get_all_library_items_from_db(&self) -> Result<Vec<LibraryRawItem>, VideoError> {
Ok(vec!())
}
fn merge_item_lists(file_system_items: Vec<LibraryRawItem>, db_items: Vec<LibraryRawItem>) -> Vec<LibraryRawItem> {
let mut all_items: Vec<LibraryRawItem> = Vec::new();
let file_system_items_which_are_not_in_database: Vec<LibraryRawItem> = file_system_items.into_iter()
.filter(|file_system_item| !Self::does_item_belong_to_db_items(&db_items, &file_system_item))
.collect();
db_items.iter().for_each(|item| all_items.push(*item));
file_system_items.iter()
.filter(|file_system_item| Self::does_item_belong_to_db_items(&db_items, file_system_item))
.for_each(|file_system_item| all_items.push(*file_system_item));
all_items
db_items.into_iter().chain(file_system_items_which_are_not_in_database).collect()
}
fn does_item_belong_to_db_items(database_items: &Vec<LibraryRawItem>, file_system_item: &LibraryRawItem) -> bool {
@@ -90,11 +87,15 @@ impl VideoPort for VideoAdapter {
todo!()
}
fn save(&self, library_item: LibraryItem) -> Result<(), VideoError> {
fn save(&self, library_item: &LibraryItem) -> Result<(), VideoError> {
todo!()
}
fn save_all(&self, library_items: &Vec<LibraryItem>) -> Result<(), VideoError> {
Ok(())
}
fn clone_box(&self) -> Box<dyn VideoPort> {
todo!()
Box::new(self.clone())
}
}
@@ -8,6 +8,7 @@ use std::io::{Error, ErrorKind};
use std::sync::{Arc, Mutex};
use lumiere_application::configuration::service::ConfigurationService;
use lumiere_application::user::service::UserService;
use lumiere_application::video::service::VideoService;
use lumiere_infrastructure::common::database_connection::DatabaseConnection;
use lumiere_infrastructure::common::database_initialisation::initialise_database_tables;
use lumiere_infrastructure::configuration::adapter::ConfigurationSqliteAdapter;
@@ -16,11 +17,13 @@ use lumiere_infrastructure::user::adapter::UserSqliteAdapter;
use lumiere_infrastructure::user::diesel_adapter::UserDieselAdapter;
use lumiere_infrastructure::user::diesel_repository::UserDieselRepository;
use lumiere_infrastructure::user::repository::UserSqliteRepository;
use lumiere_infrastructure::video::adapter::VideoAdapter;
pub struct ApplicationContext {
pub database_connection: Arc<Mutex<Connection>>,
pub configuration_service: ConfigurationService,
pub user_service: UserService,
pub video_service: VideoService,
}
impl ApplicationContext {
@@ -57,10 +60,14 @@ impl ApplicationContext {
// let user_adapter = Box::new(UserSqliteAdapter::new(user_repository.clone()));
let user_service = UserService::new(configuration_service.clone(), user_adapter.clone());
let video_adapter = Box::new(VideoAdapter::new());
let video_service = VideoService::new(video_adapter.clone());
Self {
database_connection: arc_mutex_connection.clone(),
configuration_service,
user_service,
video_service,
}
}
+1 -1
View File
@@ -12,7 +12,6 @@ use std::io::{BufReader, Error};
use std::path::Path;
use std::sync::Arc;
use lumiere_exposition::init;
use lumiere_exposition::video::video_format_content_type_mapper::map_to_content_type;
use lumiere_infrastructure::video::video_format_detector::get_content_type;
use tokio_cron_scheduler::{Job, JobScheduler};
@@ -35,6 +34,7 @@ async fn main() -> std::io::Result<()> {
let server = HttpServer::new(
move || App::new().configure(init)
.app_data(web::Data::new(Arc::new(application_context.user_service.clone())))
.app_data(web::Data::new(Arc::new(application_context.video_service.clone())))
)
.bind("0.0.0.0:19000")
// .bind_rustls_0_23(("0.0.0.0", 19000), tls_config)