package BotSync; use strict; use warnings; use Data::Dumper; use HTTP::Request; use HTTP::Response; use HTML::TreeBuilder; use HTML::Strip; use FindBin; use Epiquote; #woot! spun off, contains the code for updating episode quotes, i only need to call Epiquote::doupdate with an eid use POE qw(Component::Client::HTTP Component::Client::Keepalive); use DB; my $schema = DB->new(); my $pool = POE::Component::Client::Keepalive->new( keep_alive => 10, # seconds to keep connections alive max_open => 1000, # max concurrent connections - total max_per_host => 1, # max concurrent connections - per host timeout => 20, # max time (seconds) to establish a new connection ); POE::Component::Client::HTTP->spawn( Agent => 'Conanquotes (see simcop2387@simcop2387.info for more information)', # defaults to something long Alias => 'ua', # defaults to 'weeble' From => 'simcop2387@simcop2387.info', # defaults to undef (no header) Timeout => 60, # defaults to 180 seconds ConnectionManager => $pool, FollowRedirects => 2, # defaults to 0 (off) ); my $ses = POE::Session->create( package_states => [ BotSync => [ qw(_start gethttp_packlist getdcc_packlist httpcallback dccdone dccerror parse_packlist startupdate updatelog setepisodes packepisode getmulinks mucallback updateepisodequote checklock) ], ], ); sub _start { my $kernel = $_[KERNEL]; my $heap = $_[HEAP]; $kernel->alias_set("BotSync"); $heap->{updatelock} = 0; } sub packepisode { my ($kernel, $heap) = @_[ KERNEL, HEAP ]; my ($filename, $pack, $botsource, $size) = @_[ ARG0, ARG1, ARG2, ARG3 ]; my $epihash = $heap->{episodes}; my ($episode, $group, $crc, $special) = parsefilename($kernel, $filename); if (defined $episode) { if (!ref($episode)) { $episode =~ s/^0*//; #remove extra 0's on the start of the number if (defined $special) { if (ref($special) eq "ARRAY") { if ($special->[0] eq "HD") { if ($special->[1] eq "1080") { $epihash->{$episode}{hd}{1080}{group} = $group; $epihash->{$episode}{hd}{1080}{crc} = $crc; $epihash->{$episode}{hd}{1080}{pack}{$botsource} = $pack; $epihash->{$episode}{hd}{1080}{size} = $size; $epihash->{$episode}{hd}{1080}{botsource} = $botsource; } elsif ($special->[1] eq "720") { $epihash->{$episode}{hd}{720}{group} = $group; $epihash->{$episode}{hd}{720}{crc} = $crc; $epihash->{$episode}{hd}{720}{pack}{$botsource} = $pack; $epihash->{$episode}{hd}{720}{size} = $size; $epihash->{$episode}{hd}{720}{botsource} = $botsource; } else { #its either 1080 or 720, default to 1080 IIRC $epihash->{$episode}{hd}{1080}{group} = $group; $epihash->{$episode}{hd}{1080}{crc} = $crc; $epihash->{$episode}{hd}{1080}{pack}{$botsource} = $pack; $epihash->{$episode}{hd}{1080}{size} = $size; $epihash->{$episode}{hd}{1080}{botsource} = $botsource; } } elsif ($special->[0] eq "ALT") { $epihash->{$episode}{alt}{group} = $group; $epihash->{$episode}{alt}{crc} = $crc; $epihash->{$episode}{alt}{pack}{$botsource} = $pack; $epihash->{$episode}{alt}{size} = $size; $epihash->{$episode}{alt}{botsource} = $botsource; } elsif ($special->[0] eq "ALT2") { $epihash->{$episode}{alt2}{group} = $group; $epihash->{$episode}{alt2}{crc} = $crc; $epihash->{$episode}{alt2}{pack}{$botsource} = $pack; $epihash->{$episode}{alt2}{size} = $size; $epihash->{$episode}{alt2}{botsource} = $botsource; } } } else { $epihash->{$episode}{group} = $group; $epihash->{$episode}{crc} = $crc; $epihash->{$episode}{pack}{$botsource} = $pack; $epihash->{$episode}{size} = $size; $epihash->{$episode}{botsource} = $botsource; } } elsif (ref $episode eq "ARRAY") { for my $epi ($episode->[0] .. $episode->[1]) { #print "DEBUGEPI: $epi\n"; $epihash->{$epi}{group} = $group; $epihash->{$epi}{crc} = $crc; $epihash->{$epi}{pack}{$botsource} = $pack; $epihash->{$epi}{size} = $size; $epihash->{$epi}{botsource} = $botsource; } print "Episodes ", $episode->[0], " to ", $episode->[1], " from $group with $crc are all on pack $pack\n"; } } $heap->{episodes} = $epihash; # copy it back in. } sub parse_packlist { my ($sender, $kernel, $heap) = @_[ SENDER, KERNEL, HEAP ]; my ($botsource, $packlist) = @_[ ARG0, ARG1 ]; if (open(my $output, ">", $FindBin::Bin . "/packs/$botsource")) #this isn't fatal if it doesn't work { print $output $packlist; close($output); } else { $kernel->yield(updatelog => "unable to open file ".$FindBin::Bin ."/packs/$botsource"); } my @lines = split(/\n/, $packlist); print "----BEGIN $botsource----\n"; for my $line (@lines) { # #466 205x [700M] Detective Conan - Movie 09 - Strategy Above the Depths [KnKF][Part1][359C82E9].avi #^#pack times size Filename$ chomp $line; if ($line =~ /^\s*#(\d+)\s*\d+x\s*\[([^\]]+).\]\s*(.*)(?:[\r\n]*)$/) { $kernel->yield(packepisode => $3, $1, $botsource, $2); } else { print "BADLINE: $line\n"; } } print "-----END $botsource-----\n"; print Dumper($heap->{episodes}); $kernel->delay(setepisodes => 25); #use delay to let POE::Kernel make sure only one happens, if someone takes more than 25 seconds to respond we should go ahead and set the new ones anyway } sub getbotmsg { my $pack = shift; my $needjoin = shift; my %joinmsg = ( Kienai => "Join #Kienai and type ", AZFS => "Join #AZFS and type ", "[DCTP]Archive" => "Join #DCTP and type ", INB4DCTP => "Join #DCTP and type ", "AZFS|Kudo" => "Join #AZFS and type ", "[DCTP]Arutha" => "Join #DCTP and type " ); my %bots = ( Kienai => "/msg Sonoko-Chan XDCC send ", AZFS => "/msg [AZFS]Releases XDCC send ", "[DCTP]Archive" => "/msg [DCTP]Archive XDCC send ", INB4DCTP => "/msg INB4DCTP XDCC send ", "AZFS|Kudo" => "/msg AZFS|Kudo XDCC send ", "[DCTP]Arutha" => "/msg [DCTP]Arutha XDCC send ", ); my %sortorder = ( "[DCTP]Arutha" => 1, Kienai => 1, "AZFS|Kudo" => 2, "[DCTP]Archive" => 3, INB4DCTP => 4, ); my $getnum = sub { if (exists($sortorder{ $_[0] })) { $sortorder{ $_[0] } } else {5} }; #this is so i can have easy default action my $string = ""; for my $w (sort { $getnum->($a) <=> $getnum->($b) } keys %$pack) { $w = "[DCTP]Archive" if (!exists($bots{$w})); $string .= " | " . (($needjoin ? $joinmsg{$w} : "") . $bots{$w} . $pack->{$w}); } $string =~ s/^\s*\|\s*//; #remove the first one, i don't feel like properly using join return $string; } sub _makesuffix { my $size = shift; if (!defined($size) || $size eq "") { return (); } elsif ($size < 10) { return "${size}gb"; } else { return "${size}mb"; } } sub getepisodestrings { my $episode = shift; #print Dumper($episode); my $bot = getbotmsg($episode->{pack}, 1); my $crc = $episode->{crc}; my $group = $episode->{group}; my $size = _makesuffix($episode->{size}); my $mu = $episode->{mu}; no warnings 'uninitialized'; if (exists($episode->{hd}{1080})) { $bot .= " | 1080: " . getbotmsg($episode->{hd}{1080}{pack}) if (defined($episode->{hd}{1080}{pack})); $crc .= " | " . $episode->{hd}{1080}{crc} if (defined $episode->{hd}{1080}{crc}); $group .= " | " . $episode->{hd}{1080}{group} if (defined $episode->{hd}{1080}{group} && $group ne $episode->{hd}{1080}{group}); $size .= " | " . _makesuffix($episode->{hd}{1080}{size}) if (defined $episode->{hd}{1080}{size}); $mu .= " | 1080: " . $episode->{hd}{1080}{mu} if (defined $episode->{hd}{1080}{mu}); } if (exists($episode->{hd}{720})) { $bot .= " | 720: " . getbotmsg($episode->{hd}{720}{pack}) if (defined($episode->{hd}{720}{pack})); $crc .= " | " . $episode->{hd}{720}{crc} if (defined $episode->{hd}{720}{crc}); $group .= " | " . $episode->{hd}{720}{group} if (defined $episode->{hd}{720}{group} && $group ne $episode->{hd}{720}{group}); $size .= " | " . _makesuffix($episode->{hd}{720}{size}) if (defined $episode->{hd}{720}{size}); $mu .= " | 720: " . $episode->{hd}{720}{mu} if (defined $episode->{hd}{720}{mu}); } if (exists($episode->{alt})) { $bot .= " | Part2: " . getbotmsg($episode->{alt}{pack}) if (defined($episode->{alt}{pack})); $crc .= " | " . $episode->{alt}{crc} if (defined $episode->{alt}{crc}); $group .= " | " . $episode->{alt}{group} if (defined $episode->{alt}{group} && $group ne $episode->{alt}{group}); $size .= " | " . _makesuffix($episode->{alt}{size}) if (defined $episode->{alt}{size}); $mu .= " | " . $episode->{alt}{mu} if (defined $episode->{alt}{mu}); } if (exists($episode->{alt2})) { $bot .= " | Single File: " . getbotmsg($episode->{alt2}{pack}) if (defined($episode->{alt2}{pack})); $crc .= " | " . $episode->{alt2}{crc} if (defined($episode->{alt2}{pack})); $group .= " | " . $episode->{alt2}{group} if (defined $episode->{alt2}{group} && $group ne $episode->{alt2}{group}); $size .= " | " . _makesuffix($episode->{alt2}{size}) if (defined($episode->{alt2}{pack})); } return ($bot, $crc, $group, $size, $mu); } sub setepisodes { my ($sender, $kernel, $heap) = @_[ SENDER, KERNEL, HEAP ]; my @updated; #which episodes have been updated! print "Setting episodes..\n"; for my $epinum (keys %{ $heap->{episodes} }) { my $episode = $heap->{episodes}{$epinum}; my ($bot, $crc, $group, $size, $mu) = getepisodestrings($episode); die "Can't update episode $epinum if its an arrayref: " . Dumper($episode) if ($epinum =~ /ARRAY/); #this next one happens on .txt files and things next if ($epinum eq ""); die "Can't update episode $epinum if its undef: " . Dumper($episode) if (!defined($epinum)); my $row = $schema->episodeinfo->find_or_create({eid => $epinum}); $schema->updatebotlist($epinum, $bot) if ($bot && $bot !~ /^\s*$/); $schema->updatecrc($epinum, $crc) if ($crc && $crc !~ /^\s*$/); $schema->updategroup($epinum, $group) if ($group && $group !~ /^\s*$/); $schema->updatesize($epinum, $size) if ($size && $size !~ /^\s*$/); $schema->updatemu($epinum, $mu) if ($mu && $mu !~ /^\s*$/); #print "Setting episode $epinum :: $bot :: $crc :: $group\n"; push @updated, $epinum; } $heap->{updatethis} = \@updated; # my $url = "http://farnsworth.simcop2387.info/cgi-bin/conanedit.pl?action=edit&eid=$episode"; # my $resp = $mech->get($url); # if ($resp->is_success) # { # print "Successfully updated episode $episode\n"; # } # else # { # print "Episode $episode failed to update properly! ", $resp->status_line,"\n"; # } $kernel->yield(updatelog => "Starting updates, this will take a while"); $kernel->yield("updateepisodequote"); } sub updateepisodequote { my ($sender, $kernel, $heap) = @_[ SENDER, KERNEL, HEAP ]; print "INUPDATE: "; if (@{ $heap->{updatethis} }) { my $episode = shift @{ $heap->{updatethis} }; # my $req = HTTP::Request->new(GET => "http://farnsworth.simcop2387.info/cgi-bin/conanedit.pl?action=edit&eid=$episode"); # a simple HTTP request print "There are " . (@{ $heap->{updatethis} }) . " episodes left\n"; Epiquote::doupdate($episode); $kernel->yield("updateepisodequote"); } else { print "DONE!\n"; $kernel->yield(updatelog => "Out of things to update! this is a good thing!"); $heap->{updatelock} = 0; #unset the update lock } } sub parsefilename { #do this seperate since it's a PITA my $kernel = shift; my $filename = shift; $filename =~ s/[\r\n]+$//g; #strip the line endings if they aren't already my $s = qr/(?:\s|_)*/; #print "parse: $filename\n"; if ($filename =~ /^Detective${s}Conan${s}-${s}(\d+)${s}-?${s}.*\[([^\]]+)\]${s}\[?([[:xdigit:]]{8})\].*$/i) { return ($1, $2, $3); } elsif ($filename =~ /^Detective${s}Conan${s}-${s}(\d+)v2${s}-?${s}.*\[([^\]]+)\]${s}\[([[:xdigit:]]{8})\].*$/i) { return ($1, $2, $3); } # Detective Conan - 409 [Kienai][C04F0F911].mp4 elsif ($filename eq 'Detective Conan - 409 [Kienai][C04F0F911].mp4') { return (409, "Kienai", "04F0F911"); } if ($filename =~ /^Detective${s}Conan${s}-${s}(\d+)${s}Remastered.*\[([^\]]+)\]${s}\[([[:xdigit:]]{8})\].*$/i) { return ($1, $2, $3, ["ALT"]); } elsif ($filename =~ /^\[HorribleSubs\]${s}Detective${s}Conan${s}-${s}(\d+)${s}\[(720p|1080i|1080p)\].*$/i) { return ($1, "HorribleSubs", undef, ["HD", $2]); } elsif ($filename =~ /^Detective${s}Conan${s}-${s}(\d+)-(\d+)(?:${s}v\d+)?${s}\[([^\]]+)\]${s}\[([[:xdigit:]]{8})\].*$/i) { return ([ $1, $2 ], $3, $4); } #Detective Conan - 222-224 [DCTP][13885484C].avi wrong file name elsif ($filename =~ /^Detective${s}Conan${s}-${s}(222)-(224)${s}\[([^\]]+)\]${s}\[([[:xdigit:]]{8})\].*$/i) { return ([ $1, $2 ], $3, "1388584C"); } #Detective Conan - 345 Special Digest Edition Part 1 [Kaizou][48D4549B].avi; elsif ($filename =~ /^Detective${s}Conan${s}-${s}345${s}Special${s}Digest${s}Edition${s}Part${s}(\d)${s}\[Kaizou\]\[([[:xdigit:]]{8})\].*$/i) { if ($1 == 1) #part one { return (345, "Kaizou", $2); } else { return (345, "Kaizou", $2, ["ALT"]); } } elsif ($filename =~ /^Detective${s}Conan${s}-${s}(\d+)${s}\[([^\]]+)\]${s}(?:\[H264-AAC\]|\[H264\])?${s}\[([[:xdigit:]]{8})\].*$/) { return ($1, $2, $3, [ "HD", 1080 ]); } elsif ($filename =~ /^Detective${s}Conan${s}-${s}(\d+)${s}\[([^\]]+)\]${s}(?:\[H264-AAC\]|\[H264\])?${s}\[(?:1920x|1280x)?(1080|720)p?\]${s}\[([[:xdigit:]]{8})\].*$/ ) { return ($1, $2, $4, [ "HD", $3 ]); } elsif ($filename =~ /^Detective${s}Conan${s}-${s}OVA${s}?(\d+)${s}\[([^\]]+)\]${s}\[H264\]${s}\[([[:xdigit:]]{8})\].*$/i) { return (20000 + $1, $2, $3, [ "ALT", "H264" ]); #ignore hd ova for now } elsif ($filename =~ /^Detective${s}Conan${s}-${s}Magic${s}File${s}(\d+)(?:${s}OVA)?${s}\[([^\]]+)\]${s}\[([[:xdigit:]]{8})\].*$/i) { return (30000 + $1, $2, $3); #magic files are 30000+which magic file } elsif ($filename =~ /^Detective${s}Conan${s}-${s}Magic${s}File${s}(\d+)(?:${s}OVA)?${s}\[([^\]]+)\]${s}\[H264-AAC\]${s}\[([[:xdigit:]]{8})\].*$/i) { return (30000 + $1, $2, $3, [ "ALT", "H264" ]); #magic files are 30000+which magic file } #Detective Conan - OVA 1 [DCTP][FE02E18F].avi elsif ($filename =~ /^Detective${s}Conan${s}-${s}OVA${s}?(\d+)${s}\[([^\]]+)\]${s}\[([[:xdigit:]]{8})\].*$/i) { return (20000 + $1, $2, $3); #ovas are 20000 + } elsif ($filename =~ /^Detective${s}Conan${s}-${s}J-Drama${s}(\d+)${s}\[([^\]]+)\]${s}\[([[:xdigit:]]{8})\].*$/i) { return (30019 + $1, $2, $3); } #Detective Conan - J-Drama 2 [TimeLes].avi elsif ($filename =~ /^Detective${s}Conan${s}-${s}J-Drama${s}2${s}\[TimeLes\].*$/i) { return (30021, "TimeLes", undef); } # Detective Conan - Movie 03 - The Last Wizard of the Century [DCTP][720p][H264][6BD835B3].mp4 elsif ($filename =~ /Detective${s}Conan${s}-${s}Movie${s}(\d+)(?:${s}v\d)?${s}-${s}(?:[^\[]+)\[([^\]]+)\]${s}\[(1080|720)p\]${s}(?:\[H264\])?${s}\[([[:xdigit:]]{8})\]....$/i) { return (10000 + $1, $2, $4, [HD => $3]); } elsif ($filename =~ /Detective${s}Conan${s}-${s}Movie${s}(\d+)(?:${s}v\d)?${s}-${s}(?:[^\[]+)\[([^\]]+)\]${s}(?:\[H264\])?(?:\[DVD\])?${s}\[([[:xdigit:]]{8})\]....$/i) { return (10000 + $1, $2, $3); } elsif ($filename =~ /Detective${s}Conan${s}-${s}Movie${s}(\d+)${s}-${s}(?:[^\[]+)\[([^\]]+)\]${s}\[(?:Xvid-)?Part(\d)\]${s}\[([[:xdigit:]]{8})\]....$/i ) { return (10000 + $1, $2, $4) if ($3 == 1); return (10000 + $1, $2, $4, ["ALT"]); } elsif ($filename =~ /Detective${s}Conan${s}-${s}Movie${s}(\d+)${s}-${s}(?:[^\[]+)\[([^\]]+)\]${s}\[H264-(?:AAC|AC3)\]${s}\[([[:xdigit:]]{8})\]....$/i ) { return (10000 + $1, $2, $3, ["ALT2"]); } elsif ($filename eq "_Detective_Conan_Movie_11_-_Jolly_Roger_of_the_Deep_Azure_v2_[Kienai][DDBEA582].mp4_") { #fucking bots return (10011, "Kienai", "DDBEA582"); } # Lupin III vs Detective Conan - The Movie [M-L][1080p][3941F580].mkv elsif ($filename =~ /Lupin${s}III${s}vs${s}Detective${s}Conan${s}-${s}The${s}Movie${s}\[([^\]]+)\]\[(720|1080)p\]\[([[:xdigit:]]{8})\]\.mkv/) { #special case, no real way to genericise it. return (30010, $1, $3, [ "HD", $2 ]); } # Lupin III Part III - 01 - The Gold Ingots Summon Lupin [CF&B][374C1D73].mkv # Lupin III Part III - 02v2 - Break the Big Trap [CF&B][BF2B652E].mkv elsif ($filename =~ /Lupin${s}III${s}Part${s}III${s}-${s}(\d+)(?:v2)?${s}-${s}(?:[^\]]+)\[([^\]]+)\]\[([[:xdigit:]]{8})\].mkv/i) { return (32000 + $1, $2, $3); } # Kid the Phantom Thief (Magic Kaito) - 02 [DCTP][720p][F83A7F70].mp4 # Kid the Phantom Thief (Magic Kaito) - 07 - The Splendid Rivals [M-L][720p][H264-AAC][9308E13F].mkv elsif ($filename =~ /Kid${s}the${s}Phantom${s}Thief${s}\(Magic${s}Kaito\)${s}-${s}(\d+)${s}(?:${s}-${s}[^\]]+)?\[([^\]]+)\](?:\[720p\])?(?:\[H264-AAC\])?\[([[:xdigit:]]{8})\]\..../i){ return (40000 + $1, $2, $3); } elsif ($filename =~ /\[Kienai\]${s}GARNET${s}CROW/i) { #why the fuck are they doing non conan stuff? return (); #ignore the file } elsif ($filename =~ /^.*txt$/i) #ignore text files { return (); } else { open(my $log, ">>", $FindBin::Bin . '/botsync.log'); print $log "Can't parse $filename\n"; print "Can't parse $filename\n"; close($log); # $kernel->yield(updatelog => "Can't parse $filename"); } } sub updatelog { my ($sender, $kernel, $heap) = @_[ SENDER, KERNEL, HEAP ]; my $msg = $_[ARG0]; print "BotSyncLog: $msg\n"; $kernel->post(IRCHANDLER => msgfromdb => "#DCTV", "#DCTV", $msg); } sub getdcc_packlist { my ($sender, $kernel, $heap) = @_[ SENDER, KERNEL, HEAP ]; my ($bot) = $_[ARG0]; $kernel->yield(updatelog => "Starting XDCC transfer for $bot"); $kernel->post(IRCHANDLER => cancelotherxdcc => $bot); $kernel->post(IRCHANDLER => startxdcc => $bot); } # $kernel->post("BotSync", "dccerror", $user, $file, $error, $addr); sub dccdone { my ($sender, $kernel, $heap) = @_[ SENDER, KERNEL, HEAP ]; my ($user, $file, $addr) = @_[ ARG0, ARG1 ]; $user =~ s/!.*//; my $content; $kernel->yield(updatelog => "Got dcc file from $user named $file, beginning parsing"); open(my $fh, "<", $file) or do { $kernel->yield(updatelog => "Failed to open $file: $!"); return }; { local $/; $content = <$fh>; } close($fh); unlink($file); #uncomment after finding out it works $kernel->post("BotSync", "parse_packlist", $user, $content); } sub dccerror { my ($sender, $kernel, $heap) = @_[ SENDER, KERNEL, HEAP ]; my ($user, $file, $error, $addr) = @_[ ARG0, ARG1 ]; $kernel->yield(updatelog => "Got error '$error' from $user\@$addr for file '$file'"); } sub httpcallback { my ($sender, $kernel, $heap) = @_[ SENDER, KERNEL, HEAP ]; my ($request_packet, $response_packet) = @_[ ARG0, ARG1 ]; my $response = $response_packet->[0]; my $source = $request_packet->[1]; print "Got http response\n"; if ($response->is_success) { $kernel->yield(updatelog => "$source List came back successful, starting to parse"); my $q = $response->content(); if ($source eq "AZFS") { eval { my $tree = HTML::TreeBuilder->new_from_content($q); my $content = $tree->look_down("id", "content")->as_text(); $kernel->post("BotSync", "parse_packlist", $source, $content); }; #ignore failures in parsing } elsif ($source eq "Kienai" || $source eq "[DCTP]Arutha") { $kernel->post("BotSync", "parse_packlist", $source, $q); } } } sub gethttp_packlist { my ($kernel, $heap) = @_[ KERNEL, HEAP ]; my $source = $_[ARG0]; my %urls = ( AZFS => 'http://xdcc.omni-downloads.com/?group=Azfs', Kienai => 'http://truth-ou.com/Kienai/Sonoko-Chan.txt', "[DCTP]Arutha" => 'http://arutha.info:5750/txt' ); my $url = $urls{$source}; print "Fetching http list\n"; my $req = HTTP::Request->new(GET => $url); # a simple HTTP request $kernel->post( 'ua', 'request', # http session alias & state 'httpcallback', # my state to receive responses $req, # a simple HTTP request $source #where from ); $kernel->yield(updatelog => "Fetching $source list"); } sub getmulinks { my ($kernel, $heap) = @_[ KERNEL, HEAP ]; my $url = "http://forums.dctp.ws/index.php?topic=710.0"; print "Fetching http list\n"; my $req = HTTP::Request->new(GET => $url); # a simple HTTP request $kernel->post( 'ua', 'request', # http session alias & state 'mucallback', # my state to receive responses $req, # a simple HTTP request "mulinks" #where from ); $kernel->yield(updatelog => "Fetching mu list"); } sub mucallback { my ($sender, $kernel, $heap) = @_[ SENDER, KERNEL, HEAP ]; my ($request_packet, $response_packet) = @_[ ARG0, ARG1 ]; my $response = $response_packet->[0]; my $source = $request_packet->[1]; #print "MUCALLBACK: IN\n"; $kernel->yield("Got response from mu links\n"); if ($response->is_success) { print "MUCALLBACK: SUCCESS\n"; $kernel->yield(updatelog => "Mu links came back successful, about to attempt to parse"); my $qhtml = $response->content(); my $hs = HTML::Strip->new(); my $q = $hs->parse($qhtml); # print "---BEGIN CONTEXT---\n", $q, "\n----END CONTEXT----\n"; #0* makes it easy to remove the padding 0's that he adds while ($q =~ m|Episode #0*(\d+): (http://www.megaupload.com/\?d=........)\s*(?!\(remastered version\))|g) #should grab single episodes fine { my ($episode, $link) = ($1, $2); # print "Got link $episode at $link\n"; $heap->{episodes}{$episode}{mu} = $link; } while ($q =~ m|Episode #0*(\d+)-0*(\d+): (http://www.megaupload.com/\?d=........)|g) { my ($e1, $e2, $link) = ($1, $2, $3); for my $epi ($e1 .. $e2) { # print "Got link $epi at $link\n"; $heap->{episodes}{$epi}{mu} = $link; } } #special case for 345, i fucking hate that episode #Episode #345: #->Part 01: http://www.megaupload.com/?d=........ #->Part 02: http://www.megaupload.com/?d=........ if ($q =~ m|Episode #345:[\s\r\n]*->Part 01: (http://www.megaupload.com/\?d=........)[\s\r\n]*->Part 02: (http://www.megaupload.com/\?d=........)|i ) { # print "Yay i got 345! $1 $2\n"; $heap->{episodes}{345}{mu} = $1; $heap->{episodes}{345}{alt}{mu} = $2; } #these grab hd episodes while ($q =~ m{Episode 0*(\d+): (http://www.megaupload.com/\?d=........)\s*\((1920x1080|1280x720)\)}g) #should grab single episodes fine { my ($episode, $link, $res) = ($1, $2, $3); # print "HD: Got link $episode at $link at $res\n"; if ($res eq "1280x720") { $heap->{episodes}{$episode}{hd}{720}{mu} = $link; } elsif ($res eq "1920x1080") { $heap->{episodes}{$episode}{hd}{1080}{mu} = $link; } else { $kernel->yield(updatelog => "MULINK failure, should not happen, ever; $episode :: $link :: $res"); } } } # print "MUCALLBACK: OUT\n"; #$kernel->yield("gethttp_packlist", "AZFS"); #$kernel->yield("gethttp_packlist", "Kienai"); #$kernel->yield("getdcc_packlist", "INB4DCTP"); #don't need them yet #$kernel->yield("getdcc_packlist", "[DCTP]Archive"); $kernel->yield("getdcc_packlist", "AZFS|Kudo"); } sub checklock { my ($kernel, $heap) = @_[ KERNEL, HEAP ]; if ($heap->{updatelock}) { $kernel->yield(updatelog => "WARNING! found stuck updatelock! tell simcop2387 NOW!"); $kernel->yield(updatelog => "Lock has been reset, but use caution in starting it again"); $heap->{updatelock} = 0; } } sub startupdate { my ($kernel, $heap) = @_[ KERNEL, HEAP ]; my $who = $_[ARG0]; my $where = $_[ARG1]; $heap->{lastuser} = $who; #this could probably be more safe but i'm not considering concurrent updates very well anyway $heap->{lastwhere} = $where; if ($heap->{updatelock}) { $kernel->yield(updatelog => "Still updating, please wait"); return; } print "Starting updates\n"; $kernel->delay_add("checklock", 300); $heap->{updatelock} = 1; $kernel->yield(updatelog => "performing updates"); # $kernel->yield("getmulinks"); # $kernel->yield("gethttp_packlist", "AZFS"); # $kernel->yield("gethttp_packlist", "Kienai"); $kernel->yield("gethttp_packlist", "[DCTP]Arutha"); # $kernel->yield("getdcc_packlist", "INB4DCTP"); #don't need them yet # $kernel->yield("getdcc_packlist", "[DCTP]Archive"); } 1;