view release on metacpan or search on metacpan
lib/App/MHFS.pm view on Meta::CPAN
}
1;
}
package MHFS::HTTP::Server {
use strict; use warnings;
use feature 'say';
use IO::Socket::INET;
use Socket qw(IPPROTO_TCP TCP_KEEPALIVE TCP_NODELAY);
use IO::Poll qw(POLLIN POLLOUT POLLHUP);
use Scalar::Util qw(weaken);
use File::Path qw(make_path);
use Data::Dumper;
use Config;
MHFS::Util->import();
sub new {
my ($class, $launchsettings, $plugins, $routes) = @_;
$SIG{PIPE} = sub {
lib/App/MHFS.pm view on Meta::CPAN
MHFS::Util->import();
use strict; use warnings;
use feature 'say';
use Time::HiRes qw( usleep clock_gettime CLOCK_REALTIME CLOCK_MONOTONIC);
use URI::Escape;
use Cwd qw(abs_path getcwd);
use File::Basename;
use File::stat;
use IO::Poll qw(POLLIN POLLOUT POLLHUP);
use Data::Dumper;
use Scalar::Util qw(weaken);
use List::Util qw[min max];
use Symbol 'gensym';
use Devel::Peek;
use Encode qw(decode encode);
use constant {
MAX_REQUEST_SIZE => 8192,
};
use FindBin;
use File::Spec;
BEGIN {
lib/App/MHFS.pm view on Meta::CPAN
use constant HAS_Alien_Tar_Size => (eval "use Alien::Tar::Size; 1");
if(! HAS_Alien_Tar_Size) {
warn "Alien::Tar::Size is not available";
}
}
sub new {
my ($class, $client) = @_;
my %self = ( 'client' => $client);
bless \%self, $class;
weaken($self{'client'}); #don't allow Request to keep client alive
$self{'on_read_ready'} = \&want_request_line;
$self{'outheaders'}{'X-MHFS-CONN-ID'} = $client->{'outheaders'}{'X-MHFS-CONN-ID'};
$self{'rl'} = 0;
# we want the request
$client->SetEvents(POLLIN | MHFS::EventLoop::Poll->ALWAYSMASK );
$self{'recvrequesttimerid'} = $client->AddClientCloseTimer($client->{'server'}{'settings'}{'recvrequestimeout'}, $client->{'CONN-ID'}, 1);
return \%self;
}
# on ready ready handlers
lib/App/MHFS.pm view on Meta::CPAN
package MHFS::HTTP::Server::Client {
use strict; use warnings;
use feature 'say';
use Time::HiRes qw( usleep clock_gettime CLOCK_REALTIME CLOCK_MONOTONIC);
use IO::Socket::INET;
use Errno qw(EINTR EIO :POSIX);
use Fcntl qw(:seek :mode);
use File::stat;
use IO::Poll qw(POLLIN POLLOUT POLLHUP);
use Scalar::Util qw(looks_like_number weaken);
use Data::Dumper;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
sub new {
my ($class, $sock, $server, $serverhostinfo, $ip) = @_;
$sock->blocking(0);
my %self = ('sock' => $sock, 'server' => $server, 'time' => clock_gettime(CLOCK_MONOTONIC), 'inbuf' => '', 'serverhostname' => $serverhostinfo->{'hostname'}, 'absurl' => $serverhostinfo->{'absurl'}, 'ip' => $ip, 'X-MHFS-PROXY-KEY' => $serverh...
$self{'CONN-ID'} = int($self{'time'} * rand()); # insecure uid
$self{'outheaders'}{'X-MHFS-CONN-ID'} = sprintf("%X", $self{'CONN-ID'});
bless \%self, $class;
$self{'request'} = MHFS::HTTP::Server::Client::Request->new(\%self);
return \%self;
}
# add a connection timeout timer
sub AddClientCloseTimer {
my ($self, $timelength, $id, $is_requesttimeout) = @_;
weaken($self); #don't allow this timer to keep the client object alive
my $server = $self->{'server'};
say "CCT | add timer: $id";
$server->{'evp'}->add_timer($timelength, 0, sub {
if(! defined $self) {
say "CCT | $id self undef";
return undef;
}
# Commented out as with connection reuse on, Apache 2.4.10 seems sometimes
# pass 408 on to the next client.
#if($is_requesttimeout) {
lib/App/MHFS.pm view on Meta::CPAN
}
1;
}
package MHFS::FD::Reader {
use strict; use warnings;
use feature 'say';
use Time::HiRes qw( usleep clock_gettime CLOCK_MONOTONIC);
use IO::Poll qw(POLLIN POLLOUT POLLHUP);
use Scalar::Util qw(looks_like_number weaken);
sub new {
my ($class, $process, $fd, $func) = @_;
my %self = ('time' => clock_gettime(CLOCK_MONOTONIC), 'process' => $process, 'fd' => $fd, 'onReadReady' => $func);
say "PID " . $self{'process'}{'pid'} . 'FD ' . $self{'fd'};
weaken($self{'process'});
return bless \%self, $class;
}
sub onReadReady {
my ($self) = @_;
my $ret = $self->{'onReadReady'}($self->{'fd'});
if($ret == 0) {
$self->{'process'}->remove($self->{'fd'});
return 1;
}
lib/App/MHFS.pm view on Meta::CPAN
}
1;
}
package MHFS::FD::Writer {
use strict; use warnings;
use feature 'say';
use Time::HiRes qw( usleep clock_gettime CLOCK_MONOTONIC);
use IO::Poll qw(POLLIN POLLOUT POLLHUP);
use Scalar::Util qw(looks_like_number weaken);
sub new {
my ($class, $process, $fd, $func) = @_;
my %self = ('time' => clock_gettime(CLOCK_MONOTONIC), 'process' => $process, 'fd' => $fd, 'onWriteReady' => $func);
say "PID " . $self{'process'}{'pid'} . 'FD ' . $self{'fd'};
weaken($self{'process'});
return bless \%self, $class;
}
sub onWriteReady {
my ($self) = @_;
my $ret = $self->{'onWriteReady'}($self->{'fd'});
if($ret == 0) {
$self->{'process'}->remove($self->{'fd'});
return 1;
}
lib/App/MHFS.pm view on Meta::CPAN
use feature 'say';
use Symbol 'gensym';
use Time::HiRes qw( usleep clock_gettime CLOCK_REALTIME CLOCK_MONOTONIC);
use POSIX ":sys_wait_h";
use IO::Socket::INET;
use IO::Poll qw(POLLIN POLLOUT POLLHUP);
use Errno qw(EINTR EIO :POSIX);
use Fcntl qw(:seek :mode);
use File::stat;
use IPC::Open3;
use Scalar::Util qw(looks_like_number weaken);
use Data::Dumper;
use Devel::Peek;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
#my %CHILDREN;
#$SIG{CHLD} = sub {
# while((my $child = waitpid(-1, WNOHANG)) > 0) {
# my ($wstatus, $exitcode) = ($?, $?>> 8);
lib/App/MHFS.pm view on Meta::CPAN
if( ! (eval "use JSON; 1")) {
eval "use JSON::PP; 1" or die "No implementation of JSON available";
warn __PACKAGE__.": Using PurePerl version of JSON (JSON::PP)";
}
}
use Encode qw(decode encode);
use URI::Escape;
use Storable qw(dclone);
use Fcntl ':mode';
use Time::HiRes qw( usleep clock_gettime CLOCK_REALTIME CLOCK_MONOTONIC);
use Scalar::Util qw(looks_like_number weaken);
use POSIX qw/ceil/;
use Storable qw( freeze thaw);
#use ExtUtils::testlib;
use FindBin;
use File::Spec;
use List::Util qw[min max];
use HTML::Template;
# Optional dependency, MHFS::XS
BEGIN {
lib/App/MHFS.pm view on Meta::CPAN
1;
}
package MHFS::Plugin::Youtube {
use strict; use warnings;
use feature 'say';
use Data::Dumper;
use feature 'state';
use Encode;
use URI::Escape;
use Scalar::Util qw(looks_like_number weaken);
use File::stat;
MHFS::Util->import();
BEGIN {
if( ! (eval "use JSON; 1")) {
eval "use JSON::PP; 1" or die "No implementation of JSON available";
warn __PACKAGE__.": Using PurePerl version of JSON (JSON::PP)";
}
}
sub searchbox {
lib/App/MHFS.pm view on Meta::CPAN
$self->sendAsHTML($request, $tosend);
}
},
});
$request->{'process'} = $tprocess;
return -1;
}
sub downloadAndServe {
my ($self, $request, $video) = @_;
weaken($request);
my $filename = $video->{'out_filepath'};
my $sendit = sub {
# we can send the file
if(! $request) {
return;
}
say "sending!!!!";
$request->SendLocalFile($filename);
lib/App/MHFS.pm view on Meta::CPAN
package MHFS::Plugin::Kodi {
use strict; use warnings;
use feature 'say';
use File::Basename qw(basename);
use Cwd qw(abs_path getcwd);
use URI::Escape qw(uri_escape);
use Encode qw(decode encode);
use File::Path qw(make_path);
use Data::Dumper qw(Dumper);
use Scalar::Util qw(weaken);
use MIME::Base64 qw(encode_base64url decode_base64url);
use Devel::Peek qw(Dump);
MHFS::Util->import(qw(decode_UTF_8 encode_UTF_8 base64url_to_str str_to_base64url uri_escape_path_utf8));
BEGIN {
if( ! (eval "use JSON; 1")) {
eval "use JSON::PP; 1" or die "No implementation of JSON available";
warn __PACKAGE__.": Using PurePerl version of JSON (JSON::PP)";
}
}
lib/App/MHFS.pm view on Meta::CPAN
return;
}
}
}
}
# slow path, download it
$request->{client}{server}{settings}{TMDB} or last;
my $searchname = $medianame;
$searchname =~ s/\s\(\d\d\d\d\)// if($mediatype eq 'movies');
say "searchname $searchname";
weaken($request);
_TMDB_api_promise($request->{client}{server}, 'search/'.$params->{search}, {'query' => $searchname})->then( sub {
if($metadatatype eq 'plot' || ! -f "$metadir/plot.txt") {
make_path($metadir);
MHFS::Util::write_file("$metadir/plot.txt", $_[0]->{results}[0]{overview});
}
if($metadatatype eq 'plot') {
$request->SendLocalFile("$metadir/plot.txt");
return;
}
# thumb or fanart
lib/App/MHFS.pm view on Meta::CPAN
1;
}
package MHFS::Plugin::GetVideo {
use strict; use warnings;
use feature 'say';
use Data::Dumper qw (Dumper);
use Fcntl qw(:seek);
use Scalar::Util qw(weaken);
use URI::Escape qw (uri_escape);
use Devel::Peek qw(Dump);
no warnings "portable";
use Config;
MHFS::Util->import();
sub new {
my ($class, $settings) = @_;
lib/App/MHFS.pm view on Meta::CPAN
#return undef;
if($fmt eq 'hls') {
$video{'on_exists'} = \&video_hls_write_master_playlist;
}
# deprecated
$video{'pid'} = ASYNC(\&shellcmd_unlock, \@cmd, $video{'out_filepath'});
# our file isn't ready yet, so create a timer to check the progress and act
weaken($request); # the only one who should be keeping $request alive is the client
$request->{'client'}{'server'}{'evp'}->add_timer(0, 0, sub {
if(! defined $request) {
say "\$request undef, ignoring CB";
return undef;
}
# test if its ready to send
while(1) {
my $filename = $video{'out_filepath'};
if(! -e $filename) {
last;