| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package WWW::Google::Contacts::Roles::List; | 
| 2 |  |  |  |  |  |  | { | 
| 3 |  |  |  |  |  |  | $WWW::Google::Contacts::Roles::List::VERSION = '0.39'; | 
| 4 |  |  |  |  |  |  | } | 
| 5 |  |  |  |  |  |  |  | 
| 6 | 17 |  |  | 17 |  | 14402 | use Moose::Role; | 
|  | 17 |  |  |  |  | 43 |  | 
|  | 17 |  |  |  |  | 184 |  | 
| 7 | 17 |  |  | 17 |  | 97179 | use MooseX::Types::Moose qw( ArrayRef Int ); | 
|  | 17 |  |  |  |  | 43 |  | 
|  | 17 |  |  |  |  | 274 |  | 
| 8 | 17 |  |  | 17 |  | 97149 | use Carp qw( croak ); | 
|  | 17 |  |  |  |  | 66 |  | 
|  | 17 |  |  |  |  | 1127 |  | 
| 9 | 17 |  |  | 17 |  | 106 | use URI::Escape; | 
|  | 17 |  |  |  |  | 43 |  | 
|  | 17 |  |  |  |  | 1170 |  | 
| 10 | 17 |  |  | 17 |  | 111 | use Perl6::Junction qw( any ); | 
|  | 17 |  |  |  |  | 43 |  | 
|  | 17 |  |  |  |  | 857 |  | 
| 11 | 17 |  |  | 17 |  | 108 | use WWW::Google::Contacts::Data; | 
|  | 17 |  |  |  |  | 40 |  | 
|  | 17 |  |  |  |  | 15904 |  | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | requires 'baseurl', 'element_class'; | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | has elements => ( | 
| 16 |  |  |  |  |  |  | isa        => ArrayRef, | 
| 17 |  |  |  |  |  |  | is         => 'rw', | 
| 18 |  |  |  |  |  |  | lazy_build => 1, | 
| 19 |  |  |  |  |  |  | ); | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | has server => ( | 
| 22 |  |  |  |  |  |  | is       => 'ro', | 
| 23 |  |  |  |  |  |  | required => 1, | 
| 24 |  |  |  |  |  |  | ); | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | has pointer => ( | 
| 27 |  |  |  |  |  |  | isa      => Int, | 
| 28 |  |  |  |  |  |  | is       => 'rw', | 
| 29 |  |  |  |  |  |  | default  => 0, | 
| 30 |  |  |  |  |  |  | init_arg => undef, | 
| 31 |  |  |  |  |  |  | ); | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | sub search { | 
| 34 | 0 |  |  | 0 | 0 |  | my ( $self, $search ) = @_; | 
| 35 |  |  |  |  |  |  |  | 
| 36 | 0 |  |  |  |  |  | my $class = $self->element_class; | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  | # TODO - make something clever to match XML keys without having to bless all the objects for comparison | 
| 39 |  |  |  |  |  |  | # this could be a start; | 
| 40 |  |  |  |  |  |  | # | 
| 41 |  |  |  |  |  |  | #my $element = $class->new( server => $self->server ); | 
| 42 |  |  |  |  |  |  | #my $search_params = []; | 
| 43 |  |  |  |  |  |  | #foreach my $key ( keys %{ $search } ) { | 
| 44 |  |  |  |  |  |  | #    my $xml_key = $element->get_xml_key( $key ); | 
| 45 |  |  |  |  |  |  | #    if ( $xml_key ) { | 
| 46 |  |  |  |  |  |  | #        push @{ $search_params }, | 
| 47 |  |  |  |  |  |  | #            { | 
| 48 |  |  |  |  |  |  | #                xml_key => $xml_key, | 
| 49 |  |  |  |  |  |  | #                value   => $search->{ $key }, | 
| 50 |  |  |  |  |  |  | #            }; | 
| 51 |  |  |  |  |  |  | #    } | 
| 52 |  |  |  |  |  |  | #    else { | 
| 53 |  |  |  |  |  |  | #        croak "Can't find XML key for [$key]"; | 
| 54 |  |  |  |  |  |  | #    } | 
| 55 |  |  |  |  |  |  | #} | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | # This doesn't scale well.... SLOW | 
| 58 | 0 |  |  |  |  |  | my $to_ret = []; | 
| 59 |  |  |  |  |  |  | ELEM: | 
| 60 | 0 |  |  |  |  |  | foreach my $elem ( @{ $self->elements } ) { | 
|  | 0 |  |  |  |  |  |  | 
| 61 | 0 |  |  |  |  |  | my $obj = $class->new( server => $self->server ); | 
| 62 | 0 |  |  |  |  |  | $obj->set_from_server($elem); | 
| 63 | 0 |  |  |  |  |  | foreach my $key ( keys %{$search} ) { | 
|  | 0 |  |  |  |  |  |  | 
| 64 | 0 | 0 |  |  |  |  | next ELEM unless ( defined $obj->$key ); | 
| 65 | 0 | 0 | 0 |  |  |  | if ( ref( $obj->$key ) and ref( $obj->$key ) eq 'ARRAY' ) { | 
| 66 | 0 |  |  |  |  |  | my $search_field = $obj->$key->[0]->search_field; | 
| 67 | 0 | 0 |  |  |  |  | next ELEM unless ( defined $search_field ); | 
| 68 | 0 |  |  |  |  |  | my @values = map { $_->$search_field } @{ $obj->$key }; | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 69 | 0 |  |  |  |  |  | my $search_key = $search->{$key}; | 
| 70 |  |  |  |  |  |  |  | 
| 71 |  |  |  |  |  |  | # protocol might not match, that doesn't matter | 
| 72 | 0 | 0 |  |  |  |  | if ( $search_key =~ s{^http.?:}{} ) { | 
| 73 | 0 |  |  |  |  |  | $_ =~ s{^http.?:}{} foreach (@values); | 
| 74 |  |  |  |  |  |  | } | 
| 75 | 0 | 0 |  |  |  |  | next ELEM unless ( any(@values) eq $search_key ); | 
| 76 |  |  |  |  |  |  | } | 
| 77 |  |  |  |  |  |  | else { | 
| 78 | 0 |  |  |  |  |  | my $search_key = $search->{$key}; | 
| 79 | 0 |  |  |  |  |  | my $obj_key    = $obj->$key; | 
| 80 |  |  |  |  |  |  |  | 
| 81 |  |  |  |  |  |  | # protocol might not match, that doesn't matter | 
| 82 | 0 | 0 |  |  |  |  | if ( $search_key =~ s{^http.?:}{} ) { | 
| 83 | 0 |  |  |  |  |  | $obj_key =~ s{^http.?:}{}; | 
| 84 |  |  |  |  |  |  | } | 
| 85 | 0 | 0 |  |  |  |  | next ELEM unless ( $obj_key eq $search_key ); | 
| 86 |  |  |  |  |  |  | } | 
| 87 |  |  |  |  |  |  | } | 
| 88 | 0 |  |  |  |  |  | push @{$to_ret}, $obj; | 
|  | 0 |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | } | 
| 90 | 0 | 0 |  |  |  |  | return wantarray ? @{$to_ret} : $to_ret; | 
|  | 0 |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | } | 
| 92 |  |  |  |  |  |  |  | 
| 93 |  |  |  |  |  |  | sub next { | 
| 94 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 95 | 0 | 0 |  |  |  |  | return undef unless ( $self->elements->[ $self->pointer ] ); | 
| 96 | 0 |  |  |  |  |  | my $next = $self->elements->[ $self->pointer ]; | 
| 97 | 0 |  |  |  |  |  | $self->pointer( $self->pointer + 1 ); | 
| 98 | 0 |  |  |  |  |  | my $class = $self->element_class; | 
| 99 | 0 |  |  |  |  |  | return $class->new( server => $self->server )->set_from_server($next); | 
| 100 |  |  |  |  |  |  | } | 
| 101 |  |  |  |  |  |  |  | 
| 102 |  |  |  |  |  |  | sub _build_elements { | 
| 103 | 0 |  |  | 0 |  |  | my $self = shift; | 
| 104 |  |  |  |  |  |  |  | 
| 105 | 0 |  |  |  |  |  | my $args = {}; | 
| 106 | 0 |  |  |  |  |  | $args->{'alt'} = 'atom';    # must be atom | 
| 107 | 0 |  | 0 |  |  |  | $args->{'max-results'} ||= 9999; | 
| 108 | 0 |  | 0 |  |  |  | my $group = delete $args->{group} || 'full'; | 
| 109 | 0 |  |  |  |  |  | my $url = sprintf( '%s/%s?v=3.0', $self->baseurl, uri_escape($group) ); | 
| 110 | 0 |  |  |  |  |  | foreach my $key ( keys %$args ) { | 
| 111 | 0 |  |  |  |  |  | $url .= '&' . uri_escape($key) . '=' . uri_escape( $args->{$key} ); | 
| 112 |  |  |  |  |  |  | } | 
| 113 | 0 |  |  |  |  |  | my $res     = $self->server->get($url); | 
| 114 | 0 |  |  |  |  |  | my $content = $res->content; | 
| 115 | 0 |  |  |  |  |  | my $data    = WWW::Google::Contacts::Data->decode_xml($content); | 
| 116 | 0 |  | 0 |  |  |  | my $array   = $data->{entry} || []; | 
| 117 |  |  |  |  |  |  |  | 
| 118 | 0 | 0 |  |  |  |  | if ( ref($array) eq 'HASH' ) { | 
| 119 | 0 |  |  |  |  |  | $array = [$array]; | 
| 120 |  |  |  |  |  |  | } | 
| 121 |  |  |  |  |  |  |  | 
| 122 |  |  |  |  |  |  | # ..lots of overhead to bless them all now. | 
| 123 |  |  |  |  |  |  | #my $class = $self->element_class; | 
| 124 |  |  |  |  |  |  | #$array = [ map { $class->new( server => $self->server )->set_from_server( $_ ) } @{ $array } ]; | 
| 125 | 0 |  |  |  |  |  | return $array; | 
| 126 |  |  |  |  |  |  | } | 
| 127 |  |  |  |  |  |  |  | 
| 128 |  |  |  |  |  |  | 1; |