File Coverage

blib/lib/WWW/Connpass/Agent.pm
Criterion Covered Total %
statement 21 51 41.1
branch 0 10 0.0
condition 0 5 0.0
subroutine 7 13 53.8
pod 2 4 50.0
total 30 83 36.1


line stmt bran cond sub pod time code
1             package WWW::Connpass::Agent;
2 1     1   6 use strict;
  1         3  
  1         26  
3 1     1   4 use warnings;
  1         1  
  1         23  
4              
5 1     1   5 use parent qw/WWW::Mechanize/;
  1         2  
  1         6  
6              
7 1     1   73883 use Time::HiRes qw/gettimeofday tv_interval/;
  1         1408  
  1         5  
8 1     1   155 use HTTP::Request;
  1         9  
  1         32  
9 1     1   6 use JSON 2;
  1         12  
  1         6  
10              
11 1     1   90 use constant DEBUG => $ENV{WWW_CONNPASS_DEBUG};
  1         2  
  1         422  
12              
13             my $_JSON = JSON->new->utf8;
14              
15             sub new {
16 0     0 1   my ($class, %args) = @_;
17 0   0       my $interval = delete $args{interval} || 1.0;
18 0           my $self = $class->SUPER::new(%args);
19 0           $self->{_interval} = $interval;
20 0           $self->{_last_req_at} = undef;
21 0 0         $self->agent($args{user_agent}) if exists $args{user_agent};
22 0           $self->add_header('Accept-Encoding' => 'identity') if DEBUG;
23 0           return $self;
24             }
25              
26             sub request {
27 0     0 1   my $self = shift;
28 0 0         if (my $last_req_at = $self->{_last_req_at}) {
29 0           my $sec = tv_interval($last_req_at);
30 0 0         Time::HiRes::sleep $self->{_interval} - $sec if $sec < $self->{_interval};
31             }
32 0           my $res = $self->SUPER::request(@_);
33 0           if (DEBUG) {
34             my $req = $res->request;
35             warn "============== DEBUG ==============";
36             warn $req->as_string;
37             warn $res->as_string;
38             warn "============== END ==============";
39             }
40 0           $self->{_last_req_at} = [gettimeofday];
41 0           return $res;
42             }
43              
44             sub extract_cookie {
45 0     0 0   my ($self, $expected_key) = @_;
46              
47 0           my $result;
48             $self->cookie_jar->scan(sub {
49 0     0     my ($key, $val) = @_[1..2];
50 0 0         return if defined $result;
51 0 0         return if $key ne $expected_key;
52 0           $result = $val;
53 0           });
54              
55 0           return $result;
56             }
57              
58             sub _csrf_token {
59 0     0     my $self = shift;
60 0   0       $self->{_csrf_token} ||= $self->extract_cookie('connpass-csrftoken');
61             }
62              
63             sub request_like_xhr {
64 0     0 0   my ($self, $method, $url, $param) = @_;
65 0           my $content = $_JSON->encode($param);
66              
67 0           my $req = HTTP::Request->new($method, $url, [
68             'Content-Type' => 'application/json',
69             'Content-Length' => length $content,
70             'Accept' => 'application/json,text/javascript',
71             'Accept-Language' => 'en-US',
72             'Origin' => 'https://connpass.com',
73             'X-CSRFToken' => $self->_csrf_token(),
74             'X-Requested-With' => 'XMLHttpRequest',
75             ], $content);
76 0           return $self->request($req);
77             }
78              
79             1;
80             __END__