From f38bd060aaf569c419fe744f2cdd8dff8676cc14 Mon Sep 17 00:00:00 2001 From: Alexandre Morignot <erdnaxeli@cervoi.se> Date: Sat, 13 Jun 2015 21:27:21 +0200 Subject: [PATCH] download content using youtube-dl --- PlayBot.pl | 1 + lib/sessions/downloader.pm | 31 +++++++++ lib/sessions/downloader/ddl.pm | 124 +++++++++++++++++++++++++++++++++ lib/sites/parser.pm | 6 +- lib/utils/db.pm | 10 +++ 5 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 lib/sessions/downloader.pm create mode 100644 lib/sessions/downloader/ddl.pm diff --git a/PlayBot.pl b/PlayBot.pl index 56d84fd..61f01e1 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 0000000..bdc831c --- /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 0000000..2cac96d --- /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 011913a..4fa9138 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 9c780ee..9ef3bdb 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; -- GitLab