Notices
Computer & Technology Related Post here for help and discussion of computing and related technology. Internet, TVs, phones, consoles, computers, tablets and any other gadgets.

fookin perl

Thread Tools
 
Search this Thread
 
Old 17 June 2006, 07:03 PM
  #1  
David_Wallis
Scooby Regular
Thread Starter
 
David_Wallis's Avatar
 
Join Date: Nov 2001
Location: Leeds - It was 562.4bhp@28psi on Optimax, How much closer to 600 with race fuel and a bigger turbo?
Posts: 15,239
Likes: 0
Received 1 Like on 1 Post
Default fookin perl

Can anyone see if they can get this damn thing to work on windows...
Im fairly sure its down to the abs_path stuff, as it works if I put the script in the folder where the mp3 files are, however if i pass it a folder to work with it doesnt work, nor does it enumerate subfolders..

I also have to do set home=c:\
and set the login details..

Code:
#!/usr/bin/perl

#use strict;
use MP3::Info;
use MP3::Tag;
use CDDB;
use File::Basename;
use Cwd qw(abs_path cwd);
use Term::ReadLine;
use File::Path;


my $term = new Term::ReadLine 'mp3cddb';
unless ($term->Features->{preput})
{
	print q~Error: mp3cddb requires a full featured Term::ReadLine.
Either the ::Gnu or ::Perl versions should work
~;
	exit;
}

