diff --git a/.proverc b/.proverc new file mode 100644 index 0000000..5db3f7e --- /dev/null +++ b/.proverc @@ -0,0 +1,3 @@ +-r +-Ilib +t/ diff --git a/MANIFEST b/MANIFEST index 2dae561..ae192bb 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,10 +1,15 @@ +.proverc AUTHORS bin/peertube-dl cpanfile lib/Peertube/DL/Downloaders.pm +lib/Peertube/DL/URLHandler.pm lib/Peertube/DL/UserAgent.pm lib/Peertube/DL/Utils.pm LICENSE Makefile.PL MANIFEST This list of files README.md +t/00-use_ok.t +t/downloaders/animeflv_example_response.html +t/downloaders/gocdn.t diff --git a/Makefile.PL b/Makefile.PL index 0a93640..d39a7e9 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -3,5 +3,7 @@ use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Peertube::DL', VERSION => '0.1', - INST_SCRIPT => './bin' + INST_SCRIPT => './bin', + test => { TESTS => 't/*.t' }, + test => { TESTS => 't/*/*.t' }, ); diff --git a/bin/peertube-dl b/bin/peertube-dl index 09e4528..217092f 100755 --- a/bin/peertube-dl +++ b/bin/peertube-dl @@ -5,30 +5,20 @@ use feature 'say'; use strict; use warnings; -use Peertube::DL::UserAgent; -use Peertube::DL::Downloaders; - -my $ua = Peertube::DL::UserAgent->new( timeout => 10 ); -$ua->agent('Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0'); -my $response = $ua->get( $ARGV[0] ); -my %handlers = ( - gocdn => { reg => qr/gocdn\.html#/, subr => \&Peertube::DL::Downloaders::gocdn }, - animeid => { reg => qr/animeid\.to\/streaming\.php\?/, subr => \&Peertube::DL::Downloaders::animeid }, -); +use Peertube::DL::URLHandler; die "No url passed" unless @ARGV; -my $handled = 0; -for my $x ( keys %handlers ) { - if ( $response->decoded_content =~ m/$handlers{$x}{reg}/ ) { - eval { $handlers{$x}{subr}->( $ua, $response ); }; - if ($@) { - say $@; - } else { - $handled = 1; - last; - } - } -} +my $download_data = Peertube::DL::URLHandler::getDownloadDataFromURL( $ARGV[0] ); +my $filename = $download_data->{filename}; +my $url = $download_data->{url}; +my $ua = Peertube::DL::URLHandler::generateUA(); +my $response = $ua->get($url); -say "The url could not be handled, post a issue on https://gitea.sergiotarxz.freemyip.com/sergiotarxz/Peertube-dl/issues telling me the url which does not allow you to download the video so I add support for it." unless $handled; +die "Cannot retrieve video data" unless $response->is_success; + +my $content = $response->decoded_content; + +open my $fh, '>', $filename or die "Cannot open $filename"; +$fh->print( $response->decoded_content ) or die "Cannot write to $filename"; +close $fh; diff --git a/cpanfile b/cpanfile index 036fd97..bd7e95d 100644 --- a/cpanfile +++ b/cpanfile @@ -2,3 +2,6 @@ requires 'LWP::UserAgent'; requires 'URI::Encode'; requires 'JSON'; requires 'LWP::Protocol::https'; +requires 'Mojolicious::Lite'; +requires 'Test::Most'; +requires 'Test::MockObject'; diff --git a/lib/Peertube/DL/Downloaders.pm b/lib/Peertube/DL/Downloaders.pm index fa51abb..98ea693 100644 --- a/lib/Peertube/DL/Downloaders.pm +++ b/lib/Peertube/DL/Downloaders.pm @@ -23,28 +23,16 @@ sub gocdn { my $google_url = JSON::decode_json( $response_gocdn->decoded_content )->{file}; - my ($filename) = $ARGV[0] =~ s/^.*\///gr . '.mp4'; + my ($filename) = $response->base =~ s/^.*\///gr . '.mp4'; - say "Descargando desde $google_url."; - my $response_google = $ua->get($google_url); - - die $response_google->status_line . ' from ' . $google_url unless $response_google->is_success; - - open my $fh, '>', $filename; - - say "Imprimiendo la respuesta en el fichero."; - $fh->print( $response_google->decoded_content ); - - close $fh; - - say "$filename descargado."; + return { url => $google_url, filename => $filename }; } sub animeid { my $ua = shift; my $response = shift; my @order = ( 'id', 'title', 'refer' ); - my $url = $ARGV[0]; + my $url = $response->base; my $url_ajax = 'https://animeid.to/ajax.php?'; my ($get_params) = $response->decoded_content =~ /animeid\.to\/streaming\.php\?(.*?)"/; $get_params = { @@ -71,22 +59,24 @@ sub animeid { say "Decoding json... $ajax_data"; $ajax_data = JSON::decode_json $ajax_data; die 'No video source found.' if ( !defined $ajax_data->{source} ); - my $download_url = $ajax_data->{source}[0]{file} // die "No url found."; - my $extension = $ajax_data->{source}[0]{type} // die "No extension found."; + my $download_redirect_url = $ajax_data->{source}[0]{file} // die "No url found."; + my $extension = $ajax_data->{source}[0]{type} // die "No extension found."; $filename .= ".$extension"; - say "Downloading video from $download_url..."; + say "Getting redirect to download url from $download_redirect_url..."; my $video_response = $ua->get( - $download_url, + $download_redirect_url, Referer => $url, Host => 'animeid.to', ); - if ( $video_response->is_success ) { - open my $fh, '>', $filename; - $fh->print( $video_response->decoded_content ); - close $fh; - say $filename; + if ( $video_response->is_redirect ) { + my $video_location = $video_response->header('Location'); + die "No redirection." unless $video_location; + return { + url => $video_location, + filename => $filename, + }; } else { - die 'Video download failed because: ' . $video_response->status_line; + die 'Getting redirect failed because: ' . $video_response->status_line; } } 1; diff --git a/lib/Peertube/DL/URLHandler.pm b/lib/Peertube/DL/URLHandler.pm new file mode 100644 index 0000000..aae6a9d --- /dev/null +++ b/lib/Peertube/DL/URLHandler.pm @@ -0,0 +1,49 @@ +package Peertube::DL::URLHandler; + +use strict; +use warnings; + +use feature 'say'; + +use Peertube::DL::UserAgent; +use Peertube::DL::Downloaders; + +sub getDownloadDataFromURL { + my $url_origen = shift; + my $ua = Peertube::DL::URLHandler::generateUA(); + my $response = $ua->get($url_origen); + my %handlers = ( + gocdn => { reg => qr/gocdn\.html#/, subr => \&Peertube::DL::Downloaders::gocdn }, + animeid => { reg => qr/animeid\.to\/streaming\.php\?/, subr => \&Peertube::DL::Downloaders::animeid }, + ); + + my $handled = 0; + my $download_data; + for my $x ( keys %handlers ) { + if ( $response->decoded_content =~ m/$handlers{$x}{reg}/ ) { + eval { $download_data = $handlers{$x}{subr}->( $ua, $response ); }; + if ($@) { + warn $@; + } else { + $handled = 1; + last; + } + } + } + + die + "The url could not be handled, post a issue on https://gitea.sergiotarxz.freemyip.com/sergiotarxz/Peertube-dl/issues telling me the url which does not allow you to download the video so I add support for it." + unless $handled; + die "Download data not defined" unless defined $download_data; + die "Download data not hashref" unless ref($download_data) eq 'HASH'; + die "Filename not defined" unless exists $download_data->{filename} && $download_data->{filename}; + die "Download url not defined" unless exists $download_data->{url} && defined $download_data->{url}; + return $download_data; +} + +sub generateUA { + my $ua = Peertube::DL::UserAgent->new( timeout => 10 ); + $ua->agent('Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0'); + $ua; +} +1; diff --git a/lib/Peertube/DL/UserAgent.pm b/lib/Peertube/DL/UserAgent.pm index e5c5b90..828558c 100644 --- a/lib/Peertube/DL/UserAgent.pm +++ b/lib/Peertube/DL/UserAgent.pm @@ -12,13 +12,22 @@ use parent 'LWP::UserAgent'; my $last_progress_time; sub redirect_ok { - 1; + my $self = shift; + return $self->{peertube_redirect_ok}; +} + +sub set_redirect_ok { + my $self = shift; + return $self->{peertube_redirect_ok} = shift; } sub progress { my $self = shift; my $status = shift; my $response = shift; + + $self->{peertube_redirect_ok} = 0; + if ( !defined $last_progress_time || time > $last_progress_time + 1 ) { $last_progress_time = time; if ( $response->isa('HTTP::Response') && $status =~ /^\d/ ) { diff --git a/t/00-use_ok.t b/t/00-use_ok.t new file mode 100644 index 0000000..125be52 --- /dev/null +++ b/t/00-use_ok.t @@ -0,0 +1,11 @@ +use strict; +use warnings; + +use feature 'say'; + +use Test::Most tests => 4; + +use_ok 'Peertube::DL::URLHandler'; +use_ok 'Peertube::DL::Utils'; +use_ok 'Peertube::DL::UserAgent'; +use_ok 'Peertube::DL::Downloaders'; diff --git a/t/downloaders/animeflv_example_response.html b/t/downloaders/animeflv_example_response.html new file mode 100644 index 0000000..0afcc0c --- /dev/null +++ b/t/downloaders/animeflv_example_response.html @@ -0,0 +1,370 @@ + + + + +Digimon Adventure: (2020) Episodio 30 Sub Español — AnimeFLV + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ +
+
+
+
+ +
+ + + +
+
+
+
+
+ + +
+
+
+
+ + + +
+

