Add perlcritic release test and fix problems
[www-search-torrentz.git] / lib / WWW / Search / Torrentz / Result.pm
CommitLineData
e605ae0f
MG
1package WWW::Search::Torrentz::Result;
2
3use 5.014000;
4use strict;
5use warnings;
6use parent qw/WWW::SearchResult/;
7
318ef587 8our $VERSION = '0.001002';
e605ae0f
MG
9
10use HTML::TreeBuilder;
11use URI::Escape qw/uri_escape/;
12
13sub new{
7dcf8cda
MG
14 my ($class, %args) = @_;
15 my $self = $class->SUPER::new(@_);
16 $self->{parsed} = 0;
17
9219ba0f 18 $self->_elem($_ => $args{$_}) for qw/title verified age size seeders leechers infohash/;
7dcf8cda
MG
19 $self->{ua} = $args{ua};
20 $self->add_url("https://torrentz.eu/$args{infohash}");
21 $self
e605ae0f
MG
22}
23
24sub infohash { shift->_elem(infohash => @_) }
25sub verified { shift->_elem(verified => @_) }
26sub age { shift->_elem(age => @_) }
27sub size { shift->_elem(size => @_) }
28sub seeders { shift->_elem(seeders => @_) }
29sub leechers { shift->_elem(leechers => @_) }
30
31sub magnet{
7dcf8cda
MG
32 my ($self, $full) = @_;
33 my $infohash = $self->infohash;
34 my $title = uri_escape $self->title;
35 my $uri = "magnet:?xt=urn:btih:$infohash&dn=$title";
e605ae0f 36
7dcf8cda 37 $uri .= join '', map { "&tr=$_"} map { uri_escape $_ } $self->trackers if $full;
e605ae0f 38
7dcf8cda 39 $uri
e605ae0f
MG
40}
41
42sub parse_page {
7dcf8cda
MG
43 my $self = $_[0];
44 my $tree = HTML::TreeBuilder->new;
45 $tree->utf8_mode(1);
46 $tree->parse($self->{ua}->get($self->url)->content);
47 $tree->eof;
48
49 my $trackers = $tree->look_down(class => 'trackers');
50 $self->{trackers} //= [];
51 for my $tracker ($trackers->find('dl')) {
52 push $self->{trackers}, $tracker->find('a')->as_text;
53 }
54
55 my $files = $tree->look_down(class => 'files');
56 $self->{files} //= [];
57 $self->parse_directory(scalar $files->find('li'), '');
58
59 $self->{parsed} = 1;
e605ae0f
MG
60}
61
62sub parse_directory{
7dcf8cda
MG
63 my ($self, $directory, $prefix) = @_;
64 $prefix .= $directory->as_text . '/';
65 my $contents_ul = $directory->right->find('ul');
66 return unless defined $contents_ul; # Empty directory
67 my @children = $contents_ul->content_list;
68 my $skip = 0;
69 for my $child (@children) {
70 if ($skip) {
71 $skip = 0;
72 next;
73 }
74
75 if (defined $child->attr('class') && $child->attr('class') eq 't') {
76 $self->parse_directory($child, $prefix);
77 $skip = 1;
78 } else {
79 $child->objectify_text;
80 my ($filename, $size) = $child->find('~text');
81 push $self->{files}, +{
82 path => $prefix.$filename->attr('text'),
83 size => $size->attr('text')
84 }
85 }
e605ae0f 86 }
e605ae0f
MG
87}
88
89sub trackers{
7dcf8cda
MG
90 my $self = $_[0];
91 $self->parse_page unless $self->{parsed};
92 @{$self->{trackers}}
e605ae0f
MG
93}
94
95sub files{
7dcf8cda
MG
96 my $self = $_[0];
97 $self->parse_page unless $self->{parsed};
98 @{$self->{files}}
e605ae0f
MG
99}
100
101sub torrent{
7dcf8cda
MG
102 my $self = $_[0];
103 my $torrage = 'http://torrage.com/torrent/' . uc $self->infohash . '.torrent';
104 my $torrent = $self->{ua}->get($torrage)->content;
e605ae0f 105
7dcf8cda 106 $torrent; # TODO: if this is undef, download metadata with magnet link
e605ae0f
MG
107}
108
1091;
110__END__
111
112=encoding utf-8
113
114=head1 NAME
115
116WWW::Search::Torrentz::Result - a result of a WWW::Search::Torrentz search
117
118=head1 SYNOPSIS
119
120 my $result = $search->next_result;
121 say 'URL: ' . $result->url;
122 say 'Title: ' . $result->title;
123 say 'Infohash: ' . $result->infohash;
124 say 'Verified: ' . $result->verified;
125 say 'Age: ' . $result->age;
126 say 'Size: ' . $result->size;
127 say 'Seeders: ' . $result->seeders;
128 say 'Leechers: ' . $result->leechers;
129 say 'Magnet link: ' . $result->magnet;
130 say 'Magnet link with trackers: ' . $result->magnet(1);
131 my @tracker_list = $result->trackers;
132 my @file_list = $result->files;
133 my $torrent_file = $result->torrent;
134
135=head1 DESCRIPTION
136
137WWW::Search::Torrentz::Result is the result of a WWW::Search::Torrentz search.
138
139Useful methods:
140
141=over
142
143=item B<url>
144
145Returns a link to the torrent details page.
146
147=item B<title>
148
149Returns the torrent's title.
150
151=item B<infohash>
152
153Returns the infohash of the torrent, a 40 character hex string.
154
155=item B<verified>
156
157Returns the verification level of this torrent, or 0 if the torrent not verified. Higher is better.
158
159=item B<age>
160
161Returns the torrent's age, as returned by Torrentz. Usually a string such as '4 days', 'yesterday', 'today', '2 months'.
162
163=item B<size>
164
165Returns the torrent's size, as returned by Torrentz. A string such as '151 MB', '25 GB'.
166
167=item B<seeders>
168
169Returns the number of seeders this torrent has, as returned by Torrentz.
170
171=item B<leechers>
172
173Returns the number of leechers this torrent has, as returned by Torrentz.
174
175=item B<magnet>([I<include_trackers>])
176
177Returns a magnet link that describes this torrent.
178
179If I<include_trackers> is true, the magnet link will include the tracker list. This calls B<parse_page> if not called already.
180
181=item B<trackers>
182
183Returns a list of trackers for this torrent. Calls B<parse_page> if not called already.
184
185=item B<files>
186
187Returns a list of files this torrent includes. Calls B<parse_page> if not called already.
188
189Each element is a hashref with two keys. C<path> is the file path and C<size> is the file size, as returned by Torrentz.
190
191=item B<parse_page>
192
193Downloads the details page for this torrent and extracts the tracker and file list. It is called automatically by other methods when necessary, you shouldn't have to call it yourself.
194
195=item B<torrent>
196
197Downloads this torrent file from Torrage. If found, it returns the contents of the torrent file. Otherwise it returns undef.
198
199=back
200
201=head1 SEE ALSO
202
203=head1 AUTHOR
204
205Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
206
207=head1 COPYRIGHT AND LICENSE
208
209Copyright (C) 2013 by Marius Gavrilescu
210
211This library is free software; you can redistribute it and/or modify
212it under the same terms as Perl itself, either Perl version 5.18.1 or,
213at your option, any later version of Perl 5 you may have available.
214
215
216=cut
This page took 0.024205 seconds and 4 git commands to generate.