diff options
Diffstat (limited to 'tools/src')
-rw-r--r-- | tools/src/bin/import.rs | 106 | ||||
-rw-r--r-- | tools/src/tmdb.rs | 32 |
2 files changed, 101 insertions, 37 deletions
diff --git a/tools/src/bin/import.rs b/tools/src/bin/import.rs index c771450..3050f71 100644 --- a/tools/src/bin/import.rs +++ b/tools/src/bin/import.rs @@ -5,7 +5,7 @@ Copyright (C) 2023 metamuffin <metamuffin.org> */ use anyhow::Context; use clap::{Parser, Subcommand}; -use jellycommon::{CommmonInfo, ItemInfo}; +use jellycommon::{CommmonInfo, DirectoryInfo, ItemInfo}; use jellymatroska::read::EbmlReader; use jellyremuxer::import::import_read; use jellytools::tmdb::{tmdb_details, tmdb_image, tmdb_search}; @@ -13,7 +13,7 @@ use log::{info, warn}; use std::{ fs::File, io::{stdin, Write}, - path::PathBuf, + path::{Path, PathBuf}, process::exit, }; @@ -32,7 +32,15 @@ enum Action { title: Option<String>, #[arg(short = 'T', long)] tmdb: Option<String>, - #[arg(short = 'i', long)] + #[arg(short, long)] + input: Option<PathBuf>, + #[arg(short, long)] + series: bool, + }, + Episode { + path: PathBuf, + index: usize, + title: String, input: PathBuf, }, Set { @@ -66,23 +74,26 @@ fn main() -> anyhow::Result<()> { title, tmdb: id, input, + series, } => { + assert!(series || input.is_some(), "series or input required"); + let kind = if series { "tv" } else { "movie" }; let key = std::env::var("TMDB_API_KEY").context("tmdb api key required")?; let id = if let Some(id) = id { id.parse().unwrap() } else { let title = title.unwrap(); - let results = tmdb_search(&title, &key)?; + let results = tmdb_search(kind, &title, &key)?; info!("results:"); for (i, r) in results.results.iter().enumerate() { info!( "\t[{i}] {}: {} ({})", r.id, - r.title, + r.title.as_ref().or(r.name.as_ref()).unwrap(), r.overview.chars().take(100).collect::<String>() ); } - let res_index = if results.results.len() != 1 { + let res_index = if results.results.len() > 1 { stdin() .lines() .next() @@ -96,8 +107,8 @@ fn main() -> anyhow::Result<()> { results.results[res_index].id }; - let details = tmdb_details(id, &key).context("fetching details")?; - let ident = make_ident(&details.title); + let details = tmdb_details(kind, id, &key).context("fetching details")?; + let ident = make_ident(details.title.as_ref().or(details.name.as_ref()).unwrap()); let path = path.join(&ident); std::fs::create_dir_all(&path)?; @@ -125,36 +136,82 @@ fn main() -> anyhow::Result<()> { backdrop, description: Some(details.overview), tagline: details.tagline, - title: details.title, + title: details.title.clone().or(details.name.clone()).unwrap(), + index: None, }; - let mut iteminfo = ItemInfo { - common, - duration: Default::default(), - tracks: Default::default(), - }; - info!("{iteminfo:#?}"); info!("is this correct? [y/n]"); if stdin().lines().next().unwrap().unwrap() != "y" { exit(0) } + let k = if let Some(input) = input { + let mut iteminfo = ItemInfo { + common, + duration: Default::default(), + tracks: Default::default(), + }; + info!("{iteminfo:#?}"); + let source_path = path.join(format!("source.mkv")); + // std::fs::rename(&input, &source_path)?; + // std::os::unix::fs::symlink(&input, &source_path)?; + std::fs::copy(&input, &source_path)?; + import_source(&mut iteminfo, &source_path)?; + serde_json::to_string_pretty(&iteminfo)? + } else { + serde_json::to_string_pretty(&DirectoryInfo { + common, + kind: jellycommon::DirectoryKind::Series, + })? + }; + + if args.dry { + println!("{k}") + } else { + let mut f = File::create(path.join(if series { + "directory.json".to_string() + } else { + format!("{ident}.jelly",) + }))?; + f.write_all(k.as_bytes())?; + } + + Ok(()) + } + Action::Episode { + path, + index, + title, + input, + } => { + let ident = make_ident(&title); + let common = CommmonInfo { + poster: None, + backdrop: None, + description: None, + tagline: None, + title, + index: Some(index), + }; + let mut iteminfo = ItemInfo { + common, + duration: Default::default(), + tracks: Default::default(), + }; + let path = path.join(&ident); + std::fs::create_dir_all(&path)?; let source_path = path.join(format!("source.mkv")); // std::fs::rename(&input, &source_path)?; // std::os::unix::fs::symlink(&input, &source_path)?; std::fs::copy(&input, &source_path)?; - let input = File::open(&source_path).unwrap(); - let mut input = EbmlReader::new(input); - import_read(&source_path, &mut input, &mut iteminfo)?; - + import_source(&mut iteminfo, &source_path)?; let k = serde_json::to_string_pretty(&iteminfo)?; if args.dry { println!("{k}") } else { - let mut f = File::create(path.join(format!("{ident}.jelly")))?; + let mut f = File::create(path.join(format!("{ident}.jelly",)))?; f.write_all(k.as_bytes())?; } - Ok(()) } Action::Set { @@ -178,6 +235,7 @@ fn main() -> anyhow::Result<()> { tagline: None, description: None, title: item.to_str().unwrap().to_string(), + index: None, }, duration: 0.0, tracks: Default::default(), @@ -231,3 +289,9 @@ fn make_ident(s: &str) -> String { } out } +fn import_source(iteminfo: &mut ItemInfo, source_path: &Path) -> anyhow::Result<()> { + let input = File::open(&source_path).unwrap(); + let mut input = EbmlReader::new(input); + import_read(&source_path.to_path_buf(), &mut input, iteminfo)?; + Ok(()) +} diff --git a/tools/src/tmdb.rs b/tools/src/tmdb.rs index 6f8c341..5f21afd 100644 --- a/tools/src/tmdb.rs +++ b/tools/src/tmdb.rs @@ -21,14 +21,14 @@ pub struct TmdbQueryResult { pub backdrop_path: Option<String>, pub genre_ids: Vec<u64>, pub id: u64, - pub original_language: String, - pub original_title: String, + pub original_language: Option<String>, + pub original_title: Option<String>, pub overview: String, pub popularity: f64, pub poster_path: Option<String>, - pub release_date: String, - pub title: String, - pub video: bool, + pub release_date: Option<String>, + pub title: Option<String>, + pub name: Option<String>, pub vote_average: f64, pub vote_count: usize, } @@ -39,21 +39,21 @@ pub struct TmdbDetails { pub backdrop_path: Option<String>, pub genres: Vec<TmdbGenre>, pub id: u64, - pub original_language: String, - pub original_title: String, + pub original_language: Option<String>, + pub original_title: Option<String>, pub overview: String, pub popularity: f64, pub poster_path: Option<String>, - pub release_date: String, - pub title: String, - pub video: bool, + pub release_date: Option<String>, + pub title: Option<String>, + pub name: Option<String>, pub vote_average: f64, pub vote_count: usize, - pub budget: usize, + pub budget: Option<usize>, pub homepage: Option<String>, pub imdb_id: Option<String>, pub production_companies: Vec<TmdbProductionCompany>, - pub revenue: usize, + pub revenue: Option<usize>, pub tagline: Option<String>, } @@ -70,19 +70,19 @@ pub struct TmdbProductionCompany { pub logo_path: Option<String>, } -pub fn tmdb_search(query: &str, key: &str) -> anyhow::Result<TmdbQuery> { +pub fn tmdb_search(kind: &str, query: &str, key: &str) -> anyhow::Result<TmdbQuery> { info!("searching tmdb: {query:?}"); Ok(reqwest::blocking::get(&format!( - "https://api.themoviedb.org/3/search/movie?query={}&api_key={key}", + "https://api.themoviedb.org/3/search/{kind}?query={}&api_key={key}", query.replace(" ", "+") ))? .json::<TmdbQuery>()?) } -pub fn tmdb_details(id: u64, key: &str) -> anyhow::Result<TmdbDetails> { +pub fn tmdb_details(kind: &str, id: u64, key: &str) -> anyhow::Result<TmdbDetails> { info!("fetching details: {id:?}"); Ok(reqwest::blocking::get(&format!( - "https://api.themoviedb.org/3/movie/{id}?api_key={key}" + "https://api.themoviedb.org/3/{kind}/{id}?api_key={key}" ))? .json()?) } |