File Coverage

blib/lib/WWW/HatenaLogin.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package WWW::HatenaLogin;
2              
3 1     1   6 use strict;
  1         2  
  1         42  
4 1     1   5 use warnings;
  1         2  
  1         44  
5              
6 1     1   5 use Carp;
  1         2  
  1         102  
7 1     1   1219 use URI;
  1         10192  
  1         34  
8 1     1   491 use WWW::Mechanize;
  0            
  0            
9              
10             our $VERSION = '0.03';
11              
12             my $login_uri = 'https://www.hatena.ne.jp/login';
13             my $logout_uri = 'https://www.hatena.ne.jp/logout';
14              
15             sub new {
16             my($class, $args) = @_;
17             croak sprintf 'usage: %s->new(hash ref)', __PACKAGE__ unless $args && ref($args) eq 'HASH';
18              
19             my $self = bless {
20             cookie_domain => '.hatena.ne.jp',
21             session_key => 'rk',
22             uri => {
23             login => URI->new($login_uri),
24             logout => URI->new($logout_uri),
25             },
26             login_form => {
27             username => 'name',
28             password => 'password',
29             },
30             }, $class;
31             $self->{$_} = delete $args->{$_} || '' for qw( username password mech );
32              
33             my $opt = delete $args->{mech_opt};
34             $self->{mech} ||= WWW::Mechanize->new(
35             $opt && ref $opt ? %{ $opt } : ()
36             );
37              
38             if (delete $args->{labo}) {
39             $self->{uri}->{login}->host('www.hatelabo.jp');
40             $self->{uri}->{logout}->host('www.hatelabo.jp');
41             $self->{login_form}->{username} = 'key';
42             $self->{cookie_domain} = '.hatelabo.jp';
43             $self->{logout_check} = sub { shift->{mech}->content !~ m!https://www.hatelabo.jp/login! };
44             }
45             if (delete $args->{com}) {
46             $self->{uri}->{login}->host('www.hatena.com');
47             $self->{uri}->{logout}->host('www.hatena.com');
48             $self->{cookie_domain} = '.hatena.com';
49             }
50              
51             my $nologin = delete $args->{nologin};
52              
53             $self->login unless $nologin || $self->is_loggedin;
54             $self;
55             }
56              
57             sub has_metalink {
58             my $self = shift;
59             my $link;
60             ($link) = map { $_->url } $self->{mech}->find_link(tag => 'meta');
61             !!$link;
62             }
63              
64             sub is_loggedin {
65             my $self = shift;
66             $self->{mech}->get($self->login_uri);
67             $self->has_metalink;
68             }
69              
70             sub login_uri { shift->{uri}->{login} }
71              
72             sub logout_uri { shift->{uri}->{logout} }
73              
74             sub username {
75             my $self = shift;
76             $self->{username} = defined $_[0] ? $_[0] : $self->{username};
77             }
78              
79             sub login {
80             my($self, $args) = @_;
81              
82             if ($args) {
83             if ($args->{username}) {
84             $self->{username} = $args->{username};
85             }
86             if ($args->{password}) {
87             $self->{password} = $args->{password};
88             }
89             }
90              
91             $self->{mech}->get($self->login_uri);
92             $self->{mech}->submit_form(
93             fields => {
94             $self->{login_form}->{username} => $self->{username},
95             $self->{login_form}->{password} => $self->{password},
96             }
97             );
98              
99             !!($self->session_id) ||
100             croak 'Login failed. Please confirm your username/password';
101             }
102              
103             sub logout {
104             my $self = shift;
105             $self->{mech}->get($self->logout_uri);
106             $self->{logout_check} ? $self->{logout_check}->($self) : $self->has_metalink;
107             }
108              
109             sub mech { shift->{mech} }
110              
111             sub cookie_jar { shift->{mech}->cookie_jar }
112              
113             sub session_id {
114             my $self = shift;
115             my $rk;
116              
117             $self->cookie_jar->scan(sub {
118             my($version, $key, $val, $path, $domain, $port,
119             $path_spec, $secure, $expires, $discard, $hash) = @_;
120             return unless $key eq $self->{session_key} && $domain eq $self->{cookie_domain};
121             return if $expires && $expires < time;
122             $rk = $val;
123             });
124             $rk;
125             }
126              
127             1;
128             __END__