basic tag path traversal
[id3fs.git] / lib / ID3FS / Path.pm
index b2202c2..7ceb45b 100644 (file)
@@ -2,6 +2,15 @@ package ID3FS::Path;
 
 use strict;
 use warnings;
+use ID3FS::PathElement::Artist;
+use ID3FS::PathElement::Album;
+use ID3FS::PathElement::Boolean;
+use ID3FS::PathElement::File;
+use ID3FS::PathElement::Tag;
+use ID3FS::PathElement::Tagval;
+
+our ($STATE_INVALID, $STATE_ROOT, $STATE_WANTMORE, $STATE_TAG, $STATE_TAGVAL,
+     $STATE_BOOL, $STATE_ARTIST, $STATE_ALBUM, $STATE_FILE)=(0..8);
 
 sub new
 {
@@ -12,15 +21,26 @@ sub new
 
     $self->{db}=shift;
     $self->{path}=shift;
-
+    $self->parse();
+    print "STATE: ", $self->state(), "\n";
     return $self;
 }
 
 sub isdir
 {
     my($self)=@_;
-    return 1 if($self->{path} eq "/");
-    return 0;
+    if(($self->state() eq $STATE_FILE) ||
+       ($self->state() eq $STATE_INVALID))
+    {
+       return 0;
+    }
+    return 1;
+}
+
+sub isvalid
+{
+    my($self)=@_;
+    return($self->state() != $STATE_INVALID);
 }
 
 sub dest
@@ -32,8 +52,133 @@ sub dest
 sub dirents
 {
     my($self)=@_;
-    return $self->{db}->tags();
+    return $self->{db}->tags(@{$self->{elements}});
+#    elsif($self->state() == $STATE_WANTMORE)
+#    {
+#      return(qw(AND OR ALL));
+#    }
 }
 
+sub parse
+{
+    my($self)=@_;
+    @{$self->{components}}=split(/\//, $self->{path});
+    shift @{$self->{components}}; # drop empty field before leading /
+    print "PATH: $self->{path}\n";
+    print "COMPONENTS: ", join(' | ', @{$self->{components}}), "\n";
+    $self->state($STATE_ROOT);
+    return if($self->{path} eq "/");
+    my @parts=@{$self->{components}};
+    my($tag, $tagval);
+    $self->{elements}=[];
+    while(my $name=shift @parts)
+    {
+       print "NAME: $name\n";
+       if   ($self->state() == $STATE_INVALID)
+       {
+           print "SM: INVALID: $name\n";
+           return;
+       }
+       elsif($self->state() == $STATE_ROOT)
+       {
+           print "SM: ROOT: $name\n";
+           $tag=ID3FS::PathElement::Tag->new($self->{db}, $name);
+           if($tag)
+           {
+               push(@{$self->{elements}}, $tag);
+               $self->state($STATE_WANTMORE);
+           }
+           else
+           {
+               $self->state($STATE_INVALID);
+           }
+       }
+       elsif($self->state() == $STATE_WANTMORE)
+       {
+           print "SM: WANTMORE: $name\n";
+           $tag=ID3FS::PathElement::Tag->new($self->{db}, $name);
+           if($tag)
+           {
+               push(@{$self->{elements}}, $tag);
+#              $self->state($STATE_TAG);
+           }
+           else
+           {
+               $self->state($STATE_INVALID);
+           }
+#          if(($name eq "AND") || ($name eq "OR"))
+#          {
+#              $self->state($STATE_BOOL);
+#              push(@{$self->{elements}}, ID3FS::PathElement::Boolean->new($name));
+#          }
+#          elsif($name eq "ALL")
+#          {
+#              $self->state($STATE_ARTIST);
+#          }
+#          else
+#          {
+#              $self->state($STATE_INVALID);
+#          }
+       }
+       elsif($self->state() == $STATE_TAG)
+       {
+           print "SM: TAG: $name\n";
+           $self->state($STATE_WANTMORE);
+           next;
+           my @valid_tagvals=$self->{db}->tag_values($tag);
+           print "TAGVALUES: $name: ", join(', ', @valid_tagvals), "\n";
+           if(@valid_tagvals)
+           {
+               if(grep { $name eq $_; } @valid_tagvals)
+               {
+                   print "TAGVAL VALID\n";
+                   $self->state($STATE_TAGVAL);
+                   push(@{$self->{elements}}, ID3FS::PathElement::Tagval($name));
+               }
+               else
+               {
+                   print "ERROR: unknown tagval: $tagval\n";
+                   $self->state($STATE_INVALID);
+               }
+           }
+           else
+           {
+               $self->state($STATE_INVALID);
+           }
+       }
+       elsif($self->state() == $STATE_TAGVAL)
+       {
+           print "SM: TAGVAL: $name\n";
+       }
+       elsif($self->state() == $STATE_BOOL)
+       {
+           print "SM: BOOL: $name\n";
+       }
+       elsif($self->state() == $STATE_ARTIST)
+       {
+           print "SM: ARTIST: $name\n";
+       }
+       elsif($self->state() == $STATE_ALBUM)
+       {
+           print "SM: ALBUM: $name\n";
+       }
+       elsif($self->state() == $STATE_FILE)
+       {
+           print "SM: FILE: $name\n";
+       }
+       else
+       {
+           print "SM: ERROR: UNKNOWN STATE: $self->{state}\n";
+           $self->state($STATE_INVALID);
+       }
+    }
+}
+
+sub state
+{
+    my($self, $newstate)=@_;
+    $self->{state}=$newstate if(defined($newstate));
+    return $self->{state};
+}
 
 1;