X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=bin%2Fid3fs-index;h=f27c7f6cec95b1d6061565188aa9eae7d94c81d0;hb=d1601af7aa0993a69785157d18d8e3a029b1161a;hp=3dd1227fc06bc2615c38d15ee8db7330f53e03c9;hpb=e5ff4b33ca2396bbc32190f6aec23d4e8bf093c5;p=id3fs.git diff --git a/bin/id3fs-index b/bin/id3fs-index index 3dd1227..f27c7f6 100755 --- a/bin/id3fs-index +++ b/bin/id3fs-index @@ -1,6 +1,20 @@ #!/usr/bin/perl -w -# Ian Beckwith # +# id3fs - a FUSE-based filesystem for browsing audio metadata +# Copyright (C) 2010 Ian Beckwith +# +# 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 . use lib '/home/ianb/projects/id3fs/id3fs/lib'; # FIXME: remove use strict; @@ -14,31 +28,69 @@ my $verbose=0; my $help=0; my $basedir=undef; my $dbpath=undef; -my @extensions=qw(mp3 flac); # ogg); # FIXME +my $list=0; +my $init=0; +my @extensions=qw(mp3 flac ogg); +my $files_pruned; Configure(qw(bundling no_ignore_case)); my $optret=GetOptions( "verbose|v" => \$verbose, - "quiet|q" => sub { $verbose=0; }, "help|h" => \$help, "dir|d=s" => \$basedir, "database|f=s" => \$dbpath, "extensions|e=s" => sub { @extensions=split(/\s+|\s*,\s*/, $_[1]); }, + "list|l" => \$list, ); +if($list && !@ARGV) +{ + push(@ARGV, "."); +} usage() if(!@ARGV || !$optret || $help); +$init=1 unless($list); -if(@ARGV > 1 && !defined($basedir)) +unless(defined($basedir) && defined($dbpath)) { - die("$me: --basedir must be specified if multiple paths are supplied\n"); + $basedir=ID3FS::DB::find_db($me, $init, @ARGV); + exit unless($basedir); + my $absbase=Cwd::abs_path($basedir); + for my $dir (@ARGV) + { + if(Cwd::abs_path($dir) !~ /^\Q$absbase\E/) + { + die("$me: $dir: must be under basedir $absbase - use --basedir to specify\n"); + } + } } +my $db=ID3FS::DB->new($me, $verbose, $init, $basedir, $dbpath); +exit unless($db); -my $db=ID3FS::DB->new($me, $dbpath, $basedir, $ARGV[0]); -$db->last_update(time()); - -while(my $path=shift) +if($list) +{ + list_tags($db); +} +else { - File::Find::find( {wanted => \&wanted, follow => 1, no_chdir => 1}, $path); + $db->last_update(time()); + my $base=$db->base_dir(); + my $abs_base=Cwd::abs_path($base); + while(my $path=shift) + { + if(Cwd::abs_path($path) !~ /^$abs_base/) + { + print "$me: $path is outside $base, skipping\n"; + } + File::Find::find( {wanted => \&wanted, follow => 1, no_chdir => 1}, $path); + } + my $directories_pruned=$db->prune_directories(); + if($files_pruned || $directories_pruned) + { + print "$me: pruning removed files from db\n" if $verbose; + $db->remove_unused(); + } + print "$me: analyzing db\n" if $verbose; + $db->analyze(); } sub wanted @@ -48,6 +100,7 @@ sub wanted if(-d) { print("$_\n") if $verbose; + prune($_); } elsif(-f && scalar(grep({ $ext eq lc($_);} @extensions))) { @@ -56,16 +109,61 @@ sub wanted } } +sub prune +{ + my $dir=shift; + $dir=Cwd::abs_path($dir); + return unless(opendir(DIR, $dir)); + my $base=Cwd::abs_path($db->base_dir()); + $dir=~s/^$base\/?//; + my @oldfiles=$db->files_in($dir); + my @newfiles=grep { !/^\.\.?$/; } readdir(DIR); + closedir(DIR); + @oldfiles=sort @oldfiles; + @newfiles=sort @newfiles; + my %hash; + # hash slice! + @hash{@newfiles}=(); + for my $file (@oldfiles) + { + unless(exists($hash{$file})) + { + $files_pruned=1; + $db->unindex($dir, $file); + } + } +} + +sub list_tags +{ + my($db)=@_; + my @baretags=$db->bare_tags(); + my $valtags=$db->tags_with_values(); + if(@baretags) + { + print "BARE TAGS\n"; + print join(', ', sort @baretags), "\n\n"; + } + if(keys(%$valtags)) + { + print "TAGS WITH VALUES\n"; + for my $key (sort keys %$valtags) + { + print "$key: ", join(', ', sort(@{$valtags->{$key}})), "\n"; + } + } +} + sub usage { - die("Usage: $me [-vqh] [-d basedir] [-f dbpath] [-e mp3,ogg,flac] [--] DIR...\n". - " -v|--verbose\t\t\tVerbose\n". - " -q|--quiet\t\t\tQuiet (default)\n". - " -d|--dir=PATH\t\t\tBase directory of source files (default: ARGV[0])\n". - " -f|--database=FILE\t\tPath to database file (default: basedir/.id3fs)\n". - " -e|--extensions=EXT1,EXT2\tFile extensions to index (default: mp3, ogg, flac)\n". - " -h|--help\t\t\tThis help\n". - " --\t\t\t\tEnd of options\n"); + die("Usage: $me [-lvh] [-d basedir] [-f dbpath] [-e mp3,ogg,flac] [--] DIR...\n". + " -d|--dir=PATH Base directory of source files (default: ARGV[0])\n". + " -f|--database=FILE Path to database file (default: basedir/.id3fs)\n". + " -e|--extensions=EXT1,EXT2 File extensions to index (default: mp3, ogg, flac)\n". + " -l|list List tags in use\n" . + " -v|--verbose Verbose\n". + " -h|--help This help\n". + " -- End of options\n"); } __END__ @@ -76,7 +174,7 @@ id3fs-index - Add files to id3fs index =head1 SYNOPSIS -B [B<-vqh>] S<[B<-d >I]> S<[B<-f >I]> S<[B<-e >I]> [B<-->] [I...] +B [B<-lvh>] S<[B<-d >I]> S<[B<-f >I]> S<[B<-e >I]> [B<-->] [I...] =head1 DESCRIPTION @@ -88,13 +186,9 @@ with L. =over 4 -=item B<-v> +=item B<-l> | B<--list> -Enable verbose operation. - -=item B<-q> - -Quiet (no output). This is the default. +List tags in use in specified database. =item SI> | SI> @@ -118,6 +212,10 @@ a hidden file called B<".id3fs"> under the base directory. File extensions to consider when indexing. Defaults to B<.mp3>, B<.ogg> and B<.flac>. +=item B<-v> + +Enable verbose operation. + =item B<-h> Show a short help message. @@ -157,25 +255,27 @@ Please report any found to ianb@erislabs.net =head1 SEE ALSO -L +L, L, L, L =head1 AUTHOR Ian Beckwith +Many thanks to Aubrey Stark-Toller for help wrangling SQL. + =head1 AVAILABILITY The latest version can be found at: -B +L =head1 COPYRIGHT -Copyright 2010 Ian Beckwith +Copyright (C) 2010 Ian Beckwith 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,