mirror of
https://github.com/OMGeeky/twba.uploader.git
synced 2025-12-26 16:37:23 +01:00
cleanup
This commit is contained in:
@@ -9,7 +9,7 @@ use std::collections::HashMap;
|
||||
use std::ffi::OsStr;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tracing::instrument;
|
||||
use twba_local_db::entities::video_upload::{UploadStatus};
|
||||
use twba_local_db::entities::video_upload::UploadStatus;
|
||||
use twba_local_db::prelude::*;
|
||||
use twba_local_db::re_exports::sea_orm::{
|
||||
ActiveModelTrait, ActiveValue, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
||||
@@ -26,8 +26,7 @@ lazy_static! {
|
||||
#[derive(Debug)]
|
||||
pub struct UploaderClient {
|
||||
db: DatabaseConnection,
|
||||
reqwest_client: reqwest::Client,
|
||||
youtube_client: HashMap<String, youtube::YoutubeClient>,
|
||||
youtube_clients: HashMap<String, youtube::YoutubeClient>,
|
||||
}
|
||||
|
||||
impl UploaderClient {
|
||||
@@ -42,7 +41,7 @@ impl UploaderClient {
|
||||
let count = videos.len();
|
||||
info!("got {} videos to upload", count);
|
||||
|
||||
'video_loop: for video in videos {
|
||||
for video in videos {
|
||||
match self.upload_video(&video).await {
|
||||
Ok(_) => {
|
||||
info!("Uploaded video: {}: {}", video.id, video.name);
|
||||
@@ -50,27 +49,22 @@ impl UploaderClient {
|
||||
Err(e) => {
|
||||
error!("Error while uploading the video: {}: {}", video.id, e);
|
||||
|
||||
{
|
||||
let fail_count = video.fail_count + 1;
|
||||
let previous_fails = video
|
||||
.fail_reason
|
||||
.as_ref()
|
||||
.unwrap_or(&String::new())
|
||||
.to_string();
|
||||
let mut video = video.clone().into_active_model();
|
||||
video.fail_count = ActiveValue::Set(fail_count);
|
||||
video.fail_reason = ActiveValue::Set(Some(format!(
|
||||
"{}: {}\n\n{}",
|
||||
fail_count, e, previous_fails
|
||||
)));
|
||||
}
|
||||
// self.set_video_status_on_db(&video, Status::UploadFailed)
|
||||
// .await?;
|
||||
let fail_count = video.fail_count + 1;
|
||||
let previous_fails = video
|
||||
.fail_reason
|
||||
.as_ref()
|
||||
.unwrap_or(&String::new())
|
||||
.to_string();
|
||||
let mut video = video.clone().into_active_model();
|
||||
video.fail_count = ActiveValue::Set(fail_count);
|
||||
video.fail_reason = ActiveValue::Set(Some(format!(
|
||||
"{}: {}\n\n{}",
|
||||
fail_count, e, previous_fails
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//todo: maybe add some log to the db when videos were last uploaded?
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -86,7 +80,6 @@ impl UploaderClient {
|
||||
let part_count = video.part_count;
|
||||
let parts_folder_path = Path::new(&CONF.download_folder_path).join(video_id.to_string());
|
||||
let parts = get_part_files(&parts_folder_path, part_count).await?;
|
||||
dbg!(&parts);
|
||||
let user = Users::find_by_id(video.user_id)
|
||||
.one(&self.db)
|
||||
.await?
|
||||
@@ -96,9 +89,7 @@ impl UploaderClient {
|
||||
let all_parts_data = VideoData {
|
||||
video_tags: tags,
|
||||
video_category: 22,
|
||||
//TODO get from config
|
||||
video_privacy: VideoStatusPrivacyStatusEnum::Private,
|
||||
//TODO get from config
|
||||
playlist_privacy: PlaylistStatusPrivacyStatusEnum::Private,
|
||||
playlist_description: create_youtube_description(video, &user, Location::Playlist)?,
|
||||
playlist_title: create_youtube_title(video, &user, Location::Playlist)?,
|
||||
@@ -111,7 +102,7 @@ impl UploaderClient {
|
||||
self.set_playlist_id_for_video(video, playlist_id.clone())
|
||||
.await?;
|
||||
|
||||
'part_loop: for (part, part_number) in parts {
|
||||
for (part, part_number) in parts {
|
||||
let mut video_upload = self
|
||||
.insert_video_upload(video_id, part_number)
|
||||
.await?
|
||||
@@ -133,9 +124,7 @@ impl UploaderClient {
|
||||
video.id,
|
||||
part.display()
|
||||
);
|
||||
let upload = client_for_video
|
||||
.upload_video_part(video, &part, part_number, data)
|
||||
.await;
|
||||
let upload = client_for_video.upload_video_part(&part, data).await;
|
||||
match upload {
|
||||
Ok(uploaded_video_id) => {
|
||||
info!("uploaded part: {}", part.display());
|
||||
@@ -145,7 +134,7 @@ impl UploaderClient {
|
||||
.await?;
|
||||
video_upload.upload_status = ActiveValue::Set(UploadStatus::Uploaded);
|
||||
video_upload.youtube_video_id = ActiveValue::Set(Some(uploaded_video_id));
|
||||
video_upload = video_upload.update(&self.db).await?.into_active_model();
|
||||
video_upload.update(&self.db).await?;
|
||||
}
|
||||
Err(e) => {
|
||||
error!("could not upload part: {}", e);
|
||||
@@ -223,7 +212,7 @@ impl UploaderClient {
|
||||
}
|
||||
fn get_client_for_video(&self, video: &VideosModel) -> Result<&youtube::YoutubeClient> {
|
||||
let c = self
|
||||
.youtube_client
|
||||
.youtube_clients
|
||||
.get(&video.user_id.to_string())
|
||||
.ok_or(UploaderError::NoClient(video.user_id))?;
|
||||
Ok(c)
|
||||
@@ -248,7 +237,10 @@ async fn get_part_files(folder_path: &Path, count: i32) -> Result<Vec<(PathBuf,
|
||||
parts.push((path, part_number));
|
||||
}
|
||||
if parts.len() != count as usize {
|
||||
return Err(UploaderError::PartCountMismatch(count as usize, parts.len()));
|
||||
return Err(UploaderError::PartCountMismatch(
|
||||
count as usize,
|
||||
parts.len(),
|
||||
));
|
||||
}
|
||||
parts.sort_by_key(|a| a.1);
|
||||
Ok(parts)
|
||||
@@ -280,8 +272,6 @@ fn get_part_number_from_path(path: &Path) -> Result<usize> {
|
||||
|
||||
impl UploaderClient {
|
||||
pub async fn new(db: DatabaseConnection) -> Result<Self> {
|
||||
let reqwest_client = reqwest::Client::new();
|
||||
|
||||
let mut clients = HashMap::new();
|
||||
|
||||
let users = twba_local_db::get_watched_users(&db).await?;
|
||||
@@ -298,8 +288,7 @@ impl UploaderClient {
|
||||
|
||||
Ok(Self {
|
||||
db,
|
||||
reqwest_client,
|
||||
youtube_client: clients,
|
||||
youtube_clients: clients,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ use std::fmt::{Debug, Formatter};
|
||||
use std::path::{Path, PathBuf};
|
||||
use tokio::fs;
|
||||
use tracing::instrument;
|
||||
use twba_local_db::prelude::{UsersModel, VideosModel};
|
||||
use twba_local_db::prelude::UsersModel;
|
||||
|
||||
mod auth;
|
||||
pub(crate) mod data;
|
||||
@@ -23,18 +23,11 @@ mod flow_delegate;
|
||||
pub struct YoutubeClient {
|
||||
//TODO: change this to a thing that does exponential backoff when possible
|
||||
client: google_youtube3::YouTube<HttpsConnector<HttpConnector>>,
|
||||
user: Option<UsersModel>,
|
||||
}
|
||||
|
||||
impl YoutubeClient {
|
||||
#[instrument(skip(self, video, path, data))]
|
||||
pub(crate) async fn upload_video_part(
|
||||
&self,
|
||||
video: &VideosModel,
|
||||
path: &Path,
|
||||
part_num: usize,
|
||||
data: VideoData,
|
||||
) -> Result<String> {
|
||||
#[instrument(skip(self, path, data))]
|
||||
pub(crate) async fn upload_video_part(&self, path: &Path, data: VideoData) -> Result<String> {
|
||||
let video_data = data;
|
||||
let upload_result = self
|
||||
.upload_youtube_video_resumable(video_data, path)
|
||||
@@ -134,14 +127,7 @@ impl YoutubeClient {
|
||||
..Default::default()
|
||||
};
|
||||
let playlist_insert_call = self.client.playlists().insert(playlist);
|
||||
let (x, playlist) = playlist_insert_call
|
||||
.doit()
|
||||
.await
|
||||
// .context("could not create playlist")
|
||||
// ?
|
||||
.unwrap()
|
||||
//test
|
||||
;
|
||||
let (_, playlist) = playlist_insert_call.doit().await.unwrap();
|
||||
|
||||
playlist.id.ok_or(UploaderError::NoIdReturned)
|
||||
}
|
||||
@@ -170,7 +156,7 @@ impl YoutubeClient {
|
||||
)
|
||||
.await?;
|
||||
let client = google_youtube3::YouTube::new(hyper_client, auth);
|
||||
Ok(Self { client, user })
|
||||
Ok(Self { client })
|
||||
}
|
||||
|
||||
fn create_hyper_client() -> Client<HttpsConnector<HttpConnector>> {
|
||||
|
||||
@@ -2,12 +2,12 @@ use crate::client::youtube::flow_delegate::CustomFlowDelegate;
|
||||
use crate::errors::{AuthError, PersistentPathError};
|
||||
use crate::prelude::*;
|
||||
use google_youtube3::api::Scope;
|
||||
use google_youtube3::oauth2::authenticator::Authenticator;
|
||||
use google_youtube3::{hyper::client::HttpConnector, hyper_rustls::HttpsConnector, oauth2};
|
||||
use std::collections::HashMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tokio::fs;
|
||||
use tracing::instrument;
|
||||
use google_youtube3::oauth2::authenticator::Authenticator;
|
||||
|
||||
type Result<T> = std::result::Result<T, AuthError>;
|
||||
#[instrument]
|
||||
@@ -40,7 +40,7 @@ pub(super) async fn get_auth<USER: EasyString>(
|
||||
let user = user.map(|x| x.into());
|
||||
let method = oauth2::InstalledFlowReturnMethod::Interactive;
|
||||
let auth = oauth2::InstalledFlowAuthenticator::builder(app_secret, method)
|
||||
.flow_delegate(Box::new(CustomFlowDelegate::new(user, &crate::CONF)))
|
||||
.flow_delegate(Box::new(CustomFlowDelegate::new(user)))
|
||||
.persist_tokens_to_disk(persistent_path)
|
||||
.force_account_selection(true)
|
||||
.build()
|
||||
|
||||
@@ -26,7 +26,6 @@ pub mod substitutions {
|
||||
pub enum Location {
|
||||
Video(usize),
|
||||
Playlist,
|
||||
Other,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
@@ -83,7 +82,6 @@ pub(crate) fn create_youtube_title(
|
||||
let max_len = match target {
|
||||
Location::Video(_) => Some(YOUTUBE_TITLE_MAX_LENGTH),
|
||||
Location::Playlist => Some(YOUTUBE_TITLE_MAX_LENGTH),
|
||||
Location::Other => None,
|
||||
};
|
||||
let title = shorten_string_if_needed(title, max_len);
|
||||
Ok(title)
|
||||
@@ -94,7 +92,6 @@ fn get_title_template(target: Location) -> String {
|
||||
match target {
|
||||
Location::Video(_) => templates.video_title,
|
||||
Location::Playlist => templates.playlist_title,
|
||||
Location::Other => format!("\"{}\"", ORIGINAL_TITLE),
|
||||
}
|
||||
}
|
||||
fn get_description_template(target: Location) -> String {
|
||||
@@ -106,7 +103,6 @@ fn get_description_template(target: Location) -> String {
|
||||
match target {
|
||||
Location::Video(_) => templates.video_description,
|
||||
Location::Playlist => templates.playlist_description,
|
||||
Location::Other => templates.video_description,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,13 +216,6 @@ mod test {
|
||||
assert_eq!("123456789", test);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_youtube_title_other() {
|
||||
let (x, user) = get_test_sample_data();
|
||||
let description = create_youtube_title(&x, &user, Location::Other).unwrap();
|
||||
assert_eq!("\"wow\"", description);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_youtube_title_playlist() {
|
||||
let (x, user) = get_test_sample_data();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::errors::AuthError;
|
||||
use crate::prelude::*;
|
||||
use google_youtube3::oauth2::authenticator_delegate::InstalledFlowDelegate;
|
||||
use std::{
|
||||
fmt::{Debug, Formatter},
|
||||
future::Future,
|
||||
@@ -7,9 +8,7 @@ use std::{
|
||||
pin::Pin,
|
||||
};
|
||||
use tracing::instrument;
|
||||
use twba_backup_config::Conf;
|
||||
use twba_common::notify::NotificationRequest;
|
||||
use google_youtube3::oauth2::authenticator_delegate::InstalledFlowDelegate;
|
||||
|
||||
pub struct CustomFlowDelegate<USER: EasyString> {
|
||||
user: Option<USER>,
|
||||
@@ -23,7 +22,7 @@ impl<USER: EasyString> Debug for CustomFlowDelegate<USER> {
|
||||
}
|
||||
}
|
||||
impl<USER: EasyString> CustomFlowDelegate<USER> {
|
||||
pub(crate) fn new(user: Option<USER>, config: &'static Conf) -> Self {
|
||||
pub(crate) fn new(user: Option<USER>) -> Self {
|
||||
Self { user }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ pub(crate) use std::result::Result as StdResult;
|
||||
pub type Result<T> = StdResult<T, UploaderError>;
|
||||
|
||||
pub(crate) use tracing::{debug, error, info, trace, warn};
|
||||
pub(crate) use twba_common::prelude::{twba_backup_config, twba_local_db};
|
||||
pub(crate) use twba_common::prelude::twba_local_db;
|
||||
pub trait EasyString: Into<String> + Clone + Debug + Send + Sync {}
|
||||
impl<T> EasyString for T where T: Into<String> + Clone + Debug + Send + Sync {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user