1//! `previewgen frames <dir>` writes `background.svg` (the dot field, to rasterise once as `background.png`), `card.svg` and 2//! `frame-0001.svg`, …; `previewgen check-meta 3//! <file.html>` lists what a scraper would find wrong with a page's preview tags. 4 5use std::process::ExitCode; 6 7fn main() -> ExitCode { 8 let args: Vec<String> = std::env::args().skip(1).collect(); 9 match args.iter().map(String::as_str).collect::<Vec<_>>().as_slice() { 10 ["frames", dir] => match write(dir) { 11 Ok(count) => { 12 eprintln!("previewgen: wrote card.svg and {count} frames ({} s at {} fps) to {dir}", previewgen::seconds(), previewgen::FPS); 13 ExitCode::SUCCESS 14 } 15 Err(why) => { 16 eprintln!("previewgen: {why}"); 17 ExitCode::FAILURE 18 } 19 }, 20 ["check-meta", file] => match std::fs::read_to_string(file) { 21 Ok(html) => { 22 let problems = jev_ui::preview::missing(&html, jev_ui::preview::Kind::Video); 23 for problem in &problems { 24 eprintln!("previewgen: {problem}"); 25 } 26 if problems.is_empty() { 27 println!("previewgen: all {} tags a scraper needs are present", jev_ui::preview::required(jev_ui::preview::Kind::Video).len()); 28 ExitCode::SUCCESS 29 } else { 30 ExitCode::FAILURE 31 } 32 } 33 Err(why) => { 34 eprintln!("previewgen: {file}: {why}"); 35 ExitCode::FAILURE 36 } 37 }, 38 ["mascot"] => { 39 println!("{}", cat::Mascot::DEFAULT.name()); 40 ExitCode::SUCCESS 41 } 42 _ => { 43 eprintln!("usage: previewgen frames <dir> | previewgen check-meta <file.html> | previewgen mascot"); 44 ExitCode::from(2) 45 } 46 } 47} 48 49fn write(dir: &str) -> std::io::Result<usize> { 50 std::fs::create_dir_all(dir)?; 51 std::fs::write(format!("{dir}/background.svg"), previewgen::background())?; 52 std::fs::write(format!("{dir}/card.svg"), previewgen::card())?; 53 let frames = previewgen::frames(); 54 for (i, frame) in frames.iter().enumerate() { 55 std::fs::write(format!("{dir}/frame-{:04}.svg", i + 1), frame)?; 56 } 57 Ok(frames.len()) 58}