From 5df8afddc4604c27e6fd34d9ec8d70452b563c95 Mon Sep 17 00:00:00 2001 From: vrag Date: Tue, 14 May 2019 09:55:27 +0300 Subject: [PATCH] Added Mediafire::Api::File class --- lib/Mediafire/.Api.pm.swp | Bin 20480 -> 24576 bytes lib/Mediafire/Api.pm | 99 ++++++++++++++++++++++++++- lib/Mediafire/Api/.UploadFile.pm.swp | Bin 28672 -> 28672 bytes lib/Mediafire/Api/File.pm | 54 +++++++++++++++ lib/Mediafire/Api/UploadFile.pm | 94 +++++++++++++++++++++---- t/001_test.t | 4 ++ 6 files changed, 235 insertions(+), 16 deletions(-) create mode 100644 lib/Mediafire/Api/File.pm diff --git a/lib/Mediafire/.Api.pm.swp b/lib/Mediafire/.Api.pm.swp index d0fae70978c7a3e452befcf99ee1081baf060b78..6b378593c2056c479952bcfa9b8bbafeda44daa6 100644 GIT binary patch delta 3367 zcmb`JO>7%Q6vrpDP})Kp1XZb^)oW_l1Y#$t3N23JCd3X6Bu>Z&5GZUn_Qc-S`@!tG zm5IV8J zdGlu8o7wkf=2+d#`*k$YdQaZ~?TqbUc#zLe62`_?LJm`VPh8cys?Pg$6=UbX z7vL;-5DWkXe0&*W9{~>-pciZgzhjCI!HeKokOW)63h+J5zX4tc0%$-5_X9cgn;1U_ zUI2$LV;)n{xD9LvZD0fV6o!s~$3PcY52WD_z$x$&7zTHPesC9vf@W|t*a9|#HDERP zZ3Sb$f+xXI@Fi?Un8|Z; zG=r1Nh2fCqkdzE@QJ`DM7FJGZhM}7|Drjb|sO6wta$Juaq`M9;Ovcz~UUvweNx{)+ zO}d9P!P}{16)B^cBzRVLT%k`CU5+uNnb{UgkYQ!@$&wTl%`6uzG*cZe?PV;xB=lU~ zrN&GXZEtP6jV4Moq#fi1^198eC>5Q&ZpPqDo@?1Q>KPmwAMU$j&nR`LlhohWlS+@I z&^w`J4louDTpC9m@+9uMb!S)3(DXtqV;Ko3>n>co2@UHY7lZ>`G2T5kx@T~B1RK}U zfA5eNkB>QAbmzF~CYq_g0~P1BYlyg?NsoroNhMWVA*a{O=$8% zjrdm`Hf9$rElbiW_S7OQ7arkU;0eENp|ju+Ob0@nBKsZ7R0Vh11A$Rml29jQx%5Jn zI*sMGs{BYd6fD)YOoywJ zmM}C|fvht@id>@79QZ(+q@KeaM~7>!b%2{vOX`*DIyT;4(UMA-1iPtX#!w?rA_XgD zXaq&NkOSC)cshK?W>jpe#nQ@Ta7^_I5Sj+W4D zOBl?Uowt?taEs&?RH9m)ulCzX5$yj|w9-Fao=tCERryn1GkBvXH9M(GZD&q#f#dir5%9(pJJQ;;s8HSf1GeAa6tT|D)a>r_~miTLpi>Lq>UjV%Sr2;G^@>nh9{ksC- zRV&ATssI;X0KEUD0$h9n2=YR$0+=o}gr$OKNxp+J<;F?oZG!SwYY}e;-Yj1=_>Y!j!Z4}woz}fPzcT1(mxd3aCRoUrI{rkWmZ;bOv`FS@Nkh*4kE6xhFL|(l?k!n(R1# z<^)B9v!P|P@`6f9>yTLsw7l9{2Gx9%SH*CvoxCP+H?G-FcMr%*8khGyd1oFQ?Tzk& R0OgjcDsFMAiu%yb{sFfhqeB1y delta 262 zcmZoTz}T>WQ6b47%+puFT+f672m}}yvMybUc`wAoa9x&xp{yt|ed0oujV}B68JQ!X^b40p9Iw3=FT?A$r|53mUL9Dsgi#Fnj_EeE{P3K>QAf zK}wDS@q8ej$G(}7C6%q-&>E<%mO%jsic(8Ti}DmyN(*xG6I0^TGILU`!4fK^)KrBq NUDvL3vz)~vaR7n~MScJP diff --git a/lib/Mediafire/Api.pm b/lib/Mediafire/Api.pm index 3d29108..5af20f6 100644 --- a/lib/Mediafire/Api.pm +++ b/lib/Mediafire/Api.pm @@ -179,9 +179,104 @@ sub uploadFile { -ua => $self->{ua}, -session_token => $self->{session_token}, ); - $upload_file->uploadFile(%opt); - return $upload_file; + my $mediafire_file = $upload_file->uploadFile(%opt); + return $mediafire_file; } +=pod Вынести в отдельный класс с проверкой наличия такой директории +sub createDir { + my ($self, %opt) = @_; + my $dirname = $opt{-dirname} // croak "You must specify '-dirname' param"; + + my $url = 'https://www.mediafire.com/api/1.4/folder/create.php'; + my %param = ( + 'r' => 'sloe', + 'foldername' => $dirname, + 'parent_key' => '', + 'session_token' => $self->{session_token}, + 'response_format' => 'json', + ); + $url . = '?' . join('&', map {"$_=" . uri_escape($param{$_})} keys %param); + my $res = $self->{ua}->get($url); + my $code = $res->code; + if ($code ne '200') { + croak "Can't create dir '$dirname'. Code: $code"; + } + my $json_res = decode_json($res->decoded_content); + p $json_res; +} +=cut 1; + +__END__ +=pod + +=encoding UTF-8 + +=head1 NAME + +B - Upload and Download files from mediafire.com file sharing + +=head1 VERSION + + version 0.01 + +=head1 SYNOPSYS + +=head1 METHODS + + use Mediafire::Api; + + # Create Mediafire::Api object + my $mediafire = Mediafire::Api->new(); + + # Login on service + $mediafire->login( + -login => $login, + -password => $password, + ); + + # Upload file to server + my $remote_dir = 'myfiles'; # Directory name on server + my $filename = '/tmp/test_file.zip'; # Full file path to upload + + # Upload file on server. Return Mediafire::Api::UploadFile object + my $mediafire_file = $mediafire->uploadFile( + -file => $filename, + -path => $remote_dir, + ); + # Get uploaded file key + print "Uploaded file key: " . $mediafire_file->getDouploadKey() . "\n"; + + + +=head1 Upload Files to server + + +=head2 new() + +=head2 login(%opt) + +=head1 DEPENDENCE + +L, L, L, L, L, L, L + +=head1 AUTHORS + +=over 4 + +=item * + +Pavel Andryushin + +=back + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2019 by Pavel Andryushin. + +This is free software; you can redistribute it and/or modify it under +the same terms as the Perl 5 programming language system itself. + +=cut diff --git a/lib/Mediafire/Api/.UploadFile.pm.swp b/lib/Mediafire/Api/.UploadFile.pm.swp index 29a2734a0606a9ef3f6dda5cafa29d8a4b90a56b..aa5672a91ca0ea677b2e02739a361a9a852aaa07 100644 GIT binary patch delta 2652 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 diff --git a/lib/Mediafire/Api/File.pm b/lib/Mediafire/Api/File.pm new file mode 100644 index 0000000..fe79b51 --- /dev/null +++ b/lib/Mediafire/Api/File.pm @@ -0,0 +1,54 @@ +package Mediafire::Api::File; + +use 5.008001; +use utf8; +use strict; +use warnings; + +our $VERSION = '0.01'; + +sub new { + my ($class, %opt) = @_; + my $self = {}; + + for my $field (qw/key size name hash/) { + $self->{$field} = $opt{"-$field"}; + } + + bless $self, $class; + return $self; +} + + +########### ACCESSORS ####################### + +sub key { + if (defined($_[1])) { + $_[0]->{key} = $_[1]; + } + return $_[0]->{key}; +} + +sub size { + if (defined($_[1])) { + $_[0]->{size} = $_[1]; + } + return $_[0]->{size}; +} + +sub name { + if (defined($_[1])) { + $_[0]->{name} = $_[1]; + } + return $_[0]->{name}; +} + +sub hash { + if (defined($_[1])) { + $_[0]->{hash} = $_[1]; + } + return $_[0]->{hash}; +} + + +1; diff --git a/lib/Mediafire/Api/UploadFile.pm b/lib/Mediafire/Api/UploadFile.pm index 972b4cf..2b7bfd3 100644 --- a/lib/Mediafire/Api/UploadFile.pm +++ b/lib/Mediafire/Api/UploadFile.pm @@ -16,6 +16,8 @@ use Crypt::Digest::SHA256 qw/sha256_hex/; use Time::HiRes qw/gettimeofday/; use IO::Socket::SSL; +use Mediafire::Api::File; + use Data::Printer; our $VERSION = '0.01'; @@ -40,9 +42,9 @@ my $checkUploadFile = sub { my $microseconds = substr(join('', @sec), 0, 13); my %param = ( - 'hash' => $self->{file_hash}, - 'size' => $self->{file_size}, - 'filename' => $self->{basename}, + 'hash' => $self->{file}->hash, + 'size' => $self->{file}->size, + 'filename' => $self->{file}->name, 'unit_size' => $self->{buff_size}, 'resumable' => 'yes', 'preemptive' => 'yes', @@ -79,8 +81,52 @@ my $checkUploadFile = sub { p $response; - $self->{preemptive_quickkey} = $response->{preemptive_quickkey}; + my $file_key = $response->{preemptive_quickkey} // $response->{duplicate_quickkey}; + $self->{file}->key($file_key); $self->{upload_url} = $response->{upload_url}->{resumable}; + return $response; +}; + +my $getFileFromCache = sub { + my ($self) = @_; + + my $url = 'https://www.mediafire.com/api/1.5/upload/instant.php'; + + my @sec = gettimeofday(); + my $microseconds = substr(join('', @sec), 0, 13); + + my %param = ( + 'hash' => $self->{file}->hash, + 'size' => $self->{file}->size, + 'filename' => $self->{file}->name, + 'folder_key' => $self->{path}, + 'session_token' => $self->{session_token}, + 'response_format' => 'json', + $microseconds => '', + ); + + my $param_str = join('&', map {"$_=" . uri_escape($param{$_})} keys %param); + my $full_url = $url . '?' . $param_str; + my $res = $self->{ua}->get($full_url); + my $code = $res->code; + if ($code ne '200') { + croak "Wrong response code checkUploadFile(). Url: '$full_url'. Code: $code"; + } + my $json_res = eval { + decode_json($res->decoded_content); + }; + if ($@) { + croak "Can't parse respone '" . $res->decoded_content . "' to json"; + } + + # Get json response + my $response = $json_res->{response}; + if ($response->{result} ne 'Success') { + croak "getFileFromCache() not success"; + } + my $file_key = $response->{quickkey}; + $self->{file}->key($file_key); + return 1; }; @@ -146,10 +192,10 @@ my $uploadF = sub { "Content-Type" => "application/octet-stream", "Referer" => "https://www.mediafire.com/uploads", "Origin" => "https://www.mediafire.com", - "X-Filesize" => $self->{file_size}, - "X-Filename" => $self->{basename}, + "X-Filesize" => $self->{file}->size, + "X-Filename" => $self->{file}->name, "X-Filetype" => $file_type, - "X-Filehash" => $self->{file_hash}, + "X-Filehash" => $self->{file}->hash, "X-Unit-Hash" => $unit_hash, "X-Unit-Size" => $bytes, "X-Unit-Id" => $unit_id, @@ -176,6 +222,7 @@ my $uploadF = sub { if ($json_res->{response}->{resumable_upload}->{all_units_ready} eq 'yes') { last; } + p $json_res; ++$unit_id; @@ -187,6 +234,8 @@ my $uploadF = sub { croak "Not all parts of file '$upload_file' uploaded. Wrong answer from server"; } + p $json_res; + return 1; }; @@ -214,14 +263,31 @@ sub uploadFile { croak "File '" . $self->{upload_file} . "' not exists"; } - # Get all info about file - $self->{file_hash} = $getSha256Sum->($self->{upload_file}); - $self->{file_size} = -s $self->{upload_file}; - $self->{basename} = basename($self->{upload_file}); + $self->{file} = Mediafire::Api::File->new( + -size => -s $self->{upload_file}, + -name => basename($self->{upload_file}), + -hash => $getSha256Sum->($self->{upload_file}), + ); - $self->$checkUploadFile(); - $self->$checkResumeUpload(); - $self->$uploadF(); + + # Get upload url + my $response = $self->$checkUploadFile(); + if ($response->{hash_exists} eq 'yes') { + # No need upload file. Get file from cache + $self->$getFileFromCache(); + } + else { + # Upload file + $self->$checkResumeUpload(); + $self->$uploadF(); + } + + # Check exists file key + if (not defined($self->{file}->key)) { + croak "Key of upload file '$self->{upload_file}' not exists. Error on upload file to server"; + } + + return $self->{file}; } diff --git a/t/001_test.t b/t/001_test.t index e3f83b2..54d281d 100644 --- a/t/001_test.t +++ b/t/001_test.t @@ -73,7 +73,11 @@ sub testUploadFile { my ($mediafire, $file) = @_; my $upload_file = $mediafire->uploadFile( -file => $file, + -path => 'myfiles', ); + + my $doupload_key = $upload_file->key; + ok($doupload_key, "Test upload file. DouploadKey: $doupload_key"); }