#!/usr/bin/ruby
# Make the filenames portable to almost any filesystem
Sig.__WARN__ { |msg| die msg }; # make warnings fatal
var f = frequire('File::Find');
var u = frequire('Text::Unidecode');
var rename = false;
# Check first argument
ARGV[0] == '-r' && (
ARGV.shift;
rename = true;
);
var dir = ARGV[0] \\ "usage: #{__MAIN__} [-r] [dir]\n".die;
f.find(
Hash.new(
wanted => func(arg) {
var file = File.new(arg);
if (file.is_file) {
# Get dirname and basename
var basename = file.basename;
var dirname = file.dirname;
# Unidecode and remove unsafe characters
basename = u.unidecode(basename).to_s;
basename.gsub!(/[^A-Za-z0-9_.-]+/, '_');
basename.tr('_.-', '_.-', 's');
# Get away the extension (if any)
var ext = '';
if (var match = (basename =~ /(\.\w{1,5})\z/)) {
ext = match.cap[0];
basename.substr!(0, -ext.len);
}
# Replace any dot sequence with a space
basename.gsub!(/\./, ' ');
# Squeeze more spaces into one space char
basename = basename.words.join(' ');
# Trim filename to 255 characters (if longer)
if (basename.length > (255 - ext.len)) {
basename.substr!(0, 255 - ext.len).trim_end!;
};
# Append back the extension
basename += ext;
# Create the new filename
var new_file = (dirname + basename.lc);
# Rename the old filename to the new filename
if (new_file != file) {
say "Renaming: `#{file}' -> `#{new_file}'";
if (File.exists(new_file)) {
STDERR.print("\t...file already exists!\n");
}
elsif (rename) {
File.rename(file, new_file) || (
STDERR.print("\tcan't rename it: #{$!}\n");
);
}
}
}
},
no_chdir => 1,
) => dir.to_dir.rel2abs
);