File Coverage

blib/lib/Net/Social/Service/Vox.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Net::Social::Service::Vox;
2              
3 1     1   689 use strict;
  1         2  
  1         32  
4 1     1   5 use base qw(Net::Social::Service);
  1         1  
  1         807  
5 1     1   984 use LWP::Simple;
  1         68552  
  1         10  
6 1     1   940 use XML::XPath;
  0            
  0            
7             use XML::XPath::XMLParser;
8             use IO::Scalar;
9             use Net::Social qw(:all);
10              
11             use vars qw($VERSION);
12              
13             $VERSION = "0.1";
14              
15             =head1 NAME
16              
17             Net::Social::Service::Vox - a Vox plugin for Net::Social
18              
19             =head1 PARAMS
20              
21             For reading C needs
22              
23             =over 4
24              
25             =item username
26              
27             Your Vox username
28              
29             =back
30              
31             =cut
32              
33             sub params {(
34             read => {
35             "username" => { required => 1,
36             description => "Your Vox UserName",
37             },
38             },
39             )}
40              
41             =head1 METHODS
42              
43             =head2 friends
44              
45             Returns your friends. It defines the keys C, C, C and C.
46              
47             =cut
48              
49              
50             sub friends {
51             my $self = shift;
52             return () unless $self->{_logged_in};
53             my $user = $self->{_details}->{username};
54             my %friends;
55             foreach my $reverse ((1, 0)) {
56             # fetch all the people
57             foreach my $friend ($self->_fetch_friends($user, $reverse)) {
58             my $id = $friend->{id};
59             # set up a
60             my $existing = $friends{$id} || { type => NONE };
61             # now merge
62             foreach my $key (keys %$friend) {
63             $existing->{$key} = $friend->{$key} unless defined $existing->{$key};
64             # paying special attention to 'type'
65             if ($key eq 'type') {
66             $existing->{type} |= $friend->{type};
67             }
68             }
69             $friends{$id} = $existing;
70             }
71              
72             }
73             return values %friends;
74             }
75              
76              
77             sub _fetch_friends {
78             my $self = shift;
79             my $user = shift;
80             my $reverse = shift;
81             my $base = "http://${user}.vox.com/profile/neighbors".(($reverse)?"/reverse":"");
82             my $page = 1;
83             my @friends;
84              
85             while (1) {
86             my $xml = get("$base/page/$page/");
87             last unless defined $xml;
88             $xml =~ s!
89             my @this;
90             my $xp = XML::XPath->new( ioref => IO::Scalar->new(\$xml) );
91             my $ns = eval { $xp->find('//div[@class="member pkg"]') };
92             last if $@;
93             for my $node ($ns->get_nodelist) {
94             my $id = $node->getAttribute('at:user-xid');
95             my $name = $node->getAttribute('at:screen-name');
96             next unless defined $id;
97             my ($link) = eval { $xp->find('*/p[@class="member-name"]/a', $node)->get_nodelist };
98             next if $@;
99             next unless defined $link;
100             my $domain = $link->getAttribute('href');
101             next unless $domain;
102             my ($user) = ($domain =~ m!http://([^.]+)\.vox\.com!);
103             next unless defined $user;
104             my $person = { id => $id, name => $name, username => $user };
105             $person->{type} = ($reverse)? FRIENDED_BY : FRIENDED;
106             push @this, $person;
107             }
108             if (@this) {
109             push @friends, @this;
110             } else {
111             last;
112             }
113             $page++;
114             }
115             return @friends;
116             }
117              
118              
119             =head1 AUTHOR
120              
121             Simon Wistow
122              
123             =head1 COPYRIGHT
124              
125             Copyright, 2007 - Simon Wistow
126              
127             Distributed under the same terms as Perl itself
128              
129             =cut
130              
131              
132             1;