]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - lib/rbot/language.rb
Try to guess the default language from the locale guessed from GeText
[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     lang = locale.language
34     if locale.country
35       str = lang + "_#{locale.country}"
36       if Lang2Locale.value?(str)
37         # Get the shortest key in Lang2Locale which maps to the given lang_country
38         return Lang2Locale.select { |k, v| v == str }.transpose.first.map { |v| v.to_s }.sort { |a, b| a.length <=> b.length }.first
39       end
40     end
41     # lang_country didn't work, let's try lan
42     if Lang2Locale.value?(lang)
43       # Get the shortest key in Lang2Locale which maps to the given lang
44       return Lang2Locale.select { |k, v| v == lang }.transpose.first.map { |v| v.to_s }.sort { |a, b| a.length <=> b.length }.first
45     end
46     # all else fail, return 'english'
47     return 'english'
48   end
49
50   class Language
51     BotConfig.register BotConfigEnumValue.new('core.language', 
52       :default => Irc::Language.from_locale, :wizard => true,
53       :values => Proc.new{|bot|
54             Dir.new(Config::datadir + "/languages").collect {|f|
55               f =~ /\.lang$/ ? f.gsub(/\.lang$/, "") : nil
56             }.compact
57           },   
58       :on_change => Proc.new {|bot, v| bot.lang.set_language v},
59       :desc => "Which language file the bot should use")
60     
61     def initialize(bot, language)
62       @bot = bot
63       set_language language
64     end
65     attr_reader :language, :locale
66
67     def set_language(language)
68       l = language.to_s.gsub(/\s+/,'_').intern
69       if Lang2Locale.key?(l)
70         @locale = Lang2Locale[l]
71         debug "locale set to #{@locale}"
72         setlocale(@locale)
73       else
74         warn "Unable to set locale, unknown language #{l}"
75       end
76
77       file = Config::datadir + "/languages/#{language}.lang"
78       unless(FileTest.exist?(file))
79         raise "no such language: #{language} (no such file #{file})"
80       end
81       @language = language
82       @file = file
83       scan
84       return if @bot.plugins.nil?
85       @bot.plugins.core_modules.each { |p|
86         if p.respond_to?('set_language')
87           p.set_language(@language)
88         end
89       }
90       @bot.plugins.plugins.each { |p|
91         if p.respond_to?('set_language')
92           p.set_language(@language)
93         end
94       }
95     end
96
97     def scan
98       @strings = Hash.new
99       current_key = nil
100       IO.foreach(@file) {|l|
101         next if l =~ /^$/
102         next if l =~ /^\s*#/
103         if(l =~ /^(\S+):$/)
104           @strings[$1] = Array.new
105           current_key = $1
106         elsif(l =~ /^\s*(.*)$/)
107           @strings[current_key] << $1
108         end
109       }
110     end
111
112     def rescan
113       scan
114     end
115
116     def get(key)
117       if(@strings.has_key?(key))
118         return @strings[key][rand(@strings[key].length)]
119       else
120         raise "undefined language key"
121       end
122     end
123
124     def save
125       File.open(@file, "w") {|file|
126         @strings.each {|key,val|
127           file.puts "#{key}:"
128           val.each_value {|v|
129             file.puts "   #{v}"
130           }
131         }
132       }
133     end
134   end
135
136 end
137 end