141 lines
3.3 KiB
Perl
141 lines
3.3 KiB
Perl
package YTMusicAPI::Parsers::Utils;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use Exporter 'import';
|
|
|
|
use YTMusicAPI::Navigation;
|
|
|
|
sub parse_menu_playlists {
|
|
my ( $data, $result ) = @_;
|
|
my $watch_menu = find_objects_by_key( nav( $data, \@$MENU_ITEMS ), $MNIR );
|
|
|
|
foreach my $item ( map { $_->{$MNIR} } @$watch_menu ) {
|
|
my $icon = nav( $item, \@$ICON_TYPE, 1 );
|
|
my $watch_key;
|
|
|
|
if ( $icon eq "MUSIC_SHUFFLE" ) {
|
|
$watch_key = "shuffleId";
|
|
}
|
|
elsif ( $icon eq "MIX" ) {
|
|
$watch_key = "radioId";
|
|
}
|
|
else {
|
|
next;
|
|
}
|
|
|
|
my $watch_id =
|
|
nav( $item,
|
|
[ "navigationEndpoint", "watchPlaylistEndpoint", "playlistId" ],
|
|
1 );
|
|
unless ($watch_id) {
|
|
$watch_id = nav( $item,
|
|
[ "navigationEndpoint", "watchEndpoint", "playlistId" ], 1 );
|
|
}
|
|
|
|
if ($watch_id) {
|
|
$result->{$watch_key} = $watch_id;
|
|
}
|
|
}
|
|
}
|
|
|
|
sub get_item_text {
|
|
my ( $item, $index, $run_index, $none_if_absent ) = @_;
|
|
$run_index //= 0;
|
|
$none_if_absent //= 0;
|
|
|
|
my $column = get_flex_column_item( $item, $index );
|
|
return unless $column;
|
|
|
|
if ( $none_if_absent
|
|
&& scalar( @{ $column->{text}->{runs} } ) < $run_index + 1 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
return $column->{text}->{runs}->[$run_index]->{text};
|
|
}
|
|
|
|
sub get_flex_column_item {
|
|
my ( $item, $index ) = @_;
|
|
|
|
if ( scalar( @{ $item->{'flexColumns'} } ) <= $index
|
|
|| !
|
|
exists $item->{'flexColumns'}->[$index]
|
|
->{'musicResponsiveListItemFlexColumnRenderer'}->{'text'}
|
|
|| !
|
|
exists $item->{'flexColumns'}->[$index]
|
|
->{'musicResponsiveListItemFlexColumnRenderer'}->{'text'}->{'runs'} )
|
|
{
|
|
return undef;
|
|
}
|
|
|
|
return $item->{'flexColumns'}->[$index]
|
|
->{'musicResponsiveListItemFlexColumnRenderer'};
|
|
}
|
|
|
|
sub get_fixed_column_item {
|
|
my ( $item, $index ) = @_;
|
|
|
|
if ( !exists $item->{'fixedColumns'}->[$index]
|
|
->{'musicResponsiveListItemFixedColumnRenderer'}->{'text'}
|
|
|| !
|
|
exists $item->{'fixedColumns'}->[$index]
|
|
->{'musicResponsiveListItemFixedColumnRenderer'}->{'text'}->{'runs'} )
|
|
{
|
|
return undef;
|
|
}
|
|
|
|
return $item->{'fixedColumns'}->[$index]
|
|
->{'musicResponsiveListItemFixedColumnRenderer'};
|
|
}
|
|
|
|
sub get_dot_separator_index {
|
|
my ($runs) = @_;
|
|
my $index = 0;
|
|
|
|
foreach my $run (@$runs) {
|
|
last if ( $run->{"text"} eq " • " );
|
|
$index++;
|
|
}
|
|
|
|
return $index == scalar @$runs ? $index : $index;
|
|
}
|
|
|
|
sub parse_duration {
|
|
my ($duration) = @_;
|
|
return $duration unless defined $duration;
|
|
|
|
my @mapped_increments = ( [ 1, 60, 3600 ], reverse split /:/, $duration );
|
|
my $seconds = 0;
|
|
|
|
while ( my ( $multiplier, $time ) = splice( @mapped_increments, 0, 2 ) ) {
|
|
$seconds += $multiplier * $time;
|
|
}
|
|
|
|
return $seconds;
|
|
}
|
|
|
|
sub parse_id_name {
|
|
my ($sub_run) = @_;
|
|
return {
|
|
"id" => nav(
|
|
$sub_run, [ "navigationEndpoint", "browseEndpoint", "browseId" ], 1
|
|
),
|
|
"name" => nav( $sub_run, ["text"], 1 ),
|
|
};
|
|
}
|
|
|
|
our @EXPORT = qw(
|
|
parse_menu_playlists
|
|
get_item_text
|
|
get_flex_column_item
|
|
get_fixed_column_item
|
|
get_dot_separator_index
|
|
parse_duration
|
|
parse_id_name
|
|
);
|
|
|
|
1;
|