⫶☰ Table of contents
Angel Blessing Cards App
Screenshot

Download
Fetch youtube playlist
Fetch a youtube playlist and download the thumbnails.
For the youtube v3 api there is a nice crate. Put the config.playlist_id and the config.api_key in the config.toml.
use anyhow::Result;
use clap::Parser;
use futures::future::try_join_all;
use serde::{Deserialize, Serialize};
use youtube::{GoogleAPIRequest, YouTubeDataV3Client, initialize_client};
mod config;
use crate::config::read_config_from_toml;
#[derive(Parser)]
struct Cli {
output_path: std::path::PathBuf,
}
#[derive(Serialize, Deserialize, Debug)]
struct AngelVideo {
title: String,
thumbnail: String,
position: usize,
video: String,
}
#[derive(Serialize, Deserialize, Debug)]
struct AngelVideos {
videos: Vec<AngelVideo>,
}
#[tokio::main]
async fn main() -> Result<()> {
// Get the config.api.playlist_id and the config.api.key
let args = Cli::parse();
let config = read_config_from_toml("config.toml").expect("config.toml error");
// Initialize the HTTP client
let client = initialize_client()?;
// Create YouTube client
let mut youtube_client =
YouTubeDataV3Client::new("youtube.googleapis.com".to_string(), client).await;
// Get playlist information
let playlist = youtube_client
.list_playlist_items(config.api.playlist_id, None, None)
.with_key(&config.api.key)
.send()
.await?;
// Download thumbnails concurrently
let videos: Vec<AngelVideo> = try_join_all(playlist.items.iter().map(|v| async move {
let url = v.snippet.thumbnails.default.as_ref().unwrap().url.clone();
let video_id = v.snippet.resource_id.video_id.clone();
let thumbnail = format!("{}.jpg", video_id);
// Download image
let bytes = reqwest::get(url).await?.bytes().await?;
// Write file
tokio::fs::write(&thumbnail, &bytes).await?;
Ok::<AngelVideo, anyhow::Error>(AngelVideo {
title: v.snippet.title.to_string(),
thumbnail,
position: v.snippet.position as usize,
video: video_id,
})
}))
.await?;
let a = AngelVideos { videos };
let json = serde_json::to_string_pretty(&a)?;
std::fs::write(args.output_path, json).expect("Unable to write file");
Ok(())
}