doc tweaks
[id3fs.git] / sbin / id3fsd
index 31a480f..90b8739 100755 (executable)
 #!/usr/bin/perl -w
-# Ian Beckwith <ianb@erislabs.net>
 #
+# 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/>.
 
+use lib '/home/ianb/projects/id3fs/id3fs/lib'; # FIXME: remove
 use strict;
 use Getopt::Long qw(Configure);
+use ID3FS::DB;
+use ID3FS::Fuse;
+use POSIX;
+
 use vars qw($me);
 $me=($0=~/(?:.*\/)?(.*)/)[0];
 
+our $VERSION="1.00";
 my $verbose=0;
 my $help=0;
+my $dbpath=undef;
+my $tagdepth=undef;
 
 Configure(qw(bundling no_ignore_case));
 my $optret=GetOptions(
-    "verbose|v"  => \$verbose,
-    "quiet|q"    => sub { $verbose=0; },
-    "help|h"     => \$help,
+    "verbose|v"    => sub { $verbose++; },
+    "help|h"       => \$help,
+    "database|f=s" => \$dbpath,
+    "t|tagdepth=s" => \$tagdepth,
+    "o=s"          => sub {;}, # silently drop options passed by mount
     );
 
-usage() if(!@ARGV || !$optret || $help);
+usage() if(scalar(@ARGV) != 2 || !$optret || $help);
+
+my $source=shift;
+my $mountpoint=shift;
+
+my $db=ID3FS::DB->new($me, $verbose, 0, $source, $dbpath);
+exit unless($db);
+
+my $fuse=ID3FS::Fuse->new($db, $source, $mountpoint, $verbose, $tagdepth);
+
+# disassociate from terminal
+unless($verbose)
+{
+    my $pid=fork();
+    if(defined($pid))
+    {
+       exit if($pid);   # parent
+       POSIX::setsid(); # child
+    }
+    else
+    {
+       print "$me: couldn't drop terminal: $!\n";
+    }
+}
+
+$fuse->run();
 
 sub usage
 {
-    die("Usage: $me [-v] [-q] [-h] [--] file...\n".
-       " -v\tVerbose\n".
-       " -q\tQuiet (default)\n".
-       " -h\tThis help\n".
-       " --\tEnd of options\n");
+    die("Usage: $me [-vh] [-f <dbfile>] [-t <tagdepth>] [--] <sourcedir> <mountpoint>\n".
+       " -t|--tagdepth=NUM\tMaximum number of tags in expression (default: 10)\n" .
+       " -f|--database=FILE\tPath to database file\n" .
+       " -v\t\t\tVerbose (repeat for more verbosity)\n".
+       " -h\t\t\tThis help\n".
+       " --\t\t\tEnd of options\n");
 }
 
 __END__
 
-
 =head1 NAME
 
-program - description
+id3fsd - FUSE filesystem for browsing id3 tags
 
 =head1 SYNOPSIS
 
-B<> [I<-v>] [I<-q>] [I<-h>] [I<file>...]
+B<id3fsd> [B<-vh>] S<B<[-f >I<dbfile>]> [B<-->] I<SOURCEDIR> I<MOUNTPOINT>
 
 =head1 DESCRIPTION
 
+id3fsd provides a browsable filesystem of your music files, organised
+into sub-directories by id3 tags (or flac/ogg comments).
+
+id3fsd allows you to construct boolean queries from a tag folksonomy
+such as:
+
+  goth/AND/decade/1980s/
+  postrock/AND/NOT/rating/terrible/
+  thrash/OR/rapmetal/AND/NOT/wears-a-red-hat/
+  prog/AND/decade/1970s/OR/psychedelia/AND/decade/1960s/
+  location/sweden/AND/screamo/AND/postrock/
+
+Multiple tags can be stored in the genre tag, separated by commas.
+An index should first be created with L<id3fs-index(1)>, then id3fsd
+can mount the files in I<SOURCEDIR> on the directory I<MOUNTPOINT>.
+
+If not explicitly specified (with B<-f>), the index is searched for
+at I<SOURCEDIR>/B<.id3fs>.
+
+The resulting filesystem is read-only. Tags appear as directories,
+and files appear as symlinks to the actual files in I<SOURCEDIR>.
+
+=head1 QUICKSTART
+
+To mount a view of F<~/music> on F<~/tags>:
+
+  $ mkdir ~/tags
+  $ id3fs-index ~/music
+  $ id3fsd ~/music ~/tags
+
+You may need to be in the I<fuse> group, or be root.
+
 =head1 OPTIONS
 
 =over 4
 
-=item B<-v>
+=item I<SOURCEDIR>
+
+Directory containing actual audio files and database file F<.id3fs>
+(unless otherwise specified with B<-f>).
+
+=item I<MOUNTPOINT>
+
+Directory to mount the id3fs view of the files.
+
+=item S<B<-t >I<NUM>> | S<B<--tagdepth=>I<NUM>>
 
