Skip to content

Commit 59cd77b

Browse files
committed
#12 - ACT scrapper
1 parent 5b0b5d6 commit 59cd77b

File tree

2 files changed

+119
-0
lines changed

2 files changed

+119
-0
lines changed

lib/X/ACT/Client.pm

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package X::ACT::Client;
2+
use Mojo::Base -base;
3+
use feature qw(signatures);
4+
no warnings qw(experimental::signatures);
5+
use Mojo::UserAgent;
6+
use Mojo::URL;
7+
8+
has ua => sub{ Mojo::UserAgent->new };
9+
has user => sub{ die 'user attribute is required' };
10+
has password => sub{ die 'password attribute is required' };
11+
has url_base => sub{ Mojo::URL->new('http://workshop.barcelona.pm') };
12+
has project => 'barcelona2016';
13+
14+
sub login($self, $cb=undef) {
15+
my @form = ( form => {
16+
credential_0 => $self->user,
17+
credential_1 => $self->password,
18+
destination => '/'. $self->project .'/main'
19+
});
20+
21+
if ($cb) {
22+
return $self->ua->post(
23+
$self->_url('LOGIN'), @form, sub{ my $tx = pop; $cb->(@_, $self->_login($tx)) }
24+
);
25+
}
26+
27+
$self->_login( $self->ua->post( $self->_url('LOGIN'), @form ) );
28+
}
29+
sub _login($self, $tx) {
30+
die 'Login has failed' unless $tx->res->code == 302;
31+
$self;
32+
}
33+
34+
sub userdata($self, $cb=undef) {
35+
if ($cb) {
36+
return $self->ua->get( $self->_url('change') => sub{
37+
my $tx = pop;
38+
$cb->(@_, _userdata($tx))
39+
});
40+
}
41+
42+
_userdata( $self->ua->get($self->_url('change')) );
43+
}
44+
sub _userdata($tx, $data={}) {
45+
if ( my $err = $tx->error ) {
46+
die "$err->{code} response: $err->{message}" if $err->{code};
47+
die "Connection error: $err->{message}";
48+
}
49+
50+
my $dom = $tx->res->dom;
51+
52+
my $selector = 'input[type="radio"][checked]'
53+
. ',input[type="email"]'
54+
. ',input[type="text"]';
55+
56+
$dom->find($selector)->each(sub{
57+
$data->{$_->attr('name')} = $_->attr('value');
58+
});
59+
$dom->find('textarea')->each(sub{
60+
$data->{$_->attr('name')} = $_->text;
61+
});
62+
$dom->find('select')->each(sub{
63+
$data->{$_->attr('name')} = eval{$_->at('option[selected]')->attr('value')}||'';
64+
});
65+
66+
$data;
67+
}
68+
69+
sub _url($self, @path) {
70+
$self->url_base->clone->path( '/'. join('/', $self->project, @path) );
71+
}
72+
73+
1;

t/act-client.t

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use Test::More;
2+
3+
require_ok( 'X::ACT::Client' );
4+
5+
subtest 'User login and basic data retrieval (sync)' => sub {
6+
plan( skip_all => 'This tests need ACT credentials as ACT_USER and ACT_PASSWORD' )
7+
unless $ENV{ACT_USER} && $ENV{ACT_PASSWORD};
8+
9+
isa_ok(
10+
my $client = X::ACT::Client->new( user => $ENV{ACT_USER}, password => $ENV{ACT_PASSWORD} ),
11+
'X::ACT::Client' => 'Create an act client instance'
12+
);
13+
14+
ok( $client->login, 'Client can login' );
15+
ok( my $ud = $client->userdata, '... and get userdata()' );
16+
ok( $ud->{$_}, "'$_' was retrieved" ) for qw/ email nick_name first_name last_name /;
17+
for (qw/ tshirt_size web_page pm_group pause_id bio_en company vat address company_url town country gpg_key_id im monk_id nb_family /) {
18+
diag( "$ENV{ACT_USER} has '$_'" ) if $ud->{$_};
19+
}
20+
};
21+
22+
subtest 'User login and basic data retrieval (async)' => sub {
23+
plan( skip_all => 'This tests need ACT credentials as ACT_USER and ACT_PASSWORD' )
24+
unless $ENV{ACT_USER} && $ENV{ACT_PASSWORD};
25+
26+
isa_ok(
27+
my $client = X::ACT::Client->new( user => $ENV{ACT_USER}, password => $ENV{ACT_PASSWORD} ),
28+
'X::ACT::Client' => 'Create an act client instance'
29+
);
30+
31+
Mojo::IOLoop->delay(
32+
sub { $client->login( shift->begin ) },
33+
sub {
34+
my ( $delay, $client ) = @_;
35+
isa_ok( $client, 'X::ACT::Client', 'Async login() send client to the cb' );
36+
$client->userdata( $delay->begin );
37+
},
38+
sub {
39+
my $ud = pop;
40+
isa_ok( $ud, 'HASH', 'Async userdata() send results to the cb' );
41+
ok( $ud->{$_}, "'$_' was retrieved" ) for qw/ email nick_name first_name last_name /;
42+
}
43+
)->catch(sub{ fail(pop) })->wait;
44+
};
45+
46+
done_testing();

0 commit comments

Comments
 (0)