Fundamental autotag.pl functions
There were a few things in autotag.pl that I put in separate
functions. First of all, contains_word_char()
is a function that makes
the decision whether some text contains a word (\w
in Perl) character.
It works correctly with undefined values as well, whereas with warnings
turned on, a regular expression match on an undefined value will print a
warning. It's primarily useful because it doesn't show a warning; in order
to achieve that effect without a function you'd have to check whether the
string is defined every time.
Listing 1. The contains_word_char() function
# {{{ contains_word_char: return 1 if the text contains a word character
sub contains_word_char
{
my $text = shift @_;
return $text && length $text && $text =~ m/\w/;
}
# }}}
|
Next come the input routines. These are pretty verbose, and they
attempt to handle most cases of user interaction the program will need.
Listing 2. The get_tag() function
# {{{ get_tag: get a ID3 V2 tag, using V1 if necessary
sub get_tag
{
my $file = shift @_;
my $upgrade = shift @_;
my $mp3 = MP3::Tag->new($file);
return undef unless defined $mp3;
$mp3->get_tags();
my $tag = {};
if (exists $mp3->{ID3v2})
{
my $id3v2 = $mp3->{ID3v2};
my $frames = $id3v2->supported_frames();
while (my ($fname, $longname) = each %$frames)
{
# only grab the frames we know
next unless exists $supported_frames{$fname};
$tag->{$fname} = $id3v2->get_frame($fname);
delete $tag->{$fname} unless defined $tag->{$fname};
$tag->{$fname} = $tag->{$fname}->{Text} if $fname eq 'COMM';
$tag->{$fname} = $tag->{$fname}->{URL} if $fname eq 'WXXX';
$tag->{$fname} = '' unless defined $tag->{$fname};
}
}
elsif (exists $mp3->{ID3v1})
{
warn "No ID3 v2 TAG info in $file, using the v1 tag";
my $id3v1 = $mp3->{ID3v1};
$tag->{COMM} = $id3v1->comment();
$tag->{TIT2} = $id3v1->song();
$tag->{TPE1} = $id3v1->artist();
$tag->{TALB} = $id3v1->album();
$tag->{TYER} = $id3v1->year();
$tag->{TRCK} = $id3v1->track();
$tag->{TIT1} = $id3v1->genre();
if ($upgrade && read_yes_no("Upgrade ID3v1 tag to ID3v2 for $file?", 1))
{
set_tag($file, $tag);
}
}
else
{
warn "No ID3 TAG info in $file, creating it";
$tag = {
TIT2 => '',
TPE1 => '',
TALB => '',
TYER => 9999,
COMM => '',
};
}
print "Got tag ", Dumper $tag
if $config->DEBUG();
return $tag;
}
# }}}
|
The only slightly unusual function is read_yes_no()
, which can be
given a Y
or 1
default parameter to make the default true, and any
other parameter to make the default false. Thus, I can make the
read_yes_no()
function accept different default values when the user
presses Enter or Space. In addition, the Backspace or Delete keys will
reverse the default. It's not flashy code, but it's very useful.