$self->{db}=shift;
$self->{path}=shift;
$self->{verbose}=shift;
+ $self->{maxtagdepth}=shift;
+ $self->{curtagdepth}=0;
$self->{path} =~ s/\/\//\//g; # drop doubled slashes
$self->parse();
sub isfile
{
my($self)=@_;
- return 1 if($self->state() == $STATE_FILE);
- return 0;
+ return($self->state() == $STATE_FILE);
}
sub isvalid
my($self, $mountpoint)=@_;
if($self->state() == $STATE_FILE)
{
- return $self->filename($mountpoint, $self);
+ return $self->filename($mountpoint);
}
return "ERROR"; #should never happen?
}
# print "DIRENTS: FILE: $self->{path}\n";
if($state==$STATE_ALL)
{
- @dents=($self->artists(), $PATH_ALLTRACKS, $PATH_NOARTIST);
+ @dents=($PATH_ALLTRACKS, $PATH_NOARTIST, $self->artists());
}
elsif($state==$STATE_TAG || $state==$STATE_TAGVAL)
{
}
else
{
- @dents=($self->artists(), qw(AND OR), $PATH_ALLTRACKS, $PATH_NOARTIST);
+ if($self->{maxtagdepth} && ($self->{curtagdepth} < $self->{maxtagdepth}))
+ {
+ @dents=qw(AND OR);
+ }
+ push(@dents, $self->filter($PATH_ALLTRACKS, $PATH_NOARTIST));
+ push(@dents, $self->artists());
}
}
elsif($state==$STATE_BOOLEAN)
{
- @dents=$self->tags();
my $parent=$self->tail();
unless(defined($parent) &&
ref($parent) eq "ID3FS::PathElement::Boolean" &&
$parent->{name} eq "NOT")
{
- push(@dents, "NOT");
+ @dents=("NOT");
}
+ push(@dents,$self->tags());
}
elsif($state==$STATE_ROOT)
{
- @dents=($self->tags(), qw(ALL NOT));
+ @dents=(qw(ALL NOT), $self->tags());
}
elsif($state==$STATE_ALBUMS)
{
- @dents=($self->albums(), $PATH_ALLTRACKS, $PATH_NOALBUM);
+ @dents=($self->filter($PATH_ALLTRACKS, $PATH_NOALBUM), $self->albums());
}
elsif($state==$STATE_TRACKLIST)
{
sub state
{
my($self, $newstate)=@_;
- $self->{state}=$newstate if(defined($newstate));
+ if(defined($newstate))
+ {
+ $self->{state}=$newstate;
+ $self->{curtagdepth}++ if($newstate == $STATE_TAG);
+ }
return $self->{state};
}
print "FILENAME SQL: $sql\n" if($self->{verbose});
my ($path, $name)=$self->{db}->cmd_onerow($sql, $id);
my $id3fs_path=join('/', map { $_->{name}; } @{$self->{elements}});
- return($self->{db}->relativise($path, $name, $mountpoint, $id3fs_path));
+ return($self->{db}->relativise($path, $name, $mountpoint));
}
die("DB::filename: unhandled case\n"); #FIXME
}
return(\@tags, \@tags_vals, $lasttag);
}
+# we just filter $ALLTRACKS, $NOARTIST and $NOALBUM
+# filtering tags properly requires up to four levels of recursion
+# (tag/tagval/AND/NOT) and is too slow
sub filter
{
my($self, @dirs)=@_;
my $base=$self->{path};
my @outdirs=();
- # depth 4 to allow for tag/tagval/AND/NOT
- my $maxdepth=4;
for my $dir (@dirs)
{
-# print "\nFILTER (",$self->state(), "): $base / $dir\n";
- if($self->empty("$base/$dir", $maxdepth))
+ print "\nFILTER (",$self->state(), "): $base / $dir\n";
+ if($self->empty("$base/$dir"))
{
-# print "empty: $base / $dir\n";
+ print "empty: $base / $dir\n";
}
else
{
-# print "non-empty, accepting: $base / $dir\n";
+ print "non-empty, accepting: $base / $dir\n";
push(@outdirs, $dir);
}
}
sub empty
{
- my($self, $dir, $maxdepth)=@_;
- return 0 unless($maxdepth);
-# print "testing($maxdepth): $dir\n";
- my $path=ID3FS::Path->new($self->{db}, $dir, $self->{verbose});
-# print "PATH INVALID\n" unless($path->isvalid());
+ my($self, $dir)=@_;
+ my $path=ID3FS::Path->new($self->{db}, $dir, $self->{verbose},
+ ($self->{maxtagdepth} - $self->{curtagdepth}));
return 1 unless($path->isvalid());
my($subdirs,$subfiles)=$path->dirents();
-# print "SUBDENTS: ", join(", ", @$subdirs, @$subfiles), "\n";
-# print("SUBFILES: ", join(', ', @$subfiles), "\n") if(@$subfiles);
- return 0 if(@$subfiles);
- for my $subdir (@$subdirs)
- {
-# print "SUBSUB $dir/$subdir\n";
- if(1) #$self->dir_is_special($subdir))
- {
- if($self->empty("$dir/$subdir", ($maxdepth-1)))
- {
-# print "EMPTY: $dir / $subdir\n";
- }
- else
- {
-# print "NONEMPTY: $dir / $subdir\n";
- return 0;
- }
- }
- else
- {
- return 0;
- }
-# return 0 if($self->nonempty("$dir/$subdir", ($maxdepth-1)));
- }
+ return 0 if(@$subfiles || @$subdirs);
return 1;
}
-sub dir_is_special
-{
- my($self, $dir)=@_;
- my $id=$self->{db}->lookup_id("tags", $dir);
- if((grep { $_ eq $dir; } (qw(AND OR NOT), $PATH_ALLTRACKS,
- $PATH_NOARTIST, $PATH_NOALBUM)) ||
- ($id && $self->{db}->tag_has_values($id)))
- {
- return 1;
- }
- return 0;
-}
-
1;