#!/usr/bin/perl use warnings; use strict; use MP3::Info; use Getopt::Std; # some people name files FOO.MP3 and I don't know why use File::Glob qw/:globally :nocase/; $Getopt::Std::STANDARD_HELP_VERSION = not undef; # true! # Quick script to do two things: # 1) Check for MP3 tags and move ones that don't have them out of the way # 2) Organize stuff based on artist/album, etc # This'll do a lot to your filesystem, but it only half-heartedly tries to # behave. # pass "-d" if you want to change the dir our $opt_d; getopt 'd:'; # editable parameters: just change the strings and all will be well. # not really constants, but they were hard-coded before. my $attention = "attention"; my $done = "done"; if ($opt_d) { chdir $opt_d or die "Couldn't chdir to $opt_d: $!\n" } # Set up the $attention and $done directories for ($attention, $done) { unless (-e) { mkdir $_ or die "Couldn't mkdir $_: $!\n" } } # glob is the what the shell does -- handy function for my $f (glob "*.mp3") { my $tag = get_mp3tag $f; # check for MP3 data unless (defined($tag) && $tag->{TITLE} ne '' && $tag->{AUTHOR} ne '' && $tag->{ALBUM} ne '') { print "No tag info (or only partial info) for file $f!\n"; # move the file unless it's already there if (-e "$attention/$f") { warn "??? $attention/$f already exsists!\n" } else { rename $f, "$attention/$f" or die "Couldn't move $f: $!\n" } } # get tag data my $title = $tag->{TITLE}; my $artist = $tag->{ARTIST}; my $album = $tag->{ALBUM}; my $name = "$artist - $title.mp3"; # refuse to move if they exist if (-e "$done/$artist/$album/$artist - $title.mp3") { warn "??? $done/$artist/$album/$artist - $title.mp3 already exists!\n" } else { my $target = $done; # make the directories if they don't exist for ($artist, $album) { $target .= "/$_"; if (!-e $target) { # some checking & stuff mkdir $target or die "Couldn't mkdir $target: $!\n" } elsif (!-d $target) { # sanity check die "??? $target isn't a directory!\n" } } # finally move the file, i think if (-e "$target/$name") { warn "??? $target/$name already exists!\n" } else { rename $f, "$target/$name" or die "Couldn't move $f: $!\n" } } } __END__ ## the following is here mostly because cperl-mode is definately not everything ## it is cracked up to be. grrr. =pod =head1 NAME organize.pl - Organizes a large mp3 library into folders =head1 SYNOPSIS organize.pl [ B<-d> I ] =head1 DESCRIPTION This script takes either your pwd or the directory you specified on the command line (just one, folks) and starts organizing your mp3 collection. Requires use of the L module, available on CPAN. Any mp3 file that is missing either a) tag info, b) a title, or c) an artist is moved (not copied) to the directory F<$attention> per specification. All files with complete data are sent to sub-directories under F<$done>. The subdirectories are as follows: =over =item $done/ =over =item artist/ =over =item album/ artist - title.mp3 =back =back =back There's extensive error checking since your filesystem is being mucked around in. It dies if it can't create directories. If a file is, for whatever reason, already in place, the script doesn't move the file it's looking at and prints a warning to STDERR. Useful for shell scripts, grep, etc. =cut