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