File Coverage

blib/lib/Net/Google/Code/Issue/Attachment.pm
Criterion Covered Total %
statement 64 65 98.4
branch 16 26 61.5
condition 2 5 40.0
subroutine 9 9 100.0
pod 2 2 100.0
total 93 107 86.9


line stmt bran cond sub pod time code
1             package Net::Google::Code::Issue::Attachment;
2 10     10   28451 use Any::Moose;
  10         33434  
  10         74  
3             with 'Net::Google::Code::Role::Fetchable', 'Net::Google::Code::Role::HTMLTree';
4 10     10   13771 use Scalar::Util qw/blessed/;
  10         58  
  10         709  
5 10     10   14812 use MIME::Types;
  10         68103  
  10         487  
6 10     10   13024 use File::MMagic;
  10         184937  
  10         7765  
7              
8             has 'name' => ( isa => 'Str', is => 'rw' );
9             has 'url' => ( isa => 'Str', is => 'rw' );
10             has 'size' => ( isa => 'Str', is => 'rw' );
11             has 'id' => ( isa => 'Int', is => 'rw' );
12             has content => (
13             isa => 'Str',
14             is => 'rw',
15             lazy => 1,
16             default => sub { ($_[0]->_load)[0] },
17             );
18              
19             has content_type => (
20             isa => 'Str',
21             is => 'rw',
22             lazy => 1,
23             default => sub { ($_[0]->_load)[1] },
24             );
25              
26             sub parse {
27 5     5 1 1141 my $self = shift;
28 5         13 my $tree = shift;
29 5         35 my $need_delete = not blessed $tree;
30 5 100       31 $tree = $self->html_tree( html => $tree ) unless blessed $tree;
31 5         33 my $tr = $tree->find_by_tag_name('tr');
32              
33 5         224 my $b = $tr->find_by_tag_name('b'); # name lives here
34 5 50       307 if ($b) {
35 5         23 my $name = $b->content_array_ref->[0];
36 5         36 $name =~ s/^\s+//;
37 5         16 $name =~ s/\s+$//;
38 5         49 $self->name($name);
39              
40             # google code doesn't parse download's content type at all, we need to
41             # figure it out by ourselves
42 5         24 my $content_type = $self->_mime_type;
43 5 100       39 if ( $content_type ) {
44 1         14 $self->content_type( $content_type );
45             }
46             }
47              
48 5         37 my @tds = $tr->find_by_tag_name('td');
49 5 50       440 if (@tds) {
50 5         21 $self->url( $tds[0]->find_by_tag_name('a')->attr('href') );
51 5 50       504 if ( $self->url =~ /aid=(-?\d+)/ ) {
52 5         16 my $id = $1;
53 5         39 $self->id( $id );
54             }
55              
56 5 50       18 if ( $tds[1] ) {
57 5         27 my $size = $tds[1]->content_array_ref->[2];
58 5 50 33     85 if ( $size && $size =~ /([\d.]+)\s*(\w+)/ ) {
59 5         51 $self->size("$1 $2");
60             }
61             else {
62 0 0       0 warn 'failed to parse size' unless $size;
63             }
64             }
65             }
66              
67 5 100       25 $tree->delete if $need_delete;
68 5         218 return 1;
69             }
70              
71             sub parse_attachments {
72 2     2 1 64 my $self = shift;
73 2         5 my $element = shift;
74 2         15 my $need_delete = not blessed $element;
75 2 50       12 $element = $self->html_tree( html => $element ) unless blessed $element;
76              
77 2         5 my @attachments;
78              
79 2         9 my @items = $element->find_by_tag_name('tr');
80 2         317 while ( scalar @items ) {
81 4         10 my $tr = shift @items;
82 4         72 my $a = Net::Google::Code::Issue::Attachment->new;
83              
84 4 50       217 if ( $a->parse( $tr ) ) {
85 4         18 push @attachments, $a;
86             }
87             }
88 2 50       8 $element->delete if $need_delete;
89 2         15 return @attachments;
90             }
91              
92             sub _load {
93 1     1   3 my $self = shift;
94             #XXX weird happens if the previous fetch is also an attachment,
95             # which will make the following fetch a Bad Request.
96 1         8 $self->fetch( 'http://code.google.com' );
97              
98 1         7 my $content = $self->fetch( $self->url );
99              
100             # in case MIME::Types failed to get, let File::MMagic rescue!
101 1   50     6 my $content_type =
102             $self->_mime_type
103             || File::MMagic->new->checktype_contents($content)
104             || 'application/octet-stream';
105 1         17347 $self->content( $content );
106 1         8 $self->content_type( $content_type );
107 1         33 return $content, $content_type;
108             }
109              
110             sub _mime_type {
111 6     6   10 my $self = shift;
112 6         59 my $mime_type = MIME::Types->new->mimeTypeOf( $self->name );
113 6 100       181459 return $mime_type ? $mime_type->type : undef;
114             }
115              
116 10     10   128 no Any::Moose;
  10         23  
  10         116  
117             __PACKAGE__->meta->make_immutable;
118              
119             1;
120              
121             __END__