Skip to content

Commit 79248f8

Browse files
committed
- Support for passing search query via command line when starting gtk-youtube-viewer (closes #204)
- `Video details` and `video comments` windows now load much faster. (by using Glib::Idle to delay the loading of content) - Playlist search: the number of items in each playlist is now retrieved with a single GET request.
1 parent 8e9c44b commit 79248f8

File tree

3 files changed

+145
-80
lines changed

3 files changed

+145
-80
lines changed

bin/gtk-youtube-viewer

Lines changed: 141 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,7 +1564,14 @@ sub show_comments_window {
15641564
$feeds_window->show;
15651565
$feeds_statusbar->pop(0);
15661566

1567-
display_comments($yv_obj->comments_from_video_id($videoID));
1567+
Glib::Idle->add(
1568+
sub {
1569+
display_comments($yv_obj->comments_from_video_id($videoID));
1570+
return 0;
1571+
},
1572+
[],
1573+
Glib::G_PRIORITY_DEFAULT_IDLE
1574+
);
15681575

15691576
return 1;
15701577
}
@@ -2254,34 +2261,45 @@ sub get_next_page_spaces {
22542261

22552262
sub get_code {
22562263
my ($code, $iter) = get_selected_entry_code();
2264+
22572265
$code // return;
22582266

2259-
my $type = $liststore->get($iter, 7);
2267+
Glib::Idle->add(
2268+
sub {
2269+
my ($code, $iter) = @{$_[0]};
22602270

2261-
$type eq 'playlist' ? list_playlist($code)
2262-
: ($type eq 'channel' || $type eq 'subscription') ? uploads('channel', $code)
2263-
: $type eq 'next_page' && $code ne '' ? do {
2271+
my $type = $liststore->get($iter, 7);
22642272

2265-
my $next_page_token = $liststore->get($iter, 5);
2266-
my $results = $yv_obj->next_page($code, $next_page_token);
2273+
$type eq 'playlist' ? list_playlist($code)
2274+
: ($type eq 'channel' || $type eq 'subscription') ? uploads('channel', $code)
2275+
: $type eq 'next_page' && $code ne '' ? do {
22672276

2268-
if ($yv_utils->has_entries($results)) {
2269-
$liststore->set($iter, 0, get_next_page_spaces() . '<big><b>' . ('=' x 20) . '</b></big>');
2270-
$liststore->set($iter, 3, q{});
2271-
}
2272-
else {
2273-
$liststore->remove($iter);
2274-
die "This is the last page!\n";
2275-
}
2277+
my $next_page_token = $liststore->get($iter, 5);
2278+
my $results = $yv_obj->next_page($code, $next_page_token);
22762279

2277-
display_results($results);
2278-
}
2279-
: $type eq 'video' ? (
2280-
$CONFIG{audio_only}
2281-
? execute_cli_youtube_viewer("--id=$code")
2282-
: play_video($yv_obj->parse_json_string($liststore->get($iter, 8)))
2283-
)
2284-
: return;
2280+
if ($yv_utils->has_entries($results)) {
2281+
$liststore->set($iter, 0, get_next_page_spaces() . '<big><b>' . ('=' x 20) . '</b></big>');
2282+
$liststore->set($iter, 3, q{});
2283+
}
2284+
else {
2285+
$liststore->remove($iter);
2286+
die "This is the last page!\n";
2287+
}
2288+
2289+
display_results($results);
2290+
}
2291+
: $type eq 'video' ? (
2292+
$CONFIG{audio_only}
2293+
? execute_cli_youtube_viewer("--id=$code")
2294+
: play_video($yv_obj->parse_json_string($liststore->get($iter, 8)))
2295+
)
2296+
: ();
2297+
2298+
return 0;
2299+
},
2300+
[$code, $iter],
2301+
Glib::G_PRIORITY_DEFAULT_IDLE
2302+
);
22852303
}
22862304

22872305
sub make_row_description {
@@ -2372,33 +2390,57 @@ sub display_results {
23722390
hide_feeds_window();
23732391

23742392
if (not $from_history) {
2375-
my @video_ids;
23762393

2377-
my $position = 0;
2378-
my $video_details;
2379-
my %video_position;
2394+
my @video_ids;
2395+
my @playlist_ids;
23802396

23812397
foreach my $i (0 .. $#{$items}) {
23822398
my $item = $items->[$i];
2383-
if ($yv_utils->is_video($item)) {
2384-
$video_position{$i} = $position++;
2399+
2400+
if ($yv_utils->is_playlist($item)) {
2401+
push @playlist_ids, $yv_utils->get_playlist_id($item);
2402+
}
2403+
elsif ($yv_utils->is_video($item)) {
23852404
push @video_ids, $yv_utils->get_video_id($item);
23862405
}
23872406
}
23882407

2408+
my %id_lookup;
2409+
23892410
if (@video_ids) {
23902411
my $content_details = $yv_obj->video_details(join(',', @video_ids), VIDEO_PART);
2391-
$video_details = $content_details->{results}{items};
2412+
my $video_details = $content_details->{results}{items};
2413+
2414+
foreach my $i (0 .. $#video_ids) {
2415+
$id_lookup{$video_ids[$i]} = $video_details->[$i];
2416+
}
2417+
}
23922418

2393-
$info->{__pos__} = \%video_position;
2394-
$info->{__details__} = $video_details;
2419+
if (@playlist_ids) {
2420+
my $content_details = $yv_obj->playlist_from_id(join(',', @playlist_ids), 'contentDetails');
2421+
my $playlist_details = $content_details->{results}{items};
2422+
2423+
foreach my $i (0 .. $#playlist_ids) {
2424+
$id_lookup{$playlist_ids[$i]} = $playlist_details->[$i];
2425+
}
23952426
}
2427+
2428+
$info->{__extra_info__} = \%id_lookup;
23962429
}
23972430

23982431
foreach my $i (0 .. $#{$items}) {
23992432
my $item = $items->[$i];
24002433

24012434
if ($yv_utils->is_playlist($item)) {
2435+
2436+
# Filter out deleted playlists
2437+
my $playlist_id = $yv_utils->get_playlist_id($item) || next;
2438+
2439+
if (exists($info->{__extra_info__}{$playlist_id})) {
2440+
@{$item}{qw(contentDetails)} =
2441+
@{$info->{__extra_info__}{$playlist_id}}{qw(contentDetails)};
2442+
}
2443+
24022444
add_playlist_entry($item);
24032445
}
24042446
elsif ($yv_utils->is_channel($item)) {
@@ -2409,13 +2451,13 @@ sub display_results {
24092451
}
24102452
elsif ($yv_utils->is_video($item) or $item->{__is_video__}) {
24112453

2412-
exists($info->{__pos__}{$i}) || next;
2413-
2414-
@{$item}{qw(id contentDetails statistics snippet)} =
2415-
@{$info->{__details__}[$info->{__pos__}{$i}]}{qw(id contentDetails statistics snippet)};
2416-
24172454
# Filter out private or deleted videos
2418-
$yv_utils->get_video_id($item) || next;
2455+
my $video_id = $yv_utils->get_video_id($item) || next;
2456+
2457+
if (exists($info->{__extra_info__}{$video_id})) {
2458+
@{$item}{qw(id contentDetails statistics snippet)} =
2459+
@{$info->{__extra_info__}{$video_id}}{qw(id contentDetails statistics snippet)};
2460+
}
24192461

24202462
# Mark as video
24212463
$item->{__is_video__} = 1;
@@ -2437,6 +2479,26 @@ sub set_entry_tooltip {
24372479
$liststore->set($iter, 9, "<b>" . encode_entities($title) . "</b>" . "\n\n" . encode_entities($description));
24382480
}
24392481

2482+
sub set_thumbnail {
2483+
my ($entry, $liststore, $iter) = @_;
2484+
2485+
$liststore->set_value($iter, 1, $default_thumb);
2486+
2487+
Glib::Idle->add(
2488+
sub {
2489+
my ($entry, $liststore, $iter) = @{$_[0]};
2490+
2491+
my $thumb_url = $yv_utils->get_thumbnail_url($entry, $CONFIG{thumbnail_type});
2492+
my $pixbuf = get_pixbuf_thumbnail($thumb_url);
2493+
$liststore->set_value($iter, 1, $pixbuf);
2494+
2495+
return 0;
2496+
},
2497+
[$entry, $liststore, $iter],
2498+
Glib::G_PRIORITY_DEFAULT_IDLE
2499+
);
2500+
}
2501+
24402502
sub add_subscription_entry {
24412503
my ($subscription) = @_;
24422504

@@ -2470,8 +2532,7 @@ sub add_subscription_entry {
24702532
$liststore->set($iter, 2, "<b>$symbols{diamond}</b> " . 'Subscription' . "\n");
24712533

24722534
if ($CONFIG{show_thumbs}) {
2473-
my $pixbuf = get_pixbuf_thumbnail($yv_utils->get_thumbnail_url($subscription, $CONFIG{thumbnail_type}));
2474-
$liststore->set_value($iter, 1, $pixbuf);
2535+
set_thumbnail($subscription, $liststore, $iter);
24752536
}
24762537
}
24772538

@@ -2531,9 +2592,7 @@ sub add_video_entry {
25312592
);
25322593

25332594
if ($CONFIG{show_thumbs}) {
2534-
my $thumb_url = $yv_utils->get_thumbnail_url($video, $CONFIG{thumbnail_type});
2535-
my $pixbuf = get_pixbuf_thumbnail($thumb_url);
2536-
$liststore->set_value($iter, 1, $pixbuf);
2595+
set_thumbnail($video, $liststore, $iter);
25372596
}
25382597
}
25392598

@@ -2573,8 +2632,7 @@ sub add_channel_entry {
25732632
$liststore->set($iter, 2, reflow_text("<b>$symbols{diamond}</b> " . 'Channel' . "\n"));
25742633

25752634
if ($CONFIG{show_thumbs}) {
2576-
my $pixbuf = get_pixbuf_thumbnail($yv_utils->get_thumbnail_url($channel, $CONFIG{thumbnail_type}));
2577-
$liststore->set_value($iter, 1, $pixbuf);
2635+
set_thumbnail($channel, $liststore, $iter);
25782636
}
25792637
}
25802638

@@ -2611,39 +2669,15 @@ sub add_playlist_entry {
26112669

26122670
my $num_items_template = "<b>$symbols{numero}</b> %d items\n";
26132671
my $num_items_text = "";
2672+
26142673
if (defined($playlist->{contentDetails}{itemCount})) {
26152674
$num_items_text = sprintf $num_items_template, $playlist->{contentDetails}->{itemCount};
26162675
}
2617-
else {
2618-
# append number of items delayed
2619-
Glib::Idle->add(
2620-
sub {
2621-
my ($liststore, $iter, $text_column, $playlist_id, $playlist_id_column, $num_items_template) = @{$_[0]};
2622-
2623-
# fetch contentDetails of playlist
2624-
my $results = $yv_obj->playlist_from_id($playlist_id);
2625-
my $info = $results->{results};
2626-
my $items = $info->{items};
2627-
my $item = $items->[0];
2628-
2629-
# ensure the given iter still represents the given playlist
2630-
if ($liststore->get($iter, $playlist_id_column) eq $playlist_id) {
2631-
my $text = $liststore->get($iter, $text_column);
2632-
$text .= sprintf $num_items_template, $item->{contentDetails}->{itemCount};
2633-
$liststore->set($iter, $text_column, $text);
2634-
}
2635-
return 0;
2636-
},
2637-
[$liststore, $iter, 2, $playlist_id, 3, $num_items_template],
2638-
Glib::G_PRIORITY_DEFAULT_IDLE
2639-
);
2640-
}
26412676

26422677
$liststore->set($iter, 2, reflow_text("<b>$symbols{diamond}</b> " . 'Playlist' . "\n" . $num_items_text));
26432678

26442679
if ($CONFIG{show_thumbs}) {
2645-
my $pixbuf = get_pixbuf_thumbnail($yv_utils->get_thumbnail_url($playlist, $CONFIG{thumbnail_type}));
2646-
$liststore->set_value($iter, 1, $pixbuf);
2680+
set_thumbnail($playlist, $liststore, $iter);
26472681
}
26482682
}
26492683

@@ -3280,18 +3314,32 @@ sub set_entry_details {
32803314
# Setting the link button
32813315
my $url = make_youtube_url($type, $code);
32823316
my $linkbutton = $gui->get_object('linkbutton1');
3317+
32833318
$linkbutton->set_label($url);
32843319
$linkbutton->set_uri($url);
32853320

32863321
# Getting thumbs
32873322
foreach my $nr (qw(1 2 3)) {
3288-
if ($code =~ /$valid_video_id_re/) {
3289-
my $pixbuf = get_pixbuf_thumbnail(sprintf($CONFIG{youtube_thumb_url}, $code, $nr), 120, 90);
3290-
$gui->get_object("image$nr")->set_from_pixbuf($pixbuf);
3291-
}
3292-
else {
3293-
$gui->get_object("image$nr")->set_from_pixbuf($default_thumb);
3294-
}
3323+
3324+
$gui->get_object("image$nr")->set_from_pixbuf($default_thumb);
3325+
3326+
Glib::Idle->add(
3327+
sub {
3328+
my ($nr) = @{$_[0]};
3329+
3330+
if ($code =~ /$valid_video_id_re/) {
3331+
my $pixbuf = get_pixbuf_thumbnail(sprintf($CONFIG{youtube_thumb_url}, $code, $nr), 120, 90);
3332+
$gui->get_object("image$nr")->set_from_pixbuf($pixbuf);
3333+
}
3334+
else {
3335+
$gui->get_object("image$nr")->set_from_pixbuf($default_thumb);
3336+
}
3337+
3338+
return 0;
3339+
},
3340+
[$nr],
3341+
Glib::G_PRIORITY_DEFAULT_IDLE
3342+
);
32953343
}
32963344

32973345
# Setting textview description
@@ -3313,4 +3361,19 @@ sub on_mainw_destroy {
33133361

33143362
$notebook->set_current_page($CONFIG{default_notebook_page});
33153363

3364+
if (@ARGV) {
3365+
my $text = join(' ', @ARGV);
3366+
$search_entry->set_text($text);
3367+
$search_entry->set_position(length($text));
3368+
3369+
Glib::Idle->add(
3370+
sub {
3371+
search();
3372+
return 0;
3373+
},
3374+
[],
3375+
Glib::G_PRIORITY_DEFAULT_IDLE
3376+
);
3377+
}
3378+
33163379
'Gtk2'->main;

lib/WWW/YoutubeViewer/Playlists.pm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ PlaylistIDs can be separated by commas.
5252
=cut
5353

5454
sub playlist_from_id {
55-
my ($self, $id) = @_;
56-
$self->_get_results($self->_make_playlists_url(id => $id));
55+
my ($self, $id, $part) = @_;
56+
$self->_get_results($self->_make_playlists_url(id => $id, part => ($part // 'snippet')));
5757
}
5858

5959
=head2 playlists($channel_id)

share/gtk-youtube-viewer.glade

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2232,6 +2232,8 @@ See &lt;https://dev.perl.org/licenses/&gt; for more information.
22322232
<property name="title" translatable="yes">Video details</property>
22332233
<property name="modal">True</property>
22342234
<property name="window_position">center-on-parent</property>
2235+
<property name="default_width">300</property>
2236+
<property name="default_height">400</property>
22352237
<property name="transient_for">__MAIN__</property>
22362238
<signal name="destroy" handler="hide_details_window" swapped="no"/>
22372239
<signal name="delete-event" handler="hide_details_window" swapped="no"/>

0 commit comments

Comments
 (0)