start id3fs-tag
authorIan Beckwith <ianb@erislabs.net>
Sat, 30 Oct 2010 00:27:03 +0000 (01:27 +0100)
committerIan Beckwith <ianb@erislabs.net>
Sat, 30 Oct 2010 00:27:03 +0000 (01:27 +0100)
bin/id3fs-tag [new file with mode: 0644]

diff --git a/bin/id3fs-tag b/bin/id3fs-tag
new file mode 100644 (file)
index 0000000..29cc455
--- /dev/null
@@ -0,0 +1,296 @@
+#!/usr/bin/perl -w
+#
+# 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 strict;
+use Getopt::Long qw(Configure);
+use ID3FS::AudioFile;
+use vars qw($me);
+$me=($0=~/(?:.*\/)?(.*)/)[0];
+
+my $verbose=0;
+my $help=0;
+my ($artist, $album, $track, $tracknum, $year, $v1genre, $comment,
+    $delete_artist, $delete_album, $delete_track, $delete_tracknum,
+    $delete_year, $delete_v1genre, $delete_comment, $delete_all,
+    $delete_genre, $genre, $add_tags, $delete_tags, @replace_tags);
+
+Configure(qw(bundling no_ignore_case));
+my $optret=GetOptions(
+    "verbose|v"                    => \$verbose,
+    "help|h"                       => \$help,
+    "artist|a=s"                   => \$artist,
+    "album|l=s"                    => \$album,
+    "song|s=s"                     => \$track,
+    "tracknum|n=s"                 => \$tracknum,
+    "year|y=i"                     => \$year,
+    "v1genre|1=s"                  => \$v1genre,
+    "comment|c=s"                  => \$comment,
+    "delete-artist|A"              => \$delete_artist,
+    "delete-album|L"               => \$delete_album,
+    "delete-song|S"                => \$delete_track,
+    "delete-tracknum|N"            => \$delete_tracknum,
+    "delete-year|Y"                => \$delete_year,
+    "delete-v1genre|0"             => \$delete_v1genre,
+    "delete-comment|C"             => \$delete_comment,
+    "delete|delete-all|D"          => \$delete_all,
+    "delete-genre|G|delete-tags"   => \$delete_genre,
+    "genre|g|replace-all-tags|R=s" => \$genre,
+    "add-tags|tags|t=s"            => \$add_tags,
+    "delete-tags|T=s"              => \$delete_tags,
+    "replace-tags|r=s{2}"          => \@replace_tags,
+    );
+
+usage() if(!@ARGV || !$optret || $help);
+
+while(my $filename=shift @ARGV)
+{
+    unless(-f $filename)
+    {
+       warn("$me: $filename: not found\n");
+       next;
+    }
+    my $file=ID3FS::AudioFile->new($filename);
+    my $changes=0;
+    $changes =  do_deletes($file);
+    $changes += do_adds($file);
+    if($changes)
+    {
+       do_write($file);
+    }
+    else
+    {
+       do_display($file);
+    }
+}
+
+sub do_deletes
+{
+    my($file)=@_;
+    $file->delete_artist()           if($delete_artist);
+    $file->delete_album()            if($delete_album);
+    $file->delete_track()            if($delete_track);
+    $file->delete_tracknum()         if($delete_tracknum);
+    $file->delete_year()             if($delete_year);
+    $file->delete_v1genre()          if($delete_v1genre);
+    $file->delete_comment()          if($delete_comment);
+    $file->delete_all()              if($delete_all);
+    $file->delete_genre()            if($delete_genre);
+    $file->delete_tags($delete_tags) if($delete_tags);
+    if(@replace_tags && $replace_tags[0])
+    {
+       $file->delete_tags($replace_tags[0]);
+    }
+
+    return($delete_artist   || $delete_album  || $delete_track   ||
+          $delete_tracknum || $delete_year   || $delete_v1genre ||
+          $delete_comment  || $delete_all    || $delete_genre   ||
+          $delete_tags     || (@replace_tags && $replace_tags[0]));
+}
+
+sub do_adds
+{
+    my($file)=@_;
+    $file->artist($artist)     if($artist);
+    $file->album($album)       if($album);
+    $file->track($track)       if($track);
+    $file->tracknum($tracknum) if($tracknum);
+    $file->year($year)         if($year);
+    $file->v1genre($v1genre)   if($v1genre);
+    $file->comment($comment)   if($comment);
+    $file->genre($genre)       if($genre);
+    $file->add_tags($add_tags) if($add_tags);
+    if(@replace_tags && $replace_tags[0])
+    {
+       $file->add_tags($replace_tags[1]);
+    }
+
+    return($artist  || $album || $track    || $tracknum || $year || $v1genre ||
+          $comment || $genre || $add_tags || (@replace_tags && $replace_tags[0]));
+}
+
+sub do_write
+{
+    my($file)=@_;
+    $file->write(); 
+}
+
+sub do_display
+{
+    my($file)=@_;
+}
+
+sub usage
+{
+    die("Usage: $me [-vhALSNY0CDG] [-a ARTIST] [-l ALBUM] [-s SONG] [-n TRACKNUM] FILES...\n".
+       "       $me [-y YEAR] [-g GENRE] [-1 V1GENRE] [-c COMMENT] [--] FILES...\n".
+       "       $me [-t TAGS,TO,ADD] [-T TAGS,TO,DELETE]  FILES...\n".
+       "       $me [-r TAGS,TO,DELETE, TAGS,TO,ADD] [-R TAGS,TO,OVERWRITE,WITH] FILES...\n".
+
+       "  verbose|v                 \n".
+       "  help|h                 \n".
+       "  artist|a=s                 \n".
+       "  album|l=s                 \n".
+       "  song|s=s                 \n".
+       "  tracknum|n=s                 \n".
+       "  year|y=i                 \n".
+       "  v1genre|1=s                 \n".
+       "  comment|c=s                 \n".
+       "  delete-artist|A                 \n".
+       "  delete-album|L                 \n".
+       "  delete-song|S                 \n".
+       "  delete-tracknum|N                 \n".
+       "  delete-year|Y                 \n".
+       "  delete-v1genre|0                 \n".
+       "  delete-comment|C                 \n".
+       "  delete|delete-all|D                 \n".
+       "  delete-genre|G|delete-tags                 \n".
+       "  genre|g|replace-all-tags|R=s                 \n".
+       "  add-tags|tags|t=s                 \n".
+       "  delete-tags|T=s                 \n".
+       "  replace-tags|r=s{2}                 \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__
+
+=head1 NAME
+
+id3fs-index - Add files to id3fs index
+
+=head1 SYNOPSIS
+
+B<id3fs-index> [B<-lvh>] S<[B<-d >I<basedir>]> S<[B<-f >I<dbpath>]> S<[B<-e >I<mp3,ogg,flac>]> [B<-->] [I<DIR>...]
+
+=head1 DESCRIPTION
+
+Extracts id3 tags from mp3 files (and comment tags from ogg and flac
+files) and adds them to a sqlite database, ready for mounting
+with L<id3fsd(8)>.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-l> | B<--list>
+
+List tags in use in specified database.
+
+=item S<B<-d >I<PATH>> | S<B<--dir=>I<PATH>>
+
+Specify base directory of source files. All files will be indexed
+relative to this point.
+
+If not specified, defaults to the first non-option argument on the
+command line. Note that to avoid ambiguities, if more than one
+directory is specified on the command line, the base directory must
+be specified explicitly.
+
+All files indexed must be under the base directory.
+
+=item S<B<-f >I<FILE>> | S<B<--database=>I<FILE>>
+
+Database file to use. If not specified, defaults to
+a hidden file called B<".id3fs"> under the base directory.
+
+=item S<B<-e >I<EXT1,EXT2>> | S<B<--extensions=>I<EXT1,EXT2>>
+
+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.
+
+=item B<-->
+
+End of options.
+
+=back
+
+=head1 EXAMPLES
+
+Index all files in the current directory:
+
+    id3fs-index .
+
+Index current directory, printing each subdirectory as it recurses
+into it:
+
+    id3fs-index -v .
+
+Just index some sub-directories:
+
+    id3fs-index -d . dir1 dir2
+
+Store the database in a custom location:
+
+    id3fs-index -f ~/.id3fs/index.sqlite .
+
+Only index .mp3 and .flac files:
+
+    id3fs-index -e mp3,flac .
+
+=head1 BUGS
+
+Please report any found to ianb@erislabs.net
+
+=head1 SEE ALSO
+
+L<id3fsd(8)>, L<MP3::Tag>, L<Audio::Flac::Header>, L<Ogg::Vorbis::Header>
+
+=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:
+
+L<http://erislabs.net/ianb/projects/id3fs/>
+
+=head1 COPYRIGHT
+
+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/>.
+
+=cut