Skip to content

Commit c568548

Browse files
committed
- Added support for local playlists (CLI). (many thanks to @rgasc)
Playlists are lists of video IDs (one video ID per line) and are stored in `~/.config/youtube-viewer/playlists/` Example: youtube-viewer -lp=playlistName The `playlistName` can be a substring of a playlist filename located in the playlist directory. Playlists can be easily created with `youtube-dl`: youtube-dl --get-id PLAYLIST_URL -i >> ~/.config/youtube-viewer/playlists/my_playlist Implements and closes #345.
1 parent 2677cdd commit c568548

File tree

1 file changed

+62
-24
lines changed

1 file changed

+62
-24
lines changed

bin/youtube-viewer

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ else {
122122

123123
# Configuration dir/file
124124
my $config_dir = catdir($xdg_config_home, $execname);
125+
my $local_playlists_dir = catdir($config_dir, 'playlists');
125126
my $config_file = catfile($config_dir, "$execname.conf");
126127
my $youtube_users_file = catfile($config_dir, 'youtube_users.txt');
127128
my $authentication_file = catfile($config_dir, 'reg.dat');
@@ -130,10 +131,12 @@ my $watch_history_file = catfile($config_dir, 'watched.txt');
130131
my $api_file = catfile($config_dir, 'api.json');
131132
my $default_api_file = '/etc/youtube-viewer/api.json';
132133

133-
if (not -d $config_dir) {
134-
require File::Path;
135-
File::Path::make_path($config_dir)
136-
or warn "[!] Can't create dir '$config_dir': $!";
134+
foreach my $dir ($config_dir, $local_playlists_dir) {
135+
if (not -d $dir) {
136+
require File::Path;
137+
File::Path::make_path($dir)
138+
or warn "[!] Can't create dir <<$dir>>: $!";
139+
}
137140
}
138141

139142
sub which_command {
@@ -720,13 +723,14 @@ usage: $execname [options] ([url] | [keywords])
720723
-wv --watched-videos : list the most recent watched videos
721724
722725
* Playlists
723-
-up --playlists=s : list playlists created by a specific channel or user
724-
-sp --search-pl : search for playlists of videos
725-
--pid=s : list a playlist of videos by playlist ID
726-
--pp=s,s : play the videos from the given playlist IDs
727-
--ps=s : add video by ID or URL to a post-selected playlist
728-
or in a given playlist ID specified with `--pid`
729-
--position=i : position in the playlist where to add the video
726+
-up --playlists=s : list playlists created by a specific channel or user
727+
-sp --search-pl : search for playlists of videos
728+
--pid=s : list a playlist of videos by playlist ID
729+
--pp=s,s : play the videos from the given playlist IDs
730+
--ps=s : add video by ID or URL to a post-selected playlist
731+
or in a given playlist ID specified with `--pid`
732+
--position=i : position in the playlist where to add the video
733+
-lp --local-playlist=s : display videos from a local playlist
730734
731735
* Activities
732736
-ua --activities:s : show activity events for a given channel
@@ -1308,6 +1312,10 @@ sub apply_configuration {
13081312
get_and_play_playlists(split(/[,\s]+/, delete $opt->{play_playlists}));
13091313
}
13101314

1315+
if (defined $opt->{local_playlist}) {
1316+
print_local_playlist(delete $opt->{local_playlist});
1317+
}
1318+
13111319
if (defined $opt->{playlist_id}) {
13121320
my $playlistID = get_valid_playlist_id(delete($opt->{playlist_id})) // return;
13131321
get_and_print_videos_from_playlist($playlistID);
@@ -1566,6 +1574,7 @@ sub parse_arguments {
15661574

15671575
'fc|cf|file-channels' => \$opt{channels_from_file},
15681576
'wv|watched-videos' => \$opt{watched_videos_from_file},
1577+
'lp|local-playlist=s' => \$opt{local_playlist},
15691578

15701579
'search-videos|search|sv!' => \$opt{search_videos},
15711580
'search-channels|channels|sc!' => \$opt{search_channels},
@@ -2855,12 +2864,6 @@ sub get_videos_from_list {
28552864

28562865
my @ids = @$ids;
28572866

2858-
my %seen;
2859-
2860-
# Keep the most recent ones
2861-
@ids = reverse(@ids);
2862-
@ids = grep { !$seen{$_}++ } @ids;
2863-
28642867
my $maxResults = $yv_obj->get_maxResults;
28652868
my $totalResults = scalar(@ids);
28662869

@@ -2869,7 +2872,7 @@ sub get_videos_from_list {
28692872
@ids = grep { defined } @ids[($page - 1) * $maxResults .. $page * $maxResults - 1];
28702873

28712874
if (!@ids) {
2872-
warn_last_page();
2875+
warn_last_page() if ($page == 1 + sprintf('%0.f', 0.5 + $totalResults / $maxResults));
28732876
return __SUB__->($ids, $page - 1) if ($page > 1);
28742877
}
28752878
}
@@ -2892,20 +2895,55 @@ sub get_videos_from_list {
28922895
scalar {results => \%results, url => undef};
28932896
}
28942897

2898+
sub read_video_ids_from_file {
2899+
my ($file) = @_;
2900+
2901+
open(my $fh, '<', $file) or return;
2902+
chomp(my @ids = <$fh>);
2903+
close $fh;
2904+
2905+
my %seen;
2906+
2907+
# Keep the most recent ones
2908+
@ids = reverse(@ids);
2909+
@ids = grep { !$seen{$_}++ } @ids;
2910+
2911+
return @ids;
2912+
}
2913+
2914+
sub print_local_playlist {
2915+
my ($name) = @_;
2916+
2917+
require File::Basename;
2918+
2919+
my @playlist_files = glob("$local_playlists_dir/*");
2920+
my $regex = qr/\Q$name\E/i;
2921+
2922+
foreach my $file (@playlist_files) {
2923+
if (File::Basename::basename($file) =~ $regex) {
2924+
my @ids = reverse read_video_ids_from_file($file);
2925+
@ids || next;
2926+
return print_videos(get_videos_from_list(\@ids));
2927+
}
2928+
}
2929+
2930+
warn_no_thing_selected('playlist');
2931+
return 0;
2932+
}
2933+
28952934
sub print_watched_videos_from_file {
2896-
my ($page) = @_;
28972935

28982936
my @ids;
28992937

2900-
if ($opt{watch_history} and open(my $fh, '<', $opt{watch_history_file})) {
2901-
chomp(@ids = <$fh>);
2902-
close $fh;
2938+
if ($opt{watch_history}) {
2939+
@ids = read_video_ids_from_file($opt{watch_history_file});
29032940
}
2904-
else {
2941+
2942+
if (scalar(@ids) == 0) {
29052943
@ids = sort keys %WATCHED_VIDEOS;
29062944
}
29072945

2908-
print_videos(get_videos_from_list(\@ids, $page));
2946+
print_videos(get_videos_from_list(\@ids));
29092947
}
29102948

29112949
sub print_channels_from_file {

0 commit comments

Comments
 (0)