Digimon Adventure: (2020) Episodio 30

+

Episodio 30

+
+
+ + + + +
+
+Actualmente no hay vídeos +
+
+
+
+
+ +REPORTAR Episodio + + + +DESCARGAR Episodio +
+
+
+ + + + + + + + + + + +
SERVIDORTAMAÑOFORMATODESCARGAR
StapeMP4SUBDESCARGAR
ZippyshareMP4SUBDESCARGAR
+
+
+
+
COMPARTIR
+

Ayuda a la web dandole like a nuestras redes sociales

+
+
+
+
+
+
+
Comentarios
+
+
+ + +
+
+
+Facebook FLV +

+Twitter Kudasai +

+
+
+
Noticias de Anime
+
+
    +
+
+ +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/t/downloaders/gocdn.t b/t/downloaders/gocdn.t new file mode 100644 index 0000000..1d02317 --- /dev/null +++ b/t/downloaders/gocdn.t @@ -0,0 +1,61 @@ +use strict; +use warnings; + +use feature 'say'; + +use Test::Most tests => 2; +use Test::MockObject; + +use Peertube::DL::Downloaders; +use JSON; + +{ + # GIVEN + my $ua = Test::MockObject->new; + my $base_response = Test::MockObject->new; + my $gocdn_response = Test::MockObject->new; + my $animeflv_response_file = 't/downloaders/animeflv_example_response.html'; + my $animeflv_response_decoded; + my $download_data; + my $expected_download_data_url = 'https://example.com/anime_correct_url'; + + my $expected_download_data = { filename => 'animu-1.mp4', url => $expected_download_data_url }; + open my $fh, '<', $animeflv_response_file; + $animeflv_response_decoded = join( '', <$fh> ); + close $fh; + my $gocdn_url; + + my $expected_gocdn_url = + 'https://streamium.xyz/gocdn.php?v=QmoyaEVscFUwbDJkeUtaSVhZVTFOY2g4WkJ5akErWEhnNXJDVmJXVmFVK29MU1NUc1hXSFIxT1lJMzJ6YzdueXgvbzFkeFNJTU1kQWJ6MGkxNlFkeDFpZDZ3R01reDlWYUlqaEVmZldWaVZFVzlOQ2pESlA2RHJ4MFdCNTVnczQ='; + + $ua->mock( + get => sub { + my $self = shift; + my $url = shift; + $gocdn_url = $url; + return $gocdn_response; + } + ); + + $base_response->mock( + decoded_content => sub { + return $animeflv_response_decoded; + }, + base => sub { + return 'https://animeflv.net/ver/animu-1'; + } + ); + + $gocdn_response->mock( + is_success => sub { + 1; + }, + decoded_content => sub { + JSON::encode_json( { file => $expected_download_data_url } ); + } + ); + + $download_data = Peertube::DL::Downloaders::gocdn( $ua, $base_response ); + is $gocdn_url, $expected_gocdn_url, 'The url got from gocdn is correct.'; + is_deeply $download_data, $expected_download_data, 'The download data got is the expected one.'; +}