From 6a4a3a8ad777bd763bae124813a831daa8e9f81d Mon Sep 17 00:00:00 2001 From: OMGeeky Date: Sat, 3 Jun 2023 19:10:52 +0200 Subject: [PATCH] use anyhow result in most cases & some more tracing improvements --- Cargo.toml | 4 +- src/lib.rs | 121 +++++++++++++++++++++++++++++++------------------ src/prelude.rs | 2 + 3 files changed, 80 insertions(+), 47 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a450efb..68fddee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "google_youtube" -version = "0.1.2" +version = "0.1.3" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -18,7 +18,7 @@ serde_json = "1.0" async-trait = "0.1.60" strfmt = "0.2.2" - +anyhow = "1.0" log = "0.4" simplelog = "0.12.1" #[patch.crates-io.yup-oauth2] diff --git a/src/lib.rs b/src/lib.rs index f6f41c3..7cefc97 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ - -use crate::prelude::*; +use anyhow::{anyhow, Context}; use std::default::Default; use std::error::Error; +use std::fmt::{Debug, Formatter}; use std::path::{Path, PathBuf}; use exponential_backoff::youtube::generic_check_backoff_youtube; @@ -20,17 +20,27 @@ use google_youtube3::{ hyper::{Body, Response}, hyper_rustls::HttpsConnector, }; +#[cfg(feature = "tracing")] +use tracing::instrument; use youtube::YouTube; use youtube::{hyper, hyper_rustls::HttpsConnectorBuilder}; +use crate::prelude::*; + mod auth; -pub mod scopes; pub mod prelude; +pub mod scopes; // mod config; pub struct YoutubeClient { pub client: YouTube>, } +impl Debug for YoutubeClient { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("YoutubeClient").finish() + } +} +#[derive(Debug)] pub enum PrivacyStatus { Public, Unlisted, @@ -46,11 +56,12 @@ impl PrivacyStatus { } } impl YoutubeClient { - pub async fn new>( - path_to_application_secret: Option, - scopes: Vec, - user: Option, - ) -> Result> { + #[cfg_attr(feature = "tracing", instrument)] + pub async fn new( + path_to_application_secret: Option + Debug>, + scopes: Vec + Debug>, + user: Option + Debug>, + ) -> anyhow::Result { let scopes = scopes .into_iter() .map(|s| s.into()) @@ -64,23 +75,29 @@ impl YoutubeClient { .build(), ); - let path_to_application_secret = match path_to_application_secret { - None => "auth/service_account2.json".to_string(), - Some(s) => s.into(), - }; - - let auth = auth::get_authenticator(path_to_application_secret, &scopes, user).await?; - + let path_to_application_secret = path_to_application_secret + .map(|x| x.into()) + .unwrap_or_else(|| { + warn!("the path to the application secret was not provided. Using default!"); + "auth/service_account2.json".to_string() + }); + trace!( + "getting authenticator from path: {}", + path_to_application_secret + ); + let auth = auth::get_authenticator(path_to_application_secret, &scopes, user) + .await + .map_err(|e| anyhow!("error: {}", e)) + .context("could not get authenticator")?; + trace!("creating youtube client"); let client: YouTube> = YouTube::new(hyper_client, auth); let res = Self { client }; Ok(res) } - pub async fn find_playlist_by_name( - &self, - name: &str, - ) -> Result, Box> { + #[cfg_attr(feature = "tracing", instrument)] + pub async fn find_playlist_by_name(&self, name: &str) -> Result> { let part = vec!["snippet".to_string()]; struct PlaylistParams { @@ -100,7 +117,10 @@ impl YoutubeClient { } let para = PlaylistParams { part, mine: true }; let (_res, playlists): (Response, PlaylistListResponse) = - generic_check_backoff_youtube(&self.client, ¶, list_playlist).await??; + generic_check_backoff_youtube(&self.client, ¶, list_playlist) + .await + .map_err(|e| anyhow!("backoff error: {}", e))? + .context("list_playlist returned an error")?; if let Some(items) = playlists.items { for element in items { @@ -116,10 +136,8 @@ impl YoutubeClient { Ok(None) } - pub async fn find_playlist_or_create_by_name( - &self, - name: &str, - ) -> Result> { + #[cfg_attr(feature = "tracing", instrument)] + pub async fn find_playlist_or_create_by_name(&self, name: &str) -> Result { let playlist = self.find_playlist_by_name(name).await?; if let Some(playlist) = playlist { return Ok(playlist); @@ -128,11 +146,8 @@ impl YoutubeClient { Ok(playlist) } - pub async fn add_video_to_playlist( - &self, - video: &Video, - playlist: &Playlist, - ) -> Result<(), Box> { + #[cfg_attr(feature = "tracing", instrument)] + pub async fn add_video_to_playlist(&self, video: &Video, playlist: &Playlist) -> Result<()> { let playlist_item = PlaylistItem { snippet: Some(PlaylistItemSnippet { playlist_id: Some(playlist.id.clone().unwrap()), @@ -160,22 +175,25 @@ impl YoutubeClient { let (res, _) = generic_check_backoff_youtube(&self.client, &playlist_item, insert_playlist_item) - .await??; + .await + .map_err(|e| anyhow!("backoff error: {}", e))? + .context("insert playlist item returned an error")?; if res.status().is_success() { Ok(()) } else { - Err(format!("got status: {}", res.status().as_u16()).into()) + Err(anyhow!("got status: {}", res.status().as_u16())) } } - pub async fn upload_video, V: Into>>( + #[cfg_attr(feature = "tracing", instrument)] + pub async fn upload_video( &self, - path: impl AsRef, - title: S, - description: S, - tags: V, + path: impl AsRef + Debug, + title: impl Into + Debug, + description: impl Into + Debug, + tags: impl Into> + Debug, privacy_status: PrivacyStatus, - ) -> Result> { + ) -> Result