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