254 lines
7.8 KiB
Perl
254 lines
7.8 KiB
Perl
package YTMusicAPI::Navigation;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use Exporter 'import';
|
|
|
|
our $CONTENT = [ "contents", 0 ];
|
|
our $RUN_TEXT = [ "runs", 0, "text" ];
|
|
our $TAB_CONTENT = [ "tabs", 0, "tabRenderer", "content" ];
|
|
our $TAB_1_CONTENT = [ "tabs", 1, "tabRenderer", "content" ];
|
|
our $TWO_COLUMN_RENDERER = [ "contents", "twoColumnBrowseResultsRenderer" ];
|
|
our $SINGLE_COLUMN = [ "contents", "singleColumnBrowseResultsRenderer" ];
|
|
our $SINGLE_COLUMN_TAB = [ @$SINGLE_COLUMN, @$TAB_CONTENT ];
|
|
our $SECTION = ["sectionListRenderer"];
|
|
our $SECTION_LIST = [ @$SECTION, "contents" ];
|
|
our $SECTION_LIST_ITEM = [ @$SECTION, @$CONTENT ];
|
|
our $RESPONSIVE_HEADER = ["musicResponsiveHeaderRenderer"];
|
|
our $ITEM_SECTION = [ "itemSectionRenderer", @$CONTENT ];
|
|
our $MUSIC_SHELF = ["musicShelfRenderer"];
|
|
our $GRID = ["gridRenderer"];
|
|
our $GRID_ITEMS = [ @$GRID, "items" ];
|
|
our $MENU = [ "menu", "menuRenderer" ];
|
|
our $MENU_ITEMS = [ @$MENU, "items" ];
|
|
our $MENU_LIKE_STATUS =
|
|
[ @$MENU, "topLevelButtons", 0, "likeButtonRenderer", "likeStatus" ];
|
|
our $MENU_SERVICE = [ "menuServiceItemRenderer", "serviceEndpoint" ];
|
|
our $TOGGLE_MENU = "toggleMenuServiceItemRenderer";
|
|
our $OVERLAY_RENDERER =
|
|
[ "musicItemThumbnailOverlayRenderer", "content", "musicPlayButtonRenderer" ];
|
|
our $PLAY_BUTTON = [ "overlay", @$OVERLAY_RENDERER ];
|
|
our $NAVIGATION_BROWSE = [ "navigationEndpoint", "browseEndpoint" ];
|
|
our $NAVIGATION_BROWSE_ID = [ @$NAVIGATION_BROWSE, "browseId" ];
|
|
our $PAGE_TYPE = [
|
|
"browseEndpointContextSupportedConfigs",
|
|
"browseEndpointContextMusicConfig",
|
|
"pageType"
|
|
];
|
|
our $WATCH_VIDEO_ID = [ "watchEndpoint", "videoId" ];
|
|
our $NAVIGATION_VIDEO_ID = [ "navigationEndpoint", @$WATCH_VIDEO_ID ];
|
|
our $QUEUE_VIDEO_ID = [ "queueAddEndpoint", "queueTarget", "videoId" ];
|
|
our $NAVIGATION_PLAYLIST_ID =
|
|
[ "navigationEndpoint", "watchEndpoint", "playlistId" ];
|
|
our $WATCH_PID = [ "watchPlaylistEndpoint", "playlistId" ];
|
|
our $NAVIGATION_WATCH_PLAYLIST_ID = [ "navigationEndpoint", @$WATCH_PID ];
|
|
our $NAVIGATION_VIDEO_TYPE = [
|
|
"watchEndpoint", "watchEndpointMusicSupportedConfigs",
|
|
"watchEndpointMusicConfig", "musicVideoType",
|
|
];
|
|
our $ICON_TYPE = [ "icon", "iconType" ];
|
|
our $TOGGLED_BUTTON = [ "toggleButtonRenderer", "isToggled" ];
|
|
our $TITLE = [ "title", "runs", 0 ];
|
|
our $TITLE_TEXT = [ "title", @$RUN_TEXT ];
|
|
our $TEXT_RUNS = [ "text", "runs" ];
|
|
our $TEXT_RUN = [ @$TEXT_RUNS, 0 ];
|
|
our $TEXT_RUN_TEXT = [ @$TEXT_RUN, "text" ];
|
|
our $SUBTITLE = [ "subtitle", @$RUN_TEXT ];
|
|
our $SUBTITLE_RUNS = [ "subtitle", "runs" ];
|
|
our $SUBTITLE_RUN = [ @$SUBTITLE_RUNS, 0 ];
|
|
our $SUBTITLE2 = [ @$SUBTITLE_RUNS, 2, "text" ];
|
|
our $SUBTITLE3 = [ @$SUBTITLE_RUNS, 4, "text" ];
|
|
our $THUMBNAIL = [ "thumbnail", "thumbnails" ];
|
|
our $THUMBNAILS = [ "thumbnail", "musicThumbnailRenderer", @$THUMBNAIL ];
|
|
our $THUMBNAIL_RENDERER =
|
|
[ "thumbnailRenderer", "musicThumbnailRenderer", @$THUMBNAIL ];
|
|
our $THUMBNAIL_OVERLAY = [
|
|
"thumbnailOverlay", @$OVERLAY_RENDERER,
|
|
"playNavigationEndpoint", @$WATCH_PID
|
|
];
|
|
our $THUMBNAIL_CROPPED =
|
|
[ "thumbnail", "croppedSquareThumbnailRenderer", @$THUMBNAIL ];
|
|
our $FEEDBACK_TOKEN = [ "feedbackEndpoint", "feedbackToken" ];
|
|
our $BADGE_PATH = [
|
|
0, "musicInlineBadgeRenderer",
|
|
"accessibilityData", "accessibilityData",
|
|
"label"
|
|
];
|
|
our $BADGE_LABEL = [ "badges", @$BADGE_PATH ];
|
|
our $SUBTITLE_BADGE_LABEL = [ "subtitleBadges", @$BADGE_PATH ];
|
|
our $CATEGORY_TITLE =
|
|
[ "musicNavigationButtonRenderer", "buttonText", @$RUN_TEXT ];
|
|
our $CATEGORY_PARAMS = [
|
|
"musicNavigationButtonRenderer", "clickCommand",
|
|
"browseEndpoint", "params"
|
|
];
|
|
our $MMRIR = "musicMultiRowListItemRenderer";
|
|
our $MRLIR = "musicResponsiveListItemRenderer";
|
|
our $MTRIR = "musicTwoRowItemRenderer";
|
|
our $MNIR = "menuNavigationItemRenderer";
|
|
our $TASTE_PROFILE_ITEMS = [ "contents", "tastebuilderRenderer", "contents" ];
|
|
our $TASTE_PROFILE_ARTIST = [ "title", "runs" ];
|
|
our $SECTION_LIST_CONTINUATION =
|
|
[ "continuationContents", "sectionListContinuation" ];
|
|
our $MENU_PLAYLIST_ID =
|
|
[ @$MENU_ITEMS, 0, $MNIR, @$NAVIGATION_WATCH_PLAYLIST_ID ];
|
|
our $MULTI_SELECT = ["musicMultiSelectMenuItemRenderer"];
|
|
our $HEADER_DETAIL = [ "header", "musicDetailHeaderRenderer" ];
|
|
our $HEADER_SIDE = [ "header", "musicSideAlignedItemRenderer" ];
|
|
our $HEADER_MUSIC_VISUAL = [ "header", "musicVisualHeaderRenderer" ];
|
|
our $DESCRIPTION_SHELF = ["musicDescriptionShelfRenderer"];
|
|
our $DESCRIPTION = [ "description", @$RUN_TEXT ];
|
|
our $CAROUSEL = ["musicCarouselShelfRenderer"];
|
|
our $IMMERSIVE_CAROUSEL = ["musicImmersiveCarouselShelfRenderer"];
|
|
our $CAROUSEL_CONTENTS = [ @$CAROUSEL, "contents" ];
|
|
our $CAROUSEL_TITLE =
|
|
[ "header", "musicCarouselShelfBasicHeaderRenderer", @$TITLE ];
|
|
our $CARD_SHELF_TITLE =
|
|
[ "header", "musicCardShelfHeaderBasicRenderer", @$TITLE_TEXT ];
|
|
our $FRAMEWORK_MUTATIONS =
|
|
[ "frameworkUpdates", "entityBatchUpdate", "mutations" ];
|
|
|
|
sub nav {
|
|
my ( $root, $items, $none_if_absent ) = @_;
|
|
$none_if_absent //= 0;
|
|
|
|
if (!ref($items)) {
|
|
$root = $root->{$items};
|
|
return $root;
|
|
}
|
|
|
|
foreach my $k (@$items) {
|
|
if ( ref($root) eq 'HASH' && exists $root->{$k} ) {
|
|
$root = $root->{$k};
|
|
}
|
|
elsif ( ref($root) eq 'ARRAY' && $k =~ /^\d+$/ && $k < @$root ) {
|
|
$root = $root->[$k];
|
|
}
|
|
else {
|
|
if ($none_if_absent) {
|
|
return undef;
|
|
}
|
|
else {
|
|
die "Unable to find '$k' using path @$items on $root";
|
|
}
|
|
}
|
|
}
|
|
|
|
return $root;
|
|
}
|
|
|
|
sub find_object_by_key {
|
|
my ( $object_list, $key, $nested, $is_key ) = @_;
|
|
|
|
foreach my $item (@$object_list) {
|
|
if ($nested) {
|
|
$item = $item->{$nested};
|
|
}
|
|
if ( exists $item->{$key} ) {
|
|
return $is_key ? $item->{$key} : $item;
|
|
}
|
|
}
|
|
|
|
return undef;
|
|
}
|
|
|
|
sub find_objects_by_key {
|
|
my ( $object_list, $key, $nested ) = @_;
|
|
my @objects;
|
|
|
|
foreach my $item (@$object_list) {
|
|
if ($nested) {
|
|
$item = $item->{$nested};
|
|
}
|
|
if ( exists $item->{$key} ) {
|
|
push @objects, $item;
|
|
}
|
|
}
|
|
|
|
return \@objects;
|
|
}
|
|
|
|
our @EXPORT = qw(
|
|
$CONTENT
|
|
$RUN_TEXT
|
|
$TAB_CONTENT
|
|
$TAB_1_CONTENT
|
|
$TWO_COLUMN_RENDERER
|
|
$SINGLE_COLUMN
|
|
$SINGLE_COLUMN_TAB
|
|
$SECTION
|
|
$SECTION_LIST
|
|
$SECTION_LIST_ITEM
|
|
$RESPONSIVE_HEADER
|
|
$ITEM_SECTION
|
|
$MUSIC_SHELF
|
|
$GRID
|
|
$GRID_ITEMS
|
|
$MENU
|
|
$MENU_ITEMS
|
|
$MENU_LIKE_STATUS
|
|
$MENU_SERVICE
|
|
$TOGGLE_MENU
|
|
$OVERLAY_RENDERER
|
|
$PLAY_BUTTON
|
|
$NAVIGATION_BROWSE
|
|
$NAVIGATION_BROWSE_ID
|
|
$PAGE_TYPE
|
|
$WATCH_VIDEO_ID
|
|
$NAVIGATION_VIDEO_ID
|
|
$QUEUE_VIDEO_ID
|
|
$NAVIGATION_PLAYLIST_ID
|
|
$WATCH_PID
|
|
$NAVIGATION_WATCH_PLAYLIST_ID
|
|
$NAVIGATION_VIDEO_TYPE
|
|
$ICON_TYPE
|
|
$TOGGLED_BUTTON
|
|
$TITLE
|
|
$TITLE_TEXT
|
|
$TEXT_RUNS
|
|
$TEXT_RUN
|
|
$TEXT_RUN_TEXT
|
|
$SUBTITLE
|
|
$SUBTITLE_RUNS
|
|
$SUBTITLE_RUN
|
|
$SUBTITLE2
|
|
$SUBTITLE3
|
|
$THUMBNAIL
|
|
$THUMBNAILS
|
|
$THUMBNAIL_RENDERER
|
|
$THUMBNAIL_OVERLAY
|
|
$THUMBNAIL_CROPPED
|
|
$FEEDBACK_TOKEN
|
|
$BADGE_PATH
|
|
$BADGE_LABEL
|
|
$SUBTITLE_BADGE_LABEL
|
|
$CATEGORY_TITLE
|
|
$CATEGORY_PARAMS
|
|
$MMRIR
|
|
$MRLIR
|
|
$MTRIR
|
|
$MNIR
|
|
$TASTE_PROFILE_ITEMS
|
|
$TASTE_PROFILE_ARTIST
|
|
$SECTION_LIST_CONTINUATION
|
|
$MENU_PLAYLIST_ID
|
|
$MULTI_SELECT
|
|
$HEADER_DETAIL
|
|
$HEADER_SIDE
|
|
$HEADER_MUSIC_VISUAL
|
|
$DESCRIPTION_SHELF
|
|
$DESCRIPTION
|
|
$CAROUSEL
|
|
$IMMERSIVE_CAROUSEL
|
|
$CAROUSEL_CONTENTS
|
|
$CAROUSEL_TITLE
|
|
$CARD_SHELF_TITLE
|
|
$FRAMEWORK_MUTATIONS
|
|
nav
|
|
find_object_by_key
|
|
find_objects_by_key
|
|
);
|
|
|
|
1;
|