fixed filter
authorIan Beckwith <ianb@erislabs.net>
Sun, 17 Oct 2010 01:29:46 +0000 (02:29 +0100)
committerIan Beckwith <ianb@erislabs.net>
Sun, 17 Oct 2010 01:29:46 +0000 (02:29 +0100)
lib/ID3FS/Fuse.pm
lib/ID3FS/Path.pm

index 62dd3a8..058b868 100644 (file)
@@ -97,7 +97,7 @@ sub getdir
     return(-ENOTDIR()) unless($path->isdir());
     my @dents=();
     my($dirs, $files)=$path->dirents();
-    push(@dents, $self->filter($filename, @$dirs));
+    push(@dents, $path->filter(@$dirs));
     push(@dents, @$files);
     if(@dents)
     {
@@ -106,44 +106,6 @@ sub getdir
     return(0);
 }
 
-sub filter
-{
-    my($self, $base, @dirs)=@_;
-    my @outdirs=();
-    for my $dir (@dirs)
-    {
-       print "hascontents: $base / $dir\n";
-       my $path=ID3FS::Path->new($self->{db}, "$base/$dir");
-       next unless($path->isvalid());
-       my($subdirs,$subfiles)=$path->dirents();
-       print "SUBDENTS: ", join(", ", @$subdirs, @$subfiles), "\n";
-       next unless(@$subdirs || @$subfiles);
-       if(!@$subfiles || scalar(@$subdirs) < 3)
-       {
-           my $subdirents=0;
-           for my $subdir (@$subdirs)
-           {
-               if(grep { $_ eq $subdir; } qw(AND OR NOT))
-               {
-                   my $subsubpath=ID3FS::Path->new($self->{db}, "$base/$dir/$subdir");
-                   if($path->isvalid())
-                   {
-                       my($subsubdirs,$subsubfiles)=$subsubpath->dirents();
-                       $subdirents++ if(@$subsubdirs || @$subsubfiles);
-                   }
-               }
-               else
-               {
-                   $subdirents++;
-               }
-           }
-           next unless($subdirents);
-       }
-       push(@outdirs, $dir);
-    }
-    return(@outdirs)
-}
-
 # unused stubs
 sub mknod       { print "FUSE: mknod\n";       return -EROFS();      }
 sub mkdir       { print "FUSE: mkdir\n";       return -EROFS();      }
index dcfe0b7..8284a98 100644 (file)
@@ -30,6 +30,8 @@ sub new
     $self->{elements}=[];
     $self->{db}=shift;
     $self->{path}=shift;
+    $self->{path} =~ s/\/\//\//g; # drop doubled slashes
+
     $self->parse();
 #    print "STATE: ", $self->state(), "\n";
     return $self;
@@ -559,9 +561,9 @@ sub tags
        $sql .= "WHERE " . join(' AND ', @andclauses) . "\n";
     }
     $sql .= "GROUP BY tags.name;";
-    print "SQL(TAGS): $sql\n";
+#    print "SQL(TAGS): $sql\n";
     my @tagnames=$self->{db}->cmd_firstcol($sql);
-    print "SUBNAMES: ", join(', ', @tagnames), "\n";
+#    print "SUBNAMES: ", join(', ', @tagnames), "\n";
     return(@tagnames);
 }
 
@@ -591,7 +593,7 @@ sub artists
             "INNER JOIN artists ON files.artists_id=artists.id\n" .
             "WHERE artists.name != ''\n" .
             "GROUP BY artists.name;");
-    print "SQL(ARTISTS): $sql\n";
+#    print "SQL(ARTISTS): $sql\n";
     my @tagnames=$self->{db}->cmd_firstcol($sql);
     print "ARTISTS: ", join(', ', @tagnames), "\n";
     return(@tagnames);
@@ -623,7 +625,7 @@ sub albums
              "WHERE albums.name != ''\n" .
              "GROUP BY albums.name;");
     }
-    print "SQL(ALBUMS): \n$sql\n";
+#    print "SQL(ALBUMS): \n$sql\n";
     my @names=$self->{db}->cmd_firstcol($sql);
     print "ALBUMS: ", join(', ', @names), "\n";
     return(@names);
