diff --git a/PlayBot.pl b/PlayBot.pl index 56d84fd3f2ed942c8f8cf1f782e801c88a6d1144..61f01e12ccbc84419916b5f4fb993f9e801e5c4d 100755 --- a/PlayBot.pl +++ b/PlayBot.pl @@ -8,6 +8,7 @@ use FindBin; use lib "$FindBin::Bin/lib/"; use sessions::irc; use sessions::facebook; +use sessions::downloader; # Boucle des events POE::Kernel->run(); diff --git a/lib/sessions/downloader.pm b/lib/sessions/downloader.pm new file mode 100644 index 0000000000000000000000000000000000000000..bdc831cae9f115aada13743f93a294d1bc37b19e --- /dev/null +++ b/lib/sessions/downloader.pm @@ -0,0 +1,31 @@ +package sessions::downloader; + +use strict; +use warnings; + +use POE; + +use lib "$FindBin::Bin/lib/"; +use utils::Logging; +use sessions::downloader::ddl; + +my $log = Logging->new('STDOUT', 1); + +POE::Session->create( + inline_states => { + _start => \&on_start, + ddl => \&sessions::downloader::ddl::exec, + filename => \&sessions::downloader::ddl::filename, + signal_filename => \&sessions::downloader::ddl::signal_filename, + signal_ddl => \&sessions::downloader::ddl::signal_ddl, + }, +); + + +sub on_start { + my $kernel = $_[KERNEL]; + $kernel->alias_set('downloader'); + $log->info("session started"); +} + +1; diff --git a/lib/sessions/downloader/ddl.pm b/lib/sessions/downloader/ddl.pm new file mode 100644 index 0000000000000000000000000000000000000000..2cac96d6b6cd07b7f81e53d4bac07c4d44de8bdb --- /dev/null +++ b/lib/sessions/downloader/ddl.pm @@ -0,0 +1,124 @@ +package sessions::downloader::ddl; + +use strict; +use warnings; + +use JSON; +use POE; +use POE::Wheel::Run; + +use lib "$FindBin::Bin/lib/"; +use utils::db; +use utils::Logging; + +my $log = Logging->new('STDOUT', 1); +my $format = "%(title)s-%(id)s.%(ext)s"; +my $conf; + +BEGIN { + chdir "$FindBin::Bin/"; + local $/; + open CONF, '<', 'playbot.conf'; + my $json = <CONF>; + $conf = decode_json($json); +} + +sub exec { + my ($kernel, $heap, $id, $url) = @_[KERNEL, HEAP, ARG0, ARG1]; + return if (not $id or not $url); + $log->debug("DDL '$id' '$url' "); + + # first we need to got filename + my $child = POE::Wheel::Run->new( + Program => [ + "youtube-dl", + "--restrict-filename", + "--get-filename", + "-o", + $format, + $url, + ], + StdoutEvent => "filename", + StderrEvent => "devnull", + ); + $kernel->sig_child($child->PID, "signal_filename"); + + # we link playbot id to PID and url + $heap->{ddl}->{pb}->{$id} = { + child => $child->PID, + url => $url, + }; + + # we link wheel id to playbot id + $heap->{ddl}->{wid}->{$child->ID} = $id; + # we link PID to child object + $heap->{ddl}->{pid}->{$child->PID} = $child; +} + +sub filename { + $log->debug("DDL"); + my ($heap, $stdout_line, $wid) = @_[HEAP, ARG0, ARG1]; + return if (not exists $heap->{ddl}->{wid}->{$wid}); + + my $id = $heap->{ddl}->{wid}->{$wid}; + $heap->{ddl}->{pb}->{$id}->{filename} = $stdout_line; + $heap->{ddl}->{pb}->{$id}->{child} = undef; +} + +sub signal_filename { + $log->debug("DDL"); + my ($kernel, $heap, $pid, $status) = @_[KERNEL, HEAP, ARG1, ARG2]; + + my $child = delete $heap->{ddl}->{pid}->{$pid}; + my $id = delete $heap->{ddl}->{wid}->{$child->ID}; + + if (not defined $heap->{ddl}->{pb}->{$id}->{filename}) { + $log->error("error getting filename for $id : $status"); + $heap->{ddl}->{pb}->{$id}->{child} = undef; + + return; + } + + # we actually download the content + $child = POE::Wheel::Run->new( + Program => [ + "youtube-dl", + "--restrict-filename", + "-o", + $conf->{save_folder}."/".$format, + $heap->{ddl}->{pb}->{$id}->{url}, + ], + StdoutEvent => "devnull", + StderrEvent => "devnull", + ); + $kernel->sig_child($child->PID, "signal_ddl"); + + # we link playbot id to PID and url + $heap->{ddl}->{pb}->{$id}->{child} = $child->PID; + + # we link wheel id to playbot id + $heap->{ddl}->{wid}->{$child->ID} = $id; + # we link PID to child object + $heap->{ddl}->{pid}->{$child->PID} = $child; +} + +sub signal_ddl { + $log->debug("DDL"); + my ($heap, $pid, $status) = @_[HEAP, ARG1, ARG2]; + + my $child = delete $heap->{ddl}->{pid}->{$pid}; + my $id = delete $heap->{ddl}->{wid}->{$child->ID}; + $heap->{ddl}->{pb}->{$id}->{child} = undef; + + if ($status ne "0") { + $log->error("error downloading $id : $status"); + return; + } + + eval { + utils::db::set_filename($id, $heap->{ddl}->{pb}->{$id}->{filename}); + }; + $log->error($@) if ($@); +} + +1; diff --git a/lib/sites/parser.pm b/lib/sites/parser.pm index 011913abe07a6deb389ebc1b98737c384d63e50c..4fa9138cb018eb310ebfd64aef600a206534cb91 100644 --- a/lib/sites/parser.pm +++ b/lib/sites/parser.pm @@ -124,8 +124,10 @@ sub parse { } $dbh->commit; - # message sur irc if ($new) { + # schedule download + $kernel->post('downloader' => 'ddl' => $id, $content{url}); + $content{'id'} = '+'.$id; } else { @@ -133,6 +135,8 @@ sub parse { } $content{'tags'} = \@tags; delete $content{'url'}; + + # message sur irc $irc->yield(privmsg => $chan => utils::print::print(\%content)); } diff --git a/lib/utils/db.pm b/lib/utils/db.pm index 9c780eebc7e9a704d8f74446f54a4e9712acf27c..9ef3bdbc7eeae14bf3ee6ceccfcd2649656a1b5a 100644 --- a/lib/utils/db.pm +++ b/lib/utils/db.pm @@ -34,4 +34,14 @@ sub get_new_session { return $dbh; } +sub set_filename { + my ($id, $file) = @_; + my $dbh = main_session(); + + my $sth = $dbh->prepare('UPDATE playbot SET file = ? WHERE id = ?'); + die ("Couldn't prepare querie; aborting") unless (defined $sth); + $sth->execute($file, $id); + $dbh->commit; +} + 1;