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