1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- #!/usr/bin/ruby
- # Make 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
- if (ARGV[0] == '-r') {
- ARGV.shift
- rename = true
- }
- var dirs = ARGV || die "usage: #{__MAIN__} [-r] [dirs|files]\n"
- f.find(
- Hash(
- wanted => func(arg) {
- var file = File(Str(arg).decode_utf8)
- if (file.is_file) {
- # Ignore hidden files and directories
- if (file.split.any { .begins_with('.') }) {
- return nil
- }
- # Get dirname and basename
- var basename = file.basename
- var dirname = file.dirname
- # Unidecode and remove unsafe characters
- basename.gsub!(/[^\w\s[:punct:]]/, '')
- basename = u.unidecode(basename)
- basename.gsub!(/[^A-Za-z0-9_.-]+/, ' ')
- # 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 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)
- # 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 => 0,
- ), dirs.map { File(_).is_dir ? Dir(_) : File(_) }.map { .rel2abs }...
- )
|