Initial commit 0.001
authorMarius Gavrilescu <marius@ieval.ro>
Sun, 15 Mar 2015 10:05:03 +0000 (12:05 +0200)
committerMarius Gavrilescu <marius@ieval.ro>
Sun, 15 Mar 2015 10:05:03 +0000 (12:05 +0200)
Changes [new file with mode: 0644]
MANIFEST [new file with mode: 0644]
Makefile.PL [new file with mode: 0644]
README [new file with mode: 0644]
lib/WebService/Strike.pm [new file with mode: 0644]
lib/WebService/Strike/Torrent.pm [new file with mode: 0644]
t/WebService-Strike-Torrent.t [new file with mode: 0644]
t/WebService-Strike.t [new file with mode: 0644]
t/perlcritic.t [new file with mode: 0644]
t/perlcriticrc [new file with mode: 0644]

diff --git a/Changes b/Changes
new file mode 100644 (file)
index 0000000..3678ea0
--- /dev/null
+++ b/Changes
@@ -0,0 +1,4 @@
+Revision history for Perl extension WebService::Strike.
+
+0.001 2015-03-15T12:05
+ - Initial release
diff --git a/MANIFEST b/MANIFEST
new file mode 100644 (file)
index 0000000..2bfcc0f
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,10 @@
+Changes
+Makefile.PL
+MANIFEST
+README
+t/WebService-Strike.t
+t/WebService-Strike-Torrent.t
+t/perlcritic.t
+t/perlcriticrc
+lib/WebService/Strike.pm
+lib/WebService/Strike/Torrent.pm
diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644 (file)
index 0000000..494aabf
--- /dev/null
@@ -0,0 +1,28 @@
+use 5.014000;
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+       NAME              => 'WebService::Strike',
+       VERSION_FROM      => 'lib/WebService/Strike.pm',
+       ABSTRACT_FROM     => 'lib/WebService/Strike.pm',
+       AUTHOR            => 'Marius Gavrilescu <marius@ieval.ro>',
+       MIN_PERL_VERSION  => '5.14.0',
+       LICENSE           => 'perl',
+       SIGN              => 1,
+       BUILD_REQUIRES    => {
+               qw/Test::RequiresInternet 0
+                  Try::Tiny              0/,
+       },
+       PREREQ_PM         => {
+               qw/Date::Parse     0
+                  JSON::MaybeXS   0
+                  Sort::ByExample 0
+                  URI::Escape     0/,
+       },
+       META_ADD          => {
+               dynamic_config => 0,
+               resources      => {
+                       repository   => 'http://git.ieval.ro/?p=webservice-strike.git',
+               }
+       }
+);
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..73a6258
--- /dev/null
+++ b/README
@@ -0,0 +1,32 @@
+WebService-Strike version 0.001
+===============================
+
+INSTALLATION
+
+To install this module type the following:
+
+   perl Makefile.PL
+   make
+   make test
+   make install
+
+DEPENDENCIES
+
+This module requires these other modules and libraries:
+
+* Test::RequiresInternet
+* Try::Tiny
+* Date::Parse
+* JSON::MaybeXS
+* Sort::ByExample
+* URI::Escape
+
+COPYRIGHT AND LICENCE
+
+Copyright (C) 2015 by Marius Gavrilescu
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.20.2 or,
+at your option, any later version of Perl 5 you may have available.
+
+
diff --git a/lib/WebService/Strike.pm b/lib/WebService/Strike.pm
new file mode 100644 (file)
index 0000000..8ff1e55
--- /dev/null
@@ -0,0 +1,91 @@
+package WebService::Strike;
+
+use 5.014000;
+use strict;
+use warnings;
+use parent qw/Exporter/;
+
+our @EXPORT    = qw/strike/; ## no critic (ProhibitAutomaticExportation)
+our @EXPORT_OK = qw/strike_query strike/;
+our $VERSION = '0.001';
+our $BASE_URL = 'http://getstrike.net/api/torrents/';
+
+use JSON::MaybeXS qw/decode_json/;
+use HTTP::Tiny;
+use Sort::ByExample qw/sbe/;
+use WebService::Strike::Torrent;
+
+sub _ht { HTTP::Tiny->new(agent => "WebService-Strike/$VERSION") }
+
+sub strike_query {
+       my (@hashes) = @_;
+       my $url = "$BASE_URL/info/?hashes=" . join ',', map { uc } @hashes;
+       my $ht = _ht;
+       my $response = $ht->get($url);
+       die $response unless $response->{success}; ## no critic (RequireCarping)
+       $response = decode_json $response->{content};
+
+       die $response unless ref $response eq 'ARRAY'; ## no critic (RequireCarping)
+       my $sorter = sbe(\@hashes, {xform => sub { $_[0]->hash }});
+       my @torrents = map { WebService::Strike::Torrent->new($_) } @{$response->[1]};
+       @torrents = $sorter->(@torrents);
+       wantarray ? @torrents : $torrents[0]
+}
+
+BEGIN { *strike = \&strike_query }
+
+1;
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+WebService::Strike - Get torrent info from getstrike.net API
+
+=head1 SYNOPSIS
+
+  use WebService::Strike;
+  my $t = strike 'B425907E5755031BDA4A8D1B6DCCACA97DA14C04';
+  say $t->title;               # Arch Linux 2015.01.01 (x86\/x64)
+  say $t->magnet;              # Returns a magnet link
+  my $torrent = $t->torrent;   # Returns the torrent file
+  $t->torrent('file.torrent'); # Downloads the torrent file to 'file.torrent'
+
+=head1 DESCRIPTION
+
+Strike API is a service for getting information about a torrent given
+its info hash. WebService::Strike is a wrapper for this service.
+
+=over
+
+=item B<strike>(I<@info_hashes>)
+
+Returns a list of hashrefs, one for each info hash. The hashrefs are
+blessed into the L<WebService::Strike::Torrent> package. Dies in case
+of error.
+
+=item B<strike_query>
+
+Alias for B<strike>. Not exported by default.
+
+=back
+
+=head1 SEE ALSO
+
+L<WebService::Strike::Torrent>, L<http://getstrike.net/api/>, L<WWW::Search::Torrentz>
+
+=head1 AUTHOR
+
+Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2015 by Marius Gavrilescu
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.20.2 or,
+at your option, any later version of Perl 5 you may have available.
+
+
+=cut
diff --git a/lib/WebService/Strike/Torrent.pm b/lib/WebService/Strike/Torrent.pm
new file mode 100644 (file)
index 0000000..8c8a894
--- /dev/null
@@ -0,0 +1,179 @@
+package WebService::Strike::Torrent;
+
+use 5.014000;
+use strict;
+use warnings;
+use parent qw/Class::Accessor::Fast/;
+
+our $VERSION = '0.001';
+
+use Date::Parse qw/str2time/;
+use JSON::MaybeXS qw/decode_json/;
+use URI::Escape qw/uri_escape/;
+use WebService::Strike;
+
+__PACKAGE__->mk_ro_accessors(qw/torrent_hash torrent_title torrent_category sub_category seeds leeches file_count size upload_date uploader_username file_info file_names file_lengths/);
+
+BEGIN {
+       *hash     = *torrent_hash;
+       *title    = *torrent_title;
+       *category = *torrent_category;
+       *count    = *file_count;
+       *date     = *upload_date;
+       *uploader = *uploader_username;
+       *names    = *file_names;
+       *lengths  = *file_lengths;
+};
+
+sub new{
+       my ($self, @args) = @_;
+       $self = $self->SUPER::new(@args);
+       $self->{torrent_hash} = uc $self->hash;
+       $self->{upload_date} = str2time $self->date;
+       $self->{file_names} = $self->file_info->[0]->{file_names};
+       $self->{file_lengths} = $self->file_info->[0]->{file_lengths};
+       $self
+}
+
+sub magnet{
+       my ($self) = @_;
+       'magnet:?xt=urn:btih:' . $self->hash . '&dn=' . uri_escape $self->title
+}
+
+sub torrent{
+       my ($self, $file) = @_;
+       my $url = $WebService::Strike::BASE_URL . '/downloads/?hash=' . $self->hash;
+       my $ht = WebService::Strike::_ht(); ## no critic (ProtectPrivate)
+       my $response = $ht->get($url);
+       return unless $response->{success};
+       $response = decode_json $response->{content};
+       $url = $response->{message};
+
+       if (defined $file) {
+               $response = $ht->mirror($url, $file);
+               return $response->{success}
+       } else {
+               $response = $ht->get($url);
+               return $response->{success} && $response->{content}
+       }
+}
+
+1;
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+WebService::Strike::Torrent - Class representing information about a torrent
+
+=head1 SYNOPSIS
+
+  use WebService::Strike;
+  my $t = strike 'B425907E5755031BDA4A8D1B6DCCACA97DA14C04';
+  say $t->hash;             # B425907E5755031BDA4A8D1B6DCCACA97DA14C04
+  say $t->title;            # Arch Linux 2015.01.01 (x86/x64)
+  say $t->category;         # Applications
+  say $t->sub_category;     # '' (empty string)
+  say $t->seeds;
+  say $t->leeches;
+  say $t->count;            # 1
+  say $t->size;             # 587 MB
+  say $t->date;             # 1420495200
+  say $t->uploader;         # The_Doctor-
+  say @{$t->names};         # archlinux-2015.01.01-dual.iso
+  say @{$t->lengths};       # 615514112
+  say $t->magnet;           # magnet:?xt=urn:btih:B425907E5755031BDA4A8D1B6DCCACA97DA14C04&dn=Arch%20Linux%202015.01.01%20%28x86%2Fx64%29
+  my $tor = $t->torrent;    # $torrent contains the torrent file contents
+  $t->torrent('x.torrent'); # Download torrent file to x.torrent
+
+=head1 DESCRIPTION
+
+WebService::Strike::Torrent is a class that represents information
+about a torrent.
+
+Methods:
+
+=over
+
+=item B<hash>, B<torrent_hash>
+
+The info_hash of the torrent.
+
+=item B<title>, B<torrent_title>
+
+The title of the torrent.
+
+=item B<category>, B<torrent_category>
+
+The category of the torrent.
+
+=item B<sub_category>
+
+The subcategory of the torrent.
+
+=item B<seeds>
+
+The number of seeders.
+
+=item B<leeches>
+
+The number of leechers.
+
+=item B<count>, B<file_count>
+
+The number of files contained in the torrent.
+
+=item B<size>
+
+The total size of the files in the torrent as a human-readable string.
+See B<file_lengths> for exact sizes.
+
+=item B<date>, B<upload_date>
+
+Unix timestamp when the torrent was uploaded, with precision of one day.
+
+=item B<uploader>, B<uploader_username>
+
+Username of the user who uploaded the torrent.
+
+=item B<file_names>
+
+Arrayref of paths of files in the torrent.
+
+=item B<file_lengths>
+
+Arrayref of lengths of files in the torrent, in bytes.
+
+=item B<magnet>
+
+Magnet link for the torrent.
+
+=item B<torrent>([I<$filename>])
+
+Downloads the torrent from Strike. With no arguments, returns the
+contents of the torrent file. With an argument, stores the torrent in
+I<$filename>.
+
+Both forms return a true value for success and false for failure.
+
+=back
+
+=head1 SEE ALSO
+
+L<WebService::Strike>, L<http://getstrike.net/api/>
+
+=head1 AUTHOR
+
+Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2015 by Marius Gavrilescu
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.20.2 or,
+at your option, any later version of Perl 5 you may have available.
+
+
+=cut
diff --git a/t/WebService-Strike-Torrent.t b/t/WebService-Strike-Torrent.t
new file mode 100644 (file)
index 0000000..9787119
--- /dev/null
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use Test::More tests => 14;
+BEGIN { use_ok('WebService::Strike::Torrent') }
+
+my %data = (
+       leeches => 13,
+       size => '587 MB',
+       torrent_hash => 'b425907e5755031bda4a8d1b6dccaca97da14c04',
+       file_count => 1,
+       sub_category => '',
+       torrent_category => 'Applications',
+       file_info => [{
+               file_names => [ 'archlinux-2015.01.01-dual.iso' ],
+               file_lengths => [ 615514112 ],
+       }],
+       upload_date => 'Jan  6, 2015',
+       seeds => 645,
+       uploader_username => 'The_Doctor-',
+       torrent_title => 'Arch Linux 2015.01.01 (x86/x64)'
+);
+
+my $t = WebService::Strike::Torrent->new(\%data);
+
+is $t->hash, 'B425907E5755031BDA4A8D1B6DCCACA97DA14C04', 'hash';
+is $t->title, 'Arch Linux 2015.01.01 (x86/x64)', 'title';
+is $t->category, 'Applications', 'category';
+is $t->sub_category, '', 'sub_category';
+is $t->seeds, 645, 'seeds';
+is $t->leeches, 13, 'leeches';
+is $t->count, 1, 'count';
+is $t->size, '587 MB', 'size';
+is $t->date, 1420495200,'date';
+is $t->uploader, 'The_Doctor-', 'uploader';
+is $t->names->[0], 'archlinux-2015.01.01-dual.iso', 'names';
+is $t->lengths->[0], 615514112, 'lengths';
+is $t->magnet, 'magnet:?xt=urn:btih:B425907E5755031BDA4A8D1B6DCCACA97DA14C04&dn=Arch%20Linux%202015.01.01%20%28x86%2Fx64%29', 'magnet';
diff --git a/t/WebService-Strike.t b/t/WebService-Strike.t
new file mode 100644 (file)
index 0000000..ffd59ad
--- /dev/null
@@ -0,0 +1,27 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use Test::RequiresInternet qw/getstrike.net 80/;
+use Test::More tests => 6;
+use Try::Tiny;
+BEGIN { use_ok('WebService::Strike') };
+
+my ($t1, $t2, $t3) = strike qw/B425907E5755031BDA4A8D1B6DCCACA97DA14C04 5D4FD5A64E436A831383773F85FB38B888B9ECC9 85DF191A921C20B2DDAFF72368CAB93BA18C5ACE/;
+
+subtest 'order' => sub {
+       plan tests => 3;
+       is $t1->hash, 'B425907E5755031BDA4A8D1B6DCCACA97DA14C04', 'hash #1';
+       is $t2->hash, '5D4FD5A64E436A831383773F85FB38B888B9ECC9', 'hash #2';
+       is $t3->hash, '85DF191A921C20B2DDAFF72368CAB93BA18C5ACE', 'hash #3'
+};
+
+is $t1->date, 1420495200, 'date';
+is $t2->title, 'FreeBSD 7.1 i386.DVD.iso', 'title';
+like $t1->torrent, qr/^d/, 'torrent file starts with d';
+
+try {
+       strike 'aaa';
+} catch {
+       is $_->{status}, 404, 'non-existent torrent status is 404';
+};
diff --git a/t/perlcritic.t b/t/perlcritic.t
new file mode 100644 (file)
index 0000000..79e93dc
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/perl
+use v5.14;
+use warnings;
+
+use Test::More;
+
+BEGIN { plan skip_all => '$ENV{RELEASE_TESTING} is false' unless $ENV{RELEASE_TESTING} }
+use Test::Perl::Critic -profile => 't/perlcriticrc';
+
+all_critic_ok 'lib'
diff --git a/t/perlcriticrc b/t/perlcriticrc
new file mode 100644 (file)
index 0000000..96564fe
--- /dev/null
@@ -0,0 +1,35 @@
+severity = 1
+
+[-BuiltinFunctions::ProhibitComplexMappings]
+[-CodeLayout::RequireTidyCode]
+[-ControlStructures::ProhibitPostfixControls]
+[-ControlStructures::ProhibitUnlessBlocks]
+[-Documentation::PodSpelling]
+[-Documentation::RequirePodLinksIncludeText]
+[-InputOutput::RequireBracedFileHandleWithPrint]
+[-References::ProhibitDoubleSigils]
+[-RegularExpressions::ProhibitEnumeratedClasses]
+[-RegularExpressions::RequireLineBoundaryMatching]
+[-Subroutines::RequireFinalReturn]
+[-ValuesAndExpressions::ProhibitConstantPragma]
+[-ValuesAndExpressions::ProhibitEmptyQuotes]
+[-ValuesAndExpressions::ProhibitLeadingZeros]
+[-ValuesAndExpressions::ProhibitMagicNumbers]
+[-ValuesAndExpressions::ProhibitNoisyQuotes]
+[-Variables::ProhibitLocalVars]
+[-Variables::ProhibitPackageVars]
+[-Variables::ProhibitPunctuationVars]
+
+[BuiltinFunctions::ProhibitStringyEval]
+allow_includes = 1
+
+[RegularExpressions::RequireExtendedFormatting]
+minimum_regex_length_to_complain_about = 20
+
+[Documentation::RequirePodSections]
+lib_sections = NAME | SYNOPSIS | DESCRIPTION | AUTHOR | COPYRIGHT AND LICENSE
+script_sections = NAME | SYNOPSIS | DESCRIPTION | AUTHOR | COPYRIGHT AND LICENSE
+
+[Subroutines::RequireArgUnpacking]
+short_subroutine_statements = 5
+allow_subscripts = 1
This page took 0.023044 seconds and 4 git commands to generate.