36
Cargo.lock
generated
36
Cargo.lock
generated
@@ -9,7 +9,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2"
|
checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ab_glyph_rasterizer",
|
"ab_glyph_rasterizer",
|
||||||
"owned_ttf_parser 0.25.1",
|
"owned_ttf_parser",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1684,6 +1684,7 @@ name = "domain"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
"email_address",
|
"email_address",
|
||||||
"futures",
|
"futures",
|
||||||
@@ -2787,7 +2788,9 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"bytes",
|
||||||
"domain",
|
"domain",
|
||||||
|
"futures",
|
||||||
"infer",
|
"infer",
|
||||||
"object_store",
|
"object_store",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -3777,22 +3780,13 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "owned_ttf_parser"
|
|
||||||
version = "0.15.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "05e6affeb1632d6ff6a23d2cd40ffed138e82f1532571a26f527c8a284bb2fbb"
|
|
||||||
dependencies = [
|
|
||||||
"ttf-parser 0.15.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "owned_ttf_parser"
|
name = "owned_ttf_parser"
|
||||||
version = "0.25.1"
|
version = "0.25.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b"
|
checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ttf-parser 0.25.1",
|
"ttf-parser",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4240,10 +4234,12 @@ dependencies = [
|
|||||||
"auth",
|
"auth",
|
||||||
"axum",
|
"axum",
|
||||||
"axum-governor",
|
"axum-governor",
|
||||||
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
"domain",
|
"domain",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"export",
|
"export",
|
||||||
|
"futures",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"image-storage",
|
"image-storage",
|
||||||
"importer",
|
"importer",
|
||||||
@@ -5101,16 +5097,6 @@ dependencies = [
|
|||||||
"untrusted",
|
"untrusted",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rusttype"
|
|
||||||
version = "0.9.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3ff8374aa04134254b7995b63ad3dc41c7f7236f69528b28553da7d72efaa967"
|
|
||||||
dependencies = [
|
|
||||||
"ab_glyph_rasterizer",
|
|
||||||
"owned_ttf_parser 0.15.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.22"
|
version = "1.0.22"
|
||||||
@@ -6484,12 +6470,6 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ttf-parser"
|
|
||||||
version = "0.15.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ttf-parser"
|
name = "ttf-parser"
|
||||||
version = "0.25.1"
|
version = "0.25.1"
|
||||||
@@ -7582,12 +7562,12 @@ dependencies = [
|
|||||||
name = "wrapup-renderer"
|
name = "wrapup-renderer"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ab_glyph",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"domain",
|
"domain",
|
||||||
"image 0.25.10",
|
"image 0.25.10",
|
||||||
"imageproc",
|
"imageproc",
|
||||||
"plotters",
|
"plotters",
|
||||||
"rusttype",
|
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
|||||||
@@ -380,9 +380,7 @@ impl TryFrom<EventPayload> for DomainEvent {
|
|||||||
end_date,
|
end_date,
|
||||||
} => {
|
} => {
|
||||||
let wid = parse_uuid(&wrapup_id, "wrapup_id")?;
|
let wid = parse_uuid(&wrapup_id, "wrapup_id")?;
|
||||||
let uid = user_id
|
let uid = user_id.map(|s| parse_uuid(&s, "user_id")).transpose()?;
|
||||||
.map(|s| parse_uuid(&s, "user_id"))
|
|
||||||
.transpose()?;
|
|
||||||
let sd = chrono::NaiveDate::parse_from_str(&start_date, "%Y-%m-%d")
|
let sd = chrono::NaiveDate::parse_from_str(&start_date, "%Y-%m-%d")
|
||||||
.map_err(|e| DomainError::ValidationError(e.to_string()))?;
|
.map_err(|e| DomainError::ValidationError(e.to_string()))?;
|
||||||
let ed = chrono::NaiveDate::parse_from_str(&end_date, "%Y-%m-%d")
|
let ed = chrono::NaiveDate::parse_from_str(&end_date, "%Y-%m-%d")
|
||||||
|
|||||||
@@ -88,15 +88,13 @@ impl WrapUpRepository for PostgresWrapUpRepository {
|
|||||||
let id_str = id.value().to_string();
|
let id_str = id.value().to_string();
|
||||||
let status_str = status_to_str(status);
|
let status_str = status_to_str(status);
|
||||||
|
|
||||||
sqlx::query(
|
sqlx::query("UPDATE wrap_up_records SET status = $1, error_message = $2 WHERE id = $3")
|
||||||
"UPDATE wrap_up_records SET status = $1, error_message = $2 WHERE id = $3",
|
.bind(status_str)
|
||||||
)
|
.bind(error)
|
||||||
.bind(status_str)
|
.bind(&id_str)
|
||||||
.bind(error)
|
.execute(&self.pool)
|
||||||
.bind(&id_str)
|
.await
|
||||||
.execute(&self.pool)
|
.map_err(map_err)?;
|
||||||
.await
|
|
||||||
.map_err(map_err)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -205,10 +203,7 @@ fn row_to_record(row: &sqlx::postgres::PgRow) -> Result<WrapUpRecord, DomainErro
|
|||||||
let created_at_str: String = row.try_get("created_at").map_err(map_err)?;
|
let created_at_str: String = row.try_get("created_at").map_err(map_err)?;
|
||||||
let completed_at_str: Option<String> = row.try_get("completed_at").map_err(map_err)?;
|
let completed_at_str: Option<String> = row.try_get("completed_at").map_err(map_err)?;
|
||||||
|
|
||||||
let user_id = user_id_str
|
let user_id = user_id_str.as_deref().map(parse_uuid).transpose()?;
|
||||||
.as_deref()
|
|
||||||
.map(parse_uuid)
|
|
||||||
.transpose()?;
|
|
||||||
|
|
||||||
Ok(WrapUpRecord {
|
Ok(WrapUpRecord {
|
||||||
id: WrapUpId::from_uuid(parse_uuid(&id_str)?),
|
id: WrapUpId::from_uuid(parse_uuid(&id_str)?),
|
||||||
@@ -219,7 +214,10 @@ fn row_to_record(row: &sqlx::postgres::PgRow) -> Result<WrapUpRecord, DomainErro
|
|||||||
report_json,
|
report_json,
|
||||||
error_message,
|
error_message,
|
||||||
created_at: parse_datetime(&created_at_str)?,
|
created_at: parse_datetime(&created_at_str)?,
|
||||||
completed_at: completed_at_str.as_deref().map(parse_datetime).transpose()?,
|
completed_at: completed_at_str
|
||||||
|
.as_deref()
|
||||||
|
.map(parse_datetime)
|
||||||
|
.transpose()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,9 +259,7 @@ impl WrapUpStatsQuery for PostgresWrapUpStatsQuery {
|
|||||||
ORDER BY r.watched_at ASC"
|
ORDER BY r.watched_at ASC"
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut q = sqlx::query(&sql)
|
let mut q = sqlx::query(&sql).bind(range.start).bind(range.end);
|
||||||
.bind(range.start)
|
|
||||||
.bind(range.end);
|
|
||||||
if let Some(ref uid) = scope_bind {
|
if let Some(ref uid) = scope_bind {
|
||||||
q = q.bind(uid);
|
q = q.bind(uid);
|
||||||
}
|
}
|
||||||
@@ -307,18 +303,9 @@ impl WrapUpStatsQuery for PostgresWrapUpStatsQuery {
|
|||||||
let original_language: Option<String> =
|
let original_language: Option<String> =
|
||||||
row.try_get("original_language").map_err(map_err)?;
|
row.try_get("original_language").map_err(map_err)?;
|
||||||
|
|
||||||
let genres = genres_map
|
let genres = genres_map.get(&movie_id_str).cloned().unwrap_or_default();
|
||||||
.get(&movie_id_str)
|
let keywords = keywords_map.get(&movie_id_str).cloned().unwrap_or_default();
|
||||||
.cloned()
|
let cast = cast_map.get(&movie_id_str).cloned().unwrap_or_default();
|
||||||
.unwrap_or_default();
|
|
||||||
let keywords = keywords_map
|
|
||||||
.get(&movie_id_str)
|
|
||||||
.cloned()
|
|
||||||
.unwrap_or_default();
|
|
||||||
let cast = cast_map
|
|
||||||
.get(&movie_id_str)
|
|
||||||
.cloned()
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let cast_names: Vec<(String, u32)> = cast
|
let cast_names: Vec<(String, u32)> = cast
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -213,10 +213,7 @@ fn row_to_record(row: &sqlx::sqlite::SqliteRow) -> Result<WrapUpRecord, DomainEr
|
|||||||
let created_at_str: String = row.try_get("created_at").map_err(map_err)?;
|
let created_at_str: String = row.try_get("created_at").map_err(map_err)?;
|
||||||
let completed_at_str: Option<String> = row.try_get("completed_at").map_err(map_err)?;
|
let completed_at_str: Option<String> = row.try_get("completed_at").map_err(map_err)?;
|
||||||
|
|
||||||
let user_id = user_id_str
|
let user_id = user_id_str.as_deref().map(parse_uuid).transpose()?;
|
||||||
.as_deref()
|
|
||||||
.map(parse_uuid)
|
|
||||||
.transpose()?;
|
|
||||||
|
|
||||||
Ok(WrapUpRecord {
|
Ok(WrapUpRecord {
|
||||||
id: WrapUpId::from_uuid(parse_uuid(&id_str)?),
|
id: WrapUpId::from_uuid(parse_uuid(&id_str)?),
|
||||||
@@ -227,7 +224,10 @@ fn row_to_record(row: &sqlx::sqlite::SqliteRow) -> Result<WrapUpRecord, DomainEr
|
|||||||
report_json,
|
report_json,
|
||||||
error_message,
|
error_message,
|
||||||
created_at: parse_datetime(&created_at_str)?,
|
created_at: parse_datetime(&created_at_str)?,
|
||||||
completed_at: completed_at_str.as_deref().map(parse_datetime).transpose()?,
|
completed_at: completed_at_str
|
||||||
|
.as_deref()
|
||||||
|
.map(parse_datetime)
|
||||||
|
.transpose()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,9 +270,7 @@ impl WrapUpStatsQuery for SqliteWrapUpStatsQuery {
|
|||||||
ORDER BY r.watched_at ASC"
|
ORDER BY r.watched_at ASC"
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut q = sqlx::query(&sql)
|
let mut q = sqlx::query(&sql).bind(&start_str).bind(&end_str);
|
||||||
.bind(&start_str)
|
|
||||||
.bind(&end_str);
|
|
||||||
if let Some(ref uid) = scope_bind {
|
if let Some(ref uid) = scope_bind {
|
||||||
q = q.bind(uid);
|
q = q.bind(uid);
|
||||||
}
|
}
|
||||||
@@ -316,18 +314,9 @@ impl WrapUpStatsQuery for SqliteWrapUpStatsQuery {
|
|||||||
let original_language: Option<String> =
|
let original_language: Option<String> =
|
||||||
row.try_get("original_language").map_err(map_err)?;
|
row.try_get("original_language").map_err(map_err)?;
|
||||||
|
|
||||||
let genres = genres_map
|
let genres = genres_map.get(&movie_id_str).cloned().unwrap_or_default();
|
||||||
.get(&movie_id_str)
|
let keywords = keywords_map.get(&movie_id_str).cloned().unwrap_or_default();
|
||||||
.cloned()
|
let cast = cast_map.get(&movie_id_str).cloned().unwrap_or_default();
|
||||||
.unwrap_or_default();
|
|
||||||
let keywords = keywords_map
|
|
||||||
.get(&movie_id_str)
|
|
||||||
.cloned()
|
|
||||||
.unwrap_or_default();
|
|
||||||
let cast = cast_map
|
|
||||||
.get(&movie_id_str)
|
|
||||||
.cloned()
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let cast_names: Vec<(String, u32)> = cast
|
let cast_names: Vec<(String, u32)> = cast
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use domain::ports::{
|
|||||||
MovieRepository, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
MovieRepository, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
||||||
RemoteWatchlistRepository, ReviewRepository, SearchCommand, SearchPort, SocialQueryPort,
|
RemoteWatchlistRepository, ReviewRepository, SearchCommand, SearchPort, SocialQueryPort,
|
||||||
StatsRepository, UserProfileFieldsRepository, UserRepository, WatchEventRepository,
|
StatsRepository, UserProfileFieldsRepository, UserRepository, WatchEventRepository,
|
||||||
WatchlistRepository, WrapUpRepository, WrapUpStatsQuery, WrapUpVideoRenderer,
|
WatchlistRepository, WebhookTokenRepository, WrapUpRepository, WrapUpStatsQuery,
|
||||||
WebhookTokenRepository,
|
WrapUpVideoRenderer,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::config::AppConfig;
|
use crate::config::AppConfig;
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use domain::testing::{InMemoryWrapUpRepository, InMemoryWrapUpStatsQuery, NoopRemoteWatchlistRepository, NoopSocialQueryPort};
|
use domain::testing::{
|
||||||
|
InMemoryWrapUpRepository, InMemoryWrapUpStatsQuery, NoopRemoteWatchlistRepository,
|
||||||
|
NoopSocialQueryPort,
|
||||||
|
};
|
||||||
use domain::{
|
use domain::{
|
||||||
ports::{
|
ports::{
|
||||||
AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher, ImageStorage,
|
AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher, ImageStorage,
|
||||||
|
|||||||
@@ -205,26 +205,14 @@ fn compute_rating_extremes(rows: &[WrapUpMovieRow]) -> (Option<MovieRef>, Option
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn compute_chronological_extremes(rows: &[WrapUpMovieRow]) -> (Option<MovieRef>, Option<MovieRef>) {
|
fn compute_chronological_extremes(rows: &[WrapUpMovieRow]) -> (Option<MovieRef>, Option<MovieRef>) {
|
||||||
let first = rows
|
let first = rows.iter().min_by_key(|r| r.watched_at).map(movie_ref);
|
||||||
.iter()
|
let last = rows.iter().max_by_key(|r| r.watched_at).map(movie_ref);
|
||||||
.min_by_key(|r| r.watched_at)
|
|
||||||
.map(movie_ref);
|
|
||||||
let last = rows
|
|
||||||
.iter()
|
|
||||||
.max_by_key(|r| r.watched_at)
|
|
||||||
.map(movie_ref);
|
|
||||||
(first, last)
|
(first, last)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_year_extremes(rows: &[WrapUpMovieRow]) -> (Option<MovieRef>, Option<MovieRef>) {
|
fn compute_year_extremes(rows: &[WrapUpMovieRow]) -> (Option<MovieRef>, Option<MovieRef>) {
|
||||||
let oldest = rows
|
let oldest = rows.iter().min_by_key(|r| r.release_year).map(movie_ref);
|
||||||
.iter()
|
let newest = rows.iter().max_by_key(|r| r.release_year).map(movie_ref);
|
||||||
.min_by_key(|r| r.release_year)
|
|
||||||
.map(movie_ref);
|
|
||||||
let newest = rows
|
|
||||||
.iter()
|
|
||||||
.max_by_key(|r| r.release_year)
|
|
||||||
.map(movie_ref);
|
|
||||||
(oldest, newest)
|
(oldest, newest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ pub mod remote_watchlist;
|
|||||||
pub use remote_watchlist::RemoteWatchlistEntry;
|
pub use remote_watchlist::RemoteWatchlistEntry;
|
||||||
pub mod watch_event;
|
pub mod watch_event;
|
||||||
pub mod wrapup;
|
pub mod wrapup;
|
||||||
pub use wrapup::*;
|
|
||||||
pub use watch_event::{
|
pub use watch_event::{
|
||||||
ParsedPlaybackEvent, PersistedWatchEvent, WatchEvent, WatchEventSource, WatchEventStatus,
|
ParsedPlaybackEvent, PersistedWatchEvent, WatchEvent, WatchEventSource, WatchEventStatus,
|
||||||
WebhookToken,
|
WebhookToken,
|
||||||
};
|
};
|
||||||
|
pub use wrapup::*;
|
||||||
|
|
||||||
pub use import::{
|
pub use import::{
|
||||||
AnnotatedRow, DomainField, FieldMapping, FileFormat, ImportError, ImportRow, ParsedFile,
|
AnnotatedRow, DomainField, FieldMapping, FileFormat, ImportError, ImportRow, ParsedFile,
|
||||||
|
|||||||
@@ -1131,11 +1131,13 @@ impl WrapUpRepository for InMemoryWrapUpRepository {
|
|||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn list_global(
|
async fn list_global(&self) -> Result<Vec<crate::models::wrapup::WrapUpRecord>, DomainError> {
|
||||||
&self,
|
|
||||||
) -> Result<Vec<crate::models::wrapup::WrapUpRecord>, DomainError> {
|
|
||||||
let store = self.store.lock().unwrap();
|
let store = self.store.lock().unwrap();
|
||||||
Ok(store.iter().filter(|r| r.user_id.is_none()).cloned().collect())
|
Ok(store
|
||||||
|
.iter()
|
||||||
|
.filter(|r| r.user_id.is_none())
|
||||||
|
.cloned()
|
||||||
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_existing(
|
async fn find_existing(
|
||||||
@@ -1184,9 +1186,7 @@ impl WrapUpRepository for PanicWrapUpRepository {
|
|||||||
) -> Result<Vec<crate::models::wrapup::WrapUpRecord>, DomainError> {
|
) -> Result<Vec<crate::models::wrapup::WrapUpRecord>, DomainError> {
|
||||||
panic!("PanicWrapUpRepository called")
|
panic!("PanicWrapUpRepository called")
|
||||||
}
|
}
|
||||||
async fn list_global(
|
async fn list_global(&self) -> Result<Vec<crate::models::wrapup::WrapUpRecord>, DomainError> {
|
||||||
&self,
|
|
||||||
) -> Result<Vec<crate::models::wrapup::WrapUpRecord>, DomainError> {
|
|
||||||
panic!("PanicWrapUpRepository called")
|
panic!("PanicWrapUpRepository called")
|
||||||
}
|
}
|
||||||
async fn find_existing(
|
async fn find_existing(
|
||||||
|
|||||||
@@ -135,12 +135,9 @@ pub async fn get_report(
|
|||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
match get_wrapup::execute(&state.app_ctx, WrapUpId::from_uuid(id)).await {
|
match get_wrapup::execute(&state.app_ctx, WrapUpId::from_uuid(id)).await {
|
||||||
Ok(Some(record)) if record.status == WrapUpStatus::Ready => match record.report_json {
|
Ok(Some(record)) if record.status == WrapUpStatus::Ready => match record.report_json {
|
||||||
Some(json) => (
|
Some(json) => {
|
||||||
StatusCode::OK,
|
(StatusCode::OK, [("content-type", "application/json")], json).into_response()
|
||||||
[("content-type", "application/json")],
|
}
|
||||||
json,
|
|
||||||
)
|
|
||||||
.into_response(),
|
|
||||||
None => StatusCode::NOT_FOUND.into_response(),
|
None => StatusCode::NOT_FOUND.into_response(),
|
||||||
},
|
},
|
||||||
Ok(Some(_)) => StatusCode::ACCEPTED.into_response(),
|
Ok(Some(_)) => StatusCode::ACCEPTED.into_response(),
|
||||||
@@ -158,10 +155,7 @@ pub async fn get_report(
|
|||||||
),
|
),
|
||||||
security(("bearer_auth" = []))
|
security(("bearer_auth" = []))
|
||||||
)]
|
)]
|
||||||
pub async fn get_video(
|
pub async fn get_video(State(state): State<AppState>, Path(id): Path<Uuid>) -> impl IntoResponse {
|
||||||
State(state): State<AppState>,
|
|
||||||
Path(id): Path<Uuid>,
|
|
||||||
) -> impl IntoResponse {
|
|
||||||
let record = match state
|
let record = match state
|
||||||
.app_ctx
|
.app_ctx
|
||||||
.repos
|
.repos
|
||||||
@@ -219,11 +213,21 @@ fn render_wrapup(
|
|||||||
year: i32,
|
year: i32,
|
||||||
ctx: &application::ports::HtmlPageContext,
|
ctx: &application::ports::HtmlPageContext,
|
||||||
) -> axum::response::Response {
|
) -> axum::response::Response {
|
||||||
let rating_max = report.rating_distribution.iter().copied().max().unwrap_or(1).max(1);
|
let rating_max = report
|
||||||
let rating_pcts: [f64; 5] = std::array::from_fn(|i| {
|
.rating_distribution
|
||||||
report.rating_distribution[i] as f64 / rating_max as f64 * 100.0
|
.iter()
|
||||||
});
|
.copied()
|
||||||
let genre_max = report.top_genres.first().map(|g| g.count).unwrap_or(1).max(1);
|
.max()
|
||||||
|
.unwrap_or(1)
|
||||||
|
.max(1);
|
||||||
|
let rating_pcts: [f64; 5] =
|
||||||
|
std::array::from_fn(|i| report.rating_distribution[i] as f64 / rating_max as f64 * 100.0);
|
||||||
|
let genre_max = report
|
||||||
|
.top_genres
|
||||||
|
.first()
|
||||||
|
.map(|g| g.count)
|
||||||
|
.unwrap_or(1)
|
||||||
|
.max(1);
|
||||||
let genre_pcts: Vec<f64> = report
|
let genre_pcts: Vec<f64> = report
|
||||||
.top_genres
|
.top_genres
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -599,13 +599,23 @@ impl domain::ports::WrapUpRepository for Panic {
|
|||||||
) -> Result<(), DomainError> {
|
) -> Result<(), DomainError> {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
async fn set_complete(&self, _: &domain::value_objects::WrapUpId, _: &str) -> Result<(), DomainError> {
|
async fn set_complete(
|
||||||
|
&self,
|
||||||
|
_: &domain::value_objects::WrapUpId,
|
||||||
|
_: &str,
|
||||||
|
) -> Result<(), DomainError> {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
async fn get_by_id(&self, _: &domain::value_objects::WrapUpId) -> Result<Option<domain::models::wrapup::WrapUpRecord>, DomainError> {
|
async fn get_by_id(
|
||||||
|
&self,
|
||||||
|
_: &domain::value_objects::WrapUpId,
|
||||||
|
) -> Result<Option<domain::models::wrapup::WrapUpRecord>, DomainError> {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
async fn list_for_user(&self, _: uuid::Uuid) -> Result<Vec<domain::models::wrapup::WrapUpRecord>, DomainError> {
|
async fn list_for_user(
|
||||||
|
&self,
|
||||||
|
_: uuid::Uuid,
|
||||||
|
) -> Result<Vec<domain::models::wrapup::WrapUpRecord>, DomainError> {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
async fn list_global(&self) -> Result<Vec<domain::models::wrapup::WrapUpRecord>, DomainError> {
|
async fn list_global(&self) -> Result<Vec<domain::models::wrapup::WrapUpRecord>, DomainError> {
|
||||||
|
|||||||
@@ -196,10 +196,16 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
Arc::clone(&ctx.repos.movie),
|
Arc::clone(&ctx.repos.movie),
|
||||||
Arc::clone(&ctx.repos.search_command),
|
Arc::clone(&ctx.repos.search_command),
|
||||||
)) as Arc<dyn EventHandler>;
|
)) as Arc<dyn EventHandler>;
|
||||||
let wrapup_handler = Arc::new(application::wrapup::event_handler::WrapUpEventHandler::new(
|
let wrapup_handler = Arc::new(
|
||||||
ctx.clone(),
|
application::wrapup::event_handler::WrapUpEventHandler::new(ctx.clone()),
|
||||||
)) as Arc<dyn EventHandler>;
|
) as Arc<dyn EventHandler>;
|
||||||
let mut h = vec![poster, cleanup, search_cleanup, discovery_indexer, wrapup_handler];
|
let mut h = vec![
|
||||||
|
poster,
|
||||||
|
cleanup,
|
||||||
|
search_cleanup,
|
||||||
|
discovery_indexer,
|
||||||
|
wrapup_handler,
|
||||||
|
];
|
||||||
if let Some(e) = enrichment_handler {
|
if let Some(e) = enrichment_handler {
|
||||||
h.push(e);
|
h.push(e);
|
||||||
}
|
}
|
||||||
@@ -240,9 +246,9 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
Arc::clone(&ctx.repos.search_command),
|
Arc::clone(&ctx.repos.search_command),
|
||||||
)) as Arc<dyn EventHandler>;
|
)) as Arc<dyn EventHandler>;
|
||||||
tracing::info!("federation event handler registered");
|
tracing::info!("federation event handler registered");
|
||||||
let wrapup_handler = Arc::new(application::wrapup::event_handler::WrapUpEventHandler::new(
|
let wrapup_handler = Arc::new(
|
||||||
ctx.clone(),
|
application::wrapup::event_handler::WrapUpEventHandler::new(ctx.clone()),
|
||||||
)) as Arc<dyn EventHandler>;
|
) as Arc<dyn EventHandler>;
|
||||||
let mut h = vec![
|
let mut h = vec![
|
||||||
poster,
|
poster,
|
||||||
cleanup,
|
cleanup,
|
||||||
|
|||||||
Reference in New Issue
Block a user