#!/usr/bin/perl
##
## Author: David McKeon <@bonzoli.com>
## URL: http://bonzoli.com
## Program: sort_flacs
## Creation Date: Date: 2007/01/31 19:26:53 PST
## Last Revision: $Date$
## Version: v.5
##
#############################################################################
# David McKeon <@bonzoli.com> http://bonzoli.com #
# #
# Copyright (C) 2007-2007 David McKeon. All rights reserved. #
# #
# 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 2 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, write to: #
# #
# Free Software Foundation, Inc. #
# 59 Temple Place - Suite 330 #
# Boston, MA 02111-1307, USA. #
# #
# Or you can find the full GNU GPL online at: http://www.gnu.org #
# #
#############################################################################
## Category: Perl
##
##
##
##
##
#
$| = 1;
use Getopt::Long;
use File::Basename;
use File::Find; # Find files and run a process against them
use File::Path; # create paths/dirs
# NOTE: this program needs /usr/bin/metaflac to read flac tags
$metaflac='/usr/bin/metaflac';
my $USAGE="Usage: sort_flacs [-l target_ogg_directory] NOTE: *.flac works \n";
my $file,$mp3dir,$debug;
if (! $ARGV[0])
{
print "$USAGE\n";
exit;
}
# -d has to be first in command line.
if ($ARGV[0] eq '-l')
{
shift(@ARGV);
$mp3dir=$ARGV[0];
shift(@ARGV);
} else{
$mp3dir='.';
}
#---------------------------------------------------------------------------
Getopt::Long::Configure("no_ignore_case");
GetOptions(
"h|help" => \$help,
"V|version" => \$vers,
#-----------------------
);
#---------------------------------------------------------------------------
if($help){ exec("perldoc $0"); }
if($vers){ version(); }
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
sub version {
my($date) = "\$Date$_";
my($rvsn) = "\$Revision$_";
my($rcsd) = "\$Id$_";
$date =~ s/(.*: +)(.*?)(\s*$)/$2/g;
$rvsn =~ s/(.*: +)(.*?)(\s*$)/$2/g;
$rcsd =~ s/(.*: +)(.*?)(\s*$)/$2/g;
print <
URL: http://bonzoli.com
Creation Date: 2007/01/31 17:26:53 PST
Last Revision: $date PST
Version: v
Copyright (C) 2007-2007 David McKeon. All rights reserved.
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 2 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, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA.
Or you can find the full GNU GPL online at: http://www.gnu.org
EOF
exit;
}
sub move_to_new_dir {
##########################################################################
# FUNCTION DEFINITIONS
#-------------------------------------------------------------------------
# FUNCTION move_to_new_dir
# RECEIVES ($NEWDIR, $NEWFILE, $OLDFILE);
# RETURNS new file with path
# EXPECTS ($NEWDIR, $NEWFILE, $OLDFILE);
# SETS creates new directory when needed, then renames file to that dir
# DOES We will make directory and move file to it, if' directory doesn't exist.
my $NEWDIR=shift;
my $NEWFILE=shift;
my $OLDFILE=shift;
eval { mkpath("$NEWDIR", 1, 0755) };
if ($@) {
print "Couldn\'t create $NEWDIR: $@";
}
else
{
# Create directory worked, moving file now.
#print "Moving: mv $OLDFILE $NEWFILE\n";
if (!rename "$OLDFILE", "$NEWFILE"){
print "ERROR: Failed to move $OLDFILE to $NEWFILE!!!!\n";
}
else
{
# if' it worked then return the new file
return $NEWFILE;
}
}
# We return old file if we didn't make a good directory
return $OLDFILE;
}
sub shellify_string {
##########################################################################
# FUNCTION DEFINITIONS
#-------------------------------------------------------------------------
# FUNCTION shellify_string
# RECEIVES $string
# RETURNS $string
# DOES Going to make this line readable by shell, so mv's and copies work.
# add a backslash before unusual characters
my ( $file );
# shouldn't just shift work here?
$file = shift @_;
#print "my file is $file \n";
#If its not one of these characters put a \ in front of it.
$file =~ s|[^-a-zA-Z0-9_.,/]|\\$&|g;
# backslash newline gets ignored by sh, so we have to use quotes.
$file =~ s|\\\n|'\n'|g;
# make sure name doesn't have a leading -
$file =~ s|^-|./-|;
# null name is unprintable, make it '.'
if ($file eq '') {
$file = ".";
}
return $file;
}
sub sanitize_string {
##########################################################################
# FUNCTION DEFINITIONS
#-------------------------------------------------------------------------
# FUNCTION sanitize_string
# RECEIVES string
# RETURNS sanitized string
# DOES sanitize artist name (or filename fragment) for use as a dir name
my $string = shift;
return 'unsorted' unless $string;
$string = lc($string);
$string =~ s/\bthe\b//;
$string =~ s/_/ /g;
$string =~ s/^ +//;
$string =~ s/ +$//;
$string =~ s/ +/ /g;
$string =~ s/\// /g;
$string =~ s/[,(){}\[\]]//g;
return $string;
}
##### Main ######
foreach $_ (@ARGV)
{
my $file=$_;
my $flacfile=$file;
my ($artist, $album);
my ($name,$path,$suffix) = fileparse($file,'');
print "\nMY FLAC FILE=*$file*\n" if ($debug == 1);
$artist=`$metaflac --show-tag=artist "$file" | cut -d \= -f 2`;
$album=`$metaflac --show-tag=album "$file" | cut -d \= -f 2`;
print "INFO:->$artist,$album\n" if ($debug == 1);
chomp($artist);
chomp($album);
if ($artist) {
## IS THIS RIGHT? GET BACK TEST AGAINST FLAC
#$artist = $tag_flac->{'AUTHOR'};
#$album = $tag_flac->{'TITLE'};
# Perl module wasn't doing so well, swithed to metaflac.
} else {
$artist = "misc";
}
if (! $artist)
{
print "--> NO ID information thats usable, skipping\n";
next;
}
print "PATH IS: $artist/$album\n" if ($debug == 1);
$album = $album || "";
if ( $album =~ /^\s*$/ || $album eq 'title' ) { $album = 'misc' }
$artist = sanitize_string( $artist ) unless $artist eq 'unsorted';
$album = sanitize_string( $album ) unless $album eq 'misc';
print "==>ALBUM=>$artist/$album\n" if ($debug == 1);
my $NEWDIR="$mp3dir/$artist/$album";
my $NEWFILE="$NEWDIR/$name";
my $OLDFILE=$flacfile;
if ( $NEWFILE ne $OLDFILE)
{
$flacfile=move_to_new_dir($NEWDIR, $NEWFILE, $OLDFILE);
}
else{
print "This file *$OLDFILE* already exists, I can't move it.\n" if ($debug == 1);
}
}
######## End Main #######
#---------------------------------------------------------------------------
##
## Use "perldoc sort_flacs" to read the man page below.
#
__END__
=head1 NAME
B - Sorts flacs, based on their tags, ussually this is an APE or ogg,
I used the metaflac binary because it just seemed to work better for this info.
=head1 SYNOPSIS
B
S<[ B<-hv> ]>
S<[ I ]>
=head1 DESCRIPTION
B sorts all flacs based on tags into new artist/album/song directories.
It uses the "metaflac" binary program for tagging information. It was the best
tool for this job I could find. Most of my flacs are ripped with Sound Juicer on
Linux Fedora as of this writing. It does allow for metadata and this "metaflac" program
can read this information. If you haven't discovered "Sound Juicer" its nice/simple
and looks up your CD's as you rip them(cddb), so I was able to do my collection on 3
machines at the same time, put in cd and push left click button, move on.
=head1 QUICK START
The most common usage is as follows:
B [-l target_ogg_directory] NOTE: *.flac works
=head1 STANDARD OPTIONS
B<-h --help>
Prints this information.
B<-v --version>
Prints version information.
=head1 OPTIONS
=head1 EXAMPLE
The example below
B B<-l /mymusic/ogg> I<*.flac>
=head1 BUGS
None.
=head1 SEE ALSO
sort_flacs, sort_mp3s, sort_oggs, sort_wmas
=head1 AUTHOR AND COPYRIGHT
David McKeon <@bonzoli.com> http://bonzoli.com
Copyright (C) 2007-2007 David McKeon. All rights reserved.
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 2 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, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA.
Or you can find the full GNU GPL online at: http://www.gnu.org
=head1 VERSION
Current Revision: v.5
Last Modification: $Date$
=pod SCRIPT CATEGORIES
UNIX/System_administration
=pod OSNAMES
Any