File Coverage

blib/lib/Music/Tag/File.pm
Criterion Covered Total %
statement 105 154 68.1
branch 28 58 48.2
condition 4 12 33.3
subroutine 10 14 71.4
pod 7 7 100.0
total 154 245 62.8


line stmt bran cond sub pod time code
1             package Music::Tag::File;
2 1     1   4833 use strict; use warnings; use utf8;
  1     1   2  
  1     1   45  
  1         7  
  1         2  
  1         39  
  1         8  
  1         16  
  1         10  
3             our $VERSION = '0.4101';
4              
5             # Copyright © 2007,2010 Edward Allen III. Some rights reserved.
6             #
7             # You may distribute under the terms of either the GNU General Public
8             # License or the Artistic License, as specified in the README file.
9              
10 1     1   156 use File::Spec;
  1         2  
  1         115  
11 1     1   8 use base qw(Music::Tag::Generic);
  1         2  
  1         2947  
12              
13             sub set_values {
14 0     0 1 0 return qw( picture artist album title booklet lyrics track discnum);
15             }
16              
17             sub saved_values {
18 0     0 1 0 return qw( picture booklet lyrics );
19             }
20              
21             sub get_tag {
22 2     2 1 1486 my $self = shift;
23 2         8 my $filename = $self->info->get_data('filename');
24 2         128 my @dirs = File::Spec->splitdir( File::Spec->rel2abs($filename) );
25 2         6 my $fname = pop @dirs;
26 2         383 my $dname = File::Spec->catdir(@dirs);
27 2         7 my $album = pop @dirs;
28 2         5 my $artist = pop @dirs;
29              
30 2         5 $album =~ s/_/ /g;
31 2         15 $album =~ s/\b(\w)/uc($1)/ge;
  2         11  
32 2         13 $album =~ s/ *$//g;
33 2         7 $album =~ s/^ *//g;
34              
35 2 50       10 if ( length($album) < 2 ) {
36 0         0 $album = "";
37             }
38              
39 2         4 $artist =~ s/_/ /g;
40 2         8 $artist =~ s/\b(\w)/uc($1)/ge;
  2         8  
41 2         13 $artist =~ s/ *$//g;
42 2         10 $artist =~ s/ *$//g;
43 2 50       8 unless ( $self->info->has_data('track') ) {
44 2 50       75 if ( $fname =~ /^[^\d]*(\d+)[^\d]/ ) {
45 0         0 my $num = sprintf( "%d", $1 );
46 0         0 $self->info->set_data('track',$num);
47 0         0 $self->tagchange("TRACK");
48             }
49             else {
50 2         7 $self->info->set_data('track',0);
51 2         104 $self->tagchange("TRACK");
52             }
53             }
54 2 50       234 unless ( $self->info->has_data('title') ) {
55 2         53 my $title = $fname;
56 2         11 $title =~ s/\..+$//g;
57 2         9 $title =~ s/^\d+\.?\ +//g;
58 2         7 $title =~ s/^ *//g;
59 2         12 $title =~ s/ *$//g;
60 2         7 $self->info->set_data('title',$title);
61 2         92 $self->tagchange("TITLE");
62             }
63 2 50       193 unless ( $self->info->has_data('artist') ) {
64 2         53 $self->info->set_data('artist',$artist);
65 2         76 $self->tagchange("ARTIST");
66             }
67 2 50       198 unless ( $self->info->has_data('album') ) {
68 2         305 $self->info->set_data('album',$album);
69 2         83 $self->tagchange("ALBUM");
70             }
71 2 50       183 unless ( $self->info->has_data('disc') ) {
72 2         52 $self->info->set_data('discnum',"1/1");
73 2         174 $self->tagchange("DISC");
74             }
75              
76 2 50 33     187 if ( ( not $self->info->has_data('picture') ) or ( $self->options->{coveroverwrite} ) ) {
77 2         80 my $fname = File::Spec->catdir($dname, "folder.jpg");
78 2         13 my $pfname = File::Spec->catdir($dname, "folder.png");
79 2         12 my $cfname = File::Spec->catdir($dname, "cover.jpg");
80 2 100       140 if ( -e $fname ) {
    50          
    50          
81 1         5 $self->tagchange( "COVER ART", "from folder.jpg" );
82 1         69 $self->info->set_data('picture', $self->_cover_art($fname) );
83             }
84             elsif ( -e $pfname ) {
85 0         0 $self->tagchange( "COVER ART", "from folder.png" );
86 0         0 $self->info->set_data('picture', $self->_cover_art($pfname) );
87             }
88             elsif ( -e $cfname ) {
89 0         0 $self->tagchange( "COVER ART", "from cover.jpg" );
90 0         0 $self->info->set_data('picture', $self->_cover_art($cfname) );
91             }
92              
93             }
94 2 0 33     313 if ( ( not $self->info->has_data('lyrics') )
      33        
95             or ( $self->options->{lyricsoverwrite} )
96             or ( length( $self->info->lyrics ) < 10 ) ) {
97 2         54 my $fname = $self->info->filename;
98 2         41 $fname =~ s/\.[^\.]*$/.txt/;
99 2 50       43 if ( -e "$fname" ) {
100 0         0 $self->tagchange( "LYRICS", "from $fname" );
101 0         0 my $l = $self->_slurp_file($fname);
102 0         0 $self->info->set_data('lyrics',$l);
103 0         0 $l =~ s/\n\r?/ \/ /g;
104 0         0 $self->tagchange( "LYRICS", substr( $l, 0, 40 ) );
105             }
106             }
107 2         7 local *DIR;
108 2         83 opendir(DIR, $dname);
109 2         73 while ( my $f = readdir(DIR) ) {
110 11 100       356 next if $f =~ /^\./;
111 7         41 my $fname = File::Spec->catdir($dname, $f);
112 7 50       40 if ($f =~ /\.pdf$/i) {
113 0 0       0 unless ($self->info->has_data('booklet')) {
114 0         0 $self->tagchange( "BOOKLET", "from $f" );
115 0         0 $self->info->set_data('booklet',$f);
116             }
117             }
118             #if ($f =~ /\.txt$/i) {
119             #unless ($self->info->has_data('lyrics')) {
120             #$self->tagchange( "LYRICS", "from $fname" );
121             #my $l = $self->_slurp_file($fname);
122             #$self->info->set_data('lyrics',$l);
123             #$l =~ s/\n\r?/ \/ /g;
124             #$self->tagchange( "LYRICS", substr( $l, 0, 40 ) );
125             #}
126             #}
127 7 100       30 if ($f =~ /\.jpg$/i) {
128 3 100       8 unless ($self->info->has_data('picture')) {
129 1         37 $self->tagchange( "COVER ART", "from $f" );
130 1         64 $self->info->set_data('picture', $self->_cover_art($fname) );
131             }
132             }
133             }
134              
135              
136              
137 2         453 return $self;
138             }
139              
140             sub _slurp_file {
141 0     0   0 my $self = shift;
142 0         0 my $fname = shift;
143 0         0 local *IN;
144 0 0       0 open( IN, $fname ) or return "";
145 0         0 my $l = "";
146 0         0 while () { $l .= $_ }
  0         0  
147 0         0 close(IN);
148 0         0 return $l;
149             }
150              
151             sub _cover_art {
152 2     2   15 my $self = shift;
153 2         2 my $picture = shift;
154 2         40 my ($vol, $root, $file) = File::Spec->splitpath($picture);
155 2         13 my $pic = { "Picture Type" => "Cover (front)",
156             "MIME type" => "image/jpg",
157             Description => "",
158             filename => $file,
159             _Data => "",
160             };
161 2 50       10 if ( $picture =~ /\.png$/i ) {
162 0         0 $pic->{"MIME type"} = "image/png";
163             }
164 2         10 return $pic;
165 0         0 local *IN;
166             #unless ( open( IN, $picture ) ) {
167             # $self->error("Could not open $picture for read: $!");
168             # return undef;
169             #}
170             #my $n = 0;
171             #my $b = 1;
172             #while ($b) {
173             # $b = sysread( IN, $pic->{"_Data"}, 1024, $n );
174             # $n += $b;
175             #}
176             #close(IN);
177             #return $pic;
178             }
179              
180             sub save_cover {
181 1     1 1 9 my $self = shift;
182 1         4 my ( $vol, $dir, $file ) = File::Spec->splitpath( $self->info->get_data('filename') );
183 1         50 my $filename = File::Spec->catpath( $vol, $dir, "folder.jpg" );
184              
185             #if ($dname eq "/") { $dname = "" } else {$dname = File::Spec->catpath($vol, $dir) }
186 1         4 my $art = $self->info->get_data('picture');
187 1 50       257 if ( exists $art->{_Data} ) {
188 1         3 local *OUT;
189 1 50       8 if ( $art->{"MIME type"} eq "image/png" ) {
    50          
190 0         0 $filename = File::Spec->catpath( $vol, $dir, "folder.png" );
191             }
192             elsif ( $art->{"MIME type"} eq "image/bmp" ) {
193 0         0 $filename = File::Spec->catpath( $vol, $dir, "folder.jpg" );
194             }
195 1         6 $self->status("Saving cover image to $filename");
196 1 50       140 unless ( open OUT, ">$filename" ) {
197 0         0 $self->error("Error writing to $filename: $!, skipping.");
198 0         0 return undef;
199             }
200 1         2 my $b = 0;
201 1         2 my $l = length( $art->{_Data} );
202 1         5 while ( $b < $l ) {
203 4         75 my $s = syswrite OUT, $art->{_Data}, 1024, $b;
204 4 50       8 if ( defined $s ) {
205 4         7 $b += $s;
206             }
207             else {
208 0         0 $self->status("Error writing to $filename: $!, skipping.");
209 0         0 return undef;
210             }
211             }
212 1         10 close OUT;
213             }
214 1         4 return 1;
215             }
216              
217             sub save_lyrics {
218 0     0 1 0 my $self = shift;
219 0         0 my $fname = $self->info->get_data('filename');
220 0         0 $fname =~ s/\.[^\.]*$/.txt/;
221 0         0 my $lyrics = $self->info->get_data('lyrics');
222 0 0       0 if ($lyrics) {
223 0         0 local *OUT;
224 0         0 $self->status("Saving lyrics image to $fname");
225 0 0       0 unless ( open OUT, ">$fname" ) {
226 0         0 $self->status("Error writing to $fname: $!, skipping.");
227 0         0 return undef;
228             }
229 0         0 print OUT $lyrics;
230 0         0 close OUT;
231             }
232 0         0 return 1;
233             }
234              
235             sub set_tag {
236 1     1 1 5094 my $self = shift;
237 1 50       6 unless ( $self->options("no_savecover")) {
238 1         24 $self->save_cover( $self->info );
239             }
240 1 50 33     4 unless ( $self->options("no_savelyrics") or $self->info->get_data('filename') =~ /\.mp3$/i ) {
241 0         0 $self->save_lyrics( $self->info );
242             }
243 1         50 return $self;
244             }
245              
246             sub default_options {
247             {
248 2     2 1 2191 lyricsoverwrite => 0,
249             coveroverwrite => 0,
250             no_savecover => 0,
251             no_savelyrics => 0,
252             }
253             }
254              
255             1;
256              
257             __END__