]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/salut.rb
Try to read old language-agnostic lart/praises if language-specific ones are not...
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / salut.rb
1 # vim: set sw=2 et:\r
2 # Salutations plugin: respond to salutations\r
3 \r
4 unless Array.respond_to?(:pick_one)\r
5   debug "Defining the pick_one method for Array"\r
6   class ::Array\r
7     def pick_one\r
8       return nil if self.empty?\r
9       self[rand(self.length)]\r
10     end\r
11   end\r
12 end\r
13 \r
14 \r
15 class SalutPlugin < Plugin\r
16   BotConfig.register BotConfigBooleanValue.new('salut.all_languages',\r
17     :default => true, \r
18     :desc => "Check for a salutation in all languages and not just in the one defined by core.language",\r
19     :on_change => Proc.new {|bot, v| bot.plugins['salut'].reload}\r
20   )\r
21 \r
22   def initialize\r
23     @salutations = Hash.new\r
24     @match = nil\r
25     @main_lang_str = nil\r
26     @main_lang = nil\r
27     @all_langs = true\r
28     super\r
29     reload\r
30   end\r
31 \r
32   def set_language(what)\r
33     reload\r
34   end\r
35 \r
36   def create_match\r
37     @match = Hash.new\r
38     ar_in = Array.new\r
39     ar_out = Array.new\r
40     ar_both = Array.new\r
41     @salutations.each { |lang, hash|\r
42       hash.each { |situation, array|\r
43         case situation.to_s\r
44         when /in$/\r
45           ar_in += array\r
46         when /out$/\r
47           ar_out += array\r
48         else\r
49           ar_both += array\r
50         end\r
51       }\r
52     }\r
53     @match[:in] = Regexp.new("\\b(?:" + ar_in.uniq.map { |txt|\r
54       Regexp.escape(txt)\r
55     }.join('|') + ")\\b", Regexp::IGNORECASE) unless ar_in.empty?\r
56     @match[:out] = Regexp.new("\\b(?:" + ar_out.uniq.map { |txt|\r
57       Regexp.escape(txt)\r
58     }.join('|') + ")\\b", Regexp::IGNORECASE) unless ar_out.empty?\r
59     @match[:both] = Regexp.new("\\b(?:" + ar_both.uniq.map { |txt|\r
60       Regexp.escape(txt)\r
61     }.join('|') + ")\\b", Regexp::IGNORECASE) unless ar_both.empty?\r
62     debug "Matches: #{@match.inspect}"\r
63   end\r
64 \r
65   def listen(m)\r
66     salut = nil\r
67     [:both, :in, :out].each { |k|\r
68       next unless @match[k]\r
69       debug "Checking salutations #{k} (#{@match[k].inspect})"\r
70       if m.message =~ /^#{@match[k]}/\r
71         salut = k\r
72         break\r
73       end\r
74     }\r
75     return unless salut\r
76     h = Time.new.hour\r
77     case h\r
78     when 4...12\r
79       salut_reply(m, salut, :morning)\r
80     when 12...18\r
81       salut_reply(m, salut, :afternoon)\r
82     else\r
83       salut_reply(m, salut, :evening)\r
84     end\r
85   end\r
86 \r
87   def salut_reply(m, k, time)\r
88     debug "Replying to #{k} in the #{time}"\r
89     case k\r
90     when :both\r
91       sfx = ""\r
92     else\r
93       sfx = "-#{k}"\r
94     end\r
95     debug "Building array ..."\r
96     rep_ar = Array.new\r
97     rep_ar += @salutations[@main_lang].fetch("#{time}#{sfx}".to_sym, [])\r
98     rep_ar += @salutations[@main_lang].fetch("#{time}".to_sym, []) unless sfx.empty?\r
99     rep_ar += @salutations[@main_lang].fetch("generic#{sfx}".to_sym, [])\r
100     rep_ar += @salutations[@main_lang].fetch("generic".to_sym, []) unless sfx.empty?\r
101     debug "Choosing reply in #{rep_ar.inspect} ..."\r
102     if rep_ar.empty?\r
103       if m.public? and (m.address? or m =~ /#{Regexp.escape(@bot.nick)}/)\r
104         choice = @bot.lang.get("hello_X") % m.sourcenick\r
105       else\r
106         choice = @bot.lang.get("hello") % m.sourcenick\r
107       end\r
108     else\r
109       choice = rep_ar.pick_one\r
110       if m.public? and (m.address? or m.message =~ /#{Regexp.escape(@bot.nick)}/)\r
111         choice += "#{[',',''].pick_one} #{m.sourcenick}"\r
112         choice += [" :)", " :D", "!", "", "", ""].pick_one\r
113       end\r
114     end\r
115     debug "Replying #{choice}"\r
116     m.plainreply choice\r
117   end\r
118 \r
119   def reload\r
120     save\r
121     @main_lang_str = @bot.config['core.language']\r
122     @main_lang = @main_lang_str.to_sym\r
123     @all_langs = @bot.config['salut.all_languages']\r
124     if @all_langs\r
125       # Get all available languages\r
126       langs = Dir.new("#{@bot.botclass}/salut").collect {|f|\r
127         f =~ /salut-([^.]+)/ ? $1 : nil\r
128       }.compact\r
129       langs.each { |lang|\r
130         @salutations[lang.to_sym] = load_lang(lang)\r
131       }\r
132     else\r
133       @salutations.clear\r
134       @salutations[@main_lang] = load_lang(@main_lang_str)\r
135     end\r
136     create_match\r
137   end\r
138 \r
139   def load_lang(lang)\r
140     dir = "#{@bot.botclass}/salut"\r
141     if not File.exist?(dir)\r
142       Dir.mkdir(dir)\r
143     end\r
144     file = "#{@bot.botclass}/salut/salut-#{lang}"\r
145     if File.exist?(file)\r
146       begin\r
147         salutations = Hash.new\r
148         content = YAML::load_file(file)\r
149         content.each { |key, val|\r
150           salutations[key.to_sym] = val\r
151         }\r
152         return salutations\r
153       rescue\r
154         error "failed to read salutations in #{lang}: #{$!}"\r
155       end\r
156     end\r
157     return nil\r
158   end\r
159 \r
160   def save\r
161     return if @salutations.empty?\r
162     @salutations.each { |lang, val|\r
163       l = lang.to_s\r
164       save_lang(lang, val)\r
165     }\r
166   end\r
167 \r
168   def save_lang(lang, val)\r
169     file = "#{@bot.botclass}/salut/salut-#{lang}"\r
170     Utils.safe_save(file) { |file|\r
171       file.puts val.to_yaml\r
172     }\r
173   end\r
174 \r
175 end\r
176 \r
177 plugin = SalutPlugin.new\r
178 \r