i have this program in ruby version 1.9.3p0 that renames files passed from the shell (send to) based on regular expression conditions. Works fine except when special characters are in the filename.
ruby RegExpRename.rb "32. Esther Verhoef - Déjà vu.epub"
gives error
/RegExpRename.rb:29:in `rename': No such file or directory - (32. Esther Verhoef - DÚjÓ vu.epub, test) (Errno::ENOENT)
from C:/Users/peter/AppData/Roaming/Microsoft/Windows/SendTo/RegExpRename.rb:29:in `block in <main>'
from C:/Users/peter/AppData/Roaming/Microsoft/Windows/SendTo/RegExpRename.rb:18:in `each'
from C:/Users/peter/AppData/Roaming/Microsoft/Windows/SendTo/RegExpRename.rb:18:in `<main>'
The encoding is the culpit, my windows cp is CP850, déjà is changed in DÚjÓ
I don’t know how to solve this, please help.
Here the program
# encoding: CP850
require 'find'
require 'fileutils'
require 'Win32API'
def get_long_win32_filename(short_name)
max_path = 1024
long_name = " " * max_path
lfn_size = Win32API.new("kernel32", "GetLongPathName", ['P','P','L'],'L').call(short_name, long_name, max_path)
return (1..max_path).include?(lfn_size) ? long_name[0..lfn_size-1] : short_name
end
ARGV.each do|a|
long = get_long_win32_filename(a)
result = long.gsub(/(\w+)\s*,\s*([^\-]+)\s*\-\s*(.+\.[a-zA-Z]{3,4})/i, "\\2 \\1 - \\3")
if result == long
result = long.gsub(/(\d+\. +)(.*)/i, "\\2")
end
if result != long
if File.exist?(result)
puts "File #{result} already exists. Not renaming."
else
File.rename(a, long)
puts long + " ===> " + result
end
else
puts long_name + " don't have to be renamed"
end
end
sleep 15
Pfew.. Don’t know whether i should be happy that i finally found it or be sad that ruby makes it so difficult.
Anyhow, here is the sollution.
Problem is when a rubyscript gets a parameter in Windows7 command-prompt (or shell) it gets this (in my situation) encoded as CP1252, i have no idea why. So if i change my CP with CHCP 1252 the script runs fine, but that is no solution of course, all special characters are printed wrong.
Solution: I tell ruby the encoding IS CP1252 and convert is to my locale CP (CP850 in my case)
I wish the CP1252 could be detected and not hardcoded so that is a more generic solution.
Any suggestions ?
Here the program I used to test this out, I pass the argument “déjà.epub”, the file IS being renamed like this.