From 09321408e52d4d749801feb3a1ab4c781b637abf Mon Sep 17 00:00:00 2001 From: LuanRT Date: Sun, 27 Aug 2023 19:44:15 +0000 Subject: [PATCH] chore: v6.1.0 release --- deno/package.json | 2 +- deno/src/parser/classes/AlertWithButton.ts | 19 +++++ deno/src/parser/classes/C4TabbedHeader.ts | 5 +- .../parser/classes/ChannelHeaderLinksView.ts | 22 ++++++ deno/src/parser/classes/CompactMovie.ts | 57 +++++++++++++++ deno/src/parser/classes/VideoSecondaryInfo.ts | 70 +------------------ deno/src/parser/classes/misc/Text.ts | 68 ++++++++++++++++++ deno/src/parser/nodes.ts | 3 + deno/src/parser/parser.ts | 3 +- deno/src/parser/types/ParsedResponse.ts | 5 +- 10 files changed, 179 insertions(+), 75 deletions(-) create mode 100644 deno/src/parser/classes/AlertWithButton.ts create mode 100644 deno/src/parser/classes/ChannelHeaderLinksView.ts create mode 100644 deno/src/parser/classes/CompactMovie.ts diff --git a/deno/package.json b/deno/package.json index d44a7a7f..85250e6f 100644 --- a/deno/package.json +++ b/deno/package.json @@ -1,6 +1,6 @@ { "name": "youtubei.js", - "version": "6.0.2", + "version": "6.1.0", "description": "A wrapper around YouTube's private API. Supports YouTube, YouTube Music, YouTube Kids and YouTube Studio (WIP).", "type": "module", "types": "./dist/src/platform/lib.d.ts", diff --git a/deno/src/parser/classes/AlertWithButton.ts b/deno/src/parser/classes/AlertWithButton.ts new file mode 100644 index 00000000..d4615155 --- /dev/null +++ b/deno/src/parser/classes/AlertWithButton.ts @@ -0,0 +1,19 @@ +import Button from './Button.ts'; +import Text from './misc/Text.ts'; +import { YTNode } from '../helpers.ts'; +import { Parser, type RawNode } from '../index.ts'; + +export default class AlertWithButton extends YTNode { + static type = 'AlertWithButton'; + + text: Text; + alert_type: string; + dismiss_button: Button | null; + + constructor(data: RawNode) { + super(); + this.text = new Text(data.text); + this.alert_type = data.type; + this.dismiss_button = Parser.parseItem(data.dismissButton, Button); + } +} \ No newline at end of file diff --git a/deno/src/parser/classes/C4TabbedHeader.ts b/deno/src/parser/classes/C4TabbedHeader.ts index 4e3dc71d..3e77899e 100644 --- a/deno/src/parser/classes/C4TabbedHeader.ts +++ b/deno/src/parser/classes/C4TabbedHeader.ts @@ -2,6 +2,7 @@ import { YTNode } from '../helpers.ts'; import Parser, { type RawNode } from '../index.ts'; import Button from './Button.ts'; import ChannelHeaderLinks from './ChannelHeaderLinks.ts'; +import ChannelHeaderLinksView from './ChannelHeaderLinksView.ts'; import SubscribeButton from './SubscribeButton.ts'; import Author from './misc/Author.ts'; import Text from './misc/Text.ts'; @@ -18,7 +19,7 @@ export default class C4TabbedHeader extends YTNode { videos_count?: Text; sponsor_button?: Button | null; subscribe_button?: SubscribeButton | Button | null; - header_links?: ChannelHeaderLinks | null; + header_links?: ChannelHeaderLinks | ChannelHeaderLinksView | null; channel_handle?: Text; channel_id?: string; @@ -58,7 +59,7 @@ export default class C4TabbedHeader extends YTNode { } if (Reflect.has(data, 'headerLinks')) { - this.header_links = Parser.parseItem(data.headerLinks, ChannelHeaderLinks); + this.header_links = Parser.parseItem(data.headerLinks, [ ChannelHeaderLinks, ChannelHeaderLinksView ]); } if (Reflect.has(data, 'channelHandleText')) { diff --git a/deno/src/parser/classes/ChannelHeaderLinksView.ts b/deno/src/parser/classes/ChannelHeaderLinksView.ts new file mode 100644 index 00000000..144e51c3 --- /dev/null +++ b/deno/src/parser/classes/ChannelHeaderLinksView.ts @@ -0,0 +1,22 @@ +import { YTNode } from '../helpers.ts'; +import type { RawNode } from '../index.ts'; +import Text from './misc/Text.ts'; + +export default class ChannelHeaderLinksView extends YTNode { + static type = 'ChannelHeaderLinksView'; + + first_link?: Text; + more?: Text; + + constructor(data: RawNode) { + super(); + + if (Reflect.has(data, 'firstLink')) { + this.first_link = Text.fromAttributed(data.firstLink); + } + + if (Reflect.has(data, 'more')) { + this.more = Text.fromAttributed(data.more); + } + } +} \ No newline at end of file diff --git a/deno/src/parser/classes/CompactMovie.ts b/deno/src/parser/classes/CompactMovie.ts new file mode 100644 index 00000000..ebe5d478 --- /dev/null +++ b/deno/src/parser/classes/CompactMovie.ts @@ -0,0 +1,57 @@ +import { YTNode, type ObservedArray } from '../helpers.ts'; +import type { RawNode } from '../index.ts'; +import Parser from '../index.ts'; +import Author from './misc/Author.ts'; +import NavigationEndpoint from './NavigationEndpoint.ts'; +import Thumbnail from './misc/Thumbnail.ts'; +import Menu from './menus/Menu.ts'; +import { timeToSeconds } from '../../utils/Utils.ts'; + +export default class CompactMovie extends YTNode { + static type = 'CompactMovie'; + + id: string; + title: Text; + top_metadata_items: Text; + thumbnails: Thumbnail[]; + thumbnail_overlays: ObservedArray; + author: Author; + + duration: { + text: string; + seconds: number; + }; + + endpoint: NavigationEndpoint; + badges: ObservedArray; + use_vertical_poster: boolean; + menu: Menu | null; + + constructor(data: RawNode) { + super(); + console.log(data); + const overlay_time_status = data.thumbnailOverlays + .find((overlay: RawNode) => overlay.thumbnailOverlayTimeStatusRenderer) + ?.thumbnailOverlayTimeStatusRenderer.text || 'N/A'; + + this.id = data.videoId; + this.title = new Text(data.title); + + this.top_metadata_items = new Text(data.topMetadataItems); + this.thumbnails = Thumbnail.fromResponse(data.thumbnail); + this.thumbnail_overlays = Parser.parseArray(data.thumbnailOverlays); + this.author = new Author(data.shortBylineText); + + const durationText = data.lengthText ? new Text(data.lengthText).toString() : new Text(overlay_time_status).toString(); + + this.duration = { + text: durationText, + seconds: timeToSeconds(durationText) + }; + + this.endpoint = new NavigationEndpoint(data.navigationEndpoint); + this.badges = Parser.parseArray(data.badges); + this.use_vertical_poster = data.useVerticalPoster; + this.menu = Parser.parseItem(data.menu, Menu); + } +} \ No newline at end of file diff --git a/deno/src/parser/classes/VideoSecondaryInfo.ts b/deno/src/parser/classes/VideoSecondaryInfo.ts index d97a7bf1..a39e5143 100644 --- a/deno/src/parser/classes/VideoSecondaryInfo.ts +++ b/deno/src/parser/classes/VideoSecondaryInfo.ts @@ -24,7 +24,7 @@ export default class VideoSecondaryInfo extends YTNode { this.description = new Text(data.description); if (Reflect.has(data, 'attributedDescription')) { - this.description = new Text(this.#convertAttributedDescriptionToRuns(data.attributedDescription)); + this.description = Text.fromAttributed(data.attributedDescription); } this.subscribe_button = Parser.parseItem(data.subscribeButton, [ SubscribeButton, Button ]); @@ -34,72 +34,4 @@ export default class VideoSecondaryInfo extends YTNode { this.default_expanded = data.defaultExpanded; this.description_collapsed_lines = data.descriptionCollapsedLines; } - - #convertAttributedDescriptionToRuns(description: RawNode) { - const runs: { - text: string, - navigationEndpoint?: RawNode, - attachment?: RawNode - }[] = []; - - const content = description.content; - const command_runs = description.commandRuns; - - let last_end_index = 0; - - if (command_runs) { - for (const item of command_runs) { - const length: number = item.length; - const start_index: number = item.startIndex; - - if (start_index > last_end_index) { - runs.push({ - text: content.slice(last_end_index, start_index) - }); - } - - if (Reflect.has(item, 'onTap')) { - let attachment = null; - - if (Reflect.has(description, 'attachmentRuns')) { - const attachment_runs = description.attachmentRuns; - - for (const attatchment_run of attachment_runs) { - if ((attatchment_run.startIndex - 2) == start_index) { - attachment = attatchment_run; - break; - } - } - } - - if (attachment) { - runs.push({ - text: content.slice(start_index, start_index + length), - navigationEndpoint: item.onTap, - attachment - }); - } else { - runs.push({ - text: content.slice(start_index, start_index + length), - navigationEndpoint: item.onTap - }); - } - } - - last_end_index = start_index + length; - } - - if (last_end_index < content.length) { - runs.push({ - text: content.slice(last_end_index) - }); - } - } else { - runs.push({ - text: content - }); - } - - return { runs }; - } } \ No newline at end of file diff --git a/deno/src/parser/classes/misc/Text.ts b/deno/src/parser/classes/misc/Text.ts index f3bed41f..142a8407 100644 --- a/deno/src/parser/classes/misc/Text.ts +++ b/deno/src/parser/classes/misc/Text.ts @@ -46,6 +46,74 @@ export default class Text { } } + static fromAttributed(data: RawNode): Text { + const runs: { + text: string, + navigationEndpoint?: RawNode, + attachment?: RawNode + }[] = []; + + const content = data.content; + const command_runs = data.commandRuns; + + let last_end_index = 0; + + if (command_runs) { + for (const item of command_runs) { + const length: number = item.length; + const start_index: number = item.startIndex; + + if (start_index > last_end_index) { + runs.push({ + text: content.slice(last_end_index, start_index) + }); + } + + if (Reflect.has(item, 'onTap')) { + let attachment = null; + + if (Reflect.has(data, 'attachmentRuns')) { + const attachment_runs = data.attachmentRuns; + + for (const attatchment_run of attachment_runs) { + if ((attatchment_run.startIndex - 2) == start_index) { + attachment = attatchment_run; + break; + } + } + } + + if (attachment) { + runs.push({ + text: content.slice(start_index, start_index + length), + navigationEndpoint: item.onTap, + attachment + }); + } else { + runs.push({ + text: content.slice(start_index, start_index + length), + navigationEndpoint: item.onTap + }); + } + } + + last_end_index = start_index + length; + } + + if (last_end_index < content.length) { + runs.push({ + text: content.slice(last_end_index) + }); + } + } else { + runs.push({ + text: content + }); + } + + return new Text({ runs }); + } + /** * Converts the text to HTML. * @returns The HTML. diff --git a/deno/src/parser/nodes.ts b/deno/src/parser/nodes.ts index 26f7fdce..db7c8e86 100644 --- a/deno/src/parser/nodes.ts +++ b/deno/src/parser/nodes.ts @@ -8,6 +8,7 @@ export { default as AccountSectionList } from './classes/AccountSectionList.ts'; export { default as AppendContinuationItemsAction } from './classes/actions/AppendContinuationItemsAction.ts'; export { default as OpenPopupAction } from './classes/actions/OpenPopupAction.ts'; export { default as Alert } from './classes/Alert.ts'; +export { default as AlertWithButton } from './classes/AlertWithButton.ts'; export { default as AnalyticsMainAppKeyMetrics } from './classes/analytics/AnalyticsMainAppKeyMetrics.ts'; export { default as AnalyticsRoot } from './classes/analytics/AnalyticsRoot.ts'; export { default as AnalyticsShortsCarouselCard } from './classes/analytics/AnalyticsShortsCarouselCard.ts'; @@ -36,6 +37,7 @@ export { default as ChannelAboutFullMetadata } from './classes/ChannelAboutFullM export { default as ChannelAgeGate } from './classes/ChannelAgeGate.ts'; export { default as ChannelFeaturedContent } from './classes/ChannelFeaturedContent.ts'; export { default as ChannelHeaderLinks } from './classes/ChannelHeaderLinks.ts'; +export { default as ChannelHeaderLinksView } from './classes/ChannelHeaderLinksView.ts'; export { default as ChannelMetadata } from './classes/ChannelMetadata.ts'; export { default as ChannelMobileHeader } from './classes/ChannelMobileHeader.ts'; export { default as ChannelOptions } from './classes/ChannelOptions.ts'; @@ -67,6 +69,7 @@ export { default as SponsorCommentBadge } from './classes/comments/SponsorCommen export { default as CompactChannel } from './classes/CompactChannel.ts'; export { default as CompactLink } from './classes/CompactLink.ts'; export { default as CompactMix } from './classes/CompactMix.ts'; +export { default as CompactMovie } from './classes/CompactMovie.ts'; export { default as CompactPlaylist } from './classes/CompactPlaylist.ts'; export { default as CompactStation } from './classes/CompactStation.ts'; export { default as CompactVideo } from './classes/CompactVideo.ts'; diff --git a/deno/src/parser/parser.ts b/deno/src/parser/parser.ts index d879bea4..97bd9514 100644 --- a/deno/src/parser/parser.ts +++ b/deno/src/parser/parser.ts @@ -6,6 +6,7 @@ import PlayerCaptionsTracklist from './classes/PlayerCaptionsTracklist.ts'; import PlayerLiveStoryboardSpec from './classes/PlayerLiveStoryboardSpec.ts'; import PlayerStoryboardSpec from './classes/PlayerStoryboardSpec.ts'; import Alert from './classes/Alert.ts'; +import AlertWithButton from './classes/AlertWithButton.ts'; import type { IParsedResponse, IRawResponse, RawData, RawNode } from './types/index.ts'; @@ -310,7 +311,7 @@ export function parseResponse(data: parsed_data.overlay = overlay; } - const alerts = parseArray(data.alerts, Alert); + const alerts = parseArray(data.alerts, [ Alert, AlertWithButton ]); if (alerts.length) { parsed_data.alerts = alerts; } diff --git a/deno/src/parser/types/ParsedResponse.ts b/deno/src/parser/types/ParsedResponse.ts index da703f6b..a685a9ad 100644 --- a/deno/src/parser/types/ParsedResponse.ts +++ b/deno/src/parser/types/ParsedResponse.ts @@ -15,6 +15,7 @@ import type PlayerLiveStoryboardSpec from '../classes/PlayerLiveStoryboardSpec.t import type PlayerStoryboardSpec from '../classes/PlayerStoryboardSpec.ts'; import type VideoDetails from '../classes/misc/VideoDetails.ts'; import type Alert from '../classes/Alert.ts'; +import type AlertWithButton from '../classes/AlertWithButton.ts'; import type NavigationEndpoint from '../classes/NavigationEndpoint.ts'; import type PlayerAnnotationsExpanded from '../classes/PlayerAnnotationsExpanded.ts'; import type EngagementPanelSectionList from '../classes/EngagementPanelSectionList.ts'; @@ -44,7 +45,7 @@ export interface IParsedResponse { metadata?: SuperParsedResult; microformat?: YTNode; overlay?: YTNode; - alerts?: ObservedArray; + alerts?: ObservedArray; refinements?: string[]; estimated_results?: number; player_overlays?: SuperParsedResult; @@ -122,7 +123,7 @@ export interface IBrowseResponse { header_memo?: Memo; metadata?: SuperParsedResult; microformat?: YTNode; - alerts?: ObservedArray; + alerts?: ObservedArray; sidebar?: YTNode; sidebar_memo?: Memo; }