File Coverage

blib/lib/WWW/Google/Contacts.pm
Criterion Covered Total %
statement 30 132 22.7
branch 2 18 11.1
condition 2 6 33.3
subroutine 10 28 35.7
pod 17 17 100.0
total 61 201 30.3


line stmt bran cond sub pod time code
1             package WWW::Google::Contacts;
2             {
3             $WWW::Google::Contacts::VERSION = '0.39';
4             }
5              
6             # ABSTRACT: Google Contacts Data API
7              
8 17     17   179768 use Moose;
  17         8463365  
  17         119  
9              
10 17     17   125196 use Carp qw/croak/;
  17         42  
  17         1159  
11              
12 17     17   14538 use WWW::Google::Contacts::Server;
  17         72  
  17         870  
13 17     17   16160 use WWW::Google::Contacts::Contact;
  17         79  
  17         1006  
14 17     17   14182 use WWW::Google::Contacts::ContactList;
  17         76  
  17         755  
15 17     17   14412 use WWW::Google::Contacts::Group;
  17         71  
  17         813  
16 17     17   14052 use WWW::Google::Contacts::GroupList;
  17         99  
  17         30811  
17              
18             has username => (
19             isa => 'Str',
20             is => 'rw',
21             default => sub { $ENV{GOOGLE_USERNAME} },
22             );
23              
24             has password => (
25             isa => 'Str',
26             is => 'rw',
27             default => sub { $ENV{GOOGLE_PASSWORD} },
28             );
29              
30             has protocol => (
31             isa => 'Str',
32             is => 'ro',
33             default => 'http',
34             );
35              
36             has server => (
37             isa => 'Object',
38             is => 'ro',
39             lazy_build => 1,
40             );
41              
42             # backward compability
43             has email =>
44             ( isa => 'Str', is => 'rw', trigger => sub { $_[0]->username( $_[1] ) } );
45             has pass =>
46             ( isa => 'Str', is => 'rw', trigger => sub { $_[0]->password( $_[1] ) } );
47              
48             sub _build_server {
49 2     2   5 my $self = shift;
50 2         81 return WWW::Google::Contacts::Server->new(
51             {
52             username => $self->username,
53             password => $self->password,
54             protocol => $self->protocol
55             }
56             );
57             }
58              
59             sub new_contact {
60 3     3 1 17 my $self = shift;
61             my $args =
62             ( scalar(@_) == 1 and ref( $_[0] ) eq 'HASH' )
63 3 100 66     99 ? { %{ $_[0] }, server => $self->server }
  1         41  
64             : { @_, server => $self->server };
65 3         136 return WWW::Google::Contacts::Contact->new($args);
66             }
67              
68             sub contact {
69 0     0 1   my ( $self, $id ) = @_;
70 0           return WWW::Google::Contacts::Contact->new( id => $id,
71             server => $self->server )->retrieve;
72             }
73              
74             sub contacts {
75 0     0 1   my $self = shift;
76              
77 0           my $list =
78             WWW::Google::Contacts::ContactList->new( server => $self->server );
79 0           return $list;
80             }
81              
82             sub new_group {
83 0     0 1   my $self = shift;
84             my $args =
85             ( scalar(@_) == 1 and ref( $_[0] ) eq 'HASH' )
86 0 0 0       ? { %{ $_[0] }, server => $self->server }
  0            
87             : { @_, server => $self->server };
88 0           return WWW::Google::Contacts::Group->new($args);
89             }
90              
91             sub group {
92 0     0 1   my ( $self, $id ) = @_;
93 0           return WWW::Google::Contacts::Group->new( id => $id,
94             server => $self->server )->retrieve;
95             }
96              
97             sub groups {
98 0     0 1   my $self = shift;
99              
100 0           my $list = WWW::Google::Contacts::GroupList->new( server => $self->server );
101 0           return $list;
102             }
103              
104             # All code below is for backwards compability
105              
106             sub login {
107 0     0 1   my ( $self, $email, $pass ) = @_;
108 0           warn "This method is deprecated and will be removed shortly";
109 0           $self->email($email);
110 0           $self->pass($pass);
111 0           my $server = WWW::Google::Contacts::Server->new(
112             { username => $self->email, password => $self->password } );
113 0           $server->authenticate;
114 0           return 1;
115             }
116              
117             sub create_contact {
118 0     0 1   my $self = shift;
119 0           warn "This method is deprecated and will be removed shortly";
120 0 0         my $data = scalar @_ % 2 ? shift : {@_};
121              
122 0           my $contact = $self->new_contact;
123 0           return $self->_create_or_update_contact( $contact, $data );
124             }
125              
126             sub _create_or_update_contact {
127 0     0     my ( $self, $contact, $data ) = @_;
128              
129 0           $contact->given_name( $data->{givenName} );
130 0           $contact->family_name( $data->{familyName} );
131 0           $contact->notes( $data->{Notes} );
132             $contact->email(
133             {
134             type => "work",
135             primary => 1,
136             value => $data->{primaryMail},
137             display_name => $data->{displayName},
138             }
139 0           );
140 0 0         if ( $contact->{secondaryMail} ) {
141             $contact->add_email(
142             {
143             type => "home",
144             value => $data->{secondaryMail},
145             }
146 0           );
147             }
148              
149             # if ( $contact->{groupMembershipInfo} ) {
150             # $data->{'atom:entry'}->{'gContact:groupMembershipInfo'} = {
151             # deleted => 'false',
152             # href => $contact->{groupMembershipInfo}
153             # };
154             # }
155 0 0         if ( $contact->create_or_update ) {
156 0           return 1;
157             }
158 0           return 0;
159             }
160              
161             sub get_contacts {
162 0     0 1   my $self = shift;
163              
164 0           warn "This method is deprecated and will be removed shortly";
165 0           my $list = $self->contacts;
166 0           my @contacts;
167 0           foreach my $c ( @{ $list->elements } ) {
  0            
168 0           my $d = $c;
169             ( $d->{id} ) =
170 0           map { $_->{href} }
171 0           grep { $_->{rel} eq 'self' } @{ $d->{link} };
  0            
  0            
172 0           $d->{name} = $d->{'gd:name'};
173 0           $d->{email} = $d->{'gd:email'};
174 0           $d->{groupMembershipInfo} = $d->{'gContact:groupMembershipInfo'};
175 0           push @contacts, $d;
176             }
177 0           return @contacts;
178             }
179              
180             sub get_contact {
181 0     0 1   my ( $self, $id ) = @_;
182              
183 0           warn "This method is deprecated and will be removed shortly";
184 0           my $contact = $self->new_contact( id => $id )->retrieve;
185 0           my $data = $contact->raw_data_for_backwards_compability;
186 0           $data->{name} = $data->{'gd:name'};
187 0           $data->{email} = $data->{'gd:email'};
188 0           $data->{groupMembershipInfo} = $data->{'gContact:groupMembershipInfo'};
189 0           return $data;
190             }
191              
192             sub update_contact {
193 0     0 1   my ( $self, $id, $contact ) = @_;
194              
195 0           warn "This method is deprecated and will be removed shortly";
196 0           my $c = $self->new_contact( id => $id )->retrieve;
197 0           return $self->_create_or_update_contact( $c, $contact );
198             }
199              
200             sub delete_contact {
201 0     0 1   my ( $self, $id ) = @_;
202              
203 0           warn "This method is deprecated and will be removed shortly";
204 0           $self->new_contact( id => $id )->delete;
205             }
206              
207             sub get_groups {
208 0     0 1   my $self = shift;
209              
210 0           warn "This method is deprecated and will be removed shortly";
211 0           my $list = $self->groups;
212 0           my @groups;
213 0           foreach my $d ( @{ $list->elements } ) {
  0            
214 0 0         my $link = ref( $d->{link} ) eq 'ARRAY' ? $d->{link} : [ $d->{link} ];
215             ( $d->{id} ) =
216 0           map { $_->{href} }
217 0           grep { $_->{rel} eq 'self' } @{$link};
  0            
  0            
218             push @groups,
219             {
220             id => $d->{id},
221             title => $d->{title},
222             updated => $d->{updated},
223             exists $d->{'gContact:systemGroup'}
224 0 0         ? ( 'gContact:systemGroup' => $d->{'gContact:systemGroup'}->{'id'} )
225             : (),
226             };
227             }
228 0           return @groups;
229             }
230              
231             sub get_group {
232 0     0 1   my ( $self, $id ) = @_;
233              
234 0           warn "This method is deprecated and will be removed shortly";
235 0           my $group = $self->new_group( id => $id )->retrieve;
236 0           my $data = $group->raw_data_for_backwards_compability;
237 0           return $data;
238             }
239              
240             sub _create_or_update_group {
241 0     0     my ( $self, $group, $data ) = @_;
242              
243 0           $group->title( $data->{title} );
244 0 0         if ( $group->create_or_update ) {
245 0           return 1;
246             }
247 0           return 0;
248             }
249              
250             sub create_group {
251 0     0 1   my $self = shift;
252 0 0         my $data = scalar @_ % 2 ? shift : {@_};
253              
254 0           warn "This method is deprecated and will be removed shortly";
255 0           my $group = $self->new_group;
256 0           return $self->_create_or_update_group( $group, $data );
257             }
258              
259             sub update_group {
260 0     0 1   my ( $self, $id, $args ) = @_;
261              
262 0           warn "This method is deprecated and will be removed shortly";
263 0           my $g = $self->new_group( id => $id )->retrieve;
264 0           return $self->_create_or_update_group( $g, $args );
265             }
266              
267             sub delete_group {
268 0     0 1   my ( $self, $id ) = @_;
269              
270 0           warn "This method is deprecated and will be removed shortly";
271 0           $self->new_group( id => $id )->delete;
272             }
273              
274 17     17   185 no Moose;
  17         80  
  17         142  
