implement id3fs-index -l
[id3fs.git] / bin / id3fs-index
1 #!/usr/bin/perl -w
2 # Ian Beckwith <ianb@erislabs.net>
3 #
4
5 use lib '/home/ianb/projects/id3fs/id3fs/lib'; # FIXME: remove
6 use strict;
7 use Getopt::Long qw(Configure);
8 use ID3FS::DB;
9 use File::Find;
10 use vars qw($me);
11 $me=($0=~/(?:.*\/)?(.*)/)[0];
12
13 my $verbose=0;
14 my $help=0;
15 my $basedir=undef;
16 my $dbpath=undef;
17 my $list=0;
18 my @extensions=qw(mp3 flac ogg);
19
20 Configure(qw(bundling no_ignore_case));
21 my $optret=GetOptions(
22     "verbose|v"      => \$verbose,
23     "quiet|q"        => sub { $verbose=0; },
24     "help|h"         => \$help,
25     "dir|d=s"        => \$basedir,
26     "database|f=s"   => \$dbpath,
27     "extensions|e=s" => sub { @extensions=split(/\s+|\s*,\s*/, $_[1]); },
28     "list|l"         => \$list,
29     );
30
31 usage() if(!@ARGV || !$optret || $help);
32
33 if(@ARGV > 1 && !defined($basedir))
34 {
35     die("$me: --basedir must be specified if multiple paths are supplied\n");
36 }
37
38 my $db=ID3FS::DB->new($me, $dbpath, $basedir, $ARGV[0]);
39 if($list)
40 {
41     list_tags($db);
42 }
43 else
44 {
45     $db->last_update(time());
46
47     while(my $path=shift)
48     {
49         File::Find::find( {wanted => \&wanted, follow => 1, no_chdir => 1}, $path);
50     }
51 }
52
53 sub wanted
54 {
55     my $ext='';
56     if(/.*\.(.*)/) { $ext=lc($1); }
57     if(-d)
58     {
59         print("$_\n") if $verbose;
60     }
61     elsif(-f && scalar(grep({ $ext eq lc($_);} @extensions)))
62     {
63         s/^\.\///;
64         $db->add($_);
65     }
66 }
67
68 sub list_tags
69 {
70     my($db)=@_;
71     my @baretags=$db->bare_tags();
72     my $valtags=$db->tags_with_values();
73     if(@baretags)
74     {
75         print "BARE TAGS\n";
76         print join(', ', sort @baretags), "\n\n";
77     }
78     if(keys(%$valtags))
79     {
80         print "TAGS WITH VALUES\n";
81         for my $key (sort keys %$valtags)
82         {
83             print "$key: ", join(', ', sort(@{$valtags->{$key}})), "\n";
84         }
85     }
86 }
87
88 sub usage
89 {
90     die("Usage: $me [-vqh] [-d basedir] [-f dbpath] [-e mp3,ogg,flac] [--] DIR...\n".
91         " -v|--verbose\t\t\tVerbose\n".
92         " -q|--quiet\t\t\tQuiet (default)\n".
93         " -d|--dir=PATH\t\t\tBase directory of source files (default: ARGV[0])\n".
94         " -f|--database=FILE\t\tPath to database file (default: basedir/.id3fs)\n".
95         " -e|--extensions=EXT1,EXT2\tFile extensions to index (default: mp3, ogg, flac)\n".
96         " -h|--help\t\t\tThis help\n".
97         " --\t\t\t\tEnd of options\n");
98 }
99
100 __END__
101
102 =head1 NAME
103
104 id3fs-index - Add files to id3fs index
105
106 =head1 SYNOPSIS
107
108 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>...]
109
110 =head1 DESCRIPTION
111
112 Extracts id3 tags from mp3 files (and comment tags from ogg and flac
113 files) and adds them to a sqlite database, ready for mounting
114 with L<id3fsd(8)>.
115
116 =head1 OPTIONS
117
118 =over 4
119
120 =item B<-v>
121
122 Enable verbose operation.
123
124 =item B<-q>
125
126 Quiet (no output). This is the default.
127
128 =item S<B<-d >I<PATH>> | S<B<--dir=>I<PATH>>
129
130 Specify base directory of source files. All files will be indexed
131 relative to this point.
132
133 If not specified, defaults to the first non-option argument on the
134 command line. Note that to avoid ambiguities, if more than one
135 directory is specified on the command line, the base directory must
136 be specified explicitly.
137
138 All files indexed must be under the base directory.
139
140 =item S<B<-f >I<FILE>> | S<B<--database=>I<FILE>>
141
142 Database file to use. If not specified, defaults to
143 a hidden file called B<".id3fs"> under the base directory.
144
145 =item S<B<-e >I<EXT1,EXT2>> | S<B<--extensions=>I<EXT1,EXT2>>
146
147 File extensions to consider when indexing.
148 Defaults to B<.mp3>, B<.ogg> and B<.flac>.
149
150 =item B<-h>
151
152 Show a short help message.
153
154 =item B<-->
155
156 End of options.
157
158 =back
159
160 =head1 EXAMPLES
161
162 Index all files in the current directory:
163
164     id3fs-index .
165
166 Index current directory, printing each subdirectory as it recurses
167 into it:
168
169     id3fs-index -v .
170
171 Just index some sub-directories:
172
173     id3fs-index -d . dir1 dir2
174
175 Store the database in a custom location:
176
177     id3fs-index -f ~/.id3fs/index.sqlite .
178
179 Only index .mp3 and .flac files:
180
181     id3fs-index -e mp3,flac .
182
183 =head1 BUGS
184
185 Please report any found to ianb@erislabs.net
186
187 =head1 SEE ALSO
188
189 L<id3fsd(8)>
190
191 =head1 AUTHOR
192
193 Ian Beckwith <ianb@erislabs.net>
194
195 =head1 AVAILABILITY
196
197 The latest version can be found at:
198
199 B<http://erislabs.net/ianb/projects/id3fs/>
200
201 =head1 COPYRIGHT
202
203 Copyright 2010 Ian Beckwith <ianb@erislabs.net>
204
205 This program is free software: you can redistribute it and/or modify
206 it under the terms of the GNU General Public License as published by
207 the Free Software Foundation; either version 3 of the License, or
208 (at your option) any later version.
209
210 This program is distributed in the hope that it will be useful,
211 but WITHOUT ANY WARRANTY; without even the implied warranty of
212 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
213 GNU General Public License for more details.
214
215 You should have received a copy of the GNU General Public License
216 along with this program.  If not, see <http://www.gnu.org/licenses/>.
217
218 =cut