Initial commit

This commit is contained in:
VC
2023-09-29 17:16:47 +02:00
commit 65cbb89eb5
7 changed files with 1350 additions and 0 deletions

31
src/config.rs Normal file
View File

@@ -0,0 +1,31 @@
use std::fs::read_to_string;
use serde::Deserialize;
// General configuration Struct
#[derive(Debug, Deserialize)]
pub struct Config {
pub peertube: PeertubeConfig,
pub youtube: YoutubeConfig,
}
#[derive(Debug, Deserialize)]
pub struct PeertubeConfig {
pub base_url: String,
}
#[derive(Debug, Deserialize)]
pub struct YoutubeConfig {
pub api_key: String,
}
/// Parses the TOML file into a Config struct
pub fn parse_toml(toml_file: &str) -> Config {
let toml_config =
read_to_string(toml_file).unwrap_or_else(|e| panic!("Cannot open file {toml_file}: {e}"));
let config: Config = toml::from_str(&toml_config)
.unwrap_or_else(|e| panic!("Cannot parse TOML file {toml_file}: {e}"));
config
}

17
src/lib.rs Normal file
View File

@@ -0,0 +1,17 @@
mod config;
pub use config::parse_toml;
use config::Config;
mod peertube;
use peertube::{get_latest_video, get_max_resolution_dl};
pub fn run(config: Config) {
// Get the latest video object
let latest_vid = get_latest_video(&config.peertube.base_url).unwrap_or_else(|e| {
panic!("Cannot retrieve the latest video, something must have gone terribly wrong: {e}")
});
let dl_url = get_max_resolution_dl(&latest_vid.streaming_playlists.unwrap());
println!("{dl_url}");
}

25
src/main.rs Normal file
View File

@@ -0,0 +1,25 @@
use clap::{Arg, Command};
use tootube::*;
const DEFAULT_CONFIG_PATH: &str = "/usr/local/etc/tootube.toml";
fn main() {
let matches = Command::new(env!("CARGO_PKG_NAME"))
.version(env!("CARGO_PKG_VERSION"))
.about("A simple PeerTube to YouTube converter")
.arg(
Arg::new("config")
.short('c')
.long("config")
.value_name("CONFIG_FILE")
.help("TOML config file for tootube")
.num_args(1)
.default_value(DEFAULT_CONFIG_PATH)
.display_order(1),
)
.get_matches();
let config = parse_toml(matches.get_one::<String>("config").unwrap());
run(config);
}

90
src/peertube.rs Normal file
View File

@@ -0,0 +1,90 @@
use serde::Deserialize;
use std::{boxed::Box, error::Error};
#[derive(Debug, Deserialize)]
pub struct PeerTubeVideos {
pub total: u64,
pub data: Vec<PeerTubeVideo>,
}
#[derive(Debug, Deserialize)]
pub struct PeerTubeVideo {
pub name: String,
pub uuid: String,
pub description: String,
#[serde(rename = "streamingPlaylists")]
pub streaming_playlists: Option<Vec<PeerTubeVideoStreamingPlaylists>>,
}
#[derive(Debug, Deserialize)]
pub struct PeerTubeVideoStreamingPlaylists {
pub files: Vec<PeerTubeVideoStreamingPlaylistsFiles>,
}
#[derive(Debug, Deserialize)]
pub struct PeerTubeVideoStreamingPlaylistsFiles {
pub id: u64,
pub resolution: PeerTubeVideoStreamingPlaylistsFilesResolution,
#[serde(rename = "fileDownloadUrl")]
pub file_download_url: String,
}
#[derive(Debug, Deserialize)]
pub struct PeerTubeVideoStreamingPlaylistsFilesResolution {
pub id: u16,
}
/// This gets the last video uploaded to the PeerTube server
pub fn get_latest_video(u: &str) -> Result<PeerTubeVideo, Box<dyn Error>> {
let body = reqwest::blocking::get(format!("{}/api/v1/videos?count=1&sort=-publishedAt", u))?
.json::<PeerTubeVideos>()?;
let vid = get_video_detail(u, &body.data[0].uuid)?;
Ok(vid)
}
/// This returns the direct download URL for with the maximum resolution
pub fn get_max_resolution_dl(p: &Vec<PeerTubeVideoStreamingPlaylists>) -> String {
let max_res = p[0].files.iter().fold(std::u16::MIN, |a,b| a.resolution.id.max(&b.resolution.id));
// let mut res = 0;
// let mut dl_url = String::new();
//
// for i in p[0].files.iter() {
// if i.resolution.id > res {
// res = i.resolution.id;
// dl_url = i.file_download_url.clone();
// }
// }
//
// dl_url
"blah".to_string()
}
/// This gets all the crispy details about one particular video
fn get_video_detail(u: &str, v: &str) -> Result<PeerTubeVideo, Box<dyn Error>> {
let body =
reqwest::blocking::get(format!("{}/api/v1/videos/{}", u, v))?.json::<PeerTubeVideo>()?;
Ok(body)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_max_resolution_dl() {
let str_plist: Vec<PeerTubeVideoStreamingPlaylists> = vec![
PeerTubeVideoStreamingPlaylists {
files: vec![PeerTubeVideoStreamingPlaylistsFiles { id: 1025, resolution: PeerTubeVideoStreamingPlaylistsFilesResolution { id: 990 }, file_download_url: "meh!".to_string() },
PeerTubeVideoStreamingPlaylistsFiles { id: 1027, resolution: PeerTubeVideoStreamingPlaylistsFilesResolution { id: 1720 }, file_download_url: "blah".to_string() },
PeerTubeVideoStreamingPlaylistsFiles { id: 1026, resolution: PeerTubeVideoStreamingPlaylistsFilesResolution { id: 360 }, file_download_url: "nope".to_string() },
]
}
];
assert_eq!("blah".to_string(), get_max_resolution_dl(&str_plist));
}
}