fix file splitting; tweaks
[id3fs.git] / lib / ID3FS / Path.pm
1 package ID3FS::Path;
2
3 use strict;
4 use warnings;
5 use feature 'switch';
6 use ID3FS::PathElement::Artist;
7 use ID3FS::PathElement::Album;
8 use ID3FS::PathElement::Boolean;
9 use ID3FS::PathElement::File;
10 use ID3FS::PathElement::Tag;
11 use ID3FS::PathElement::Tagval;
12
13 our ($STATE_INVALID, $STATE_ROOT, $STATE_TAG, $STATE_TAGVAL,
14      $STATE_BOOLEAN, $STATE_ARTISTS, $STATE_ALBUMS, $STATE_TRACKLIST,
15      $STATE_FILE)=(0..8);
16
17 sub new
18 {
19     my $proto=shift;
20     my $class=ref($proto) || $proto;
21     my $self={};
22     bless($self,$class);
23
24     $self->{db}=shift;
25     $self->{path}=shift;
26     $self->parse();
27     print "STATE: ", $self->state(), "\n";
28     return $self;
29 }
30
31 sub isdir
32 {
33     my($self)=@_;
34     if(($self->state() == $STATE_FILE) ||
35        ($self->state() == $STATE_INVALID))
36     {
37         return 0;
38     }
39     return 1;
40 }
41
42 sub isfile
43 {
44     my($self)=@_;
45     return 1 if($self->state() == $STATE_FILE);
46     return 0;
47 }
48
49 sub isvalid
50 {
51     my($self)=@_;
52     return($self->state() != $STATE_INVALID);
53 }
54
55 sub dest
56 {
57     my($self)=@_;
58     if($self->state() == $STATE_FILE)
59     {
60         return $self->{db}->filename(@{$self->{elements}});
61     }
62     return "ERROR"; #should never happen?
63 }
64
65 sub dirents
66 {
67     my($self)=@_;
68     my @dents=();
69     given($self->state())
70     {
71         when($STATE_TAG)
72         {
73             @dents=qw(AND ARTISTS ALBUMS TRACKS);
74         }
75         when($STATE_BOOLEAN)
76         {
77             @dents=$self->{db}->tags(@{$self->{elements}});
78         }
79         when($STATE_ROOT)
80         {
81             @dents=("ALL", $self->{db}->tags(@{$self->{elements}}));
82         }
83         when($STATE_ARTISTS)
84         {
85             @dents=$self->{db}->artists(@{$self->{elements}});
86         }
87         when($STATE_ALBUMS)
88         {
89             @dents=$self->{db}->albums(@{$self->{elements}});
90         }
91         when($STATE_TRACKLIST)
92         {
93             @dents=$self->{db}->tracks(@{$self->{elements}});
94         }
95         default
96         {
97             print "DIRENTS: UNHANDLED STATE: $_\n";
98         }
99     }
100     return(@dents);
101 }
102
103 sub parse
104 {
105     my($self)=@_;
106     @{$self->{components}}=split(/\//, $self->{path});
107     shift @{$self->{components}}; # drop empty field before leading /
108     print "PATH: $self->{path}\n";
109 #    print "COMPONENTS: ", join(' | ', @{$self->{components}}), "\n";
110     $self->state($STATE_ROOT);
111     return if($self->{path} eq "/");
112     my @parts=@{$self->{components}};
113     my($tag, $tagval);
114     $self->{elements}=[];
115     while(my $name=shift @parts)
116     {
117         print "NAME: $name\n";
118         given($self->state())
119         {
120             when($STATE_INVALID)
121             {
122                 print "SM: INVALID: $name\n";
123                 return;
124             }
125             when($STATE_ROOT)
126             {
127                 print "SM: ROOT: $name\n";
128                 if($name eq "ALL")
129                 {
130                     $self->state($STATE_ARTISTS);
131                 }
132                 else
133                 {
134                     $tag=ID3FS::PathElement::Tag->new($self->{db}, $name);
135                     if($tag)
136                     {
137                         push(@{$self->{elements}}, $tag);
138                         $self->state($STATE_TAG);
139                     }
140                     else
141                     {
142                         $self->state($STATE_INVALID);
143                     }
144                 }
145             }
146             when($STATE_TAG)
147             {
148                 print "SM: TAG: $name\n";
149                 given($name)
150                 {
151                     when("AND")
152                     {
153                         $self->state($STATE_BOOLEAN);
154 #                       push(@{$self->{elements}}, ID3FS::PathElement::Boolean->new($name));
155                     }
156                     when("ARTISTS")
157                     {
158                         $self->state($STATE_ARTISTS);
159                     }
160                     when("ALBUMS")
161                     {
162                         $self->state($STATE_ALBUMS);
163                     }
164                     when("TRACKS")
165                     {
166                         $self->state($STATE_TRACKLIST);
167                     }
168
169 #                   when("OR")  { ; }
170 #                   when("NOT") { ; }
171                     default
172                     {
173                         $self->state($STATE_INVALID);
174                     }
175                 }
176             }
177
178 #           when(255) #FIXME - dead code
179 #           {
180 #               my @valid_tagvals=$self->{db}->tag_values($tag);
181 #               print "TAGVALUES: $name: ", join(', ', @valid_tagvals), "\n";
182 #               if(@valid_tagvals)
183 #               {
184 #                   if(grep { $name eq $_; } @valid_tagvals)
185 #                   {
186 #                       print "TAGVAL VALID\n";
187 #                       $self->state($STATE_TAGVAL);
188 #                       push(@{$self->{elements}}, ID3FS::PathElement::Tagval($name));
189 #                   }
190 #                   else
191 #                   {
192 #                       print "ERROR: unknown tagval: $tagval\n";
193 #                       $self->state($STATE_INVALID);
194 #                   }
195 #           }
196             when($STATE_TAGVAL)
197             {
198                 print "SM: TAGVAL: $name\n";
199             }
200             when($STATE_BOOLEAN)
201             {
202                 print "SM: BOOLEAN: $name\n";
203                 my $tag=ID3FS::PathElement::Tag->new($self->{db}, $name);
204                 if($tag)
205                 {
206                     push(@{$self->{elements}}, $tag);
207                     $self->state($STATE_TAG);
208                 }
209                 else
210                 {
211                     $self->state($STATE_INVALID);
212                 }
213             }
214             when($STATE_ARTISTS)
215             {
216                 print "SM: ARTIST: $name\n";
217                 my $artist=ID3FS::PathElement::Artist->new($self->{db}, $name);
218                 push(@{$self->{elements}}, $tag);
219                 if($artist)
220                 {
221                     push(@{$self->{elements}}, $artist);
222                     $self->state($STATE_ALBUMS);
223                 }
224                 else
225                 {
226                     $self->state($STATE_INVALID);
227                 }
228             }
229             when($STATE_ALBUMS)
230             {
231                 print "SM: ALBUM: $name\n";
232                 my $album=ID3FS::PathElement::Album->new($self->{db}, $name);
233                 push(@{$self->{elements}}, $album);
234                 if($album)
235                 {
236                     push(@{$self->{elements}}, $album);
237                     $self->state($STATE_TRACKLIST);
238                 }
239                 else
240                 {
241                     $self->state($STATE_INVALID);
242                 }
243             }
244             when($STATE_TRACKLIST)
245             {
246                 print "SM: TRACKLIST: $name\n";
247                 my $track=ID3FS::PathElement::File->new($self->{db}, $name);
248                 push(@{$self->{elements}}, $track);
249                 if($track)
250                 {
251                     push(@{$self->{elements}}, $track);
252                     $self->state($STATE_FILE);
253                 }
254                 else
255                 {
256                     $self->state($STATE_INVALID);
257                 }
258             }
259             when($STATE_FILE)
260             {
261                 print "SM: FILE: $name\n";
262                 # Can't have anything after a filename
263                 $self->state($STATE_INVALID);
264             }
265             default
266             {
267                 print "SM: ERROR: UNKNOWN STATE: $self->{state}\n";
268                 $self->state($STATE_INVALID);
269             }
270         }
271     }
272 }
273
274 sub state
275 {
276     my($self, $newstate)=@_;
277     $self->{state}=$newstate if(defined($newstate));
278     return $self->{state};
279 }
280
281 1;