Compare commits
2 commits
3c1cc92461
...
39b32da5a4
Author | SHA1 | Date | |
---|---|---|---|
39b32da5a4 | |||
9f7f337efd |
9 changed files with 58 additions and 20 deletions
|
@ -269,7 +269,7 @@ impl<T> CacheEntry<T> {
|
|||
impl<T> From<T> for CacheEntry<T> {
|
||||
fn from(f: T) -> Self {
|
||||
Self::Some {
|
||||
last_update: OffsetDateTime::now_utc(),
|
||||
last_update: util::now_sec(),
|
||||
data: f,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,14 +53,20 @@ impl<T: TryFrom<YouTubeItem>> MapResponse<Paginator<T>> for response::Continuati
|
|||
lang: crate::param::Language,
|
||||
_deobf: Option<&crate::deobfuscate::Deobfuscator>,
|
||||
) -> Result<MapResult<Paginator<T>>, ExtractionError> {
|
||||
let mut actions = self.on_response_received_actions;
|
||||
let items = actions
|
||||
.try_swap_remove(0)
|
||||
let items = self
|
||||
.on_response_received_actions
|
||||
.and_then(|mut actions| {
|
||||
actions
|
||||
.try_swap_remove(0)
|
||||
.map(|action| action.append_continuation_items_action.continuation_items)
|
||||
})
|
||||
.or_else(|| {
|
||||
self.continuation_contents
|
||||
.map(|contents| contents.rich_grid_continuation.contents)
|
||||
})
|
||||
.ok_or(ExtractionError::InvalidData(Cow::Borrowed(
|
||||
"no item section renderer",
|
||||
)))?
|
||||
.append_continuation_items_action
|
||||
.continuation_items;
|
||||
"no continuation items",
|
||||
)))?;
|
||||
|
||||
let mut mapper = response::YouTubeListMapper::<YouTubeItem>::new(lang);
|
||||
mapper.map_response(items);
|
||||
|
|
|
@ -140,6 +140,12 @@ pub(crate) struct AlertRenderer {
|
|||
pub text: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct ResponseContext {
|
||||
pub visitor_data: Option<String>,
|
||||
}
|
||||
|
||||
// CONTINUATION
|
||||
|
||||
#[serde_as]
|
||||
|
@ -153,8 +159,12 @@ pub(crate) struct Continuation {
|
|||
alias = "onResponseReceivedCommands",
|
||||
alias = "onResponseReceivedEndpoints"
|
||||
)]
|
||||
#[serde_as(as = "VecSkipError<_>")]
|
||||
pub on_response_received_actions: Vec<ContinuationActionWrap>,
|
||||
#[serde_as(as = "Option<VecSkipError<_>>")]
|
||||
pub on_response_received_actions: Option<Vec<ContinuationActionWrap>>,
|
||||
/// Used for channel video rich grid renderer
|
||||
///
|
||||
/// A/B test seen on 19.10.2022
|
||||
pub continuation_contents: Option<RichGridContinuationContents>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
@ -173,8 +183,16 @@ pub(crate) struct ContinuationAction {
|
|||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct ResponseContext {
|
||||
pub visitor_data: Option<String>,
|
||||
pub(crate) struct RichGridContinuationContents {
|
||||
pub rich_grid_continuation: RichGridContinuation,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct RichGridContinuation {
|
||||
#[serde_as(as = "VecLogError<_>")]
|
||||
pub contents: MapResult<Vec<YouTubeListItem>>,
|
||||
}
|
||||
|
||||
// YouTube Music
|
||||
|
|
|
@ -66,8 +66,8 @@ pub(crate) struct VideoResultsWrap {
|
|||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct VideoResults {
|
||||
#[serde_as(as = "VecLogError<_>")]
|
||||
pub contents: MapResult<Vec<VideoResultsItem>>,
|
||||
#[serde_as(as = "Option<VecLogError<_>>")]
|
||||
pub contents: Option<MapResult<Vec<VideoResultsItem>>>,
|
||||
}
|
||||
|
||||
/// Video metadata item
|
||||
|
|
|
@ -102,7 +102,10 @@ impl MapResponse<VideoDetails> for response::VideoDetails {
|
|||
.two_column_watch_next_results
|
||||
.results
|
||||
.results
|
||||
.contents;
|
||||
.contents
|
||||
.ok_or(ExtractionError::ContentUnavailable(Cow::Borrowed(
|
||||
"Video not found",
|
||||
)))?;
|
||||
warnings.append(&mut primary_results.warnings);
|
||||
|
||||
let mut primary_info = None;
|
||||
|
|
|
@ -11,8 +11,8 @@ use serde::{Deserialize, Serialize};
|
|||
use time::macros::format_description;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
use crate::deobfuscate::DeobfData;
|
||||
use crate::error::Error;
|
||||
use crate::{deobfuscate::DeobfData, util};
|
||||
|
||||
const FILENAME_FORMAT: &[time::format_description::FormatItem] =
|
||||
format_description!("[year]-[month]-[day]_[hour]-[minute]-[second]");
|
||||
|
@ -81,7 +81,7 @@ impl Default for Info {
|
|||
Self {
|
||||
package: "rustypipe".to_owned(),
|
||||
version: "0.1.0".to_owned(),
|
||||
date: OffsetDateTime::now_utc(),
|
||||
date: util::now_sec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ impl Mul<u8> for TimeAgo {
|
|||
|
||||
impl From<TimeAgo> for OffsetDateTime {
|
||||
fn from(ta: TimeAgo) -> Self {
|
||||
let ts = OffsetDateTime::now_utc();
|
||||
let ts = util::now_sec();
|
||||
match ta.unit {
|
||||
TimeUnit::Second => ts - Duration::seconds(ta.n as i64),
|
||||
TimeUnit::Minute => ts - Duration::minutes(ta.n as i64),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use time::{Date, Month};
|
||||
use time::{Date, Month, OffsetDateTime};
|
||||
|
||||
pub const fn month_from_n(n: u8) -> Option<Month> {
|
||||
match n {
|
||||
|
@ -42,3 +42,14 @@ pub fn shift_months(date: Date, months: i32) -> Date {
|
|||
pub fn shift_years(date: Date, years: i32) -> Date {
|
||||
shift_months(date, years * 12)
|
||||
}
|
||||
|
||||
/// Get the current datetime without milli/micro/nanoseconds
|
||||
pub fn now_sec() -> OffsetDateTime {
|
||||
OffsetDateTime::now_utc()
|
||||
.replace_millisecond(0)
|
||||
.unwrap()
|
||||
.replace_microsecond(0)
|
||||
.unwrap()
|
||||
.replace_nanosecond(0)
|
||||
.unwrap()
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ mod protobuf;
|
|||
|
||||
pub mod dictionary;
|
||||
|
||||
pub use date::{month_from_n, shift_months, shift_years};
|
||||
pub use date::{month_from_n, now_sec, shift_months, shift_years};
|
||||
pub use protobuf::ProtoBuilder;
|
||||
|
||||
use std::{
|
||||
|
|
Loading…
Add table
Reference in a new issue