@@ -648,7 +650,7 @@ sub artist_albums
             "INNER JOIN artists ON artists.id=files.artists_id\n" .
             "WHERE artists.id=? and albums.name <> ''\n" .
             "GROUP BY albums.name\n");
-    print "ARTIST_ALBUMS SQL: $sql\n";
+#    print "ARTIST_ALBUMS SQL: $sql\n";
     my @albums=$self->{db}->cmd_firstcol($sql, $artist_id);
     print "ALBUMS: ", join(', ', @albums), "\n";
     return(@albums);
@@ -673,7 +675,7 @@ sub artist_tracks
             "INNER JOIN albums  ON albums.id=files.albums_id\n" .
             "WHERE artists.id=? AND albums.name=''\n" .
             "GROUP BY files.name\n");
-    print "ARTIST_TRACKS SQL: $sql\n";
+#    print "ARTIST_TRACKS SQL: $sql\n";
     my @names=$self->{db}->cmd_firstcol($sql, $artist_id);
     print "ARTISTTRACKS: ", join(', ', @names), "\n";
     return(@names);
@@ -687,7 +689,7 @@ sub album_tracks
             "INNER JOIN artists ON artists.id=files.artists_id\n" .
             "WHERE artists.id=? AND albums.id=?\n" .
             "GROUP BY files.name\n");
-    print "ALBUM_TRACKS SQL($artist_id, $album_id): $sql\n";
+#    print "ALBUM_TRACKS SQL($artist_id, $album_id): $sql\n";
     my @names=$self->{db}->cmd_firstcol($sql, $artist_id, $album_id);
     print "TRACKS: ", join(', ', @names), "\n";
     return(@names);
@@ -731,7 +733,7 @@ sub tracks
        $sql .= "WHERE artists.name =''\n";
     }
     $sql .= "GROUP BY files.name;";
-    print "TRACKS SQL($self->{path}): $sql\n";
+#    print "TRACKS SQL($self->{path}): $sql\n";
     my @names=$self->{db}->cmd_firstcol($sql);
     print "TRACKS: ", join(', ', @names), "\n";
     return(@names);
@@ -748,7 +750,7 @@ sub filename
                 "INNER JOIN paths ON files.paths_id=paths.id\n" .
                 "WHERE files.id=?\n" .
                 "GROUP BY paths.name, files.name");
-       print "FILENAME SQL: $sql\n";
+#      print "FILENAME SQL: $sql\n";
        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));
@@ -993,7 +995,7 @@ sub tags_with_values
     my $sql=("SELECT p.name, t.name  FROM tags t\n" .
             "INNER JOIN tags p ON t.parents_id=p.id\n" .
             "GROUP BY p.name, t.name\n");
-    print "SQL: $sql\n";
+#    print "SQL: $sql\n";
     my $result=$self->{db}->cmd_rows($sql);
     my $tags={};
     for my $pair (@$result)
@@ -1003,4 +1005,85 @@ sub tags_with_values
     return $tags;
 }
 
+
+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 "FILTER (",$self->state(), "): $base / $dir\n";
+       if($self->empty("$base/$dir", $maxdepth))
+       {
+#          print "empty: $base / $dir\n";
+       }
+       else
+       {
+#          print "accepting: $base / $dir\n";
+           push(@outdirs, $dir);
+       }
+    }
+    return(@outdirs);
+}
+
+sub empty
+{
+    my($self, $dir, $maxdepth)=@_;
+    return 1 unless($maxdepth);
+#    print "testing($maxdepth): $dir\n";
+    my $path=ID3FS::Path->new($self->{db}, $dir);
+#    print "PATH INVALID\n" unless($path->isvalid());
+    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 1;
+}
+
+sub tagname_has_values
+{
+    my($self, $name)=@_;
+    my $id=$self->{db}->lookup_id("tags", $name);
+    return 0 unless($id);
+    return $self->{db}->tag_has_values($id);
+
+}
+
+sub dir_is_special
+{
+    my($self, $dir)=@_;
+    if((grep { $_ eq $dir; }
+       qw(AND OR NOT), $PATH_ALLTRACKS, $PATH_NOARTIST, $PATH_NOALBUM) ||
+       ($self->tagname_has_values($dir)))
+    {
+       return 1;
+    }
+    return 0;
+}
+
 1;