fix relativising symlinks
[id3fs.git] / lib / ID3FS / Path.pm
index e99a801..0326af6 100644 (file)
@@ -1,3 +1,19 @@
+# id3fs - a FUSE-based filesystem for browsing audio metadata
+# Copyright (C) 2010  Ian Beckwith <ianb@erislabs.net>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
 package ID3FS::Path;
 
 use strict;
@@ -79,7 +95,7 @@ sub dirents
 #    print "DIRENTS: FILE: $self->{path}\n";
     if($state==$STATE_ALL)
     {
-       @dents=($PATH_ALLTRACKS, $PATH_NOARTIST, $self->artists());
+       @dents=($self->filter($PATH_ALLTRACKS, $PATH_NOARTIST), $self->artists());
     }
     elsif($state==$STATE_TAG || $state==$STATE_TAGVAL)
     {
@@ -94,10 +110,7 @@ sub dirents
            {
                @dents=qw(AND OR);
            }
-           push(@dents, ($ENABLE_FILTER ?
-                         $self->filter($PATH_ALLTRACKS, $PATH_NOARTIST) :
-                         ($PATH_ALLTRACKS, $PATH_NOARTIST)));
-           push(@dents, $self->artists());
+           push(@dents, $self->filter($PATH_ALLTRACKS, $PATH_NOARTIST), $self->artists());
        }
     }
     elsif($state==$STATE_BOOLEAN)
@@ -116,7 +129,7 @@ sub dirents
     }
     elsif($state==$STATE_ALBUMS)
     {
-       @dents=($self->filter($PATH_ALLTRACKS, $PATH_NOALBUM), $self->albums());
+       @dents=$self->filter($PATH_ALLTRACKS, $PATH_NOALBUM, $self->albums());
     }
     elsif($state==$STATE_TRACKLIST)
     {
@@ -504,11 +517,19 @@ sub tags
 #    print "THASVALS: $hasvals\n";
 #    print "TPARENT: ", (defined($parent)? $parent : "NO"), "\n";
     my @ids=();
-    my $sql=("SELECT tags.name FROM (\n" .
-            $self->tags_subselect() .
-            ") AS subselect\n" .
-            "INNER JOIN files_x_tags ON subselect.files_id=files_x_tags.files_id\n" .
-            "INNER JOIN tags ON files_x_tags.tags_id=tags.id\n");
+    my $sql="SELECT tags.name FROM ";
+    if($self->in_or())
+    {
+       $sql .= "files_x_tags\n";
+    }
+    else
+    {
+       $sql .= ("(\n" .
+                $self->tags_subselect() .
+                ") AS subselect\n" .
+                "INNER JOIN files_x_tags ON subselect.files_id=files_x_tags.files_id\n");
+    }
+    $sql .= "INNER JOIN tags ON files_x_tags.tags_id=tags.id\n";
     my @andclauses=();
     my $id=$self->trailing_tag_id();
 
@@ -667,7 +688,7 @@ sub filename
        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));
+       return($self->{db}->relativise($path, $name, $mountpoint, $self->{path}));
     }
     # should never happen
     return "ERROR";
@@ -679,6 +700,8 @@ sub tags_subselect
     my $hasvals=$self->expecting_values();
     if($self->{in_all})
     {
+       # FIXME: is this used?
+       die "IN_ALL CALLED!!\n";
        return "\tSELECT id FROM files AS files_id\n";
     }
     my $tree=$self->{tagtree};
@@ -743,7 +766,7 @@ sub sql_start
     return $sql;
 }
 
-
+# FIXME: remove
 sub constraints_tag_list
 {
     my($self, @constraints)=@_;
@@ -785,6 +808,7 @@ sub constraints_tag_list
 sub filter
 {
     my($self, @dirs)=@_;
+    return(@dirs) unless($ENABLE_FILTER);
     my $base=$self->{path};
     my @outdirs=();
     for my $dir (@dirs)
@@ -814,4 +838,20 @@ sub empty
     return 1;
 }
 
+# if path is .../OR/ or .../OR/NOT
+sub in_or
+{
+    my($self)=@_;
+    my $tail=$self->tail();
+    return 0 unless($tail);
+    return 0 unless($tail->type() eq "boolean");
+    return 1 if($tail->name() eq "OR");
+    return 0 unless($tail->name() eq "NOT");
+    my $parent=$self->tail_parent();
+    return 0 unless($parent);
+    return 0 unless($parent->type() eq "boolean");
+    return 1 if($parent->name() eq "OR");
+    return 0;
+}
+
 1;