mirror of
https://framagit.org/veretcle/tootube.git
synced 2025-07-20 20:41:17 +02:00
♻️: refactor src/peertube.rs and src/youtube.rs code to be more efficient regarding reqwest management
This commit is contained in:
258
src/peertube.rs
258
src/peertube.rs
@@ -1,6 +1,9 @@
|
||||
use crate::{config::PeertubeConfig, error::TootubeError};
|
||||
use log::debug;
|
||||
use reqwest::Client;
|
||||
use reqwest::{
|
||||
header::{HeaderMap, HeaderValue},
|
||||
Client,
|
||||
};
|
||||
use rpassword::prompt_password;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{boxed::Box, cmp::Ordering, error::Error, io::stdin};
|
||||
@@ -96,28 +99,6 @@ pub struct PeerTubeVideoStreamingPlaylistsFilesResolution {
|
||||
pub id: u16,
|
||||
}
|
||||
|
||||
/// This gets the last video uploaded to the PeerTube server
|
||||
pub async fn get_latest_video(u: &str) -> Result<PeerTubeVideo, Box<dyn Error>> {
|
||||
let body = reqwest::get(format!("{}/api/v1/videos?count=1&sort=-publishedAt", u))
|
||||
.await?
|
||||
.json::<PeerTubeVideos>()
|
||||
.await?;
|
||||
|
||||
let vid = get_video_detail(u, &body.data[0].uuid).await?;
|
||||
|
||||
Ok(vid)
|
||||
}
|
||||
|
||||
/// This gets all the crispy details about one particular video
|
||||
async fn get_video_detail(u: &str, v: &str) -> Result<PeerTubeVideo, Box<dyn Error>> {
|
||||
let body = reqwest::get(format!("{}/api/v1/videos/{}", u, v))
|
||||
.await?
|
||||
.json::<PeerTubeVideo>()
|
||||
.await?;
|
||||
|
||||
Ok(body)
|
||||
}
|
||||
|
||||
/// This function makes the registration process a little bit easier
|
||||
#[tokio::main]
|
||||
pub async fn register(config: &PeertubeConfig) -> Result<(), Box<dyn Error>> {
|
||||
@@ -173,107 +154,140 @@ pub async fn register(config: &PeertubeConfig) -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_refresh_token(config: &PeertubeConfig) -> Result<String, Box<dyn Error>> {
|
||||
// unwrap is safe here, this function is only called when oauth2 is present
|
||||
let oauth2_config = config.oauth2.as_ref().unwrap().clone();
|
||||
// retrieve the refresh_token from the file
|
||||
let refresh_token = read_to_string(&oauth2_config.refresh_token).await?;
|
||||
|
||||
debug!(
|
||||
"Opened file {} to retrieve Token",
|
||||
&oauth2_config.refresh_token
|
||||
);
|
||||
|
||||
let params = PeerTubeUsersToken {
|
||||
client_id: oauth2_config.client_id.clone(),
|
||||
client_secret: oauth2_config.client_secret.clone(),
|
||||
grant_type: "refresh_token".to_string(),
|
||||
refresh_token: Some(refresh_token),
|
||||
username: None,
|
||||
password: None,
|
||||
};
|
||||
|
||||
let client = Client::new();
|
||||
let oauth2_token = client
|
||||
.post(format!("{}/api/v1/users/token", config.base_url))
|
||||
.form(¶ms)
|
||||
.send()
|
||||
.await?
|
||||
.json::<PeerTubeUsersTokenResponse>()
|
||||
.await?;
|
||||
|
||||
debug!("Retrieved access_token: {}", &oauth2_token.access_token);
|
||||
|
||||
// write the new refresh token to the file
|
||||
write(&oauth2_config.refresh_token, oauth2_token.refresh_token).await?;
|
||||
|
||||
debug!(
|
||||
"Written refresh_token to file {}",
|
||||
&oauth2_config.refresh_token
|
||||
);
|
||||
|
||||
Ok(oauth2_token.access_token)
|
||||
#[derive(Debug)]
|
||||
pub struct PeerTube {
|
||||
base_url: String,
|
||||
client: Client,
|
||||
}
|
||||
|
||||
pub async fn get_original_video_source(
|
||||
uuid: &str,
|
||||
config: &PeertubeConfig,
|
||||
) -> Result<String, Box<dyn Error>> {
|
||||
let access_token = get_refresh_token(config).await?;
|
||||
|
||||
let client = Client::new();
|
||||
|
||||
let source_vid = client
|
||||
.get(format!("{}/api/v1/videos/{}/source", config.base_url, uuid))
|
||||
.header("Authorization", format!("Bearer {}", &access_token))
|
||||
.send()
|
||||
.await?
|
||||
.json::<PeerTubeVideoSourceResponse>()
|
||||
.await?;
|
||||
|
||||
debug!("Got the Source Vid URL: {}", &source_vid.file_download_url);
|
||||
|
||||
let video_file_token = client
|
||||
.post(format!("{}/api/v1/videos/{}/token", config.base_url, uuid))
|
||||
.header("Authorization", format!("Bearer {}", &access_token))
|
||||
.send()
|
||||
.await?
|
||||
.json::<PeerTubeVideoTokenResponse>()
|
||||
.await?;
|
||||
|
||||
debug!("Got the File Token: {}", &video_file_token.files.token);
|
||||
|
||||
Ok(format!(
|
||||
"{}?videoFileToken={}",
|
||||
source_vid.file_download_url, video_file_token.files.token
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn delete_original_video_source(
|
||||
uuid: &str,
|
||||
config: &PeertubeConfig,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let access_token = get_refresh_token(config).await?;
|
||||
|
||||
let client = Client::new();
|
||||
|
||||
let res = client
|
||||
.delete(format!(
|
||||
"{}/api/v1/videos/{}/source/file",
|
||||
config.base_url, uuid
|
||||
))
|
||||
.header("Authorization", format!("Bearer {}", &access_token))
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
if !res.status().is_success() {
|
||||
return Err(TootubeError::new(&format!(
|
||||
"Cannot delete source video file {}: {}",
|
||||
uuid,
|
||||
res.text().await?
|
||||
))
|
||||
.into());
|
||||
impl PeerTube {
|
||||
/// Create a new PeerTube struct with a basic embedded reqwest::Client
|
||||
pub fn new(base_url: &str) -> Self {
|
||||
PeerTube {
|
||||
base_url: format!("{}/api/v1", base_url),
|
||||
client: Client::new(),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
/// Retrieve the refresh_token and access_token and update the embedded reqwest::Client to have
|
||||
/// the default required header
|
||||
pub async fn with_client(
|
||||
mut self,
|
||||
client_id: &str,
|
||||
client_secret: &str,
|
||||
refresh_token_path: &str,
|
||||
) -> Result<Self, Box<dyn Error>> {
|
||||
let refresh_token = read_to_string(refresh_token_path).await?;
|
||||
|
||||
let params = PeerTubeUsersToken {
|
||||
client_id: client_id.to_string(),
|
||||
client_secret: client_secret.to_string(),
|
||||
grant_type: "refresh_token".to_string(),
|
||||
refresh_token: Some(refresh_token),
|
||||
username: None,
|
||||
password: None,
|
||||
};
|
||||
|
||||
let req = self
|
||||
.client
|
||||
.post(&format!("{}/users/token", self.base_url))
|
||||
.form(¶ms)
|
||||
.send()
|
||||
.await?
|
||||
.json::<PeerTubeUsersTokenResponse>()
|
||||
.await?;
|
||||
|
||||
write(refresh_token_path, req.refresh_token).await?;
|
||||
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert(
|
||||
"Authorization",
|
||||
HeaderValue::from_str(&format!("Bearer {}", req.access_token))?,
|
||||
);
|
||||
|
||||
self.client = reqwest::Client::builder()
|
||||
.default_headers(headers)
|
||||
.build()?;
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// This gets the last video uploaded to the PeerTube server
|
||||
pub async fn get_latest_video(&self) -> Result<PeerTubeVideo, Box<dyn Error>> {
|
||||
let body = self
|
||||
.client
|
||||
.get(format!(
|
||||
"{}/videos?count=1&sort=-publishedAt",
|
||||
self.base_url
|
||||
))
|
||||
.send()
|
||||
.await?
|
||||
.json::<PeerTubeVideos>()
|
||||
.await?;
|
||||
|
||||
let vid = self.get_video_detail(&body.data[0].uuid).await?;
|
||||
|
||||
Ok(vid)
|
||||
}
|
||||
|
||||
/// This gets all the crispy details about one particular video
|
||||
async fn get_video_detail(&self, v: &str) -> Result<PeerTubeVideo, Box<dyn Error>> {
|
||||
let body = self
|
||||
.client
|
||||
.get(format!("{}/videos/{}", self.base_url, v))
|
||||
.send()
|
||||
.await?
|
||||
.json::<PeerTubeVideo>()
|
||||
.await?;
|
||||
|
||||
Ok(body)
|
||||
}
|
||||
|
||||
/// Get the original video source
|
||||
pub async fn get_original_video_source(&self, uuid: &str) -> Result<String, Box<dyn Error>> {
|
||||
let source_vid = self
|
||||
.client
|
||||
.get(format!("{}/videos/{}/source", self.base_url, uuid))
|
||||
.send()
|
||||
.await?
|
||||
.json::<PeerTubeVideoSourceResponse>()
|
||||
.await?;
|
||||
|
||||
debug!("Got the Source Vid URL: {}", &source_vid.file_download_url);
|
||||
|
||||
let video_file_token = self
|
||||
.client
|
||||
.post(format!("{}/videos/{}/token", self.base_url, uuid))
|
||||
.send()
|
||||
.await?
|
||||
.json::<PeerTubeVideoTokenResponse>()
|
||||
.await?;
|
||||
|
||||
debug!("Got the File Token: {}", &video_file_token.files.token);
|
||||
|
||||
Ok(format!(
|
||||
"{}?videoFileToken={}",
|
||||
source_vid.file_download_url, video_file_token.files.token
|
||||
))
|
||||
}
|
||||
|
||||
/// Delete the original video source
|
||||
pub async fn delete_original_video_source(&self, uuid: &str) -> Result<(), Box<dyn Error>> {
|
||||
let res = self
|
||||
.client
|
||||
.delete(format!("{}/videos/{}/source/file", self.base_url, uuid))
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
if !res.status().is_success() {
|
||||
return Err(TootubeError::new(&format!(
|
||||
"Cannot delete source video file {}: {}",
|
||||
uuid,
|
||||
res.text().await?
|
||||
))
|
||||
.into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user