1
Fork 0
bauke-xyz/source/video/mod.rs

139 lines
3.3 KiB
Rust
Raw Normal View History

//! Templates, data structures and logic for the video pages.
2023-01-07 13:57:19 +00:00
use std::{fs, path::Path};
use {
askama::Template,
color_eyre::{eyre::eyre, Result},
serde::Deserialize,
};
2023-01-07 13:57:19 +00:00
mod filters;
/// The template for videos.
2023-01-07 13:57:19 +00:00
#[derive(Debug, Template)]
#[template(path = "video.html")]
pub struct VideoTemplate {
/// Deep Rock Galactic data.
pub drg: Option<DeepRockGalacticData>,
2023-01-16 20:31:13 +00:00
/// The title of the page.
2023-01-07 13:57:19 +00:00
pub page_title: String,
2023-01-16 20:31:13 +00:00
/// Markdown rendered by [`comrak`].
2023-01-07 13:57:19 +00:00
pub rendered_markdown: String,
2023-01-16 20:31:13 +00:00
/// Data for a speedrun video.
2023-01-07 13:57:19 +00:00
pub speedrun: Option<SpeedrunData>,
2023-01-16 20:31:13 +00:00
/// The YouTube video ID.
2023-01-07 13:57:19 +00:00
pub video_id: String,
}
/// The frontmatter data for a video.
2023-01-07 13:57:19 +00:00
#[derive(Debug, Deserialize)]
2023-01-13 13:57:09 +00:00
pub struct VideoData {
/// Deep Rock Galactic data.
pub drg: Option<DeepRockGalacticData>,
2023-01-16 20:31:13 +00:00
/// The YouTube video ID.
2023-01-07 13:57:19 +00:00
pub id: String,
2023-01-16 20:31:13 +00:00
/// The title of the page.
2023-01-07 13:57:19 +00:00
pub page_title: String,
2023-01-16 20:31:13 +00:00
/// Data for a speedrun video.
2023-01-07 13:57:19 +00:00
pub speedrun: Option<SpeedrunData>,
2023-01-16 20:31:13 +00:00
/// Tags for the video.
2023-01-13 13:57:09 +00:00
#[serde(default)]
pub tags: Vec<String>,
2023-01-07 13:57:19 +00:00
}
/// Data for speedrun videos.
2023-01-07 13:57:19 +00:00
#[derive(Debug, Deserialize)]
pub struct SpeedrunData {
2023-01-16 20:31:13 +00:00
/// Video chapters as with timestamps and chapter titles.
2023-01-07 13:57:19 +00:00
pub chapters: Option<Vec<(String, String)>>,
2023-01-16 20:31:13 +00:00
/// A link to the entry for this specific speedrun.
2023-01-07 13:57:19 +00:00
pub entry: String,
2023-01-16 20:31:13 +00:00
/// A link to the leaderboard for this speedrun's category.
2023-01-07 13:57:19 +00:00
pub leaderboard: String,
2023-01-16 20:31:13 +00:00
/// Deep Rock Galactic mods used in the run.
pub mods: Option<Vec<String>>,
2023-01-07 13:57:19 +00:00
}
/// Additional data for Deep Rock Galactic videos.
#[derive(Debug, Deserialize)]
pub struct DeepRockGalacticData {
/// Deep Rock Galactic mods used in the run.
pub mods: Option<Vec<String>>,
}
/// Compile and write all the found videos to their respective locations.
2023-01-07 13:57:19 +00:00
pub fn write_all(public_dir: &Path) -> Result<()> {
let video_datas = {
let mut data = vec![];
2023-01-29 13:33:48 +00:00
for dir in ["2022", "2023"] {
2023-01-07 13:57:19 +00:00
for file in fs::read_dir(format!("source/video/{dir}"))? {
let file_path = file?.path();
if file_path.extension().unwrap() != "md" {
continue;
}
let file_contents = fs::read_to_string(&file_path)?;
2023-01-07 13:57:19 +00:00
let (video_data, markdown) =
match toml_frontmatter::parse::<VideoData>(&file_contents) {
Ok(parsed) => parsed,
Err(error) => {
println!("{:?} {}", file_path.file_name().unwrap(), error);
continue;
}
};
2023-01-07 13:57:19 +00:00
data.push((video_data, markdown.to_string()));
}
}
data
};
let video_dir = public_dir.join("v");
let expected_video_count = video_datas.len();
2023-01-07 13:57:19 +00:00
for (video_data, markdown) in video_datas {
let video_dir = video_dir.join(&video_data.id.to_lowercase());
2023-01-07 13:57:19 +00:00
fs::create_dir_all(&video_dir)?;
let template = VideoTemplate {
drg: video_data.drg,
2023-01-07 13:57:19 +00:00
page_title: video_data.page_title,
rendered_markdown: comrak::markdown_to_html(
&markdown,
&Default::default(),
),
speedrun: video_data.speedrun,
video_id: video_data.id,
};
2023-01-09 14:43:05 +00:00
fs::write(
video_dir.join("index.html"),
crate::minify::html(template.render()?)?,
)?;
2023-01-07 13:57:19 +00:00
}
let actual_video_count = fs::read_dir(video_dir)?.count();
if expected_video_count != actual_video_count {
return Err(eyre!(
"Expected {} videos, found {}",
expected_video_count,
actual_video_count
));
}
2023-01-07 13:57:19 +00:00
Ok(())
}