File Coverage

blib/lib/WWW/Asg.pm
Criterion Covered Total %
statement 91 104 87.5
branch 16 26 61.5
condition 2 5 40.0
subroutine 16 18 88.8
pod 3 3 100.0
total 128 156 82.0


line stmt bran cond sub pod time code
1             package WWW::Asg;
2 3     3   82273 use strict;
  3         6  
  3         121  
3 3     3   17 use warnings;
  3         5  
  3         83  
4 3     3   18 use utf8;
  3         10  
  3         20  
5              
6 3     3   66 use Carp;
  3         5  
  3         296  
7 3     3   3450 use LWP::UserAgent;
  3         188958  
  3         126  
8 3     3   32 use Digest::MD5 qw(md5_hex);
  3         215  
  3         249  
9 3     3   3342 use HTML::TreeBuilder::XPath;
  3         330161  
  3         47  
10 3     3   8313 use Encode;
  3         85360  
  3         354  
11 3     3   33 use URI;
  3         9  
  3         434  
12 3     3   6308 use DateTime::Format::ISO8601;
  3         1677950  
  3         263  
13 3     3   40 use DateTime::Format::Strptime;
  3         6  
  3         4206  
14              
15             #use Smart::Comments;
16              
17             =head1 NAME
18              
19             WWW::Asg - Get video informations from Asg.to
20              
21             =head1 VERSION
22              
23             Version 0.05
24              
25             =cut
26              
27             our $VERSION = '0.05';
28              
29             =head1 SYNOPSIS
30              
31             use WWW::Asg;
32              
33             my $asg = WWW::Asg->new();
34             my @videos = $asg->latest_videos($page);
35             foreach my $v ( @videos ) {
36             print $asg->{embed} . "\n";
37             }
38              
39             =cut
40              
41             my $strp = DateTime::Format::Strptime->new(
42             pattern => '%Y.%m.%d %H:%M',
43             locale => 'ja_JP',
44             time_zone => 'Asia/Tokyo',
45             );
46             my %default_condition = (
47             q => '',
48             searchVideo => 'true',
49             minimumLength => '',
50             searchCategory => 'any',
51             sort => 'date',
52             );
53             my $embed_code_format =
54             '';
55              
56             =head1 SUBROUTINES/METHODS
57              
58             =head2 new
59             =cut
60              
61             sub new {
62 3     3 1 600430 my ( $class, %opt ) = @_;
63 3         25 my $self = bless {%opt}, $class;
64              
65 3 50       79 $self->{ua} = LWP::UserAgent->new unless $self->{ua};
66              
67 3         13764 $self;
68             }
69              
70             =head2 search(%condition)
71             =cut
72              
73             sub search {
74 0     0 1 0 my ( $self, %condition ) = @_;
75 0         0 %condition = ( %default_condition, %condition );
76              
77 0         0 my $uri = URI->new('http://asg.to/search');
78 0         0 $uri->query_form( \%condition );
79 0         0 my $res = $self->{ua}->get( $uri->as_string );
80 0 0       0 return () unless $res->is_success;
81              
82 0         0 $self->_extract_videos( $res->decoded_content );
83             }
84              
85             =head2 latest_videos($page)
86             =cut
87              
88             sub latest_videos {
89 0     0 1 0 my ( $self, $page ) = @_;
90 0   0     0 $page ||= 1;
91 0         0 my $res = $self->{ua}->get("http://asg.to/new-movie?page=$page");
92 0 0       0 return () unless $res->is_success;
93              
94 0         0 $self->_extract_videos( $res->decoded_content );
95             }
96              
97             sub _extract_videos {
98 2     2   20 my ( $self, $html ) = @_;
99              
100 2         134 my $tree = HTML::TreeBuilder::XPath->new;
101 2         1371 $tree->parse($html);
102              
103 2         492326 my $video_nodes = $tree->findnodes('//div[@id="list"]/div');
104              
105 2         299140 my @videos = ();
106 2         9 foreach my $node (@$video_nodes) {
107 22         86 my $video = $self->_extract_video($node);
108 22 100 66     161 next if not $video or not %$video;
109 20         64 push @videos, $video;
110             }
111              
112 2         2142 @videos;
113             }
114              
115             sub _extract_video {
116 22     22   49 my ( $self, $node ) = @_;
117 22         54 my $video = {};
118              
119 22         85 my $link_node = $node->findnodes('h3/a')->[0];
120 22 100       12754 return undef unless $link_node;
121              
122             # url
123 20         77 my $url = $link_node->findvalue('@href');
124             return undef
125 20 50       5678 unless $url =~ /(http:\/\/asg\.to)?\/contentsPage\.html\?mcd=([^?&]+)/;
126 20         85 $video->{url} = "http://asg.to$url";
127              
128             # mcd
129 20         65 $video->{mcd} = $2;
130              
131             # title
132 20         70 my $title = $link_node->findvalue('@title');
133 20 50       5291 $title = $1 if $title =~ /.+アダルト動画:(.+)/;
134 20         76 $video->{title} = $self->_trim($title);
135              
136 20         76 my $list_info_nodes = $node->findnodes('div[@class="list-info"]/p');
137              
138             # description
139 20         58687 my $description = $list_info_nodes->[3]->findvalue('.');
140 20 100       5177 $description = $1 if $description =~ /.*紹介文:\s*(.+)/;
141 20         138 $video->{description} = $self->_trim($description);
142              
143             # thumbnail
144 20         152 $video->{thumbnail} = $node->findvalue('a/img[@class="shift-left"]/@src');
145              
146             # date
147 20         28794 my $date = $list_info_nodes->[0]->findvalue('.');
148 20         4096 $video->{date} = $self->_date($date);
149              
150             # ccd
151 20         741 my $ccd_node = $list_info_nodes->[1]->findnodes('a')->[0];
152 20         7965 my $ccd = $ccd_node->findvalue('@href');
153 20 50       9062 if ( $ccd =~ /(http:\/\/asg\.to)?\/categoryPage\.html\?ccd=([^?&]+)/ ) {
154 20         291 $video->{ccd} = $2;
155             }
156 20         72 $video->{ccd_text} = $self->_trim( $ccd_node->findvalue('.') );
157              
158             # play time
159 20         150 my $play_time = $list_info_nodes->[2]->findvalue('.');
160 20 100       3977 if ( $play_time =~ /.*\s([0-9]{1,3}:[0-9]{1,2}).*/ ) {
161 19         43 my $play_time_text = $1;
162 19         103 my @splited = split ':', $play_time_text;
163 19         74 my $play_time_sec = int( $splited[0] ) * 60 + int( $splited[1] );
164 19         44 $video->{play_time} = $play_time_sec;
165 19         49 $video->{play_time_text} = $self->_trim($play_time_text);
166             }
167              
168             # embed code
169 20         148 $video->{embed} = sprintf( $embed_code_format, $video->{mcd} );
170              
171             ### $video
172 20         109 return $video;
173             }
174              
175             sub _date {
176 26     26   5322 my ( $self, $date_str ) = @_;
177 26         77 $self->_trim($date_str);
178              
179 26         46 my $dt = undef;
180 26 100       346 if ( $date_str =~ /.*([0-9]{2,4}\.[0-9]{2}\.[0-9]{2} [0-9]{2}:[0-9]{2}).*/ )
    50          
181             {
182 22         70 my $date = "20" . $1;
183 22         190 $dt = $strp->parse_datetime($date);
184             }
185             elsif ( $date_str =~
186             /.*([0-9]{4}\-[0-9]{2}\-[0-9]{2}T[0-9]{2}:[0-9]{2}(:[0-9]{2}Z)?).*/ )
187             {
188 4         12 my $date = $1;
189 4         38 $dt = DateTime::Format::ISO8601->new->parse_datetime($date);
190             }
191             else {
192 0         0 return undef;
193             }
194              
195 26         33796 return $dt->iso8601;
196             }
197              
198             sub _trim {
199 105     105   4430 my ( $self, $str ) = @_;
200 105 50       1346 $str =~ s/^[\s ]*(.*?)[\s ]*$/$1/ if $str;
201 105         367 return $str;
202             }
203              
204             =head1 AUTHOR
205              
206             Tatsuya Fukata C<< >>
207              
208             =head1 BUGS
209              
210             Please report any bugs or feature requests to C, or through
211             the web interface at L. I will be notified, and then you'll
212             automatically be notified of progress on your bug as I make changes.
213              
214             =head1 SUPPORT
215              
216             You can find documentation for this module with the perldoc command.
217              
218             perldoc WWW::Asg
219              
220             You can also look for information at:
221              
222             =over 4
223              
224             =item * RT: CPAN's request tracker (report bugs here)
225              
226             L
227              
228             =item * AnnoCPAN: Annotated CPAN documentation
229              
230             L
231              
232             =item * CPAN Ratings
233              
234             L
235              
236             =item * Search CPAN
237              
238             L
239              
240             =back
241              
242             =head1 LICENSE AND COPYRIGHT
243              
244             Copyright 2012 Tatsuya FUKATA.
245              
246             This program is free software; you can redistribute it and/or modify it
247             under the terms of either: the GNU General Public License as published
248             by the Free Software Foundation; or the Artistic License.
249              
250             See http://dev.perl.org/licenses/ for more information.
251              
252              
253             =cut
254              
255             1; # End of WWW::Asg