#!/usr/bin/perl use strict; use warnings; use LWP::UserAgent; use File::Basename; use IPC::Cmd qw( can_run ); # Parameters my $TOP_URL = 'http://geekandsundry.com/shows/critical-role/'; my $PG_MATCH = qr/\new(); if (!$ua) { die('Unable to init UA: ' . $! . "\n"); } $ua->agent($UA_STR); $ua->timeout($TIMEOUT); $ua->env_proxy(); # Read the existing INI file my %old_ytids = (); { my $fh = undef(); open($fh, '<', $INI_PATH) or die('Unable to read ini file: ' . $INI_PATH . ': ' . $! . "\n"); my $url = undef(); while (<$fh>) { if (/^\s*#\s*(https?\:\/\/[^\s]+)/i) { $url = $1; } elsif (/([\w\-]+)/) { if (!$url) { $url = 'Unknown'; } $old_ytids{$1} = $url; $url = undef(); if ($DEBUG > 1) { print STDERR 'Found existing YTID: ' . $1 . ' # ' . $old_ytids{$1} . "\n"; } } } close($fh); } # Use the top-level page to find episode-specific pages my @episodes = (); { my $url = $TOP_URL; NEXT_PAGE: { if ($DEBUG) { print STDERR 'Loading top page: ' . $url . "\n"; } my $response = $ua->get($url); if (!$response->is_success()) { die(basename($0) . ": Unable to fetch top-level page\n"); } foreach my $link (split(/\decoded_content())) { if ($link =~ /\s+href=\"([^\"]+)\"/) { my $href = $1; if ($href =~ $EP_EXCLUDE) { next; } if ($href =~ $EP_MATCH) { push(@episodes, $href); } } } if ($response->decoded_content() =~ $PG_MATCH) { $url = $1; redo NEXT_PAGE; } } } if ($DEBUG) { print STDERR 'Episode URLs (' . scalar(@episodes) . "):\n\t" . join("\n\t", @episodes) . "\n"; } # Find each episode's YTID my %ytids = (); { foreach my $url (@episodes) { my $response = $ua->get($url); if (!$response->is_success()) { die(basename($0) . ': Unable to fetch episode page: ' . $url . "\n"); } if ($response->decoded_content() =~ /data-ytid=\"([^\"]+)\"/) { $ytids{$1} = $url; } elsif ($DEBUG > 0) { print STDERR 'No YTID found on: ' .$url . "\n"; if ($DEBUG > 1) { print STDERR "\tPage content:\n" . $response->decoded_content() . "\n\n"; } } } } if ($DEBUG) { print STDERR 'YouTube IDs (' . scalar(keys(%ytids)) . "):\n\t" . join("\n\t", keys(%ytids)) . "\n"; } # Drop known episodes { foreach my $id (keys(%ytids)) { if (exists($old_ytids{$id})) { if ($DEBUG > 1) { print 'Ignoring known episode: ' . $id . ' # ' . $old_ytids{$id} . "\n"; } delete($ytids{$id}); } } } # Update the INI file { my $fh = undef(); open($fh, '>>', $INI_PATH) or die('Unable to write ini file: ' . $INI_PATH . ': ' . $! . "\n"); foreach my $id (keys(%ytids)) { if ($DEBUG) { print 'Adding episode: ' . $id . ' # ' . $ytids{$id} . "\n"; } print $fh "\n# " . $ytids{$id} . "\n" . $id . "\n"; } close($fh); } # Autodate my @autodate = ($ENV{'HOME'} . '/bin/video/yt/autodate.sh'); if (can_run($autodate[0])) { if ($DEBUG) { print STDERR "Executing autodate script...\n"; } system(@autodate); } # Cleanup exit(0);