]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - lib/rbot/language.rb
gettext: change depricated and removed setlocale
[user/henk/code/ruby/rbot.git] / lib / rbot / language.rb
1 #-- vim:sw=2:et
2 #++
3 #
4 # :title: Language module for rbot
5 #
6 # This module takes care of language handling for rbot:
7 # setting the core.language value, loading the appropriate
8 # .lang file etc.
9
10 module Irc
11 class Bot
12   class Language
13
14     # This constant hash holds the mapping
15     # from long language names to the usual POSIX
16     # locale specifications
17     Lang2Locale = {
18       :english  => 'en',
19       :british_english  => 'en_GB',
20       :american_english  => 'en_US',
21       :italian  => 'it',
22       :french   => 'fr',
23       :german   => 'de',
24       :dutch    => 'nl',
25       :japanese => 'ja',
26       :russian  => 'ru',
27       :finnish  => 'fi',
28       :traditional_chinese => 'zh_TW',
29       :simplified_chinese => 'zh_CN'
30     }
31     # On WIN32 it appears necessary to have ".UTF-8" explicitly for gettext to use UTF-8
32     Lang2Locale.each_value {|v| v.replace(v + '.UTF-8')}
33
34     # Return the shortest language for the current
35     # GetText locale
36     def Language.from_locale
37       return 'english' unless defined?(GetText)
38       lang = locale.language
39       if locale.country
40         str = lang + "_#{locale.country}"
41         if Lang2Locale.value?(str)
42           # Get the shortest key in Lang2Locale which maps to the given lang_country
43           lang_str = Lang2Locale.select { |k, v| v == str }.transpose.first.map { |v| v.to_s }.sort { |a, b| a.length <=> b.length }.first
44           if File.exist?(File.join(Config::datadir, "languages/#{lang_str}.lang"))
45             return lang_str
46           end
47         end
48       end
49       # lang_country didn't work, let's try lan
50       if Lang2Locale.value?(lang)
51         # Get the shortest key in Lang2Locale which maps to the given lang
52         lang_str = Lang2Locale.select { |k, v| v == lang }.transpose.first.map { |v| v.to_s }.sort { |a, b| a.length <=> b.length }.first
53         if File.exist?(File.join(Config::datadir, "/languages/#{lang_str}.lang"))
54           return lang_str
55         end
56       end
57       # all else fail, return 'english'
58       return 'english'
59     end
60
61     Config.register Config::EnumValue.new('core.language',
62       :default => Irc::Bot::Language.from_locale, :wizard => true,
63       :values => Proc.new{|bot|
64             Dir.new(Config::datadir + "/languages").collect {|f|
65               f =~ /\.lang$/ ? f.gsub(/\.lang$/, "") : nil
66             }.compact
67           },
68       :on_change => Proc.new {|bot, v| bot.lang.set_language v},
69       :desc => "Which language file the bot should use")
70
71     def initialize(bot, language)
72       @bot = bot
73       set_language language
74     end
75     attr_reader :language
76
77     def set_language(language)
78       lang_str = language.to_s.downcase.gsub(/\s+/,'_')
79       lang_sym = lang_str.intern
80       if defined?(GetText) and Lang2Locale.key?(lang_sym)
81         GetText.set_locale(Lang2Locale[lang_sym])
82         debug "locale set to #{locale}"
83         rbot_gettext_debug
84       else
85         warning "Unable to set locale, unknown language #{language} (#{lang_str})"
86       end
87
88       file = Config::datadir + "/languages/#{lang_str}.lang"
89       unless(FileTest.exist?(file))
90         raise "no such language: #{lang_str} (no such file #{file})"
91       end
92       @language = lang_str
93       @file = file
94       scan
95       return if @bot.plugins.nil?
96       @bot.plugins.core_modules.each { |p|
97         if p.respond_to?('set_language')
98           p.set_language(@language)
99         end
100       }
101       @bot.plugins.plugins.each { |p|
102         if p.respond_to?('set_language')
103           p.set_language(@language)
104         end
105       }
106     end
107
108     def scan
109       @strings = Hash.new
110       current_key = nil
111       IO.foreach(@file) {|l|
112         next if l =~ /^$/
113         next if l =~ /^\s*#/
114         if(l =~ /^(\S+):$/)
115           @strings[$1] = Array.new
116           current_key = $1
117         elsif(l =~ /^\s*(.*)$/)
118           @strings[current_key] << $1
119         end
120       }
121     end
122
123     def rescan
124       scan
125     end
126
127     def get(key)
128       if(@strings.has_key?(key))
129         return @strings[key][rand(@strings[key].length)]
130       else
131         raise "undefined language key"
132       end
133     end
134
135     def save
136       File.open(@file, "w") {|file|
137         @strings.each {|key,val|
138           file.puts "#{key}:"
139           val.each_value {|v|
140             file.puts "   #{v}"
141           }
142         }
143       }
144     end
145   end
146
147 end
148 end