fix: handle playlist not found
This commit is contained in:
parent
de9e3c6ed9
commit
79b7fcf92c
5 changed files with 49 additions and 23 deletions
|
|
@ -533,16 +533,7 @@ fn map_channel_content(
|
|||
|
||||
Ok(MapResult::ok(content))
|
||||
}
|
||||
None => match alerts {
|
||||
Some(alerts) => Err(ExtractionError::ContentUnavailable(
|
||||
alerts
|
||||
.into_iter()
|
||||
.map(|a| a.alert_renderer.text)
|
||||
.collect::<Vec<_>>()
|
||||
.join(" "),
|
||||
)),
|
||||
None => Err(ExtractionError::InvalidData("no contents".into())),
|
||||
},
|
||||
None => Err(response::alerts_to_err(alerts)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,8 +68,12 @@ impl MapResponse<Playlist> for response::Playlist {
|
|||
lang: Language,
|
||||
_deobf: Option<&Deobfuscator>,
|
||||
) -> Result<MapResult<Playlist>, ExtractionError> {
|
||||
// TODO: think about a deserializer that deserializes only first list item
|
||||
let mut tcbr_contents = self.contents.two_column_browse_results_renderer.contents;
|
||||
let (contents, header) = match (self.contents, self.header) {
|
||||
(Some(contents), Some(header)) => (contents, header),
|
||||
_ => return Err(response::alerts_to_err(self.alerts)),
|
||||
};
|
||||
|
||||
let mut tcbr_contents = contents.two_column_browse_results_renderer.contents;
|
||||
let video_items = some_or_bail!(
|
||||
some_or_bail!(
|
||||
some_or_bail!(
|
||||
|
|
@ -121,11 +125,11 @@ impl MapResponse<Playlist> for response::Playlist {
|
|||
}
|
||||
None => {
|
||||
let header_banner = some_or_bail!(
|
||||
self.header.playlist_header_renderer.playlist_header_banner,
|
||||
header.playlist_header_renderer.playlist_header_banner,
|
||||
Err(ExtractionError::InvalidData("no thumbnail found".into()))
|
||||
);
|
||||
|
||||
let mut byline = self.header.playlist_header_renderer.byline;
|
||||
let mut byline = header.playlist_header_renderer.byline;
|
||||
let last_update_txt = byline
|
||||
.try_swap_remove(1)
|
||||
.map(|b| b.playlist_byline_renderer.text);
|
||||
|
|
@ -140,14 +144,14 @@ impl MapResponse<Playlist> for response::Playlist {
|
|||
let n_videos = match ctoken {
|
||||
Some(_) => {
|
||||
ok_or_bail!(
|
||||
util::parse_numeric(&self.header.playlist_header_renderer.num_videos_text),
|
||||
util::parse_numeric(&header.playlist_header_renderer.num_videos_text),
|
||||
Err(ExtractionError::InvalidData("no video count".into()))
|
||||
)
|
||||
}
|
||||
None => videos.len() as u64,
|
||||
};
|
||||
|
||||
let playlist_id = self.header.playlist_header_renderer.playlist_id;
|
||||
let playlist_id = header.playlist_header_renderer.playlist_id;
|
||||
if playlist_id != id {
|
||||
return Err(ExtractionError::WrongResult(format!(
|
||||
"got wrong playlist id {}, expected {}",
|
||||
|
|
@ -155,10 +159,9 @@ impl MapResponse<Playlist> for response::Playlist {
|
|||
)));
|
||||
}
|
||||
|
||||
let name = self.header.playlist_header_renderer.title;
|
||||
let description = self.header.playlist_header_renderer.description_text;
|
||||
let channel = self
|
||||
.header
|
||||
let name = header.playlist_header_renderer.title;
|
||||
let description = header.playlist_header_renderer.description_text;
|
||||
let channel = header
|
||||
.playlist_header_renderer
|
||||
.owner_text
|
||||
.and_then(|link| ChannelId::try_from(link).ok());
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ pub use channel_rss::ChannelRss;
|
|||
use serde::Deserialize;
|
||||
use serde_with::{json::JsonString, serde_as, DefaultOnError, VecSkipError};
|
||||
|
||||
use crate::error::ExtractionError;
|
||||
use crate::serializer::{
|
||||
ignore_any,
|
||||
text::{Text, TextComponent},
|
||||
|
|
@ -471,3 +472,16 @@ impl IsShort for Vec<TimeOverlay> {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alerts_to_err(alerts: Option<Vec<Alert>>) -> ExtractionError {
|
||||
match alerts {
|
||||
Some(alerts) => ExtractionError::ContentUnavailable(
|
||||
alerts
|
||||
.into_iter()
|
||||
.map(|a| a.alert_renderer.text)
|
||||
.collect::<Vec<_>>()
|
||||
.join(" "),
|
||||
),
|
||||
None => ExtractionError::InvalidData("no contents".into()),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,17 @@ use serde_with::{DefaultOnError, VecSkipError};
|
|||
use crate::serializer::text::{Text, TextComponent};
|
||||
use crate::serializer::{MapResult, VecLogError};
|
||||
|
||||
use super::{ContentRenderer, ContentsRenderer, ThumbnailsWrap, VideoListItem};
|
||||
use super::{Alert, ContentRenderer, ContentsRenderer, ThumbnailsWrap, VideoListItem};
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Playlist {
|
||||
pub contents: Contents,
|
||||
pub header: Header,
|
||||
pub contents: Option<Contents>,
|
||||
pub header: Option<Header>,
|
||||
pub sidebar: Option<Sidebar>,
|
||||
#[serde_as(as = "Option<DefaultOnError>")]
|
||||
pub alerts: Option<Vec<Alert>>,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
|
|
|
|||
|
|
@ -211,6 +211,21 @@ async fn playlist_cont2() {
|
|||
assert!(playlist.videos.count.unwrap() > 100);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn playlist_not_found() {
|
||||
let rp = RustyPipe::builder().strict().build();
|
||||
let err = rp
|
||||
.query()
|
||||
.playlist("PLbZIPy20-1pN7mqjckepWF78ndb6ci_qz")
|
||||
.await
|
||||
.unwrap_err();
|
||||
|
||||
assert!(matches!(
|
||||
err,
|
||||
Error::Extraction(ExtractionError::ContentUnavailable(_))
|
||||
));
|
||||
}
|
||||
|
||||
//#VIDEO DETAILS
|
||||
|
||||
#[tokio::test]
|
||||
|
|
|
|||
Reference in a new issue