refactor: http-axum split into api/html/federation modules, router.rs, templates per page group

This commit is contained in:
2026-10-25 21:46:03 +01:00
parent a931fb548f
commit 614aec8df9
97 changed files with 5317 additions and 5160 deletions

View File

@@ -4,6 +4,7 @@ pub mod diary;
pub mod goals;
pub mod import;
pub mod insights;
pub mod mappers;
pub mod movies;
pub mod rendering;
pub mod search;

View File

@@ -0,0 +1,20 @@
use crate::FeedEntryDto;
use domain::models::FeedEntry;
use super::movies::{movie_to_dto, review_to_dto};
pub fn feed_entry_to_dto(e: &FeedEntry) -> FeedEntryDto {
use domain::models::ReviewSource;
let actor_url = match e.review().source() {
ReviewSource::Remote { actor_url } => Some(actor_url.clone()),
ReviewSource::Local => None,
};
FeedEntryDto {
movie: movie_to_dto(e.movie()),
review: review_to_dto(e.review()),
user_id: e.review().user_id().value(),
user_display_name: e.user_display_name().to_string(),
is_federated: e.review().is_remote(),
actor_url,
}
}

View File

@@ -0,0 +1,12 @@
use crate::GoalDto;
pub fn goal_with_progress_to_dto(g: &domain::models::GoalWithProgress) -> GoalDto {
GoalDto {
year: g.goal.year(),
target_count: g.goal.target_count(),
current_count: g.current_count,
percentage: g.percentage(),
is_complete: g.is_complete(),
goal_type: g.goal.goal_type().clone(),
}
}

View File

@@ -0,0 +1,10 @@
//! Pure domain -> DTO mappers (depend only on `domain` and this crate).
mod diary;
mod goals;
mod movies;
mod search;
pub use diary::*;
pub use goals::*;
pub use movies::*;
pub use search::*;

View File

@@ -0,0 +1,50 @@
use crate::{DiaryEntryDto, MovieDto, ReviewDto};
use domain::models::{DiaryEntry, Movie, MovieSummary, Review};
pub fn movie_to_dto(movie: &Movie) -> MovieDto {
MovieDto {
id: movie.id().value(),
title: movie.title().value().to_string(),
release_year: movie.release_year().value(),
director: movie.director().map(|d| d.to_string()),
poster_path: movie.poster_path().map(|p| p.value().to_string()),
genres: vec![],
runtime_minutes: None,
original_language: None,
overview: None,
collection_name: None,
}
}
pub fn summary_to_dto(summary: &MovieSummary) -> MovieDto {
MovieDto {
id: summary.movie.id().value(),
title: summary.movie.title().value().to_string(),
release_year: summary.movie.release_year().value(),
director: summary.movie.director().map(|d| d.to_string()),
poster_path: summary.movie.poster_path().map(|p| p.value().to_string()),
genres: summary.genres.clone(),
runtime_minutes: summary.runtime_minutes,
original_language: summary.original_language.clone(),
overview: summary.overview.clone(),
collection_name: summary.collection_name.clone(),
}
}
pub fn review_to_dto(review: &Review) -> ReviewDto {
ReviewDto {
id: review.id().value(),
rating: review.rating().value(),
comment: review.comment().map(|c| c.value().to_string()),
watched_at: domain::value_objects::format_watched_at(review.watched_at()),
watch_medium: review.watch_medium().copied(),
spoilers: review.spoilers(),
}
}
pub fn entry_to_dto(entry: &DiaryEntry) -> DiaryEntryDto {
DiaryEntryDto {
movie: movie_to_dto(entry.movie()),
review: review_to_dto(entry.review()),
}
}

View File

@@ -0,0 +1,22 @@
use crate::search::PersonDto;
use domain::models::person::Person;
pub fn person_to_dto(p: &Person) -> PersonDto {
PersonDto {
id: p.id().value(),
external_id: p.external_id().value().to_string(),
name: p.name().to_string(),
known_for_department: p.known_for_department().map(str::to_string),
profile_path: p.profile_path().map(str::to_string),
biography: p.biography().map(str::to_string),
birthday: p.birthday().map(|d| d.to_string()),
deathday: p.deathday().map(|d| d.to_string()),
place_of_birth: p.place_of_birth().map(str::to_string),
also_known_as: p.also_known_as().to_vec(),
homepage: p.homepage().map(str::to_string),
imdb_url: p
.imdb_id()
.map(|id| format!("https://www.imdb.com/name/{id}")),
enriched: p.enriched_at().is_some(),
}
}