]>
Commit | Line | Data |
---|---|---|
1 | package WWW::Search::Torrentz::Result; | |
2 | ||
3 | use 5.014000; | |
4 | use strict; | |
5 | use warnings; | |
6 | use parent qw/WWW::SearchResult/; | |
7 | ||
8 | our $VERSION = '0.002'; | |
9 | ||
10 | use HTML::TreeBuilder; | |
11 | use URI::Escape qw/uri_escape/; | |
12 | ||
13 | sub new{ | |
14 | my ($class, %args) = @_; | |
15 | my $self = $class->SUPER::new(@_); | |
16 | $self->{parsed} = 0; | |
17 | ||
18 | $self->_elem($_ => $args{$_}) for qw/title verified age size seeders leechers infohash/; | |
19 | $self->{ua} = $args{ua}; | |
20 | $self->add_url("https://torrentz.eu/$args{infohash}"); | |
21 | $self | |
22 | } | |
23 | ||
24 | sub infohash { shift->_elem(infohash => @_) } | |
25 | sub verified { shift->_elem(verified => @_) } | |
26 | sub age { shift->_elem(age => @_) } | |
27 | sub size { shift->_elem(size => @_) } | |
28 | sub seeders { shift->_elem(seeders => @_) } | |
29 | sub leechers { shift->_elem(leechers => @_) } | |
30 | ||
31 | sub magnet{ | |
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"; | |
36 | ||
37 | $uri .= join '', map { "&tr=$_"} map { uri_escape $_ } $self->trackers if $full; | |
38 | ||
39 | $uri | |
40 | } | |
41 | ||
42 | sub parse_page { | |
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; | |
60 | } | |
61 | ||
62 | sub parse_directory{ | |
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 | } | |
86 | } | |
87 | } | |
88 | ||
89 | sub trackers{ | |
90 | my $self = $_[0]; | |
91 | $self->parse_page unless $self->{parsed}; | |
92 | @{$self->{trackers}} | |
93 | } | |
94 | ||
95 | sub files{ | |
96 | my $self = $_[0]; | |
97 | $self->parse_page unless $self->{parsed}; | |
98 | @{$self->{files}} | |
99 | } | |
100 | ||
101 | sub torrent{ | |
102 | my $self = $_[0]; | |
103 | my $torrage = 'http://torrage.com/torrent/' . uc $self->infohash . '.torrent'; | |
104 | my $torrent = $self->{ua}->get($torrage)->content; | |
105 | ||
106 | $torrent; # TODO: if this is undef, download metadata with magnet link | |
107 | } | |
108 | ||
109 | 1; | |
110 | __END__ | |
111 | ||
112 | =encoding utf-8 | |
113 | ||
114 | =head1 NAME | |
115 | ||
116 | WWW::Search::Torrentz::Result - [DEPRECATED] 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 | ||
137 | WWW::Search::Torrentz::Result is the result of a WWW::Search::Torrentz search. | |
138 | ||
139 | Useful methods: | |
140 | ||
141 | =over | |
142 | ||
143 | =item B<url> | |
144 | ||
145 | Returns a link to the torrent details page. | |
146 | ||
147 | =item B<title> | |
148 | ||
149 | Returns the torrent's title. | |
150 | ||
151 | =item B<infohash> | |
152 | ||
153 | Returns the infohash of the torrent, a 40 character hex string. | |
154 | ||
155 | =item B<verified> | |
156 | ||
157 | Returns the verification level of this torrent, or 0 if the torrent not verified. Higher is better. | |
158 | ||
159 | =item B<age> | |
160 | ||
161 | Returns 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 | ||
165 | Returns the torrent's size, as returned by Torrentz. A string such as '151 MB', '25 GB'. | |
166 | ||
167 | =item B<seeders> | |
168 | ||
169 | Returns the number of seeders this torrent has, as returned by Torrentz. | |
170 | ||
171 | =item B<leechers> | |
172 | ||
173 | Returns the number of leechers this torrent has, as returned by Torrentz. | |
174 | ||
175 | =item B<magnet>([I<include_trackers>]) | |
176 | ||
177 | Returns a magnet link that describes this torrent. | |
178 | ||
179 | If 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 | ||
183 | Returns a list of trackers for this torrent. Calls B<parse_page> if not called already. | |
184 | ||
185 | =item B<files> | |
186 | ||
187 | Returns a list of files this torrent includes. Calls B<parse_page> if not called already. | |
188 | ||
189 | Each 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 | ||
193 | Downloads 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 | ||
197 | Downloads 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 | ||
205 | Marius Gavrilescu, E<lt>marius@ieval.roE<gt> | |
206 | ||
207 | =head1 COPYRIGHT AND LICENSE | |
208 | ||
209 | Copyright (C) 2013 by Marius Gavrilescu | |
210 | ||
211 | This library is free software; you can redistribute it and/or modify | |
212 | it under the same terms as Perl itself, either Perl version 5.18.1 or, | |
213 | at your option, any later version of Perl 5 you may have available. | |
214 | ||
215 | ||
216 | =cut |