fix: clippy — collapse nested ifs, use div_ceil
Some checks failed
CI / Check / Test (push) Failing after 41s
Some checks failed
CI / Check / Test (push) Failing after 41s
This commit is contained in:
@@ -13,7 +13,8 @@ fn decode_image(bytes: &[u8]) -> Result<DynamicImage, String> {
|
|||||||
std::fs::write(&input, bytes).map_err(|e| e.to_string())?;
|
std::fs::write(&input, bytes).map_err(|e| e.to_string())?;
|
||||||
let status = std::process::Command::new("ffmpeg")
|
let status = std::process::Command::new("ffmpeg")
|
||||||
.args([
|
.args([
|
||||||
"-y", "-i",
|
"-y",
|
||||||
|
"-i",
|
||||||
&input.to_string_lossy(),
|
&input.to_string_lossy(),
|
||||||
&output.to_string_lossy(),
|
&output.to_string_lossy(),
|
||||||
])
|
])
|
||||||
@@ -78,20 +79,20 @@ impl SlideRenderer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut backgrounds = Vec::new();
|
let mut backgrounds = Vec::new();
|
||||||
if let Some(dir) = bg_dir {
|
if let Some(dir) = bg_dir
|
||||||
if let Ok(entries) = std::fs::read_dir(dir) {
|
&& let Ok(entries) = std::fs::read_dir(dir)
|
||||||
for entry in entries.flatten() {
|
{
|
||||||
let path = entry.path();
|
for entry in entries.flatten() {
|
||||||
let ext = path
|
let path = entry.path();
|
||||||
.extension()
|
let ext = path
|
||||||
.and_then(|e| e.to_str())
|
.extension()
|
||||||
.unwrap_or("")
|
.and_then(|e| e.to_str())
|
||||||
.to_lowercase();
|
.unwrap_or("")
|
||||||
if matches!(ext.as_str(), "jpg" | "jpeg" | "png" | "webp") {
|
.to_lowercase();
|
||||||
match image::open(&path) {
|
if matches!(ext.as_str(), "jpg" | "jpeg" | "png" | "webp") {
|
||||||
Ok(img) => backgrounds.push(img.to_rgba8()),
|
match image::open(&path) {
|
||||||
Err(e) => tracing::warn!("bg load {}: {e}", path.display()),
|
Ok(img) => backgrounds.push(img.to_rgba8()),
|
||||||
}
|
Err(e) => tracing::warn!("bg load {}: {e}", path.display()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,14 +209,7 @@ impl SlideRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a small thumbnail from raw image bytes, resized to `size x size`.
|
/// Draw a small thumbnail from raw image bytes, resized to `size x size`.
|
||||||
fn draw_thumbnail(
|
fn draw_thumbnail(canvas: &mut RgbaImage, bytes: &[u8], x: i64, y: i64, tw: u32, th: u32) {
|
||||||
canvas: &mut RgbaImage,
|
|
||||||
bytes: &[u8],
|
|
||||||
x: i64,
|
|
||||||
y: i64,
|
|
||||||
tw: u32,
|
|
||||||
th: u32,
|
|
||||||
) {
|
|
||||||
if let Ok(img) = decode_image(bytes) {
|
if let Ok(img) = decode_image(bytes) {
|
||||||
let thumb = img.resize_exact(tw, th, image::imageops::FilterType::Triangle);
|
let thumb = img.resize_exact(tw, th, image::imageops::FilterType::Triangle);
|
||||||
image::imageops::overlay(canvas, &thumb.to_rgba8(), x, y);
|
image::imageops::overlay(canvas, &thumb.to_rgba8(), x, y);
|
||||||
@@ -223,10 +217,7 @@ impl SlideRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Find cast photo bytes matching `name` (case-insensitive substring).
|
/// Find cast photo bytes matching `name` (case-insensitive substring).
|
||||||
fn find_cast_photo<'a>(
|
fn find_cast_photo<'a>(name: &str, cast_images: &'a [(String, Vec<u8>)]) -> Option<&'a [u8]> {
|
||||||
name: &str,
|
|
||||||
cast_images: &'a [(String, Vec<u8>)],
|
|
||||||
) -> Option<&'a [u8]> {
|
|
||||||
let lower = name.to_lowercase();
|
let lower = name.to_lowercase();
|
||||||
cast_images
|
cast_images
|
||||||
.iter()
|
.iter()
|
||||||
@@ -406,7 +397,11 @@ impl SlideRenderer {
|
|||||||
|
|
||||||
let thumb_size = 60u32;
|
let thumb_size = 60u32;
|
||||||
// offset text right when cast photos present
|
// offset text right when cast photos present
|
||||||
let text_offset = if cast_images.is_empty() { 60 } else { thumb_size as i32 + 20 };
|
let text_offset = if cast_images.is_empty() {
|
||||||
|
60
|
||||||
|
} else {
|
||||||
|
thumb_size as i32 + 20
|
||||||
|
};
|
||||||
|
|
||||||
for (i, d) in report.top_directors.iter().take(5).enumerate() {
|
for (i, d) in report.top_directors.iter().take(5).enumerate() {
|
||||||
let y = start_y + (i as i32) * row_h;
|
let y = start_y + (i as i32) * row_h;
|
||||||
@@ -425,23 +420,9 @@ impl SlideRenderer {
|
|||||||
|
|
||||||
let rank = format!("{}.", i + 1);
|
let rank = format!("{}.", i + 1);
|
||||||
self.draw_left(&mut img, &rank, margin, y + 10, 36.0, GOLD);
|
self.draw_left(&mut img, &rank, margin, y + 10, 36.0, GOLD);
|
||||||
self.draw_left(
|
self.draw_left(&mut img, &d.name, margin + text_offset, y + 10, 36.0, WHITE);
|
||||||
&mut img,
|
|
||||||
&d.name,
|
|
||||||
margin + text_offset,
|
|
||||||
y + 10,
|
|
||||||
36.0,
|
|
||||||
WHITE,
|
|
||||||
);
|
|
||||||
let detail = format!("{} films avg {:.1}\u{2605}", d.count, d.avg_rating);
|
let detail = format!("{} films avg {:.1}\u{2605}", d.count, d.avg_rating);
|
||||||
self.draw_left(
|
self.draw_left(&mut img, &detail, margin + text_offset, y + 54, 24.0, DIM);
|
||||||
&mut img,
|
|
||||||
&detail,
|
|
||||||
margin + text_offset,
|
|
||||||
y + 54,
|
|
||||||
24.0,
|
|
||||||
DIM,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.stamp_logo(&mut img);
|
self.stamp_logo(&mut img);
|
||||||
@@ -472,7 +453,11 @@ impl SlideRenderer {
|
|||||||
self.draw_centered(&mut img, "Top Actors", (h / 8) as i32, 56.0, GOLD);
|
self.draw_centered(&mut img, "Top Actors", (h / 8) as i32, 56.0, GOLD);
|
||||||
|
|
||||||
let thumb_size = 60u32;
|
let thumb_size = 60u32;
|
||||||
let text_offset = if cast_images.is_empty() { 60 } else { thumb_size as i32 + 20 };
|
let text_offset = if cast_images.is_empty() {
|
||||||
|
60
|
||||||
|
} else {
|
||||||
|
thumb_size as i32 + 20
|
||||||
|
};
|
||||||
|
|
||||||
for (i, a) in report.top_actors.iter().take(5).enumerate() {
|
for (i, a) in report.top_actors.iter().take(5).enumerate() {
|
||||||
let y = start_y + (i as i32) * row_h;
|
let y = start_y + (i as i32) * row_h;
|
||||||
@@ -490,23 +475,9 @@ impl SlideRenderer {
|
|||||||
|
|
||||||
let rank = format!("{}.", i + 1);
|
let rank = format!("{}.", i + 1);
|
||||||
self.draw_left(&mut img, &rank, margin, y + 10, 36.0, GOLD);
|
self.draw_left(&mut img, &rank, margin, y + 10, 36.0, GOLD);
|
||||||
self.draw_left(
|
self.draw_left(&mut img, &a.name, margin + text_offset, y + 10, 36.0, WHITE);
|
||||||
&mut img,
|
|
||||||
&a.name,
|
|
||||||
margin + text_offset,
|
|
||||||
y + 10,
|
|
||||||
36.0,
|
|
||||||
WHITE,
|
|
||||||
);
|
|
||||||
let detail = format!("{} films avg {:.1}\u{2605}", a.count, a.avg_rating);
|
let detail = format!("{} films avg {:.1}\u{2605}", a.count, a.avg_rating);
|
||||||
self.draw_left(
|
self.draw_left(&mut img, &detail, margin + text_offset, y + 54, 24.0, DIM);
|
||||||
&mut img,
|
|
||||||
&detail,
|
|
||||||
margin + text_offset,
|
|
||||||
y + 54,
|
|
||||||
24.0,
|
|
||||||
DIM,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.stamp_logo(&mut img);
|
self.stamp_logo(&mut img);
|
||||||
@@ -539,7 +510,12 @@ impl SlideRenderer {
|
|||||||
self.draw_centered(&mut img, &detail, (h / 8) as i32 + 64, 28.0, DIM);
|
self.draw_centered(&mut img, &detail, (h / 8) as i32 + 64, 28.0, DIM);
|
||||||
|
|
||||||
let bar_area_w = (w as i32 - margin * 2 - 200) as u32;
|
let bar_area_w = (w as i32 - margin * 2 - 200) as u32;
|
||||||
let max_count = report.top_genres.first().map(|g| g.count).unwrap_or(1).max(1);
|
let max_count = report
|
||||||
|
.top_genres
|
||||||
|
.first()
|
||||||
|
.map(|g| g.count)
|
||||||
|
.unwrap_or(1)
|
||||||
|
.max(1);
|
||||||
|
|
||||||
for (i, g) in report.top_genres.iter().take(8).enumerate() {
|
for (i, g) in report.top_genres.iter().take(8).enumerate() {
|
||||||
let y = start_y + (i as i32) * 80;
|
let y = start_y + (i as i32) * 80;
|
||||||
@@ -555,11 +531,7 @@ impl SlideRenderer {
|
|||||||
BAR_BG,
|
BAR_BG,
|
||||||
);
|
);
|
||||||
if bar_w > 0 {
|
if bar_w > 0 {
|
||||||
draw_filled_rect_mut(
|
draw_filled_rect_mut(&mut img, Rect::at(margin, bar_y).of_size(bar_w, 12), GOLD);
|
||||||
&mut img,
|
|
||||||
Rect::at(margin, bar_y).of_size(bar_w, 12),
|
|
||||||
GOLD,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,23 +621,9 @@ impl SlideRenderer {
|
|||||||
} else {
|
} else {
|
||||||
m.title.clone()
|
m.title.clone()
|
||||||
};
|
};
|
||||||
self.draw_left(
|
self.draw_left(&mut img, &title, x + text_x_offset, y + 36, 26.0, WHITE);
|
||||||
&mut img,
|
|
||||||
&title,
|
|
||||||
x + text_x_offset,
|
|
||||||
y + 36,
|
|
||||||
26.0,
|
|
||||||
WHITE,
|
|
||||||
);
|
|
||||||
let sub = format!("({})", m.year);
|
let sub = format!("({})", m.year);
|
||||||
self.draw_left(
|
self.draw_left(&mut img, &sub, x + text_x_offset, y + 68, 22.0, DIM);
|
||||||
&mut img,
|
|
||||||
&sub,
|
|
||||||
x + text_x_offset,
|
|
||||||
y + 68,
|
|
||||||
22.0,
|
|
||||||
DIM,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
self.draw_left(&mut img, "-", x, y + 36, 26.0, DIM);
|
self.draw_left(&mut img, "-", x, y + 36, 26.0, DIM);
|
||||||
}
|
}
|
||||||
@@ -702,7 +660,7 @@ impl SlideRenderer {
|
|||||||
.min_by_key(|&c| {
|
.min_by_key(|&c| {
|
||||||
let tw = w / c;
|
let tw = w / c;
|
||||||
let th = (tw as f32 / poster_ratio) as u32;
|
let th = (tw as f32 / poster_ratio) as u32;
|
||||||
let rows_needed = (h + th - 1) / th;
|
let rows_needed = h.div_ceil(th);
|
||||||
let total = rows_needed * c;
|
let total = rows_needed * c;
|
||||||
// prefer filling screen with fewer leftover pixels
|
// prefer filling screen with fewer leftover pixels
|
||||||
let waste_y = (rows_needed * th).saturating_sub(h);
|
let waste_y = (rows_needed * th).saturating_sub(h);
|
||||||
@@ -713,7 +671,7 @@ impl SlideRenderer {
|
|||||||
|
|
||||||
let thumb_w = w / cols;
|
let thumb_w = w / cols;
|
||||||
let thumb_h = (thumb_w as f32 / poster_ratio) as u32;
|
let thumb_h = (thumb_w as f32 / poster_ratio) as u32;
|
||||||
let total_rows = (h + thumb_h - 1) / thumb_h;
|
let total_rows = h.div_ceil(thumb_h);
|
||||||
let total_cells = (total_rows * cols) as usize;
|
let total_cells = (total_rows * cols) as usize;
|
||||||
|
|
||||||
for i in 0..total_cells {
|
for i in 0..total_cells {
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ pub async fn execute(
|
|||||||
start_date: chrono::NaiveDate,
|
start_date: chrono::NaiveDate,
|
||||||
end_date: chrono::NaiveDate,
|
end_date: chrono::NaiveDate,
|
||||||
) -> Result<(), DomainError> {
|
) -> Result<(), DomainError> {
|
||||||
if let Ok(Some(rec)) = ctx.repos.wrapup_repo.get_by_id(&wrapup_id).await {
|
if let Ok(Some(rec)) = ctx.repos.wrapup_repo.get_by_id(&wrapup_id).await
|
||||||
if rec.status == WrapUpStatus::Ready || rec.status == WrapUpStatus::Generating {
|
&& (rec.status == WrapUpStatus::Ready || rec.status == WrapUpStatus::Generating)
|
||||||
tracing::debug!("wrapup {} already {}, skipping", wrapup_id.value(), if rec.status == WrapUpStatus::Ready { "ready" } else { "generating" });
|
{
|
||||||
return Ok(());
|
tracing::debug!("wrapup {} already {:?}, skipping", wrapup_id.value(), rec.status);
|
||||||
}
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.repos
|
ctx.repos
|
||||||
@@ -99,11 +99,7 @@ pub async fn execute(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn resolve_images(
|
async fn resolve_images(ctx: &AppContext, paths: &[String], label: &str) -> Vec<(String, Vec<u8>)> {
|
||||||
ctx: &AppContext,
|
|
||||||
paths: &[String],
|
|
||||||
label: &str,
|
|
||||||
) -> Vec<(String, Vec<u8>)> {
|
|
||||||
let mut images = Vec::new();
|
let mut images = Vec::new();
|
||||||
for path in paths.iter().take(20) {
|
for path in paths.iter().take(20) {
|
||||||
match ctx.services.image_storage.get(path).await {
|
match ctx.services.image_storage.get(path).await {
|
||||||
|
|||||||
Reference in New Issue
Block a user