App-MHFS

 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;



( run in 0.311 second using v1.01-cache-2.11-cpan-a9ef4e587e4 )