if ($ARGV[0] eq "-h" || $ARGV[0] eq "--help")
{
	print q~	 mp3cddb Version 1.0
performs cddb lookups and renaming of mp3s using directories as albums

usage: mp3cddb [-h|--help] [-g|--genres] [-n|--nocddb] [-nr|--norename
               [directory [directory]]

--help:	    print this help message
--genres:   print out a list of all accepted ID3v1 genres
--nocddb:   do not try to do any cddb lookup.  Useful if the id3 tags are more
            accurate than the FreeDB data.
--norename: do not rename any files, only set ID3 tags
directory:  a directory containing mp3s that are numerically in track order.
            if no directory is provided, the current working directory is used.
~;
	exit;
}

if ($ARGV[0] eq "-g" || $ARGV[0] eq "--genres")
{
	print "Accepted ID3v1 Genres:\n\n";
	print join("\n", sort @{MP3::Tag::ID3v1::genres()}) . "\n";
	exit;
}

my $nocddb = 0;
if($ARGV[0] eq "-n" || $ARGV[0] eq "--nocddb")
{
	$nocddb = 1;
	shift @ARGV;
}

my $norename = 0;
if($ARGV[0] eq "-nr" || $ARGV[0] eq "--norename")
{
	$norename = 1;
	shift @ARGV;
}


my %Config;
if (open(CONFIG, $ENV{"HOME"} . "/.mp3cddb"))
{
	while (<CONFIG>)
	{
		next if (/^(\#.*|\s*)$/);
		chomp;
		my ($key, $val) = split(/\s+=\s+/, $_, 2);
		if (defined $Config{$key})
		{
			print "Error: you have multiple $key declirations in ~/.mp3cddb\n";
			exit;
		}
		$Config{$key} = $val;
	}
	close(CONFIG);
	
	if (!$Config{"RENAME"} && !$Config{"DONTRENAME"})
	{
		print "You seem to want me to rename files, yet you don't tell me how to...\n" . 
			"I might be smart, but I can't read your mind..only ~/.mp3cddb\n";
		exit;
	}
	if($Config{"RENAME"}){ &check_config_rename($Config{"RENAME"}); }
	if($Config{"RENAMEVA"}){ &check_config_rename($Config{"RENAMEVA"}); }

	# thanks to irc://irc.openprojects.net/#perl !
	# rlandrum: if($var =~ /\{([^\}]+)\}/ && (@x = ($1 =~ m/\%a[aty]/g)) && @x == 1) {
	# xsdg:		perl -e '$txt = "%a - {%b -}%c"; if($txt =~ m#^[^}]* ([^{]* \{ [^}]* \%[^}]+ \})+ [^{}]*$#x){print "moo"}'
	# xsdg:		moo
}
else
{
	print "you don't seem to have a $ENV{'HOME'}/.mp3cddb config file.\n" .
		"I am now writing an example one there, be sure to read it and change as needed!\n";
	&write_config;
	exit;
}

if (! @ARGV)
{
	# ****** DW *******
	print "\nSupposed to set path to CWD as you didnt specify anything\n";
	push(@ARGV, cwd);
}

# global hash of what we ended up doing
my %result;
# global array so that we can re-display errors (in case they get missed)
my @errors;

my $cddb = new CDDB (Debug=>0, Protocol_Version=>5) or die "unable to connect to CDDB: $!";

# having the complete absolute paths is a GOOD THING

my @albums = map { abs_path($_) } @ARGV;


ALBUM: foreach my $album (@albums)
{
	next ALBUM unless (-d $album);
	
	my @cdtoc;
	my @cddb_query;
	my @tracks_in;
	my %disc_info;
	
	print "Working on $album\n";
	
	# wow you really have to quote the hell out of stuff for glob
	my $quoted = $album;
	$quoted =~ s/([\[\]])/\\$1/g;
	
	foreach my $file (sort
			  {
			    $a=~m!^.*/[^/\d]*(\d+)[^/]+$!;
			    my $c=$1;
			    $b=~m!^.*/[^/\d]*(\d+)[^/]+$!;
			    my $d=$1;
			    $c <=> $d
			  }
			  glob quotemeta($quoted) . "/*.[Mm][Pp]3")
	{
		my $info  = get_mp3info($file);
		push (@cdtoc, $info );
		push (@tracks_in, basename($file));
	}
	
	unless ($#tracks_in >= 1)
	{
		&do_error("There are 1 or fewer mp3s in '$album'", $album);
		next ALBUM;
	}
	
	my ($my_disc_id,
		$my_total_tracks,
		$my_total_time,
		@my_frames) = &build_cddb_query(@cdtoc);
	
	print "searching for discid: $my_disc_id, total tracks: $my_total_tracks, total time: ".
	  int($my_total_time/60).":".($my_total_time%60)."\n";
	
	my @discs;
	unless($nocddb)
	{
		@discs = $cddb->get_discs($my_disc_id, [@my_frames], $my_total_time);
	}

	my $newblank = 0;
	if (! @discs)
	{
		print q~
Disk was not found.
Enter a DiscID then Genre (from freedb.org) to use,
a url from freedb.org with the DiscID and Genre in it,
`blank' to create a blank record,
`id3' to aquire data form ID3 tags as a single-artist album,
`id3va' to aquire artists from ID3 tags as a various-artist album,
or leave empty to skip.
~;
		my $new_disc_id = $term->readline("DiscID: ");
		if ($new_disc_id eq "blank")
		{
			$newblank = 1;
		}
		elsif ($new_disc_id eq "id3")
		{
			$newblank = 2;
		}
		elsif ($new_disc_id eq "id3va")
		{
			$newblank = 3;
		}
		elsif (($new_disc_id =~ /^[a-f0-9]{8}$/i) &&
		       ((my $new_genre = $term->readline("Genre: ")) ne ""))
		{
			@{$discs[0]} = ($new_genre, $new_disc_id, "");
		}
		elsif($new_disc_id =~ /cat=(.+?)\&id=([a-f0-9]{8})/i)
		{
			@{$discs[0]} = ($1, $2, "");
		}
		else
		{
			&do_error("Skipped directory '$album'", $album);
			next ALBUM;
		}
	}
	
	my @ranking;
	if (!$newblank)
	{
	
		$|=1;					# unbuffer output...buffer craps up the status output
	
		foreach my $disc (@discs)
		{
			print ".";			# nice status if there are lots of CD's
			
			my ($genre, $cddb_id, $title) = @$disc;
			$disc_info{"$cddb_id ($genre)"} = $cddb->get_disc_details($genre, $cddb_id);
			unless($disc_info{"$cddb_id ($genre)"})
			{
				&do_error("Could not find $cddb_id ($genre) for '$album'", $album);
				next ALBUM;
			}
			$disc_info{"$cddb_id ($genre)"}->{'dgenre'} ||= $genre;
		}
	
		print "\n";				# end status stuff
		$|=0;					# can buffer again
	
		push (@my_frames, $my_total_time * 75);
		my @my_lengths = &offsets_to_seconds (@my_frames);
		my %distance;
		foreach my $cddb_id (sort keys %disc_info)
		{
			my $disc_time = ($disc_info{$cddb_id}->{'disc length'} =~ /(\d+)/)[0];
			my $disc_id = $disc_info{$cddb_id}->{'discid'};
			my @track_offsets = @{$disc_info{$cddb_id}->{'offsets'}};
			
			push (@track_offsets, $disc_time * 75 + $track_offsets[0]);
			my @track_lengths = &offsets_to_seconds (@track_offsets);
			
			$distance{$cddb_id} = &sqr_distance (\@track_lengths, \@my_lengths);
		}
		
		@ranking = sort { $distance{$a} <=> $distance{$b} } keys %distance;
	}
	elsif($newblank == 1)
	{
		$disc_info{"new"}->{'dtitle'} = "";
		foreach my $i (0..$#tracks_in)
		{
			$disc_info{"new"}->{'ttitles'}[$i] = "";
		}
		@ranking = ("new");
	}
	elsif($newblank == 2 || $newblank == 3)
	{
		$disc_info{"new"} = get_id3tags($album, ($newblank==3), @tracks_in);
		@ranking = ("new");
	}

	if (my $choice = &prompt_best ($album, \@ranking, \%disc_info, \@tracks_in))
	{
		&tag_files ($album, $disc_info{$choice}, \@tracks_in);
		$result{$album} = "tagged";
	
		if ($Config{'DORENAME'} && !$norename)
		{
			if (&do_rename ($album, $disc_info{$choice}, \@tracks_in))
			{
				$result{$album} .= " and renamed";
			}
		}
	}
	else
	{
		print "skipping $album, moving on\n\n\n";
		$result{$album} = "skipped";
	}
}

print "Summary of actions:\n";

foreach my $album ( sort keys %result )
{
	print "$result{$album}\t  $album\n";
}

if (@errors)
{
	print "\n\nThere seem to have been some errors:\n\n";
	print "$_\n\n" foreach @errors;
}

exit;


####################
#		   #
#  My subroutines  #
#		   #
#  influenced by   #
# Thomas Geffert's #
#	  tagit.pl #
####################

sub get_id3tags
{
	my ($album, $va, @tracks_in) = @_;
	my $info;

	my $mp3 = MP3::Tag->new($album."/".$tracks_in[0]);
	my @temp = $mp3->autoinfo();
	$info->{'dtitle'} = $temp[2]." / ".$temp[3];
	$info->{'dyear'} = $temp[5];
	$info->{'dgenre'} = $temp[6];
	$info->{'comment'} = $temp[4];
	$mp3->close();

	foreach my $i (0..$#tracks_in) {
		my $mp3 = MP3::Tag->new($album."/".$tracks_in[$i]);
		my @temp = $mp3->autoinfo();
		if($va)
		{
			$info->{'ttitles'}[$i] = $temp[2]." / ".$temp[0];
		}
		else
		{
			$info->{'ttitles'}[$i] = $temp[0];
		}
		$mp3->close();
	}
	return $info;
}	

# prints the error and adds it to the global array of errors
# if $album is defined, it's a fatal error for that album and $result is updated as such
sub do_error
{
	my ($error, $album) = @_;
	print "$error\n\n\n";
	push(@errors, $error);
	$result{$album} = "error";
}
sub check_config_rename
{
	my $rename=shift;
	unless ($rename =~ m!
^(?:
	# each start can be anything not special
	[^{}%]*
		# test to make sure {}'s match and has only 1 proper %tag
		(?: \{ [^{}%]* \% (?:a[tagy]|t[abnt]) [^{}%]* \} |
			# or test just proper %tag not in {}'s
			\% (?:a[tagy]|t[abnt])
		)
)+
# end can be anything not special
[^{}%]* $
								   !oix)
# had enough RegEx fun for today? =)
	{
		print qq!You seem to have a bad RENAME[VA] line in ~/.mp3cddb.	Please check:
	You have matching {}\'s
	You have only 1 %tag inside of each {}
	You are using the apropriate tags (%at, %ta, etc)
!;
		exit;
	}

	if ($rename =~ m/\%t[abnt].*\//i)
	{
		print q!RENAME[VA] contains track-specific data (ta, tb, tn, tt) inside of a directory name.
This will break the renaming, please limit directory names to whole-album data
!;
		exit;
	}

}
sub do_rename
{
	my ($album, $info, @tracks) = (shift, shift,  @{+shift});

	my ($new_dir, @new_files) = &new_names ($album, $info, \@tracks);
	
	if (&make_path($new_dir, $album))
	{
		foreach my $num (0 .. $#tracks)
		{
			unless( rename "$new_dir/$tracks[$num]", "$new_dir/$new_files[$num]" )
			{
				&do_error("Couldn't move '$album/$tracks[$num]' to\n'$new_dir/$new_files[$num]'\nReason: $!", $album);
				return undef;
			}
		}
	}
	else
	{
		#make_path errored or something
		return undef;
	}

	return 1;
}

sub make_path
{
	my ($new_path, $old_path) = @_;
	
	return 1 if $new_path eq $old_path;
	
	mkpath(dirname($new_path), 0, 755);

	if ( -d $new_path )
	{
		# $new_path already exists, lets move everything into it and get rid of $old_path
	
		my $album_glob = $old_path;
		$album_glob =~ s/(\s)/\\$1/oig;
	
		foreach my $file (glob("$album_glob/*"))
		{
			unless( rename $file, "$new_path/" . basename($file) )
			{
				&do_error("Couldn't move '$file' to '$new_path/" . basename($file) . "'\nReason: $!", $old_path);
				return undef;
			}
		}
	
		if (glob("$album_glob/*"))
		{
			&do_error("There seems to be something left in '$old_path', yet it should be empty");
		}
		else
		{
			unless( rmdir($old_path) )
			{
				&do_error("Couldn't remove empty '$old_path'\nReason: $!");
			}
		}
	}
	else
	{
		# $new_path doesn't exist, so we can just rename old to new and be done
		unless( rename $old_path, $new_path )
		{
			&do_error("Couldn't move '$old_path' to '$new_path'\nReason: $!", $old_path);
			return undef;
		}
	}
	return 1;
}


# For my own reference
#	%at:  Album Title
#	%aa:  Album Artist
#	%ag:  Album Genre
#	%ay:  Album Year
#	%ac:  Album Comment
#	%tn:  Track Number (padded to 2 characters, 01..10..99)
#	%tt:  Track Title
#	%ta:  Track Artist (always set)
#	%tb:  Track Artist (only set if different from Album)
#	{.*(%..).*}: optional block
#	%%, %{, %}: replaced by %, {, and }

sub new_names {
	my ($album, $info, @tracks) = (shift, shift,  @{+shift});
	my @renamed;
	my %tag_info;

	# for %%, %{, and %}
	$tag_info{'%'} = '%';
	$tag_info{'{'} = '{';
	$tag_info{'}'} = '}';
	# get whole-album vars
	($tag_info{'aa'}, $tag_info{'at'}) = &split_title($info->{'dtitle'});
	$tag_info{'ag'} = $info->{'dgenre'};
	$tag_info{'ay'} = $info->{'dyear'};
	$tag_info{'ac'} = $info->{'comment'};
	my ($new_dir, $new_file);

	if($info->{'NoVA'} || !$Config{'RENAMEVA'}){
		$Config{'RENAME'} =~ /^(.*?)(?:\/)?([^\/]+)$/o;
		($new_dir, $new_file) = ($1, $2);
	} else {
		$Config{'RENAMEVA'} =~ /^(.*?)(?:\/)?([^\/]+)$/o;
		($new_dir, $new_file) = ($1, $2);
	}
	

	if ($new_dir)
	{
		foreach my $key (keys %tag_info)
		{
			$tag_info{$key} =~ tr!\/\\\:\?\"|\*!-!;
			$tag_info{$key} =~ tr!<>![]!;
			$tag_info{$key} =~ tr! !_! if $Config{'UNDERSCORE'};
		}

		# only album stuff (a[tagy]) is allowed in the dir name
		$new_dir =~ s!
					  (?:
						\{ ([^%{}]*) \% (a[tagy]|[%{}]) ([^%{}]*) \}
						 | ([^%{}]*) \% (a[tagy]|[%{}]) ([^%{}]*)
					  )
					 !
					 ( $5
					   ? $4.$tag_info{$5}.$6
					   : ( $tag_info{$2}
						   ? $1.$tag_info{$2}.$3
						   : ''
						 )
					 )!xoge;
		# if it's complete (starts with /) it's fine, otherwise complete it from $album
		unless($new_dir =~ /^\//o)
		{
			$new_dir = dirname($album) . "/" . $new_dir;
		}
	}
	else
	{
		# if there's no new directory in the config, just use $album
		$new_dir = $album;
	}
	
	foreach my $tNumber (0 .. $#tracks)
	{
		$tag_info{'tn'} = sprintf("%02u", $tNumber + 1);
		if($info->{'NoVA'})
		{
			($tag_info{'tb'}, $tag_info{'tt'}) = (undef, $info->{'ttitles'}[$tNumber]);
		}
		else
		{
			($tag_info{'tb'}, $tag_info{'tt'}) = &split_title($info->{'ttitles'}[$tNumber]);
		}
		# ta is always set, tb sometimes (VA cds)
		$tag_info{'ta'} = $tag_info{'tb'} || $tag_info{'aa'};

		# we have to do this each time to hit the new track info
		foreach my $key (keys %tag_info)
		{
			$tag_info{$key} =~ tr!\/\\\:\?\"|\*!-!;
			$tag_info{$key} =~ tr!<>![]!;
			$tag_info{$key} =~ tr! !_! if $Config{'UNDERSCORE'};
		}
		
		my $newname = $new_file;
		
		unless($newname =~ /\.\S{1,3}$/o)
		{
			$newname .= ".mp3";
		}
		
		$newname =~ s!
					  (?:
						\{ ([^%{}]*) \% (a[tagy]|t[abnt]|[%{}]) ([^%{}]*) \}
						 | ([^%{}]*) \% (a[tagy]|t[abnt]|[%{}]) ([^%{}]*)
					  )
					 !
					 ( $5
					   ? $4.$tag_info{$5}.$6
					   : ( $tag_info{$2}
						   ? $1.$tag_info{$2}.$3
						   : ''
						 )
					 )!xoge;
		push(@renamed, $newname);
	}
	return $new_dir, @renamed;
}

sub tag_files
{
	my ($album, $info, @tracks) = (shift, shift, @{+shift});
	
	my ($aArtist, $aTitle) = &split_title($info->{'dtitle'});
	
	foreach my $tNumber (0 .. $#tracks)
	{
		my ($tArtist, $tTitle);
		if($info->{'NoVA'})
		{
			$tTitle = $info->{'ttitles'}[$tNumber];
		}
		else
		{
			($tArtist, $tTitle) = &split_title($info->{'ttitles'}[$tNumber]);
		}
		
		# if there's a track artist, use it...otherwise use album artist
		$tArtist ||= $aArtist;
		
		my $mp3 = MP3::Tag->new($album . "/" . $tracks[$tNumber]);
		$mp3->get_tags();
		
		if ($Config{"DELID3V1"} && exists $mp3->{ID3v1})
		{
			$mp3->{ID3v1}->remove_tag();
		}
		
		if ($Config{"DELID3V2"} && exists $mp3->{ID3v2})
		{
			$mp3->{ID3v2}->remove_tag();
		}
		
		if ($Config{"ID3V1"})
		{
			# remove_tag on ID3v1 doesn't actually remove it, just blanks it..
			#so we don't have to worry about recreating it
			$mp3->new_tag("ID3v1") unless exists $mp3->{ID3v1};
			
			$mp3->{ID3v1}->song($tTitle);
			$mp3->{ID3v1}->artist($tArtist); 
			$mp3->{ID3v1}->album($aTitle);
			$mp3->{ID3v1}->comment($info->{'comment'}) if $info->{'comment'};
			$mp3->{ID3v1}->year($info->{'dyear'}) if $info->{'dyear'};
			$mp3->{ID3v1}->genre($info->{'dgenre'}) if $info->{'dgenre'};
			$mp3->{ID3v1}->track($tNumber + 1);
			
			$mp3->{ID3v1}->write_tag();
		}
		
		if ($Config{"ID3V2"})
		{
			# remove_tag on ID3v2 actually destorys the tag, so we have to re-create it when we delete it
			$mp3->new_tag("ID3v2") unless exists $mp3->{ID3v2} && !$Config{"DELID3V2"};
			
			my $frameID = $mp3->{ID3v2}->get_frame_ids;
			
			# remove frame (does nothing if it doesn't exist) and then add new one
			$mp3->{ID3v2}->remove_frame("TIT2"); $mp3->{ID3v2}->add_frame("TIT2", $tTitle);
			# artist could be either TPE1 or TPE2, so nuke both
			$mp3->{ID3v2}->remove_frame("TPE1"); $mp3->{ID3v2}->remove_frame("TPE1");
			$mp3->{ID3v2}->add_frame("TPE1", $tArtist);
			
			$mp3->{ID3v2}->remove_frame("TALB"); $mp3->{ID3v2}->add_frame("TALB", $aTitle);
			$mp3->{ID3v2}->remove_frame("COMM"); $mp3->{ID3v2}->add_frame("COMM", "ENG", "Comment",	 $info->{'comment'}) if $info->{'comment'};
			$mp3->{ID3v2}->remove_frame("TYER"); $mp3->{ID3v2}->add_frame("TYER", $info->{'dyear'}) if $info->{'dyear'};
			$mp3->{ID3v2}->remove_frame("TCON"); $mp3->{ID3v2}->add_frame("TCON", $info->{'dgenre'}) if $info->{'dgenre'};
			$mp3->{ID3v2}->remove_frame("TRCK"); $mp3->{ID3v2}->add_frame("TRCK", ($tNumber + 1) );
			
			$mp3->{ID3v2}->write_tag();
		}
	}
}

sub prompt_best
{
	my $album = shift;
	my @ranking = @{+shift};
	my %disc_info = %{+shift};
	my @tracks_in = @{+shift};
	
	my $current = $ranking[0];
	
 SELECT: while (1)
	{
		if ($#ranking)
		{
			print "\nMore than one possible matches are available.\n" .
				"The following is a list of all possible ones, sorted by my best guess:\n";
			
			foreach my $choice_num (0 .. $#ranking)
			{
				print join("\t", '', $choice_num + 1, $disc_info{$ranking[$choice_num]}->{'dgenre'},
						   $disc_info{$ranking[$choice_num]}->{'dtitle'},
						   $disc_info{$ranking[$choice_num]}->{'discid'}) . "\n";
			}
			print "\nThis is my best guess or your current selection:\n\n";
		}
		else
		{
			print "\nHere is the only available match:\n\n";
		}
		
		my $var_artist = &print_info($disc_info{$current});
		if($var_artist) {$disc_info{$current}->{'NoVA'} = 0;}
		else {$disc_info{$current}->{'NoVA'} = 1;}
		while (1)
		{
			print "\nChoices:\nUse this match (Y)\n";
			print "View a different match (1-" . ($#ranking + 1) . ")\n" if $#ranking;
			print "Edit album info (e)\n";
			print "Edit track listing (t)\n";
			print "Show example renamed filenames (s)\n" if $Config{'DORENAME'};
			print "Disregard this album entirely (n)\n";
			
			print "This appears to be a Various Artist CD, select (a) if the artist (1st) " .
				"and track name (2nd) to be switched or (v) if this really isn't a VA cd.\n" if $var_artist;
			my $key = $term->readline("? ");
			
			if ($key =~ /^y$/oi || $key eq "")
			{
				return $current;
			}
			elsif (1 <= $key && $key <= ($#ranking + 1))
			{
				$current = $ranking[$key - 1];
				next SELECT;
			}
			elsif ($key =~ /^n$/oi)
			{
				return undef;
			}
			elsif ($key =~ /^e$/oi)
			{
				&edit_disc ($disc_info{$current});
				next SELECT;
			}
			elsif ($key =~ /^t$/oi)
			{
				&edit_track ($disc_info{$current});
				next SELECT;
			}
			elsif ($key =~ /^s$/oi)
			{
				my($new_dir, @renamed) =  &new_names ($album, $disc_info{$current}, \@tracks_in);
				foreach my $file (@renamed)
				{
					print "$new_dir/$file\n";
				}
			}
			elsif ($var_artist && $key =~ /^a$/oi)
			{
				&swap_titles ($disc_info{$current});
				next SELECT;
			}
			elsif ($var_artist && $key =~ /^v$/oi)
			{
				$disc_info{$current}->{'NoVA'} = 1;
				next SELECT;
			}
		}
	}
}

sub edit_disc
{
	my ($info) = @_;
	
	my ($artist, $real_title) = &split_title($info->{'dtitle'});
	my ($input1, $input2);
	
	$input1 = $term->readline("Artist: ",$artist);
	
	$input2 = $term->readline("Title: ",$real_title);
	$info->{'dtitle'} = $input1 . " / " . $input2;
	
	print "Make sure this matches the --genres list to be able to write to ID3V1 tags\n";
	$info->{'dgenre'} = $term->readline("Genre: ",$info->{'dgenre'});
	$info->{'dyear'} = $term->readline("Year: ",$info->{'dyear'});
	$info->{'comment'} = $term->readline("Comment ", $info->{'comment'});
}

sub edit_track
{
	my ($info) = @_;

	foreach my $track_number (0 .. $#{$info->{'ttitles'}})
	{
		my ($track_artist, $track_title);
		if($info->{'NoVA'}) 
		{
			$track_title = $info->{'ttitles'}[$track_number];
		}
		else
		{
			($track_artist, $track_title) = &split_title($info->{'ttitles'}[$track_number]);
		}
		if ($track_artist || $info->{'prompt'})
		{
			$track_artist = $term->readline("Track " . ($track_number + 1) .". Artist ", $track_artist);
		}
		$track_title = $term->readline("Track " . ($track_number + 1) .". Title	 ", $track_title);
		$info->{'ttitles'}[$track_number] = ($track_artist?"$track_artist / " :'') . $track_title;
	}
}

sub print_info
{
	my ($info) = @_;

	my ($artist, $real_title) = &split_title($info->{'dtitle'});
	my $var_artist = 0;
	
	print "Artist:\t$artist\nTitle:\t$real_title\n";
	print "Year:\t$info->{'dyear'}\n" if $info->{'dyear'};
	print "Genre:\t$info->{'dgenre'}\n" if $info->{'dgenre'};
	print "Comment:\t$info->{'comment'}\n" if $info->{'comment'};
	
	my @track_titles  = @{$info->{'ttitles'}};
	
	foreach my $track_number (0 .. $#track_titles)
	{
		my ($artist, $title);
		if($info->{'NoVA'})
		{
			$title = $track_titles[$track_number];
		}
		else
		{
			($artist, $title) = &split_title($track_titles[$track_number]);
		}
		printf "%2d.  %-40s%-s\n", ($track_number + 1), ($artist?$artist:$title), ($artist?$title:'');
		$var_artist = 1 if $artist;
	}
	return $var_artist;
}

sub swap_titles {
	my ($info) = @_;
	
	foreach my $track_number (0 .. $#{$info->{'ttitles'}})
	{
		my ($artist, $title) = &split_title($info->{'ttitles'}[$track_number]);
		$info->{'ttitles'}[$track_number] = "$title / $artist" if $artist;
	}
}

sub split_title
{
	local $_ = shift;
	
	my ($artist, $title);
	
	if (/(.*?)\s*\/\s*(.*)/)  { ($artist, $title) = ($1, $2) }
	elsif (/(.*?)\s+-+\s+(.*)/)	 { ($artist, $title) = ($1, $2) }
	else						 { ($artist, $title) = (undef, $_) }
	
	for ($artist, $title) { s/^\s*//; s/\s*$// }
	
	return ($artist, $title);
}


#######################
#		      #
#  CDDB Lookup Stuff  #
#		      #
#  by Meng Weng Wong  #
#######################

sub sqr_distance
{
	my @vector1 = @{+shift};
	my @vector2 = @{+shift};
	my $total = 0;

	foreach my $dimension (0 .. ($#vector1 < $#vector2 ? $#vector1 : $#vector2)) # too much paranoia never hurt anyone
	{
		my $difference = abs($vector1[$dimension] - $vector2[$dimension]);
		my $square	   = $difference ** 2;
		$total		  += $square;
	}
	return $total;
}

sub frames_to_ss
{
	my $frames = shift;
	my $ss = int($frames / 75);
	return $ss;
}

sub ss_to_mmss
{
	my $ss = shift;
	my $mm = $ss / 60;
	   $ss = $ss % 60;
	return sprintf ("%02d:%02d", $mm, $ss);
}

sub offsets_to_seconds
{
	my @offsets = @_;
	my @track_lengths = ();
	while (@offsets > 1)
	{
		unshift(@track_lengths, pop (@offsets) - $offsets[-1]);
	}
	return map { &frames_to_ss ($_) } @track_lengths;
}

sub build_cddb_query
{
	my @cdtoc = @_;
	my $count = 1;
	
	foreach (@cdtoc)
	{
		my ($mm, $ss) = ($_->{MM}, $_->{SS});
	}
	
	my $discid = cddb_discid(@cdtoc);
	
	my @frames		   = &invent_frame_numbers(@cdtoc);
	my $total_time	   = &total_time(@cdtoc);
	my $total_tracks   = @cdtoc;
	
	my $login		   = $ENV{USER};
	my $hostname	   = &hostname; use Sys::Hostname; $hostname = `hostname` if $hostname !~ /\./;
	my $client_name	   = "mp3cddb";
	my $client_version = "beta";

	return ( $discid,
			 $total_tracks,
			 $total_time,
			 @frames );
}

sub cddb_sum
{
	my ($n, $ret) = (shift, 0);
	for (split //, $n) { $ret += $_ }
	return $ret;
}

sub total_time
{
	my @cdtoc	   = @_;
	my $total_time = 0;
	
	foreach my $track (@cdtoc)
	{
		my $track_time = $track->{MM} * 60 + $track->{SS};
		$total_time += $track_time;
	}
	return $total_time;
}


sub cddb_discid
{
	my @cdtoc	   = @_;
	my $n		   = 0;
	my $total_time = 0;
	
	foreach my $track (@cdtoc)
	{
		my $track_time = $track->{MM} * 60 + $track->{SS};
		$n			+= &cddb_sum($total_time);
		$total_time +=			 $track_time;
	}
	return sprintf("%08x", ($n % 0xFF) << 24 | $total_time << 8 | @cdtoc);
}

sub invent_frame_numbers
{
	my @cdtoc	   = @_;
	my $n		   = 0;
	my $total_time = 0;
	
	foreach my $track (@cdtoc)
	{
		$track->{FRAME_OFFSET} = $total_time * 75;
		
		my $track_time	= $track->{MM} * 60 + $track->{SS};
		$total_time	   += $track_time;
	}
	return map { $_->{FRAME_OFFSET} } @cdtoc;
}


###################################
#				  #
#  Write the example config file  #
#				  #
###################################

sub write_config{
	open(WRITE, ">" . $ENV{"HOME"} . "/.mp3cddb") || die "couldn't write example config file!";
	print WRITE
q~# mp3cddb example configuration file
# YOU MUST ENABLE ONE OF THE RENAME LINES OR ELSE THE PROGRAM WILL NOT RUN!
# to enable one of the lines remove the # (comment) from before it, or add your own to the bottom
# options are 1 for true, 0 for false


# ID3V1 / ID3V2: write ID3 V1/2 tags
ID3V1 = 1
ID3V2 = 1

# DELID3V1 / DELID3V2: delete any existing ID3 V1/2
# if both this and above are set, then it will remove any existing tag and write a new clean one
DELID3V1 = 0
DELID3V2 = 0


# DORENAME: Rename the Files
DORENAME = 1

# UNDERSCORE: convert all spaces to underscores in file names
UNDERSCORE = 0

# RENAME: defines how to rename the files / directory

# Available variables:
#  %at:  Album Title
#  %aa:  Album Artist
#  %ag:  Album Genre
#  %ay:  Album Year
#  %ac:  Album Comment
#  %tn:  Track Number (padded to 2 characters, 01..10..99)
#  %tt:  Track Title
#  %ta:  Track Artist (always set)
#  %tb:  Track Artist (only set if different from Album)
# In case you actually want a literal %, {, or } there are the following:
#  %%, %{, %}: replaced by %, {, and }

# You can make a portion optional by enclosing in within {}, for example:
#  %aa - {%ay - }%at
# Will write either "Artist - Title" or "Artist - Year - Title"
# NOTE: do NOT put more than one variable within a single {}!

# Here are a few examples, showing options and how directories are handled
# READ THROUGH ALL OF THEM to get an idea of how exactly you want yours to be
# hint: just look for the output that closest resembles your current output!

# Each example shows the results on the following 2 files:
# /mp3s/New Downloads/into the unknown-Bad_religion-aps/01-its_only_over_when-bad_religion-aps.mp3
# /mp3s/Ska/VA-Ska_Sucks/Ska Sucks- 01- Dance Hall Crashers- He Wants Me Back.mp3


#  1. Ignore directories: if RENAME has no directory info, only the files
#     inside a directory are renamed

# Very simple
#RENAME = %tn - %tt
# /mp3s/New Downloads/into the unknown-Bad_religion-aps/01 - Its Only Over When.mp3
# /mp3s/Ska/VA-Ska_Sucks/01 - He Wants Me Back.mp3

# Show artist only when different from album
#RENAME = %tn - {%tb - }%tt
# /mp3s/New Downloads/into the unknown-Bad_religion-aps/01 - Its Only Over When.mp3
# /mp3s/Ska/VA-Ska_Sucks/01 - Dance Hall Crashers - He Wants Me Back.mp3

# Always shows artist
#RENAME = %tn - %ta - %tt
# /mp3s/New Downloads/into the unknown-Bad_religion-aps/01 - Bad Religion - Its Only Over When.mp3
# /mp3s/Ska/VA-Ska_Sucks/01 - Dance Hall Crashers - He Wants Me Back.mp3


#  2. Rename directory: if RENAME has some directory information, then then the
#     directory above the files will also be renamed.  if RENAME contains more
#     than one directory, it will create the extra ones

# Again, simple example:
#RENAME = %aa - %at/%tn - %tt
# /mp3s/New Downloads/Bad Religion - Into the Unknown/01 - Its Only Over When.mp3
# /mp3s/Ska/VA - Ska Sucks/01 - He Wants Me Back.mp3

# Show year, if it's defined
#RENAME = %aa - {%ay - }%at/%tn - %tt
# /mp3s/New Downloads/Bad Religion - 1983 - Into the Unknown/01 - Its Only Over When.mp3
# /mp3s/Ska/VA - Ska Sucks/01 - He Wants Me Back.mp3

# More than one directory:
#RENAME = %aa/%at/%tn - %tt
# /mp3s/New Downloads/Bad Religion/Into the Unknown/01 - Its Only Over When.mp3
# /mp3s/Ska/VA/Ska Sucks/01 - He Wants Me Back.mp3

# Combination with more than 1 directory, optional year, optional track artist
#RENAME = %aa/{%ay - }%at/%tn - {%tb - }%tt
# /mp3s/New Downloads/Bad Religion/1983 - Into the Unknown/01 - Its Only Over When.mp3
# /mp3s/Ska/VA/Ska Sucks/01 - Dance Hall Crashers - He Wants Me Back.mp3


#  3. Absolute directory: if RENAME is an absolute directory, then the
#     directory is moved to the proper location

# Again, simple example:
#RENAME = /mp3s/%aa - %at/%tn - %tt
# /mp3s/Bad Religion - Into the Unknown/01 - Its Only Over When.mp3
# /mp3s/VA - Ska Sucks/01 - He Wants Me Back.mp3

# All of the above exactly, just add a /something to the front of them...

# My personal format:
#RENAME = /mp3s/%ag/%aa - {%ay - }%at/%tn - {%tb - }%tt
# /mp3s/Punk/Bad Religion - 1983 - Into the Unknown/01 - Its Only Over When.mp3
# /mp3s/Ska/VA - Ska Sucks/01 - Dance Hall Crashers - He Wants Me Back.mp3
~;
	close(WRITE);
}

Last edited by David_Wallis; 17 June 2006 at 07:05 PM.
Old 17 June 2006, 09:26 PM
  #2  
mykp
Scooby Regular
 
mykp's Avatar
 
Join Date: Jan 2006
Location: On the Cat and Fiddle
Posts: 1,483
Likes: 0
Received 0 Likes on 0 Posts
Default

Havent used perl for years but do you have a /.mp3cddb specified?

The script should create one for you as thats where it pucks up the $env bit from, if it isnt doing it might be a problem with permission and not being able to write to the folder.

Have you had any error message and what version of activestate perl are you using?
Related Topics
Thread
Thread Starter
Forum
Replies
Last Post
CarpetCleaner
Non Scooby Related
31
27 June 2003 12:03 PM
V5
Member's Gallery
5
04 June 2003 03:47 PM
Reffro
Non Scooby Related
75
05 December 2002 11:12 PM
Sith
Other Marques
2
01 December 2002 03:12 PM
Little Miss WRX
Sport
9
26 November 2002 08:49 PM



Quick Reply: fookin perl



All times are GMT +1. The time now is 03:33 AM.