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> {
|
impl<T> From<T> for CacheEntry<T> {
|
||||||
fn from(f: T) -> Self {
|
fn from(f: T) -> Self {
|
||||||
Self::Some {
|
Self::Some {
|
||||||
last_update: OffsetDateTime::now_utc(),
|
last_update: util::now_sec(),
|
||||||
data: f,
|
data: f,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,14 +53,20 @@ impl<T: TryFrom<YouTubeItem>> MapResponse<Paginator<T>> for response::Continuati
|
||||||
lang: crate::param::Language,
|
lang: crate::param::Language,
|
||||||
_deobf: Option<&crate::deobfuscate::Deobfuscator>,
|
_deobf: Option<&crate::deobfuscate::Deobfuscator>,
|
||||||
) -> Result<MapResult<Paginator<T>>, ExtractionError> {
|
) -> Result<MapResult<Paginator<T>>, ExtractionError> {
|
||||||
let mut actions = self.on_response_received_actions;
|
let items = self
|
||||||
let items = actions
|
.on_response_received_actions
|
||||||
.try_swap_remove(0)
|
.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(
|
.ok_or(ExtractionError::InvalidData(Cow::Borrowed(
|
||||||
"no item section renderer",
|
"no continuation items",
|
||||||
)))?
|
)))?;
|
||||||
.append_continuation_items_action
|
|
||||||
.continuation_items;
|
|
||||||
|
|
||||||
let mut mapper = response::YouTubeListMapper::<YouTubeItem>::new(lang);
|
let mut mapper = response::YouTubeListMapper::<YouTubeItem>::new(lang);
|
||||||
mapper.map_response(items);
|
mapper.map_response(items);
|
||||||
|
|
|
@ -140,6 +140,12 @@ pub(crate) struct AlertRenderer {
|
||||||
pub text: String,
|
pub text: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub(crate) struct ResponseContext {
|
||||||
|
pub visitor_data: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
// CONTINUATION
|
// CONTINUATION
|
||||||
|
|
||||||
#[serde_as]
|
#[serde_as]
|
||||||
|
@ -153,8 +159,12 @@ pub(crate) struct Continuation {
|
||||||
alias = "onResponseReceivedCommands",
|
alias = "onResponseReceivedCommands",
|
||||||
alias = "onResponseReceivedEndpoints"
|
alias = "onResponseReceivedEndpoints"
|
||||||
)]
|
)]
|
||||||
#[serde_as(as = "VecSkipError<_>")]
|
#[serde_as(as = "Option<VecSkipError<_>>")]
|
||||||
pub on_response_received_actions: Vec<ContinuationActionWrap>,
|
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)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
@ -173,8 +183,16 @@ pub(crate) struct ContinuationAction {
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub(crate) struct ResponseContext {
|
pub(crate) struct RichGridContinuationContents {
|
||||||
pub visitor_data: Option<String>,
|
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
|
// YouTube Music
|
||||||
|
|
|
@ -66,8 +66,8 @@ pub(crate) struct VideoResultsWrap {
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub(crate) struct VideoResults {
|
pub(crate) struct VideoResults {
|
||||||
#[serde_as(as = "VecLogError<_>")]
|
#[serde_as(as = "Option<VecLogError<_>>")]
|
||||||
pub contents: MapResult<Vec<VideoResultsItem>>,
|
pub contents: Option<MapResult<Vec<VideoResultsItem>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Video metadata item
|
/// Video metadata item
|
||||||
|
|
|
@ -102,7 +102,10 @@ impl MapResponse<VideoDetails> for response::VideoDetails {
|
||||||
.two_column_watch_next_results
|
.two_column_watch_next_results
|
||||||
.results
|
.results
|
||||||
.results
|
.results
|
||||||
.contents;
|
.contents
|
||||||
|
.ok_or(ExtractionError::ContentUnavailable(Cow::Borrowed(
|
||||||
|
"Video not found",
|
||||||
|
)))?;
|
||||||
warnings.append(&mut primary_results.warnings);
|
warnings.append(&mut primary_results.warnings);
|
||||||
|
|
||||||
let mut primary_info = None;
|
let mut primary_info = None;
|
||||||
|
|
|
@ -11,8 +11,8 @@ use serde::{Deserialize, Serialize};
|
||||||
use time::macros::format_description;
|
use time::macros::format_description;
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
|
|
||||||
use crate::deobfuscate::DeobfData;
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
use crate::{deobfuscate::DeobfData, util};
|
||||||
|
|
||||||
const FILENAME_FORMAT: &[time::format_description::FormatItem] =
|
const FILENAME_FORMAT: &[time::format_description::FormatItem] =
|
||||||
format_description!("[year]-[month]-[day]_[hour]-[minute]-[second]");
|
format_description!("[year]-[month]-[day]_[hour]-[minute]-[second]");
|
||||||
|
@ -81,7 +81,7 @@ impl Default for Info {
|
||||||
Self {
|
Self {
|
||||||
package: "rustypipe".to_owned(),
|
package: "rustypipe".to_owned(),
|
||||||
version: "0.1.0".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 {
|
impl From<TimeAgo> for OffsetDateTime {
|
||||||
fn from(ta: TimeAgo) -> Self {
|
fn from(ta: TimeAgo) -> Self {
|
||||||
let ts = OffsetDateTime::now_utc();
|
let ts = util::now_sec();
|
||||||
match ta.unit {
|
match ta.unit {
|
||||||
TimeUnit::Second => ts - Duration::seconds(ta.n as i64),
|
TimeUnit::Second => ts - Duration::seconds(ta.n as i64),
|
||||||
TimeUnit::Minute => ts - Duration::minutes(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> {
|
pub const fn month_from_n(n: u8) -> Option<Month> {
|
||||||
match n {
|
match n {
|
||||||
|
@ -42,3 +42,14 @@ pub fn shift_months(date: Date, months: i32) -> Date {
|
||||||
pub fn shift_years(date: Date, years: i32) -> Date {
|
pub fn shift_years(date: Date, years: i32) -> Date {
|
||||||
shift_months(date, years * 12)
|
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 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;
|
pub use protobuf::ProtoBuilder;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
|
Loading…
Add table
Reference in a new issue