diff options
Diffstat (limited to 'bin/fileupdate.pl')
-rwxr-xr-x | bin/fileupdate.pl | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/bin/fileupdate.pl b/bin/fileupdate.pl new file mode 100755 index 00000000..4353d057 --- /dev/null +++ b/bin/fileupdate.pl @@ -0,0 +1,346 @@ +#!/usr/bin/perl -w + +# Find and file away MP3's. Run multiple times and will +# ignore addition of duplicates in db (based on MD5 hash +# of full file path. + +use FindBin qw($Bin); +require "$Bin/init"; + +use Data::Dumper; +use Getopt::Long; + +use vars qw($help $pretend $id3 $rename $sort $all $verbose); + +Getopt::Long::Configure('bundling','no_ignore_case'); +GetOptions + ("h|help" => \&usage, + "p|pretend" => \$pretend, + "i|id3" => \$id3, + "r|rename" => \$rename, + "s|sort" => \$sort, + "a|all" => \$all, + "rename_all" => \$rename_all, + "sort_all" => \$sort_all, + "v|verbose" => \$verbose); + +if ( !$help && !$all && !$id3 && !$rename && !$sort && !$rename_all && !$sort_all ) { + usage(); +} + +if ($help) { + usage(); +} + +if($id3 or $all) +{ + my @flagged = $ampache->get_table_where("flagged","WHERE type = 'setid3'"); + + foreach my $update(@flagged) + { + my @info = $ampache->get_song_info($update->{'song'}); + my $cmd = update_id3_tag($ampache,@info); + if($rename or $all) + { + if($verbose){ print "Marking for rename after id3\n"; } + if(!$pretend){ $ampache->change_flags(@info,'setid3','ren'); } + } + else + { + if($sort or $all) + { + if($verbose){ print "Marking for sort after id3\n"; } + if(!$pretend){ $ampache->change_flags(@info,'setid3','sort'); } + } + else + { + if($verbose){ print "Stopping after id3 update\n"; } + if(!$pretend){ $ampache->change_flags(@info,'setid3','notify'); } + } + } + } +} + +if($rename or $all) +{ + my $filename = ''; + my @flagged = $ampache->get_table_where("flagged","WHERE type = 'ren'"); + foreach my $update (@flagged) + { + my @info = $ampache->get_song_info($update->{'song'}); + my $cmd = rename_file($ampache,\$filename,@info); + if(!$pretend){ $ampache->update_song($cmd,@info); } + if($sort or $all) + { + if($verbose){ print "Marking for sort after rename\n"; } + if(!$pretend){ $ampache->change_flags(@info,'ren','sort'); } + } + else + { + if($verbose){ print "Updating filename in DB after rename\n"; } + if(!$pretend){ $ampache->change_flags(@info,'ren','notify'); } + } + } +} + +if ($rename_all) { + my $filename = ''; + my @flagged = $ampache->get_table_where("catalog,song","WHERE catalog.catalog_type='local' AND catalog.id=song.catalog","song.id AS song"); + foreach my $update (@flagged) { + my @info = $ampache->get_song_info($update->{'song'}); + my $cmd = rename_file($ampache,\$filename,@info); + if(!$pretend){ $ampache->update_song($cmd,@info); } + } # End Foreach +} # End Rename All + +if ($sort_all) { + my $filename = ''; + my @flagged = $ampache->get_table_where("catalog,song","WHERE catalog.catalog_type='local' AND catalog.id=song.catalog","song.id AS song"); + foreach my $update(@flagged) + { + my @info = $ampache->get_song_info($update->{'song'}); + my $cmd = sort_file($ampache,\$filename,@info); + if(!$pretend){ $ampache->update_song($cmd,@info); } + if($verbose){ print "Updating filename in DB after sort\n"; } + if(!$pretend){ $ampache->change_flags(@info,'sort','notify'); } + } +} # End Sort ALL + + +if($sort or $all) +{ + my $filename = ''; + my @flagged = $ampache->get_table_where("flagged","WHERE type = 'sort'"); + foreach my $update(@flagged) + { + my @info = $ampache->get_song_info($update->{'song'}); + my $cmd = sort_file($ampache,\$filename,@info); + if(!$pretend){ $ampache->update_song($cmd,@info); } + if($verbose){ print "Updating filename in DB after sort\n"; } + if(!$pretend){ $ampache->change_flags(@info,'sort','notify'); } + } +} + +# # # # # +# subs +# # # # # # # + +# %A = album name +# %a = artist name +# %C = catalog path (for the specified song) +# %c = comment +# %g = genre +# %y = year +# %T = track number +# %t = song title +# +# %filename I use for filename + +sub get_catalog_setting +{ + my ($self,$catalog,$setting) = @_; + #bless $self; + my $cmd = $self->get_catalog_option($catalog,$setting); + return $cmd; +} + +sub update_id3_tag +{ + my ($self,$song) = @_; + my $id3set = get_catalog_setting($self,$song->{'catalog'},'id3_set_command'); + $id3set =~ s/\Q%A\E/$song->{'album'}/g; + $id3set =~ s/\Q%a\E/$song->{'artist'}/g; + $id3set =~ s/\Q%C\E/$song->{'catalog'}/g; + $id3set =~ s/\Q%c\E/$song->{'comment'}/g; + if(($song->{'genre'} * 1) < 255){$id3set =~ s/\Q%g\E/$song->{'genre'}/g;} + else{$id3set =~ s/ -g %g//g;} + $id3set =~ s/\Q%T\E/$song->{'track'}/g; + $id3set =~ s/\Q%t\E/$song->{'title'}/g; + $id3set =~ s/\Q%y\E/$song->{'year'}/g; + $id3set =~ s/\Q%filename\E//g; + # $id3set =~ s/([\'\"])/\\$1/g; + my $filename = $song->{'file'}; + my $id3tag_command = "$id3set \"$filename\""; + return do_call($id3tag_command); +} + +sub rename_file +{ + my ($self,$filename,$song) = @_; + my $ren_pattern = get_catalog_setting($self,$song->{'catalog'},'rename_pattern'); + #my $sort_pattern = get_catalog_setting($self,$song->{'catalog'},'sort_pattern'); + my $basedir; + if( $song->{'file'} =~ m/^(.*)\/.*?$/ ) + { + $basedir = $1; + } + else{ die "Could not determine base directory for $song->{'file'}\n"; } + + # We want to pad track numbers with leading zeros: + if($song->{'track'} < 10) + { + $song->{'track'} = "0".$song->{'track'}; + } + + # we need to clean title,album,artist,comment,genre,track, and year + $song->{'title'} =~ s/[\/]/-/g; + $song->{'album'} =~ s/[\/]/-/g; + $song->{'artist'} =~ s/[\/]/-/g; + $song->{'comment'} =~ s/[\/]/-/g; + $song->{'genre'} =~ s/[\/]/-/g; + $song->{'track'} =~ s/[\/]/-/g; + $song->{'year'} =~ s/[\/]/-/g; + + $ren_pattern =~ s/\Q%A\E/$song->{'album'}/g; + $ren_pattern =~ s/\Q%a\E/$song->{'artist'}/g; + $ren_pattern =~ s/\Q%C\E/$song->{'catalog'}/g; + $ren_pattern =~ s/\Q%c\E/$song->{'comment'}/g; + $ren_pattern =~ s/\Q%g\E/$song->{'genre'}/g; + $ren_pattern =~ s/\Q%T\E/$song->{'track'}/g; + $ren_pattern =~ s/\Q%t\E/$song->{'title'}/g; + $ren_pattern =~ s/\Q%y\E/$song->{'year'}/g; + $ren_pattern =~ s/\Q%filename\E/$song->{'file'}/g; + my $oldfilename = $song->{'file'}; + my $newfilename = $basedir . "/" . $ren_pattern; + # result is backslashes in filename + # $newfilename =~ s/([\'\"])/\\$1/g; + + print "\tNew: $newfilename -- OLD: $oldfilename\n"; + + if(! -e "$newfilename") + { + my $ren_command = "mv \"$oldfilename\" \"$newfilename\""; + $filename = $newfilename; + do_call($ren_command); + return $filename; + } + else + { + print STDERR "File exists: $newfilename\n"; + $filename = $oldfilename; + return $filename; + } +} + +sub sort_file +{ + my ($self, $filename, $song) = @_; + my $basename; + my $basedir; + if( $song->{'file'} =~ m/^(.*)\/(.*?)$/ ) + { + $basename = $2; + $basedir = $1 + } + else{ die "Could not determine base name for $song->{'file'}\n"; } + + # we need to clean title,album,artist,comment,genre,track, and year + $song->{'title'} =~ s/[\/]/-/g; + $song->{'album'} =~ s/[\/]/-/g; + $song->{'artist'} =~ s/[\/]/-/g; + $song->{'comment'} =~ s/[\/]/-/g; + $song->{'genre'} =~ s/[\/]/-/g; + $song->{'track'} =~ s/[\/]/-/g; + $song->{'year'} =~ s/[\/]/-/g; + + my $location = get_catalog_setting($self,$song->{'catalog'},'sort_pattern'); + $location =~ s/\Q%A\E/$song->{'album'}/g; + $location =~ s/\Q%a\E/$song->{'artist'}/g; + $location =~ s/\Q%C\E/$song->{'catalog'}/g; + $location =~ s/\Q%c\E/$song->{'comment'}/g; + $location =~ s/\Q%g\E/$song->{'genre'}/g; + $location =~ s/\Q%T\E/$song->{'track'}/g; + $location =~ s/\Q%t\E/$song->{'title'}/g; + $location =~ s/\Q%y\E/$song->{'year'}/g; + # result is wrong paths + # $location =~ s/([\'\"])/\\$1/g; + + create($location); + + # The basename is calculated so we can see if the file already exists + if(! -e "$location/$basename") + { + my $cmd = "/bin/mv \"".$song->{'file'}."\" \"$location\""; + my $ret = do_call($cmd); + if(empty_dir($basedir)) + { + print "Removing empty directory $basedir\n"; + $cmd = "/bin/rmdir \"$basedir\""; + do_call($cmd); + } + $filename = $location."/".$basename; + return $filename; + } + else + { + print STDERR "File exists: $location/$basename\n"; + $filename = $song->{'file'}; + return $filename; + } +} + +sub usage +{ + my $usage = qq{ + fileupdate [--id3|--rename|--rename_all|--sort|--sort_all|--all] [--help] [--pretend] [--verbose] + --pretend Display command taken, without actually doing anything. + + --id3 Update id3 tags for all files flagged with 'id3' + + --rename Rename files flagged with 'rename' + + --rename_all Renames all files based on id3 info + + --sort Sort files flagged with 'sort' + + --sort_all Sort all files based on id3 info + + --all Performs id3 update, rename, and sort + for all files flagged with 'id3' + --verbose Shows detailed information about what's happening. + + --help This message + }; + die $usage; +} + +sub do_call +{ + my @cmd = @_; + my $return = 0; + + if($verbose && !$pretend){ print "@cmd\n";} + if($pretend){ print "@cmd\n"; } + else + { + $return = system @cmd; + } + return $return; +} + +sub create +{ + my ($path) = @_; + if(! -e $path) + { + return do_call("mkdir","-p",$path); + } + return 1; +} + +# empty_dir borrowed from Tom Phoenix (rootbeer@teleport.com) +# posted in comp.lang.perl.misc on 3/21/97 + +sub empty_dir ($) +{ + local(*DIR, $_); + return unless opendir DIR, $_[0]; + while (defined($_ = readdir DIR)) { + next if /^\.\.?$/; + closedir DIR; + return 0; + } + closedir DIR; + 1; +} +1; |