-module Irc
-module Language
+#-- vim:sw=2:et
+#++
+#
+# :title: Language module for rbot
+#
+# This module takes care of language handling for rbot:
+# setting the core.language value, loading the appropriate
+# .lang file etc.
+module Irc
+class Bot
class Language
- BotConfig.register BotConfigEnumValue.new('core.language',
- :default => "english", :wizard => true,
- :values => Dir.new(Config::DATADIR + "/languages").collect {|f|
- f =~ /\.lang$/ ? f.gsub(/\.lang$/, "") : nil
- }.compact,
+
+ # This constant hash holds the mapping
+ # from long language names to the usual POSIX
+ # locale specifications
+ Lang2Locale = {
+ :english => 'en',
+ :british_english => 'en_GB',
+ :american_english => 'en_US',
+ :italian => 'it',
+ :french => 'fr',
+ :german => 'de',
+ :dutch => 'nl',
+ :japanese => 'ja',
+ :russian => 'ru',
+ :traditional_chinese => 'zh_TW',
+ :simplified_chinese => 'zh_CN'
+ }
+ # On WIN32 it appears necessary to have ".UTF-8" explicitly for gettext to use UTF-8
+ Lang2Locale.each_value {|v| v.replace(v + '.UTF-8')}
+
+ # Return the shortest language for the current
+ # GetText locale
+ def Language.from_locale
+ return 'english' unless defined?(GetText)
+ lang = locale.language
+ if locale.country
+ str = lang + "_#{locale.country}"
+ if Lang2Locale.value?(str)
+ # Get the shortest key in Lang2Locale which maps to the given lang_country
+ lang_str = Lang2Locale.select { |k, v| v == str }.transpose.first.map { |v| v.to_s }.sort { |a, b| a.length <=> b.length }.first
+ if File.exist?(File.join(Config::datadir, "languages/#{lang_str}.lang"))
+ return lang_str
+ end
+ end
+ end
+ # lang_country didn't work, let's try lan
+ if Lang2Locale.value?(lang)
+ # Get the shortest key in Lang2Locale which maps to the given lang
+ lang_str = Lang2Locale.select { |k, v| v == lang }.transpose.first.map { |v| v.to_s }.sort { |a, b| a.length <=> b.length }.first
+ if File.exist?(File.join(Config::datadir, "/languages/#{lang_str}.lang"))
+ return lang_str
+ end
+ end
+ # all else fail, return 'english'
+ return 'english'
+ end
+
+ Config.register Config::EnumValue.new('core.language',
+ :default => Irc::Bot::Language.from_locale, :wizard => true,
+ :values => Proc.new{|bot|
+ Dir.new(Config::datadir + "/languages").collect {|f|
+ f =~ /\.lang$/ ? f.gsub(/\.lang$/, "") : nil
+ }.compact
+ },
:on_change => Proc.new {|bot, v| bot.lang.set_language v},
:desc => "Which language file the bot should use")
- def initialize(language)
+ def initialize(bot, language)
+ @bot = bot
set_language language
end
+ attr_reader :language
def set_language(language)
- file = Config::DATADIR + "/languages/#{language}.lang"
+ lang_str = language.to_s.downcase.gsub(/\s+/,'_')
+ lang_sym = lang_str.intern
+ if defined?(GetText) and Lang2Locale.key?(lang_sym)
+ setlocale(Lang2Locale[lang_sym])
+ debug "locale set to #{locale}"
+ rbot_gettext_debug
+ else
+ warning "Unable to set locale, unknown language #{language} (#{lang_str})"
+ end
+
+ file = Config::datadir + "/languages/#{lang_str}.lang"
unless(FileTest.exist?(file))
- raise "no such language: #{language} (no such file #{file})"
+ raise "no such language: #{lang_str} (no such file #{file})"
end
- @language = language
+ @language = lang_str
@file = file
scan
+ return if @bot.plugins.nil?
+ @bot.plugins.core_modules.each { |p|
+ if p.respond_to?('set_language')
+ p.set_language(@language)
+ end
+ }
+ @bot.plugins.plugins.each { |p|
+ if p.respond_to?('set_language')
+ p.set_language(@language)
+ end
+ }
end
def scan