275             __PACKAGE__->meta->make_immutable;
276             1;
277             __END__
278              
279             =head1 NAME
280              
281             WWW::Google::Contacts - Google Contacts Data API
282              
283             =head1 CURRENTLY NOT WORKING
284              
285             This module is currently not working. Some time back, Google obsoleted the authentication method
286             used by this module.
287              
288             Patches for updating how authentication is handled are more than welcome!
289              
290             =head1 SYNOPSIS
291              
292             use WWW::Google::Contacts;
293              
294             my $google = WWW::Google::Contacts->new(
295             username => "your.username",
296             password => "your.password",
297             protocol => "https",
298             );
299              
300             # Create a new contact
301             my $contact = $google->new_contact;
302             $contact->full_name("Emmett Brown");
303             $contact->name_prefix("Dr");
304             $contact->email('doctor@timetravel.org');
305             $contact->hobby("Time travel");
306             $contact->jot([ "Went back in time", "Went forward in time", "Became blacksmith" ]),
307             $contact->create; # save it to the server
308              
309             # Now search for the given name, and read the jots
310             my @contacts = $google->contacts->search({ given_name => "Emmett" });
311             foreach my $c ( @contacts ) {
312             print "Got the following jots about the good doctor\n";
313             foreach my $jot ( @{ $c->jot } ) {
314             print "Jot: " . $jot->value . "\n";
315             }
316             print "And now he goes back to the future\n";
317             $c->delete;
318             }
319              
320             # Print the names of all groups
321             my $groups = $google->groups;
322             while ( my $group = $groups->next ) {
323             print "Title = " . $group->title . "\n";
324             }
325              
326             # Add the contact to existing group 'Movie stars' and to a new group 'Back to the future'
327             my $new_group = $google->new_group({ title => "Back to the future" });
328             $new_group->create; # create on server
329              
330             my @groups = $google->groups->search({ title => "Movie stars" });
331             my $movie_stars_group = shift @groups;
332              
333             $contact->add_group_membership( $new_group );
334             $contact->add_group_membership( $movie_stars_group );
335             $contact->update;
336              
337              
338             =head1 DESCRIPTION
339              
340             This module implements 'Google Contacts Data API' according L<http://code.google.com/apis/contacts/docs/3.0/developers_guide_protocol.html>
341              
342             B<NOTE> This new interface is still quite untested. Please report any bugs.
343              
344             =head1 CONSTRUCTOR
345              
346             =head2 new( username => .., password => .. , protocol => ..)
347              
348             I<username> and I<password> are required arguments and must be valid Google credentials. If you do not have a Google account
349             you can create one at L<https://www.google.com/accounts/NewAccount>.
350              
351             I<protocol> defaults to B<http>, but can optionally be set to B<https>.
352              
353             =head1 METHODS
354              
355             =head2 $google->new_contact
356              
357             Returns a new empty L<WWW::Google::Contacts::Contact> object.
358              
359             =head2 $google->contact( $id )
360              
361             Given a valid contact ID, returns a L<WWW::Google::Contacts::Contact> object populated with contact data from Google.
362              
363             =head2 $google->contacts
364              
365             Returns a L<WWW::Google::Contacts::ContactList> object which can be used to iterate over all your contacts.
366              
367             =head2 $google->new_group
368              
369             Returns a new L<WWW::Google::Contacts::Group> object.
370              
371             =head2 $google->group( $id )
372              
373             Given a valid group ID, returns a L<WWW::Google::Contacts::Group> object populated with group data from Google.
374              
375             =head2 $google->groups
376              
377             Returns a L<WWW::Google::Contacts::GroupList> object which can be used to iterate over all your groups.
378              
379             =head1 DEPRECATED METHODS
380              
381             The old module interface is still available, but its use is discouraged. It will eventually be removed from the module.
382              
383             =over 4
384              
385             =item * new/login
386              
387             my $gcontacts = WWW::Google::Contacts->new();
388             $gcontacts->login('fayland@gmail.com', 'pass') or die 'login failed';
389              
390             =item * create_contact
391              
392             $gcontacts->create_contact( {
393             givenName => 'FayTestG',
394             familyName => 'FayTestF',
395             fullName => 'Fayland Lam',
396             Notes => 'just a note',
397             primaryMail => 'primary@example.com',
398             displayName => 'FayTest Dis',
399             secondaryMail => 'secndary@test.com', # optional
400             } );
401              
402             return 1 if created
403              
404             =item * get_contacts
405              
406             my @contacts = $gcontacts->get_contacts;
407             my @contacts = $gcontacts->get_contacts( {
408             group => 'thin', # default to 'full'
409             } )
410             my @contacts = $gcontacts->get_contacts( {
411             updated-min => '2007-03-16T00:00:00',
412             start-index => 10,
413             max-results => 99, # default as 9999
414             } );
415              
416             get contacts from this account.
417              
418             C<group> refers L<http://code.google.com/apis/contacts/docs/2.0/reference.html#Projections>
419              
420             C<start-index>, C<max_results> etc refer L<http://code.google.com/apis/contacts/docs/2.0/reference.html#Parameters>
421              
422             =item * get_contact($id)
423              
424             my $contact = $gcontacts->get_contact('http://www.google.com/m8/feeds/contacts/account%40gmail.com/base/1');
425              
426             get a contact by B<id>
427              
428             =item * update_contact
429              
430             my $status = $gcontacts->update_contact('http://www.google.com/m8/feeds/contacts/account%40gmail.com/base/123623e48cb4e70a', {
431             givenName => 'FayTestG2',
432             familyName => 'FayTestF2',
433             fullName => 'Fayland Lam2',
434             Notes => 'just a note2',
435             primaryMail => 'primary@example2.com',
436             displayName => 'FayTest2 Dis',
437             secondaryMail => 'secndary@test62.com', # optional
438             } );
439              
440             update a contact
441              
442             =item * delete_contact($id)
443              
444             my $status = $gcontacts->delete_contact('http://www.google.com/m8/feeds/contacts/account%40gmail.com/base/1');
445              
446             The B<id> is from C<get_contacts>.
447              
448             =item * create_group
449              
450             my $status = $gcontacts->create_group( { title => 'Test Group' } );
451              
452             Create a new group
453              
454             =item * get_groups
455              
456             my @groups = $gcontacts->get_groups;
457             my @groups = $gcontacts->get_groups( {
458             updated-min => '2007-03-16T00:00:00',
459             start-index => 10,
460             max-results => 99, # default as 9999
461             } );
462              
463             Get all groups.
464              
465             =item * get_group($id)
466              
467             my $group = $gcontacts->get_group('http://www.google.com/m8/feeds/groups/account%40gmail.com/base/6e744e7d0a4b398c');
468              
469             get a group by B<id>
470              
471             =item * update_group($id, { title => $title })
472              
473             my $status = $gcontacts->update_group( 'http://www.google.com/m8/feeds/groups/account%40gmail.com/base/6e744e7d0a4b398c', { title => 'New Test Group 66' } );
474              
475             Update a group
476              
477             =item * delete_group
478              
479             my $status = $gcontacts->delete_contact('http://www.google.com/m8/feeds/groups/account%40gmail.com/base/6e744e7d0a4b398c');
480              
481             =back
482              
483             =head1 SEE ALSO
484              
485             L<WWW::Google::Contacts::Contact>
486              
487             L<WWW::Google::Contacts::ContactList>
488              
489             L<WWW::Google::Contacts::Group>
490              
491             L<WWW::Google::Contacts::GroupList>
492              
493             L<http://code.google.com/apis/contacts/docs/3.0/developers_guide_protocol.html>
494              
495             =head1 ACKNOWLEDGEMENTS
496              
497             Fayland Lam - who wrote the first version of this module
498              
499             John Clyde - who shared his code about Contacts API with Fayland
500              
501             =head1 TODO
502              
503             =over 4
504              
505             =item More POD
506              
507             =item Unit tests. Very lame right now
508              
509             =item Images
510              
511             =item Fix bugs :)
512              
513             =back
514              
515             =head1 AUTHOR
516              
517             Magnus Erixzon <magnus@erixzon.com>
518              
519             =head1 COPYRIGHT AND LICENSE
520              
521             This software is copyright (c) 2010 by Magnus Erixzon.
522              
523             This is free software; you can redistribute it and/or modify it under
524             the same terms as perl itself.
525              
526             =cut