Mp3: filter extra slashes
[id3fs.git] / lib / ID3FS / File / Mp3.pm
1 package ID3FS::File::Mp3;
2
3 use strict;
4 use warnings;
5 use MP3::Tag;
6
7 sub new
8 {
9     my $proto=shift;
10     my $class=ref($proto) || $proto;
11     my $self={};
12     bless($self,$class);
13
14     $self->{path}=shift;
15     $self->{mp3}=MP3::Tag->new($self->{path});
16     $self->get_tags();
17     $self->{v1}=undef;
18     $self->{v1}=$self->{mp3}->{ID3v1} if(exists($self->{mp3}->{ID3v1}));
19     $self->{v2}=undef;
20     $self->{v2}=$self->{mp3}->{ID3v2} if(exists($self->{mp3}->{ID3v2}));
21
22     # FIXME
23     $self->{tags}={};
24
25     return $self;
26 }
27
28 sub choose
29 {
30     my ($self, $func, $verbose)=@_;
31     my $thing=undef;
32     if(defined($self->{v2}))
33     {
34         $thing=$self->{v2}->$func();
35     }
36     if(defined($self->{v1}) && (!defined($thing) || !length($thing)))
37     {
38         $thing=$self->{v1}->$func();
39     }
40     if(!defined($thing) || !length($thing))
41     {
42         warn("$self->{path}: no $func defined in ID3 tags\n") if($verbose);
43         return undef;
44     }
45     $thing=~s/\//-/g; # drop slashes
46     return $thing;
47 }
48
49 sub artist    { shift->choose("artist", 1); }
50 sub album     { shift->choose("album", 1);  }
51 # We don't care if year is not set
52 sub year      { shift->choose("year", 0);   }
53 sub audiotype { return "mp3";               }
54 sub haspic    { return undef;               } # FIXME
55 sub v1genre
56 {
57     my($self)=@_;
58     my $genre=undef;
59     if(defined($self->{v1}))
60     {
61         $genre=$self->{v1}->genre();
62         $genre =~ s/\//-/g if(defined($genre));
63     }
64     return $genre;
65 }
66
67 sub tags
68 {
69     my $self=shift;
70     return({}) unless(exists($self->{mp3}->{ID3v2}) && defined($self->{mp3}->{ID3v2}));
71     my $genre=$self->{mp3}->{ID3v2}->genre();
72     return({}) unless(defined($genre) && length($genre));
73     my @tags=split(/\s*,\s*/, $genre);
74     for my $tag (@tags)
75     {
76         if($tag=~/([^\/]+)\/(.*)/)
77         {
78             my $tagname=$1;
79             my $tagval=$2;
80             $tagval=~s/\//-/g;
81             $self->{tags}->{$tagname}=$tagval;
82         }
83         else
84         {
85             $self->{tags}->{$tag}=undef;
86         }
87     }
88     return $self->{tags};
89 }
90
91 sub get_tags
92 {
93     my ($self)=@_;
94     # MP3::Tag->get_tags shows cryptic debug info via print when it finds
95     # an unhandled id3v2 version, in addition to the warning, so use
96     # select to send prints to /dev/null
97     my $oldout=undef;
98     if(open(NULL,">/dev/null"))
99     {
100         $oldout=select(NULL);
101     }
102     eval { $self->{mp3}->get_tags; };
103     warn("$self->{path}: $@\n") if($@);
104     if(defined($oldout))
105     {
106         select($oldout);
107         close(NULL);
108     }
109 }
110
111 1;
112