#!/usr/bin/perl # Filename: oggmv # Author: David Ljung # Description: Moves an ogg file according to its vorbiscomment tags use strict; ################################################## # Setup the variables ################################################## my $PROGNAME = $0; $PROGNAME =~ s|.*/||; my $MODE = 0755; # Dir permissions my $ILL_CHARS = '\s~()!*?\"\'\/'; ################################################## # Usage ################################################## sub usage { my $msg; foreach $msg (@_) { print "ERROR: $msg\n"; } print "\n"; print "Usage:\t$PROGNAME [-d] [-v] ..\n"; print "\tMoves an ogg file according to its vorbiscomment tags\n"; print "\t-v\tSet verbose mode\n"; print "\t-d\tSet debug mode\n"; print "\n"; exit -1; } sub parse_args { my @oggs; my $arg; while ($#ARGV>=0) { $arg=shift(@ARGV); if ($arg =~ /^-h$/) { usage(); } if ($arg =~ /^-d$/) { $MAIN::DEBUG=1; next; } if ($arg =~ /^-v$/) { $MAIN::VERBOSE=1; next; } if ($arg =~ /^-/) { usage("Unknown option: $arg"); } push(@oggs,$arg); } usage("No oggs defined") if (!@oggs); @oggs; } sub clean { my ($str) = @_; $str =~ s/\s+$//; $str =~ s|/|-|g; $str =~ s/[$ILL_CHARS]/_/g; $str =~ s/_+/_/g; $str =~ s/_+$//; $str =~ s/^_+//; $str =~ s/\-+/\-/g; $str =~ s/\-+$//; $str =~ s/^\-+//; $str; } ################################################## # Main code ################################################## sub main { my (@oggs) = parse_args(); foreach my $ogg ( @oggs ) { if (! -f $ogg) { print STDERR "[$PROGNAME] Warning: Couldn't find ogg [$ogg]\n"; next; } # Get ogg tags open(TAGS,"vorbiscomment \Q$ogg\E |") || die("[$PROGNAME] Couldn't run vorbiscomment [$ogg]\n"); my %i; ($i{title},$i{artist},$i{album},$i{note}) = ("unknown","unknown","unknown"); while() { chomp; next if /^\s*$/; die("[$PROGNAME] Bad vorbiscomment: [$_]") unless /^(\S+)=(.*)$/; my ($key,$val) = (lc($1),clean($2)); $i{$key} = $val; } close(TAGS); if ($i{artist} eq "unknown" || ($i{title} eq "unknown" && $i{album} eq "unknown")) { print STDERR "[$PROGNAME] Error: No vorbiscomment for ogg [$ogg]\n"; next; } print STDERR "[$PROGNAME] Warning: Missing vorbiscomment for ogg [$ogg]\n" if ($i{title} eq "unknown" || $i{artist} eq "unknown" || $i{album} eq "unknown"); # PATH: //.ogg # Make the directories (-d $i{artist}) || mkdir($i{artist},$MODE) || die("[$PROGNAME] Couldn't make directory [$i{artist}]\n"); (-d "$i{artist}/$i{album}") || mkdir("$i{artist}/$i{album}",$MODE) || die("[$PROGNAME] Couldn't make directory [$i{artist}/$i{album}]\n"); my $file = $i{tracknumber} ? sprintf("$i{artist}/$i{album}/%0.2d-$i{title}.ogg",$i{tracknumber}) : "$i{artist}/$i{album}/$i{title}.ogg"; if (-f $file) { print STDERR "[$PROGNAME] ERROR: $file already exists.\n"; next; } # Move it system("/bin/mv \"$ogg\" \"$file\""); if ($?) { print STDERR "[$PROGNAME] ERROR: $file already exists.\n"; } else { print "$ogg -> $file\n" if ($MAIN::VERBOSE); } } } main();