All pastes #36649 Raw Edit

Mine

public text v1 · immutable
#36649 ·published 2006-01-13 02:10 UTC
rendered paste body
#!/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 = "$title - $artist.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<directory> ]

=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<MP3::Info|MP3::Info> 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