basic tag path traversal
[id3fs.git] / lib / ID3FS / Path.pm
1 package ID3FS::Path;
2
3 use strict;
4 use warnings;
5 use ID3FS::PathElement::Artist;
6 use ID3FS::PathElement::Album;
7 use ID3FS::PathElement::Boolean;
8 use ID3FS::PathElement::File;
9 use ID3FS::PathElement::Tag;
10 use ID3FS::PathElement::Tagval;
11
12 our ($STATE_INVALID, $STATE_ROOT, $STATE_WANTMORE, $STATE_TAG, $STATE_TAGVAL,
13      $STATE_BOOL, $STATE_ARTIST, $STATE_ALBUM, $STATE_FILE)=(0..8);
14
15 sub new
16 {
17     my $proto=shift;
18     my $class=ref($proto) || $proto;
19     my $self={};
20     bless($self,$class);
21
22     $self->{db}=shift;
23     $self->{path}=shift;
24     $self->parse();
25     print "STATE: ", $self->state(), "\n";
26     return $self;
27 }
28
29 sub isdir
30 {
31     my($self)=@_;
32     if(($self->state() eq $STATE_FILE) ||
33        ($self->state() eq $STATE_INVALID))
34     {
35         return 0;
36     }
37     return 1;
38 }
39
40 sub isvalid
41 {
42     my($self)=@_;
43     return($self->state() != $STATE_INVALID);
44 }
45
46 sub dest
47 {
48     my($self)=@_;
49     return "FIXME";
50 }
51
52 sub dirents
53 {
54     my($self)=@_;
55     return $self->{db}->tags(@{$self->{elements}});
56 #    elsif($self->state() == $STATE_WANTMORE)
57 #    {
58 #       return(qw(AND OR ALL));
59 #    }
60 }
61
62 sub parse
63 {
64     my($self)=@_;
65     @{$self->{components}}=split(/\//, $self->{path});
66     shift @{$self->{components}}; # drop empty field before leading /
67     print "PATH: $self->{path}\n";
68     print "COMPONENTS: ", join(' | ', @{$self->{components}}), "\n";
69     $self->state($STATE_ROOT);
70     return if($self->{path} eq "/");
71     my @parts=@{$self->{components}};
72     my($tag, $tagval);
73     $self->{elements}=[];
74     while(my $name=shift @parts)
75     {
76         print "NAME: $name\n";
77         if   ($self->state() == $STATE_INVALID)
78         {
79             print "SM: INVALID: $name\n";
80             return;
81         }
82         elsif($self->state() == $STATE_ROOT)
83         {
84             print "SM: ROOT: $name\n";
85             $tag=ID3FS::PathElement::Tag->new($self->{db}, $name);
86             if($tag)
87             {
88                 push(@{$self->{elements}}, $tag);
89                 $self->state($STATE_WANTMORE);
90             }
91             else
92             {
93                 $self->state($STATE_INVALID);
94             }
95         }
96         elsif($self->state() == $STATE_WANTMORE)
97         {
98             print "SM: WANTMORE: $name\n";
99             $tag=ID3FS::PathElement::Tag->new($self->{db}, $name);
100             if($tag)
101             {
102                 push(@{$self->{elements}}, $tag);
103 #               $self->state($STATE_TAG);
104             }
105             else
106             {
107                 $self->state($STATE_INVALID);
108             }
109 #           if(($name eq "AND") || ($name eq "OR"))
110 #           {
111 #               $self->state($STATE_BOOL);
112 #               push(@{$self->{elements}}, ID3FS::PathElement::Boolean->new($name));
113 #           }
114 #           elsif($name eq "ALL")
115 #           {
116 #               $self->state($STATE_ARTIST);
117 #           }
118 #           else
119 #           {
120 #               $self->state($STATE_INVALID);
121 #           }
122         }
123         elsif($self->state() == $STATE_TAG)
124         {
125             print "SM: TAG: $name\n";
126             $self->state($STATE_WANTMORE);
127             next;
128             my @valid_tagvals=$self->{db}->tag_values($tag);
129             print "TAGVALUES: $name: ", join(', ', @valid_tagvals), "\n";
130             if(@valid_tagvals)
131             {
132                 if(grep { $name eq $_; } @valid_tagvals)
133                 {
134                     print "TAGVAL VALID\n";
135                     $self->state($STATE_TAGVAL);
136                     push(@{$self->{elements}}, ID3FS::PathElement::Tagval($name));
137                 }
138                 else
139                 {
140                     print "ERROR: unknown tagval: $tagval\n";
141                     $self->state($STATE_INVALID);
142                 }
143             }
144             else
145             {
146                 $self->state($STATE_INVALID);
147             }
148         }
149         elsif($self->state() == $STATE_TAGVAL)
150         {
151             print "SM: TAGVAL: $name\n";
152         }
153         elsif($self->state() == $STATE_BOOL)
154         {
155             print "SM: BOOL: $name\n";
156         }
157         elsif($self->state() == $STATE_ARTIST)
158         {
159             print "SM: ARTIST: $name\n";
160         }
161         elsif($self->state() == $STATE_ALBUM)
162         {
163             print "SM: ALBUM: $name\n";
164         }
165         elsif($self->state() == $STATE_FILE)
166         {
167             print "SM: FILE: $name\n";
168         }
169         else
170         {
171             print "SM: ERROR: UNKNOWN STATE: $self->{state}\n";
172             $self->state($STATE_INVALID);
173         }
174     }
175 }
176
177 sub state
178 {
179     my($self, $newstate)=@_;
180     $self->{state}=$newstate if(defined($newstate));
181     return $self->{state};
182 }
183
184 1;