blib/lib/Net/Google/Code/Issue/Comment.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 87 | 115 | 75.6 |
branch | 16 | 34 | 47.0 |
condition | 1 | 6 | 16.6 |
subroutine | 10 | 11 | 90.9 |
pod | 3 | 3 | 100.0 |
total | 117 | 169 | 69.2 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package Net::Google::Code::Issue::Comment; | ||||||
2 | 9 | 9 | 24561 | use Any::Moose; | |||
9 | 79104 | ||||||
9 | 78 | ||||||
3 | 9 | 9 | 16569 | use Net::Google::Code::Issue::Attachment; | |||
9 | 35 | ||||||
9 | 472 | ||||||
4 | 9 | 9 | 7690 | use Net::Google::Code::Issue::Util; | |||
9 | 42 | ||||||
9 | 346 | ||||||
5 | 9 | 9 | 1575 | use Net::Google::Code::DateTime; | |||
9 | 19 | ||||||
9 | 452 | ||||||
6 | with 'Net::Google::Code::Role::HTMLTree'; | ||||||
7 | extends 'Net::Google::Code::Issue::Base'; | ||||||
8 | with 'Net::Google::Code::Role::Authentication'; | ||||||
9 | 9 | 9 | 56 | use Params::Validate ':all'; | |||
9 | 17 | ||||||
9 | 2379 | ||||||
10 | |||||||
11 | 9 | 9 | 13038 | use XML::FeedPP; | |||
9 | 194339 | ||||||
9 | 13978 | ||||||
12 | |||||||
13 | |||||||
14 | has 'updates' => ( isa => 'HashRef', is => 'rw', default => sub { {} } ); | ||||||
15 | has 'author' => ( isa => 'Str', is => 'rw' ); | ||||||
16 | has 'content' => ( isa => 'Str', is => 'rw' ); | ||||||
17 | has 'sequence' => ( isa => 'Int', is => 'rw' ); | ||||||
18 | has 'date' => ( isa => 'DateTime', is => 'rw' ); | ||||||
19 | has 'attachments' => ( | ||||||
20 | isa => 'ArrayRef[Net::Google::Code::Issue::Attachment]', | ||||||
21 | is => 'rw', | ||||||
22 | default => sub { [] }, | ||||||
23 | ); | ||||||
24 | |||||||
25 | has 'issue_id' => ( | ||||||
26 | isa => 'Int', | ||||||
27 | is => 'rw', | ||||||
28 | ); | ||||||
29 | |||||||
30 | sub parse { | ||||||
31 | 8 | 8 | 1 | 14444 | my $self = shift; | ||
32 | 8 | 17 | my $element = shift; | ||||
33 | 8 | 43 | my $need_delete = not blessed $element; | ||||
34 | 8 | 50 | 38 | $element = $self->html_tree( html => $element ) unless blessed $element; | |||
35 | |||||||
36 | 8 | 37 | my $author = $element->look_down( class => 'author' ); | ||||
37 | 8 | 480 | my @a = $author->find_by_tag_name('a'); | ||||
38 | 8 | 330 | $self->sequence( $a[0]->content_array_ref->[0] ); | ||||
39 | 8 | 83 | $self->author( $a[1]->content_array_ref->[0] ); | ||||
40 | 8 | 69 | $self->date(Net::Google::Code::DateTime->new_from_string( $element->look_down( class => 'date' )->attr('title') )); | ||||
41 | 8 | 45 | my $content = $element->find_by_tag_name('pre')->as_text; | ||||
42 | 8 | 712 | $content =~ s/^\s+//; | ||||
43 | 8 | 57 | $content =~ s/\s+$//; | ||||
44 | 8 | 21 | $content =~ s/\r\n/\n/g; | ||||
45 | 8 | 100 | 52 | $self->content($content) | |||
46 | unless $content eq '(No comment was entered for this change.)'; | ||||||
47 | |||||||
48 | 8 | 29 | my $updates = $element->look_down( class => 'updates' ); | ||||
49 | 8 | 100 | 859 | if ($updates) { | |||
50 | 5 | 18 | my $box_inner = $element->look_down( class => 'box-inner' ); | ||||
51 | 5 | 657 | my $content = $box_inner->content_array_ref; | ||||
52 | 5 | 29 | while (@$content) { | ||||
53 | 5 | 10 | my $tag = shift @$content; | ||||
54 | 5 | 15 | my $value = shift @$content; | ||||
55 | 5 | 50 | 33 | 26 | if ( ref $value && $value->as_HTML =~ m! ! ) { |
||
56 | # this happens when there's no value for $tag | ||||||
57 | 0 | 0 | $value = ''; | ||||
58 | } | ||||||
59 | else { | ||||||
60 | 5 | 9 | shift @$content; # this is for the |
||||
61 | } | ||||||
62 | |||||||
63 | 5 | 28 | my $key = $tag->content_array_ref->[0]; | ||||
64 | 5 | 33 | $key =~ s/:$//; | ||||
65 | 5 | 15 | $value =~ s/^\s+//; | ||||
66 | 5 | 13 | $value =~ s/\s+$//; | ||||
67 | |||||||
68 | 5 | 100 | 12 | if ( $key eq 'Labels' ) { | |||
69 | |||||||
70 | # $value here is like "-Pri-2 -Area-Unknown Pri-3 Area-BrowserUI" | ||||||
71 | 1 | 4 | my @items = split /\s+/, $value; | ||||
72 | 1 | 3 | for my $value (@items) { | ||||
73 | 1 | 2 | push @{$self->updates->{labels}}, $value; | ||||
1 | 13 | ||||||
74 | } | ||||||
75 | } | ||||||
76 | else { | ||||||
77 | 4 | 30 | $self->updates->{ lc $key } = $value; | ||||
78 | } | ||||||
79 | } | ||||||
80 | |||||||
81 | } | ||||||
82 | |||||||
83 | 8 | 24 | my $att_tag = $element->look_down( class => 'attachments' ); | ||||
84 | 8 | 796 | my @attachments; | ||||
85 | |||||||
86 | 8 | 100 | 56 | @attachments = | |||
87 | Net::Google::Code::Issue::Attachment->parse_attachments($att_tag) | ||||||
88 | if $att_tag; | ||||||
89 | 8 | 52 | $self->attachments( \@attachments ); | ||||
90 | |||||||
91 | 8 | 50 | 31 | $self->delete if $need_delete; | |||
92 | 8 | 34 | return 1; | ||||
93 | } | ||||||
94 | |||||||
95 | sub parse_hybrid { | ||||||
96 | 0 | 0 | 1 | 0 | my $self = shift; | ||
97 | 0 | 0 | my $element = shift; | ||||
98 | 0 | 0 | my $need_delete = not blessed $element; | ||||
99 | 0 | 0 | 0 | $element = $self->html_tree( html => $element ) unless blessed $element; | |||
100 | 0 | 0 | my $updates = $element->look_down( class => 'updates' ); | ||||
101 | 0 | 0 | 0 | if ($updates) { | |||
102 | 0 | 0 | my $box_inner = $element->look_down( class => 'box-inner' ); | ||||
103 | 0 | 0 | my $content = $box_inner->content_array_ref; | ||||
104 | 0 | 0 | while (@$content) { | ||||
105 | 0 | 0 | my $tag = shift @$content; | ||||
106 | 0 | 0 | my $value = shift @$content; | ||||
107 | 0 | 0 | 0 | 0 | if ( ref $value && $value->as_HTML =~ m! ! ) { |
||
108 | # this happens when there's no value for $tag | ||||||
109 | 0 | 0 | $value = ''; | ||||
110 | } | ||||||
111 | else { | ||||||
112 | 0 | 0 | shift @$content; # this is for the |
||||
113 | } | ||||||
114 | |||||||
115 | 0 | 0 | my $key = $tag->content_array_ref->[0]; | ||||
116 | 0 | 0 | $key =~ s/:$//; | ||||
117 | 0 | 0 | $value =~ s/^\s+//; | ||||
118 | 0 | 0 | $value =~ s/\s+$//; | ||||
119 | |||||||
120 | 0 | 0 | 0 | if ( $key ne 'Labels' ) { | |||
121 | 0 | 0 | $self->updates->{ lc $key } = $value; | ||||
122 | } | ||||||
123 | } | ||||||
124 | } | ||||||
125 | |||||||
126 | 0 | 0 | my $att_tag = $element->look_down( class => 'attachments' ); | ||||
127 | 0 | 0 | my @attachments; | ||||
128 | |||||||
129 | 0 | 0 | 0 | @attachments = | |||
130 | Net::Google::Code::Issue::Attachment->parse_attachments($att_tag) | ||||||
131 | if $att_tag; | ||||||
132 | 0 | 0 | $self->attachments( \@attachments ); | ||||
133 | 0 | 0 | 0 | $element->delete if $need_delete; | |||
134 | 0 | 0 | return 1; | ||||
135 | } | ||||||
136 | |||||||
137 | sub _load_from_xml { | ||||||
138 | 9 | 9 | 12 | my $self = shift; | |||
139 | 9 | 50 | my $ref = | ||||
140 | Net::Google::Code::Issue::Util->translate_from_xml( shift, | ||||||
141 | type => 'comment' ); | ||||||
142 | |||||||
143 | 9 | 33 | for my $k ( keys %$ref ) { | ||||
144 | 86 | 100 | 296 | if ( $self->can($k) ) { | |||
145 | 32 | 89 | $self->{$k} = $ref->{$k}; | ||||
146 | } | ||||||
147 | } | ||||||
148 | 9 | 37 | return $self; | ||||
149 | } | ||||||
150 | |||||||
151 | sub list { | ||||||
152 | 1 | 1 | 1 | 5219 | my $self = shift; | ||
153 | 1 | 29 | validate( @_, { max_results => { optional => 1, type => SCALAR }, } ); | ||||
154 | |||||||
155 | 1 | 6 | my %args = ( max_results => 1_000_000_000, @_ ); | ||||
156 | |||||||
157 | 1 | 20 | my $url = $self->feeds_issues_url . '/' . $self->issue_id . | ||||
158 | '/comments/full?'; | ||||||
159 | 1 | 14 | require URI::Escape; | ||||
160 | 1 | 4 | for my $k ( keys %args ) { | ||||
161 | 1 | 50 | 6 | next unless $args{$k}; | |||
162 | 1 | 4 | my $v = $args{$k}; | ||||
163 | 1 | 5 | $k =~ s/_/-/g; | ||||
164 | 1 | 10 | $url .= "$k=" . URI::Escape::uri_escape($v) . '&'; | ||||
165 | } | ||||||
166 | |||||||
167 | 1 | 66 | my $ua = $self->ua; | ||||
168 | 1 | 9 | my $res = $ua->get($url); | ||||
169 | 1 | 50 | 84 | if ( $res->is_success ) { | |||
170 | 1 | 62 | my $feed = XML::FeedPP->new($res->content); | ||||
171 | 1 | 16722 | my @items = $feed->get_item; | ||||
172 | 18 | 189 | my @list = map { | ||||
173 | 1 | 21 | my $t = Net::Google::Code::Issue::Comment->new( | ||||
174 | 45 | 151 | map { $_ => $self->$_ } | ||||
175 | 9 | 19 | grep { $self->$_ } qw/project email password token issue_id/ | ||||
176 | ); | ||||||
177 | 9 | 37 | $t->_load_from_xml($_); | ||||
178 | } @items; | ||||||
179 | 1 | 50 | 150 | return wantarray ? @list : \@list; | |||
180 | } | ||||||
181 | else { | ||||||
182 | 0 | die "try to get $url failed: " | |||||
183 | . $res->status_line . "\n" | ||||||
184 | . $res->content; | ||||||
185 | } | ||||||
186 | } | ||||||
187 | |||||||
188 | 9 | 9 | 114 | no Any::Moose; | |||
9 | 24 | ||||||
9 | 118 | ||||||
189 | __PACKAGE__->meta->make_immutable; | ||||||
190 | 1; | ||||||
191 | |||||||
192 | __END__ |