From aca7229ea21ad9b00e2f5690f6427ded5f96fdad Mon Sep 17 00:00:00 2001 From: trizen Date: Tue, 13 Oct 2020 16:54:09 +0300 Subject: [PATCH] - Added the `-wv` (--watched-videos) command-line option for listing watched videos as a playlist. (closes https://github.com/trizen/youtube-viewer/issues/322) It requires the config-option "remember_watched" to be set to 1. (which is disabled by default) The video IDs are stored in the file: ~/.config/youtube-viewer/watched.txt The filename can be changed by modifying the value of the config-option "watched_file". --- bin/youtube-viewer | 73 +++++++++++++++++++++++++++++++++++++--- lib/WWW/YoutubeViewer.pm | 4 +++ 2 files changed, 72 insertions(+), 5 deletions(-) diff --git a/bin/youtube-viewer b/bin/youtube-viewer index 98dccc25..caae2ba5 100755 --- a/bin/youtube-viewer +++ b/bin/youtube-viewer @@ -15,7 +15,7 @@ #------------------------------------------------------- # youtube-viewer # Created on: 02 June 2010 -# Latest edit on: 10 October 2020 +# Latest edit on: 13 October 2020 # https://github.com/trizen/youtube-viewer #------------------------------------------------------- @@ -707,6 +707,7 @@ usage: $execname [options] ([url] | [keywords]) -id --videoids=s,s : play YouTube videos by their IDs -rv --related=s : show related videos for a video ID or URL -sv --search-videos : search for YouTube videos (default mode) + -wv --watched-videos : list the most recent watched videos * Playlists -up --playlists=s : list playlists created by a specific channel or user @@ -1322,6 +1323,10 @@ sub apply_configuration { print_channels_from_file(); } + if (delete $opt->{watched_videos_from_file}) { + print_watched_videos_from_file(); + } + if (defined $opt->{uploads}) { my $str = delete $opt->{uploads}; @@ -1550,6 +1555,7 @@ sub parse_arguments { 'video-ids|videoids|id|ids=s' => \$opt{play_video_ids}, 'fc|cf|file-channels' => \$opt{channels_from_file}, + 'wv|watched-videos' => \$opt{watched_videos_from_file}, 'search-videos|search|sv!' => \$opt{search_videos}, 'search-channels|channels|sc!' => \$opt{search_channels}, @@ -2424,7 +2430,7 @@ sub warn_last_page { } sub warn_first_page { - warn colored("\n[!] No previous page available...", 'bold red') . "\n"; + warn colored("\n[!] This is the first page!", 'bold red') . "\n"; } sub warn_no_thing_selected { @@ -2832,6 +2838,61 @@ sub update_channel_file { close $fh; } +sub get_watched_videos_from_file { + my ($page) = @_; + + $page //= $yv_obj->get_page; + + my @ids; + + if ($opt{remember_watched} and open(my $fh, '<', $opt{watched_file})) { + chomp(@ids = <$fh>); + close $fh; + } + else { + @ids = keys %watched_videos; + } + + my %seen; + + # Keep the most recent ones + @ids = reverse(@ids); + @ids = grep { !$seen{$_}++ } @ids; + + my $maxResults = $yv_obj->get_maxResults; + + if ($page >= 1 and scalar(@ids) >= $maxResults) { + + @ids = grep { defined } @ids[($page - 1) * $maxResults .. $page * $maxResults - 1]; + + if (!@ids) { + warn_last_page(); + return get_watched_videos_from_file($page - 1) if ($page > 1); + } + } + + my %results; + my @videos; + + foreach my $id (@ids) { + push @videos, {id => {kind => "youtube#video", videoId => $id},}; + } + +#<<< + $results{items} = \@videos; + $results{pageInfo} = {resultsPerPage => scalar(@videos), totalResults => scalar(@videos)}; + $results{nextPageToken} = sub { get_watched_videos_from_file($page + 1) }; + $results{prevPageToken} = sub { get_watched_videos_from_file(($page > 1) ? ($page - 1) : do { warn_first_page(); 1 }) }; +#>>> + + scalar {results => \%results, url => undef}; +} + +sub print_watched_videos_from_file { + my ($page) = @_; + print_videos(get_watched_videos_from_file($page)); +} + sub print_channels_from_file { open(my $fh, '<:utf8', $opt{youtube_users_file}) or do { @@ -3598,14 +3659,14 @@ sub download_video { sub save_watched_video { my ($video_id) = @_; - if ($opt{remember_watched} and not exists($watched_videos{$video_id})) { - $watched_videos{$video_id} = 1; + $watched_videos{$video_id} = 1; + + if ($opt{remember_watched}) { open my $fh, '>>', $opt{watched_file} or return; say {$fh} $video_id; close $fh; } - $watched_videos{$video_id} = 1; return 1; } @@ -4736,6 +4797,8 @@ Set to C<1> to remember and highlight watched videos across multiple sessions. The video IDs are saved in the filename specified by C. +This option is also required for C<--watched-videos>. + =head2 remove_played_file When C is enabled, remove the file after playing it. diff --git a/lib/WWW/YoutubeViewer.pm b/lib/WWW/YoutubeViewer.pm index 9401e332..6e2944bc 100644 --- a/lib/WWW/YoutubeViewer.pm +++ b/lib/WWW/YoutubeViewer.pm @@ -1092,6 +1092,10 @@ sub post_as_json { sub from_page_token { my ($self, $url, $token) = @_; + if (ref($token) eq 'CODE') { + return $token->(); + } + my $pt_url = ( defined($token) ? (