#!perl # iTunes Library Mover, similar to http://www.get411.com/ but handles Japanese filenames as well use strict; use File::Copy; use File::Basename qw( fileparse ); use URI::Escape; use Encode; our $fs_encoding = "cp932"; our $library = "G:/iTunes-Export/Library.xml"; our $copy_to = "G:/iTunes-Export/Music"; our $new_src = "Volumes/HDPG/iTunes-Export/Music"; my $is_test_run = $ARGV[0] && $ARGV[0] eq '--dry-run'; my $backup = $is_test_run ? $library : make_backup($library); my $out; unless ($is_test_run) { rename $library, $backup or die "$backup: $!"; open $out, ">", $library or die "$library: $!"; } open my $in, "<", $backup or die "$backup: $!"; my $count = 0; while (<$in>) { s!(Music Folder).*()!$1file://localhost/$new_src/$2!; s{(Locationfile://localhost/)(.*)()} { my($prefix, $path, $postfix) = ($1, $2, $3); my $raw_path = uri_unescape($path); $raw_path =~ s/&/&/g; Encode::from_to($raw_path, "utf-8" => $fs_encoding); my($name, $orig_path, $suf) = fileparse($raw_path, qw( mp3 m4p m4a wav )); my $new_path = sprintf '%s/%04d %s%s', $copy_to, $count++, $name, $suf; if (-e $raw_path) { if (!$is_test_run) { warn "Copying $raw_path\n"; copy $raw_path, $new_path or die "$new_path: $!"; } else { # warn "copy to $new_path"; } } else { warn "$raw_path not found\n"; } $new_path =~ s/^\Q$copy_to\E/$new_src/; $new_path =~ s/&/&/g; Encode::from_to($new_path, $fs_encoding => "utf-8"); $prefix . uri_escape($new_path, "^A-Za-z0-9\-_.!~*'()/") . $postfix }eg; print $out $_ unless $is_test_run; } sub make_backup { my $file = shift; if ($file =~ /(.*)(\.\w+)$/) { return $1 . " " . time . $2; } die "Can't make backup filename"; }