3 # id3fs - a FUSE-based filesystem for browsing audio metadata
4 # Copyright (C) 2010 Ian Beckwith <ianb@erislabs.net>
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 use lib '/home/ianb/projects/id3fs/id3fs/lib'; # FIXME: remove
21 use Getopt::Long qw(Configure);
25 $me=($0=~/(?:.*\/)?(.*)/)[0];
33 my @extensions=qw(mp3 flac ogg);
36 Configure(qw(bundling no_ignore_case));
37 my $optret=GetOptions(
38 "verbose|v" => \$verbose,
39 "quiet|q" => sub { $verbose=0; },
41 "dir|d=s" => \$basedir,
42 "database|f=s" => \$dbpath,
43 "extensions|e=s" => sub { @extensions=split(/\s+|\s*,\s*/, $_[1]); },
51 usage() if(!@ARGV || !$optret || $help);
52 $init=1 unless($list);
54 unless(defined($basedir) && defined($dbpath))
56 $basedir=ID3FS::DB::find_db($me, $init, @ARGV);
57 exit unless($basedir);
58 my $absbase=Cwd::abs_path($basedir);
61 if(Cwd::abs_path($dir) !~ /^\Q$absbase\E/)
63 die("$me: $dir: must be under basedir $absbase - use --basedir to specify\n");
67 my $db=ID3FS::DB->new($me, $verbose, $init, $basedir, $dbpath);
76 $db->last_update(time());
77 my $base=$db->base_dir();
78 my $abs_base=Cwd::abs_path($base);
81 if(Cwd::abs_path($path) !~ /^$abs_base/)
83 print "$me: $path is outside $base, skipping\n";
85 File::Find::find( {wanted => \&wanted, follow => 1, no_chdir => 1}, $path);
87 my $directories_pruned=$db->prune_directories();
88 if($files_pruned || $directories_pruned)
90 print "$me: removing data from pruned files\n" if $verbose;
93 print "$me: analyzing db\n" if $verbose;
100 if(/.*\.(.*)/) { $ext=lc($1); }
103 print("$_\n") if $verbose;
106 elsif(-f && scalar(grep({ $ext eq lc($_);} @extensions)))
117 $dir=Cwd::abs_path($dir);
118 return unless(opendir(DIR, $dir));
119 my $base=Cwd::abs_path($db->base_dir());
121 my @oldfiles=$db->files_in($dir);
122 my @newfiles=grep { !/^\.\.?$/; } readdir(DIR);
124 @oldfiles=sort @oldfiles;
125 @newfiles=sort @newfiles;
128 for my $file (@oldfiles)
130 unless(exists($hash{$file}))
133 $db->unindex($dir, $file);
141 my @baretags=$db->bare_tags();
142 my $valtags=$db->tags_with_values();
146 print join(', ', sort @baretags), "\n\n";
150 print "TAGS WITH VALUES\n";
151 for my $key (sort keys %$valtags)
153 print "$key: ", join(', ', sort(@{$valtags->{$key}})), "\n";
160 die("Usage: $me [-vqh] [-d basedir] [-f dbpath] [-e mp3,ogg,flac] [--] DIR...\n".
161 " -v|--verbose\t\t\tVerbose\n".
162 " -q|--quiet\t\t\tQuiet (default)\n".
163 " -d|--dir=PATH\t\t\tBase directory of source files (default: ARGV[0])\n".
164 " -f|--database=FILE\t\tPath to database file (default: basedir/.id3fs)\n".
165 " -e|--extensions=EXT1,EXT2\tFile extensions to index (default: mp3, ogg, flac)\n".
166 " -h|--help\t\t\tThis help\n".
167 " --\t\t\t\tEnd of options\n");
174 id3fs-index - Add files to id3fs index
178 B<id3fs-index> [B<-vqh>] S<[B<-d >I<basedir>]> S<[B<-f >I<dbpath>]> S<[B<-e >I<mp3,ogg,flac>]> [B<-->] [I<DIR>...]
182 Extracts id3 tags from mp3 files (and comment tags from ogg and flac
183 files) and adds them to a sqlite database, ready for mounting
192 Enable verbose operation.
196 Quiet (no output). This is the default.
198 =item S<B<-d >I<PATH>> | S<B<--dir=>I<PATH>>
200 Specify base directory of source files. All files will be indexed
201 relative to this point.
203 If not specified, defaults to the first non-option argument on the
204 command line. Note that to avoid ambiguities, if more than one
205 directory is specified on the command line, the base directory must
206 be specified explicitly.
208 All files indexed must be under the base directory.
210 =item S<B<-f >I<FILE>> | S<B<--database=>I<FILE>>
212 Database file to use. If not specified, defaults to
213 a hidden file called B<".id3fs"> under the base directory.
215 =item S<B<-e >I<EXT1,EXT2>> | S<B<--extensions=>I<EXT1,EXT2>>
217 File extensions to consider when indexing.
218 Defaults to B<.mp3>, B<.ogg> and B<.flac>.
222 Show a short help message.
232 Index all files in the current directory:
236 Index current directory, printing each subdirectory as it recurses
241 Just index some sub-directories:
243 id3fs-index -d . dir1 dir2
245 Store the database in a custom location:
247 id3fs-index -f ~/.id3fs/index.sqlite .
249 Only index .mp3 and .flac files:
251 id3fs-index -e mp3,flac .
255 Please report any found to ianb@erislabs.net
263 Ian Beckwith <ianb@erislabs.net>
267 The latest version can be found at:
269 B<http://erislabs.net/ianb/projects/id3fs/>
273 Copyright 2010 Ian Beckwith <ianb@erislabs.net>
275 This program is free software: you can redistribute it and/or modify
276 it under the terms of the GNU General Public License as published by
277 the Free Software Foundation; either version 3 of the License, or
278 (at your option) any later version.
280 This program is distributed in the hope that it will be useful,
281 but WITHOUT ANY WARRANTY; without even the implied warranty of
282 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
283 GNU General Public License for more details.
285 You should have received a copy of the GNU General Public License
286 along with this program. If not, see <http://www.gnu.org/licenses/>.