-Enable verbose operation.
+Maximum number of tags in an expression. A query with many ANDs and
+NOTs can get quite slow. This option allows a cutoff before things get
+too slow, as well as providing some eventual limit when processes
+recurse into the filesystem. The default is 10.
 
-=item B<-q>
+=item S<B<-f >I<FILE>> | S<B<--database=>I<FILE>>
 
-Quiet (no output). This is the default.
+Use database in I<FILE>. The default is I<SOURCEDIR>/B<.id3fs>.
+
+=item B<-v>
+
+Enable verbose operation. Repeat for more verbosity.  If verbose is
+enabled, id3fsd does not detach from the terminal.
 
 =item B<-h>
 
@@ -63,35 +161,136 @@ End of options.
 
 =back
 
-=head1 FILES
+=head1 FILESYSTEM LAYOUT
+
+A path in the filesystem consists of a tag query expression, followed
+by directories containing the matching files, arranged by artist and
+album.
+
+Example paths:
+
+  /krautrock/AND/year/1971/
+  /krautrock/AND/year/1971/Can
+  /krautrock/AND/year/1971/Can/Tago Mago/01-Paperhouse.mp3
+  /krautrock/AND/year/1971/Can/NOALBUM/Can - Oh Yeah (Live).mp3
+  /krautrock/AND/year/1971/Can/TRACKS/01-Paperhouse.mp3
+  /krautrock/AND/year/1971/Can/TRACKS/Can - Oh Yeah (Live).mp3
+  /krautrock/AND/year/1971/NOARTIST/unknown-track.mp3
+  /krautrock/AND/year/1971/TRACKS/01-Paperhouse.mp3
+
+id3fs supports OR, AND and NOT. NOT has the highest precedence,
+followed by AND, so F<foo/OR/NOT/bar/AND/baz> is parsed as
+(foo OR ((NOT bar) AND baz)).
+
+=head2 Tags
+
+Tags are extracted from the B<genre> tag of audio files with
+L<id3fs-index(1)>.
+
+Within the genre frame/comment, tags are separated by commas.
+
+Tags can have values, separated by a slash, eg I<metal/thrash>,
+I<rating/5>. Certain tags are automatically filled in from other file
+metadata, see L</"Special Tags>.
+
+=head2 Special Directories
+
+=over 4
+
+=item B<ALL>
+
+This is a special directory in the root of the filesystem, that
+provides access to all the indexed files, regardless of tags assigned.
+
+=item B<TRACKS>
+
+All tracks that match the given tag expression, whether they have an
+assigned artist and album or not.
+
+=item B<NOARTIST>
+
+Tracks matching the given expression that do not have an artist tag.
+
+=item B<NOALBUM>
+
+Tracks matching the given expression that do not have an album tag.
+
+=back
+
+=head2 Special Tags
+
+Several tags are automatically derived from other metadata in the
+audio files:
+
+=over 4
+
+=item B<year>
+
+Extracted from the B<year> or B<DATE> tag. If not found defaults to
+B<year/UNKNOWN>.
+
+=item B<decade>
+
+Also extracted from the B<year> or B<DATE> tag. If not found
+defaults to B<decade/UNKNOWN>.
+
+=item B<v1genre>
+
+If a mp3 file has an ID3V1.1 genre tag, its value is assigned to
+v1genre.
+
+=item B<audiotype>
+
+Type of audio file (mp3, ogg, flac). Always set.
+
+=back
+
+=head1 FUSE AND MOUNTING AUTOMATICALLY
+
+For others to be able to view your id3fs mount(s), you need to set the
+option B<user_allow_other> in F</etc/fuse.conf>.
+
+To mount a filesystem automatically, put an entry in F</etc/fstab>
+like:
 
-=head1 ENVIRONMENT
+  id3fsd#/source/dir    /mount/point    defaults   0   0
 
-=head1 DIAGNOSTICS
+=head1 CAVEATS
+
+Because id3fs offers a combinatorial explosion of views of your files,
+processes recursing into the mount point will take a B<long> time to
+traverse it.
+
+Ensure your backups, cron jobs, F</etc/updatedb.conf>, etc. are
+configured to exclude the mount point.
 
 =head1 BUGS
 
-None known. Please report any found to ianb@erislabs.net
+Please report any found to ianb@erislabs.net
 
 =head1 SEE ALSO
 
+L<id3fs-index(1)>, L<http://fuse.sourceforge.net>
+
 =head1 AUTHOR
 
 Ian Beckwith <ianb@erislabs.net>
 
+Many thanks to Aubrey Stark-Toller for help wrangling SQL.
+
 =head1 AVAILABILITY
 
 The latest version can be found at:
 
-B<http://erislabs.net/ianb/projects/id3fs/>
+L<http://erislabs.net/ianb/projects/id3fs/>
 
 =head1 COPYRIGHT
 
-Copyright 2010 Ian Beckwith <ianb@erislabs.net>
+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
+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,