watchdogs/src/yt_meta.rs
2024-10-05 01:21:43 +02:00

138 lines
3.5 KiB
Rust

use std::{path::PathBuf, process::Stdio};
// yt metadata
pub fn get_youtube_metadata(path: &PathBuf) -> Option<YouTubeMeta> {
let cmd = std::process::Command::new("mkvextract")
.arg("-q")
.arg("attachments")
.arg(path.to_str().unwrap())
.arg("1:/proc/self/fd/1")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.unwrap();
let out = cmd.wait_with_output().unwrap();
let stdout = String::from_utf8_lossy(&out.stdout).to_string();
//let stderr = String::from_utf8_lossy(&out.stderr).to_string();
// println!("path {path:?} -- stdout {stdout} -- stderr {stderr}");
let val = serde_json::from_str(&stdout).ok()?;
log::info!("Extracted YouTube Metadata from {path:?}");
Some(YouTubeMeta { inner: val })
}
pub struct YouTubeMeta {
inner: serde_json::Value,
}
impl YouTubeMeta {
pub fn title(&self) -> String {
self.inner
.as_object()
.unwrap()
.get("title")
.unwrap()
.as_str()
.unwrap()
.to_owned()
}
pub fn youtube_id(&self) -> Option<String> {
self.inner
.as_object()
.unwrap()
.get("id")
.unwrap()
.as_str()
.map(std::borrow::ToOwned::to_owned)
}
pub fn description(&self) -> Option<String> {
self.inner
.as_object()
.unwrap()
.get("description")
.unwrap()
.as_str()
.map(std::borrow::ToOwned::to_owned)
}
pub fn uploader_name(&self) -> Option<String> {
self.inner
.as_object()
.unwrap()
.get("uploader")
.unwrap()
.as_str()
.map(std::borrow::ToOwned::to_owned)
}
pub fn uploader_id(&self) -> Option<String> {
self.inner
.as_object()
.unwrap()
.get("channel_id")
.unwrap()
.as_str()
.map(std::borrow::ToOwned::to_owned)
}
pub fn duration(&self) -> Option<i64> {
self.inner
.as_object()
.unwrap()
.get("duration")
.unwrap()
.as_i64()
.map(|x| x.to_owned())
}
pub fn views(&self) -> Option<i64> {
self.inner
.as_object()
.unwrap()
.get("view_count")
.unwrap()
.as_i64()
.map(|x| x.to_owned())
}
pub fn categories(&self) -> Option<Vec<String>> {
self.inner
.as_object()
.unwrap()
.get("categories")
.unwrap_or(&serde_json::json!(Vec::<&str>::new()))
.as_array()
.unwrap()
.iter()
.map(|x| x.as_str().map(std::borrow::ToOwned::to_owned))
.collect()
}
pub fn tags(&self) -> Option<Vec<String>> {
if let Some(tags) = self.inner.as_object().unwrap().get("tags") {
return tags
.as_array()
.unwrap()
.iter()
.map(|x| x.as_str().map(std::borrow::ToOwned::to_owned))
.collect();
}
None
}
pub fn upload_date(&self) -> Option<chrono::NaiveDate> {
self.inner
.as_object()
.unwrap()
.get("upload_date")
.unwrap()
.as_str()
.map(|x| chrono::NaiveDate::parse_from_str(x, "%Y%m%d").unwrap())
}
}