use strict; use warnings; #-------------------------------------------------------------------------------------------------------------- # fixname #-------------------------------------------------------------------------------------------------------------- sub fixname { if(!$_) { return; } # prevent null entrys being processed $main::id3_writeme = 0; # ----------------------------------------- # local Vars # ----------------------------------------- my $file = $_; my $newfile = $file; my $tmpr = 1; my @tmp_arr; my $tag = 0; my $art = ""; my $tit = ""; my $tra = ""; my $alb = ""; my $gen = ""; my $year = ""; my $com = ""; my $newart = ""; my $newtit = ""; my $newtra = ""; my $newalb = ""; my $newgen = ""; my $newyear = ""; my $newcom = ""; my $tmp = ""; my $t_s = ""; my $tl = 0; my $file_ext_length = 0; my $trunc_char_length = 0; my $l = 0; my $enum_n = 0; my $file_ext = ""; my $tmpfile = ""; $main::cwd = cwd; # ----------------------------------------- # make sure file is allowed to be renamed # ----------------------------------------- if((!-d $file) && ($main::ig_type || $file =~ /\.($main::file_ext_2_proc)$/i)) { $tmpr = 0; } if($main::proc_dirs && -d $file) { $tmpr = 0; } if($main::proc_dirs && $main::ig_type) { $tmpr = 0; } if(&match_filter($file) == 0) { return; } if($tmpr == 1) { return; } # Print dir if pwd != last dir (for recursive mode). if( $main::recr && $main::last_recr_dir ne "$main::cwd" && $main::proc_dirs == 0 ) { $main::last_recr_dir = $main::cwd; &nf_print(" "); &nf_print($main::cwd); } # Fetch mp3 tags if file is a mp3 and id3 mode is enabled # $tag will =1 only if tags r found & id3 mode is enabled if($main::id3_mode & $file =~ /.*\.mp3$/) { @tmp_arr = &get_tags($file); if($tmp_arr[0] eq "id3v1") { $tag = 1; $newart = $art = $tmp_arr[1]; $newtit = $tit = $tmp_arr[2]; $newtra = $tra = $tmp_arr[3]; $newalb = $alb = $tmp_arr[4]; $newgen = $gen = $tmp_arr[5]; $newyear = $year = $tmp_arr[6]; $newcom = $com = $tmp_arr[7]; } } # --------------------------------------- # Stuff todo before 1st basic cleanup # --------------------------------------- # Scenify Season & Episode numbers if($main::scene) { $newfile =~ s/(^|\W)(\d+)(x)(\d+)/$1.qw(S).$2.qw(E).$4/ie; } # Unscene Season & Episode numbers if($main::unscene) { $newfile =~ s/(S)(\d+)(E)(\d+)/$2.qw(x).$4/ie; } # remove patterns if($main::kill_sp_patterns) { for (@main::kill_patterns_arr) { $newfile =~ s/$_//ig; } } # remove list of words if($main::kill_cwords) { if(-d $file) { for(@main::kill_words_arr) { $newfile =~ s/(^|-|_|\.|\s+|\,|\+|\(|\[)($_)(\]|\)|-|_|\.|\s+|\,|\+|$)/$1.$3/eig; } } else { for(@main::kill_words_arr) { $newfile =~ s/(^|-|_|\.|\s+|\,|\+|\(|\[)($_)(\]|\)|-|_|\.|\s+|\,|\+)/$1.$3/eig; } } } # remove user entered word (also replace if anything is specified) if($main::replace) { $newfile =~ s/($main::rpwold_escaped)/$main::rpwnew/ig; } # Front append if($main::front_a) { $newfile = $main::faw.$newfile; } # End append if($main::end_a) { $newfile =~ s/(.*)(\..*$)/$1$main::eaw$2/g; } # convert underscores to spaces if($main::spaces) { # underscores to spaces $newfile =~ s/(\s|_)+/$main::space_character/g; if($tag) { $newart =~ s/(\s|_)+/$main::space_character/g; $newtit =~ s/(\s|_)+/$main::space_character/g; $newalb =~ s/(\s|_)+/$main::space_character/g; $newcom =~ s/(\s|_)+/$main::space_character/g; } } # pad - if($main::pad_dash == 1) { $newfile =~ s/(\s*|_|\.)(-)(\s*|_|\.)/$main::space_character."-".$main::space_character/eg; } # Dots to spaces if($main::dot2space) { if(-d $file) { $newfile =~ s/\./$main::space_character/g; } else { $newfile =~ s/\./$main::space_character/g; # put last dot back in front of the ext # there may be a cleaner way to do this but oh well $newfile =~ s/(.*)($main::space_character)(.{3,4}$)/$1\.$3/g; } } # remove nasty characters if($main::sp_char) { $newfile =~ s/[\~\@\%\{\}\[\]\"\<\>\!\`\'\,\#\(|\)]//g; } # remove all digits if($main::rm_digits) { $t_s = ""; $newfile =~ s/\d+//g; } # remove digits from front of filename if($main::digits) { # remove leading digits (Track Nr) $newfile =~ s/^\d*\s*//; } if($main::split_dddd) { if($newfile =~ /(.*?)(\d{3,4})(.*)/) { @tmp_arr = ($1, $2, $3); if(length $tmp_arr[1] == 3) { $tmp_arr[1] =~ s/(\d{1})(\d{2})/$1."x".$2/e; $newfile = $tmp_arr[0].$tmp_arr[1].$tmp_arr[2]; } elsif(length $tmp_arr[1] == 4) { if($tmp_arr[1] !~ /^(19|20)(\d+)/) { $tmp_arr[1] =~ s/(\d{2})(\d{2})/$1."x".$2/e; $newfile = $tmp_arr[0].$tmp_arr[1].$tmp_arr[2]; } } } } # ---------------------------------- # Preliminary cleanup # ---------------------------------- if($main::cleanup == 1) { # "fix Artist - - track" type filenames that can pop up when stripping words $newfile =~ s/-(\s|_|\.)+-/-/g; # rm trailing characters $newfile =~ s/(\s|_|\.|-)+(\..{3,4})$/$2/e; # remove leading chars $newfile =~ s/^(\s|_|\.|-)+//; # I hate mpeg or jpeg as extensions personally :P $newfile =~ s/\.mpeg$/\.mpg/i; $newfile =~ s/\.jpeg$/\.jpg/i; } # International Character translation # WARNING: This might break really badly on some systems, esp. non-Unix ones... # if you see alot of ? in your filenames, you need to add the correct codepage for the filesystem. if($main::intr_char) { $newfile =~ s/Å/Aa/g; $newfile =~ s/Ä/Ae/g; $newfile =~ s/Á/A/g; $newfile =~ s/Æ/ae/g; $newfile =~ s/ß/ss/g; $newfile =~ s/É/E/g; $newfile =~ s/Í/I/g; $newfile =~ s/Ñ/N/g; $newfile =~ s/Ó/O/g; $newfile =~ s/Ö/Oe/g; $newfile =~ s/Ø/Oo/g; $newfile =~ s/Ü/Ue/g; $newfile =~ s/Ú/U/g; $newfile =~ s/ã/a/g; $newfile =~ s/à/a/g; # mems 1st addition to int support $newfile =~ s/á/a/g; $newfile =~ s/å/aa/g; $newfile =~ s/æ/ae/g; $newfile =~ s/ä/ae/g; $newfile =~ s/ç/c/g; $newfile =~ s/é/e/g; $newfile =~ s/è/e/g; $newfile =~ s/í/i/g; $newfile =~ s/ñ/n/g; $newfile =~ s/ø/oo/g; $newfile =~ s/ö/oe/g; $newfile =~ s/ó/o/g; $newfile =~ s/ô/o/g; $newfile =~ s/ú/u/g; $newfile =~ s/ü/ue/g; $newfile =~ s/¿//g; $newfile =~ s/¡//g; $newfile =~ s/´//g; } # Apply casing if($main::case) { $newfile =~ s/(^| |\.|_|\(|-)([A-Za-zÅÄÁÆßÉÍÑÓÖØÜÚãàáåæäçéèíñøöóôúü])(([A-Za-zÅÄÁÆßÉÍÑÓÖØÜÚãàáåæäçéèíñøöóôúü]|\'|\¿|\¡|\´)*)/$1.uc($2).lc($3)/eg; if($tag) { $newart =~ s/(^| |\.|_|\(|-)([A-Za-zÅÄÁÆßÉÍÑÓÖØÜÚãàáåæäçéèíñøöóôúü])(([A-Za-zÅÄÁÆßÉÍÑÓÖØÜÚãàáåæäçéèíñøöóôúü]|\'|\¿|\¡|\´)*)/$1.uc($2).lc($3)/eg; $newtit =~ s/(^| |\.|_|\(|-)([A-Za-zÅÄÁÆßÉÍÑÓÖØÜÚãàáåæäçéèíñøöóôúü])(([A-Za-zÅÄÁÆßÉÍÑÓÖØÜÚãàáåæäçéèíñøöóôúü]|\'|\¿|\¡|\´)*)/$1.uc($2).lc($3)/eg; $newalb =~ s/(^| |\.|_|\(|-)([A-Za-zÅÄÁÆßÉÍÑÓÖØÜÚãàáåæäçéèíñøöóôúü])(([A-Za-zÅÄÁÆßÉÍÑÓÖØÜÚãàáåæäçéèíñøöóôúü]|\'|\¿|\¡|\´)*)/$1.uc($2).lc($3)/eg; $newcom =~ s/(^| |\.|_|\(|-)([A-Za-zÅÄÁÆßÉÍÑÓÖØÜÚãàáåæäçéèíñøöóôúü])(([A-Za-zÅÄÁÆßÉÍÑÓÖØÜÚãàáåæäçéèíñøöóôúü]|\'|\¿|\¡|\´)*)/$1.uc($2).lc($3)/eg; } } # Specific word casing if($main::sp_word) { my $word = ""; foreach $word(@main::word_casing_arr) { chomp $word; $newfile =~ s/(^|\s+|_|\.)($word)(\s+|_|\.|\..{3,4}$)/$1.$word.$3/egi; if($tag) { $newart =~ s/(^|\s+|_|\.)($word)(\s+|$)/$1.$word.$3/egi; $newtit =~ s/(^|\s+|_|\.)($word)(\s+|$)/$1.$word.$3/egi; $newalb =~ s/(^|\s+|_|\.)($word)(\s+|$)/$1.$word.$3/egi; $newcom =~ s/(^|\s+|_|\.)($word)(\s+|$)/$1.$word.$3/egi; } } } # 1st letter of filename should be uc if($main::case) { $newfile =~ s/^(\w)/uc($1)/e; if($tag) { $newart =~ s/^(\w)/uc($1)/e; $newtit =~ s/^(\w)/uc($1)/e; $newalb =~ s/^(\w)/uc($1)/e; $newcom =~ s/^(\w)/uc($1)/e; } } # Pad digits with 0 if($main::pad_digits_w_zero) { # rm extra 0's $newfile =~ s/(^|\s+|\.|_)(\d{1,2})(x0)(\d{2})(\s+|\.|_|\..{3,4}$)/$1.$2."x".$4.$5/ieg; # pad NxN $newfile =~ s/(^|\s+|\.|_)(\dx)(\d)(\s+|\.|_|\..{3,4}$)/$1."0".$2."0".$3.$4/ie; # NxN to 0Nx0N $newfile =~ s/(^|\s+|\.|_)(\d\dx)(\d)(\s+|\.|_|\..{3,4}$)/$1.$2."0".$3.$4/ie; # NNxN to NNx0N $newfile =~ s/(^|\s+|\.|_)(\dx)(\d\d)(\s+|\.|_|\..{3,4}$)/$1."0".$2.$3.$4/ie; # NxNN to 0NxNN # clean scene style # rm extra 0's $newfile =~ s/(^s|\s+s|\.s|_s)(\d{1,2})(e0)(\d{2})(\s+|\.|_|\..{3,4}$)/$1.$2."e".$4.$5/ieg; $newfile =~ s/(^s|\s+s|\.s|_s)(\d)(e)(\d)(\s+|\.|_|\..{3,4}$)/$1."0".$2."0".$3.$4.$5/ie; # sNeN to S0Ne0N $newfile =~ s/(^s|\s+s|\.s|_s)(\d\d)(e)(\d)(\s+|\.|_|\..{3,4}$)/$1.$2.$3."0".$4.$5/ie; # sNNeN to sNNe0N $newfile =~ s/(^s|\s+s|\.s|_s)(\d)(e)(\d\d)(\s+|\.|_|\..{3,4}$)/$1."0".$2.$3.$4.$5/ie; # SNeNN to S0NeNN } # Pad digits with " - " (must come after pad digits with 0 to catch any new if($main::pad_digits) { # optimize me $tmp = " - "; $newfile =~ s/(\s+)(\d\d|\d+x\d+)(\s+)/$tmp.$2.$tmp/ie; $newfile =~ s/(\s+)(\d\d|\d+x\d+)(\..{3,4}$)/$tmp.$2.$3/ie; $newfile =~ s/^(\d\d|\d+x\d+)(\s+)/$1.$tmp/ie; } # ---------------------------------- # Post General cleanup # ---------------------------------- if($main::cleanup == 1) { # remove childless brackets () [] {} $newfile =~ s/(\(|\[|\{)(\s|_|\.|\+|-)*(\)|\]|\})//g; # remove doubled up -'s $newfile =~ s/-(\s|_|\.)+-|--/-/g; # rm trailing characters $newfile =~ s/(\s|\+|_|\.|-)+(\..{3,4})$/$2/; # rm leading characters $newfile =~ s/^(\s|\+|_|\.|-)+//; # rm extra whitespaces $newfile =~ s/\s+/ /g; $newfile =~ s/$main::space_character+/$main::space_character/g; # change file extension to lower case and remove anyspaces before file ext $newfile =~ s/^(.*)(\..{3,4})$/$1.lc($2)/e; if(-d $file) { $newfile =~ s/(\s|\+|_|\.|-)+$//; } if($tag) { # remove childless brackets () [] {} $newart =~ s/(\(|\[|\{)(\s|_|\.|\+|-)*(\)|\]|\})//g; $newtit =~ s/(\(|\[|\{)(\s|_|\.|\+|-)*(\)|\]|\})//g; $newalb =~ s/(\(|\[|\{)(\s|_|\.|\+|-)*(\)|\]|\})//g; # remove leading / trailing whitspaces $newart =~ s/(^\s+)|(\s+$)//g; $newtit =~ s/(^\s+)|(\s+$)//g; $newalb =~ s/(^\s+)|(\s+$)//g; $newcom =~ s/(^\s+)|(\s+$)//g; } } # ---------------------------------- # stuff todo after final cleanup # ---------------------------------- # lowercase all if($main::lc_all) { $newfile = lc($newfile); } # uppercase all if($main::uc_all) { $newfile = uc($newfile); } # guess tag :P if($main::id3_guess_tag == 1 && $_ =~ /.*\.mp3$/) { ($newart, $newtra, $newtit, $newalb) = &guess_tags($file); } # truncate file $l = length $newfile; if($l > $main::max_fn_length && $main::truncate == 0) { &nf_print("$file", "ERROR: $newfile exceeds maximum filename length.\n"); return; } if($l > $main::truncate_to && $main::truncate == 1) { $file_ext = $newfile; $file_ext =~ s/^(.*)(\.)(.{3,4})$/$3/e; $file_ext_length = length $file_ext; # doesnt include . in length # var for adjusted truncate to, gotta take into account file ext length $tl = $main::truncate_to - ($file_ext_length + 1); # adjust tl to allow for added enum digits if enum mode is enabled if($main::enum && $main::enum_pad) { $tl = $tl - $main::enum_pad_zeros } elsif($main::enum) { $tl = $tl - length "$main::enum_count"; } # start truncating # from front if($main::truncate_style == 0) { $newfile =~ s/^(.*)(.{$tl})(\..{$file_ext_length})$/$2.$3/e; } # from end elsif($main::truncate_style == 1) { $newfile =~ s/^(.{$tl})(.*)(\..{$file_ext_length})$/$1.$3/e; } # from middle elsif($main::truncate_style == 2) { my $tl = int ($tl - length $main::trunc_char) / 2; $newfile =~ s/^(.{$tl})(.*)(.{$tl})(\..{$file_ext_length})$/$1.$main::trunc_char.$3.$4/e; } } if($main::space) { $newfile =~ s/\s+|_+/$main::space_character/g; } # Enumerate if($main::enum) { $enum_n = $main::enum_count; if($main::enum_pad == 1) { $a = "%.$main::enum_pad_zeros"."d"; $enum_n = sprintf($a, $enum_n); } if($main::enum_opt == 0) { if(-d $file) { $newfile = $enum_n; } else { # numbers and file ext only $newfile =~ s/^.*\././; $newfile = "$enum_n"."$newfile"; } } elsif($main::enum_opt == 1) { # Insert N at begining of filename $newfile = "$enum_n"."$newfile"; } elsif($main::enum_opt == 2) { # Insert N at end of filename but before file ext $newfile =~ s/(.*)(\..*$)/$1$enum_n$2/g; } $main::enum_count++; } # End of cleanups # set user entered tags if any if($main::id3_art_set && $file =~ /.*\.mp3$/i) { $newart = $main::id3_art_str; $tag = 1; } if($main::id3_alb_set && $file =~ /.*\.mp3$/i) { $newalb = $main::id3_alb_str; $tag = 1; } if($main::id3_gen_set && $file =~ /.*\.mp3$/i) { $newgen = $main::id3_gen_str; $tag = 1; } if($main::id3_year_set && $file =~ /.*\.mp3$/i) { $newyear = $main::id3_year_str; $tag = 1; } if($main::id3_com_set && $file =~ /.*\.mp3$/i) { $newcom = $main::id3_com_str; $tag = 1; } if($main::id3v1_rm && $file =~ /.*\.mp3$/i) { if(!$main::testmode) { &rm_tags($file, "id3v1"); } else { $main::tags_rm++; } $tmp = "printme"; } if($main::id3v2_rm && $_ =~ /.*\.mp3$/i) { if(!$main::testmode) { &rm_tags($file, "id3v2"); } else { $main::tags_rm++; } $tmp = "printme"; } if($main::id3v1_rm && $main::id3v2_rm && $file =~ /.*\.mp3$/i) { $tag = 0; } # no tags and no fn change if($tag == 0 && $file eq $newfile) { if($tmp eq "printme") { &nf_print($file, $newfile); } return; } if($tag) { # fn & tags havent changed if( $main::id3_writeme == 0 && $file eq $newfile && $art eq $newart && $tit eq $newtit && $tra eq $newtra && $alb eq $newalb && $com eq $newcom && $gen eq $newgen && $year eq $newyear ) { if($tmp eq "printme") { &nf_print($file, $newfile); } return; } # one or more tags changed, write n bump counter if( $main::id3_writeme == 1 || $art ne $newart || $tit ne $newtit || $tra ne $newtra || $alb ne $newalb || $com ne $newcom || $gen ne $newgen || $year ne $newyear ) { if(!$main::testmode) { &write_tags($file, $newart, $newtit, $newtra, $newalb, $newcom, $newgen, $newyear); } $main::id3_change++; } } # check for and apply filename changes if($file ne $newfile) { if($main::fat32fix) { # work around case insensitive filesystem renaming problems $tmpfile = $newfile."-FSFIX"; if( -e $tmpfile && !$main::overwrite) { $main::tmpfilefound++; $main::tmpfilelist .= "$tmpfile\n"; return; } if (!$main::testmode) { rename $file, $tmpfile; if(-e $newfile && !$main::overwrite) { &nf_print("$file", "ERROR: $newfile allready exists - fs fix mode"); rename $tmpfile, $file; return; } else { rename $tmpfile, $newfile; } } } elsif(!$main::testmode) { if(-e $newfile && !$main::overwrite) { $main::suggestF++; &nf_print("$file", "ERROR: $newfile allready exists - normal mode"); return; } else { rename $file, $newfile; } } $main::change++; } if($tag) { &nf_print ( $file, $newfile, $art, $tit, $tra, $alb, $com, $gen, $year, $newart, $newtit, $newtra, $newalb, $newcom, $newgen, $newyear ); } else { &nf_print("$file", "$newfile"); } }; 1;