App-MHFS
view release on metacpan or search on metacpan
lib/MHFS/Plugin/BitTorrent/Client/Interface.pm view on Meta::CPAN
package MHFS::Plugin::BitTorrent::Client::Interface v0.7.0;
use 5.014;
use strict; use warnings;
use feature 'say';
use MHFS::BitTorrent::Client;
use MHFS::Util qw(escape_html do_multiples get_SI_size);
use URI::Escape qw(uri_escape);
sub is_video {
my ($name) = @_;
my ($ext) = $name =~ /\.(mkv|avi|mp4|webm|flv|ts|mpeg|mpg|m2t|m2ts|wmv)$/i;
return $ext;
}
sub is_mhfs_music_playable {
my ($name) = @_;
return $name =~ /\.(?:flac|mp3|wav)$/i;
}
sub play_in_browser_link {
my ($file, $urlfile) = @_;
return '<a href="video?name=' . $urlfile . '&fmt=hls">HLS (Watch in browser)</a>' if(is_video($file));
return '<a href="music?ptrack=' . $urlfile . '">Play in MHFS Music</a>' if(is_mhfs_music_playable($file));
return 'N/A';
}
sub torrentview {
my ($request) = @_;
my $qs = $request->{'qs'};
my $server = $request->{'client'}{'server'};
my $evp = $server->{'evp'};
# dump out the status, if the torrent's infohash is provided
if(defined $qs->{'infohash'}) {
my $hash = $qs->{'infohash'};
do_multiples({
'bytes_done' => sub { MHFS::BitTorrent::Client::torrent_d_bytes_done($server, $hash, @_); },
'size_bytes' => sub { MHFS::BitTorrent::Client::torrent_d_size_bytes($server, $hash, @_); },
'name' => sub { MHFS::BitTorrent::Client::torrent_d_name($server, $hash, @_); },
}, sub {
if( ! defined $_[0]) { $request->Send404; return;}
my ($data) = @_;
my $torrent_raw = $data->{'name'};
my $bytes_done = $data->{'bytes_done'};
my $size_bytes = $data->{'size_bytes'};
# print out the current torrent status
my $torrent_name = ${escape_html($torrent_raw)};
my $size_print = get_SI_size($size_bytes);
my $done_print = get_SI_size($bytes_done);
my $percent_print = (sprintf "%u%%", ($bytes_done/$size_bytes)*100);
my $buf = '<h1>Torrent</h1>';
$buf .= '<h3><a href="../video">Video</a> | <a href="../music">Music</a></h3>';
$buf .= '<table border="1" >';
$buf .= '<thead><tr><th>Name</th><th>Size</th><th>Done</th><th>Downloaded</th></tr></thead>';
$buf .= "<tbody><tr><td>$torrent_name</td><td>$size_print</td><td>$percent_print</td><td>$done_print</td></tr></tbody>";
$buf .= '</table>';
# Assume we are downloading, if the bytes don't match
if($bytes_done < $size_bytes) {
$buf .= '<meta http-equiv="refresh" content="3">';
$request->SendHTML($buf);
}
else {
# print out the files with usage options
MHFS::BitTorrent::Client::torrent_file_information($server, $qs->{'infohash'}, $torrent_raw, sub {
if(! defined $_[0]){ $request->Send404; return; };
my ($tfi) = @_;
my @files = sort (keys %$tfi);
$buf .= '<br>';
$buf .= '<table border="1" >';
$buf .= '<thead><tr><th>File</th><th>Size</th><th>DL</th><th>Play in browser</th></tr></thead>';
$buf .= '<tbody';
foreach my $file (@files) {
my $htmlfile = ${escape_html($file)};
my $urlfile = uri_escape($file);
my $link = '<a href="get_video?name=' . $urlfile . '&fmt=noconv">DL</a>';
my $playlink = play_in_browser_link($file, $urlfile);
$buf .= "<tr><td>$htmlfile</td><td>" . get_SI_size($tfi->{$file}{'size'}) . "</td><td>$link</td>";
$buf .= "<td>$playlink</td>" if(!defined($qs->{'playinbrowser'}) || ($qs->{'playinbrowser'} == 1));
$buf .= "</tr>";
}
$buf .= '</tbody';
$buf .= '</table>';
$request->SendHTML($buf);
});
}
});
}
else {
MHFS::BitTorrent::Client::torrent_list_torrents($server, sub{
if(! defined $_[0]){ $request->Send404; return; };
my ($rtresponse) = @_;
my @lines = split( /\n/, $rtresponse);
my $buf = '<h1>Torrents</h1>';
$buf .= '<h3><a href="video?action=browsemovies">Browse Movies</a> | <a href="video">Video</a> | <a href="music">Music</a></h3>';
$buf .= '<table border="1" >';
$buf .= '<thead><tr><th>Name</th><th>Hash</th><th>Size</th><th>Done</th><th>Private</th></tr></thead>';
$buf .= "<tbody>";
my $curtor = '';
while(1) {
if($curtor =~ /^\[(u?)['"](.+)['"],\s'(.+)',\s([0-9]+),\s([0-9]+),\s([0-9]+)\]$/) {
my %torrent;
my $is_unicode = $1;
$torrent{'name'} = $2;
$torrent{'hash'} = $3;
$torrent{'size_bytes'} = $4;
$torrent{'bytes_done'} = $5;
$torrent{'private'} = $6;
if($is_unicode) {
my $escaped_unicode = $torrent{'name'};
$torrent{'name'} =~ s/\\u(.{4})/chr(hex($1))/eg;
$torrent{'name'} =~ s/\\x(.{2})/chr(hex($1))/eg;
my $decoded_as = $torrent{'name'};
$torrent{'name'} = ${escape_html($torrent{'name'})};
if($qs->{'logunicode'}) {
say 'unicode escaped: ' . $escaped_unicode;
say 'decoded as: ' . $decoded_as;
say 'html escaped ' . $torrent{'name'};
}
}
$buf .= '<tr><td>' . $torrent{'name'} . '</td><td>' . $torrent{'hash'} . '</td><td>' . $torrent{'size_bytes'} . '</td><td>' . $torrent{'bytes_done'} . '</td><td>' . $torrent{'private'} . '</td></tr>';
$curtor = '';
}
else {
my $line = shift @lines;
if(! $line) {
last;
}
$curtor .= $line;
}
}
$buf .= '</tbody></table>';
$request->SendHTML($buf);
});
}
}
sub torrentload {
my ($request) = @_;
my $packagename = __PACKAGE__;
my $self = $request->{'client'}{server}{'loaded_plugins'}{$packagename};
if((exists $request->{'qs'}{'dlsubsystem'}) && (exists $request->{'qs'}{'privdata'}) ) {
my $subsystem = $request->{'qs'}{'dlsubsystem'};
if(exists $self->{'dlsubsystems'}{$subsystem}) {
my $server = $request->{'client'}{'server'};
$self->{'dlsubsystems'}{$subsystem}->dl($server, $request->{'qs'}{'privdata'}, sub {
my ($result, $destdir) = @_;
if(! $result) {
say "failed to dl torrent";
$request->Send404;
return;
}
MHFS::BitTorrent::Client::torrent_start($server, \$result, $destdir, {
'on_success' => sub {
my ($hexhash) = @_;
$request->SendRedirectRawURL(301, 'view?infohash=' . $hexhash);
},
'on_failure' => sub {
$request->Send404;
}
});
});
return;
}
}
$request->Send404;
}
sub new {
my ($class, $settings) = @_;
my $self = { 'dlsubsystems' => {}};
bless $self, $class;
$self->{'routes'} = [
[ '/torrent/view', \&torrentview ],
[ '/torrent/load', \&torrentload ]
];
( run in 0.682 second using v1.01-cache-2.11-cpan-39bf76dae61 )