Skip to content

Instantly share code, notes, and snippets.

@citrus-lemon
Last active December 29, 2017 02:28
Show Gist options
  • Save citrus-lemon/f406c183d1fab1bb9699dfb7d8a9c3bb to your computer and use it in GitHub Desktop.
Save citrus-lemon/f406c183d1fab1bb9699dfb7d8a9c3bb to your computer and use it in GitHub Desktop.
Encode set changing methods
#!/usr/bin/env ruby
# Codeset changing methods
begin
require 'rchardet'
rescue LoadError
end
module CodesetChange
module_function
def file_rename(a,b,force=false)
unless File.exist? b or force
File.rename a, b
else
raise Errno::EEXIST.new b
end
end
def character_escape(str)
str
.gsub(/%([0-9A-F]{2})/){ $1.to_i(16).chr }
.gsub(/\\([0-7]{3})/){ $1.to_i(8).chr }
end
def decode(str, encoding, default_coding = Encoding.default_external)
encoding = CharDet.detect(str)["encoding"] unless encoding
str.force_encoding(encoding).encode(default_coding)
rescue => e
STDERR.puts "\x1b[31m#{str}\x1b[0m cannot encode as #{encoding}"
raise e
end
def change_name(path, opts)
unless File.exist?(path || '')
STDERR.puts "File '#{path}' not exist"
return
end
obj = File.join(
File.dirname(path),
decode(character_escape(File.basename(path)), opts[:encoding], opts[:outcoding])
)
return if obj == path
file_rename(
path,
obj
)
rescue => e
STDERR.puts "File \n '#{File.dirname(path)}'\n '#{File.basename(path)}' \n cannot encode to #{opts[:encoding]}"
STDERR.puts e
end
def recursion(dir, opts)
unless File.directory? dir
STDERR.puts "File '#{dir}' not exist or not directory"
return
end
root_no_dir = if opts[:no_this_dir]
opts[:no_this_dir] = false
true
else
false
end
Dir.foreach dir do |c|
next if c == '.' or c == '..'
p = File.join(dir,c)
if File.directory? p
recursion p, opts
else
change_name(p, opts)
end
end
change_name(dir, opts) unless root_no_dir
end
end
if __FILE__ == $0
require 'optparse'
options = {
:outcoding => Encoding.default_external
}
optdir = nil
OptionParser.new do |opts|
opts.banner = "Usage: codeset.rb [options]"
opts.on( "-d", "--directory DIR", "Directory input" ) do |dir|
optdir = dir
end
opts.on( "-D", "--directory-without-self [DIR]", String,
"Directory input (recursion without itself)" ) do |dir|
options[:no_this_dir] = true
optdir = dir if dir
end
opts.on( "-e", "--encoding [Encoding]", "Encoding Method" ) do |opt|
options[:encoding] = opt ? Encoding.find(opt) : Encoding::UTF_8
end
opts.on( "-o", "--output-encoding [Encoding]", "Set output Encoding" ) do |opt|
options[:outcoding] = opt ? Encoding.find(opt) : Encoding::UTF_8
end
opts.on( "-h", "--help", "Prints this help" ) do
puts opts
exit
end
end.parse!
unless options[:encoding]
if defined? CharDet
STDERR.puts "no encoding unsured, use autodetecting..."
else
STDERR.puts "if you want to use autodetecting"
STDERR.puts " `gem install rchardet`"
STDERR.puts "no encoding unsured, exit!"
exit
end
end
optdir ? CodesetChange::recursion(optdir, options) : ARGV.map{|e| CodesetChange::change_name(e, options)}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment