--- /dev/null
+# vim: set sw=2 et:\r
+# Salutations plugin: respond to salutations\r
+\r
+unless Array.respond_to?(:pick_one)\r
+ debug "Defining the pick_one method for Array"\r
+ class ::Array\r
+ def pick_one\r
+ return nil if self.empty?\r
+ self[rand(self.length)]\r
+ end\r
+ end\r
+end\r
+\r
+\r
+class SalutPlugin < Plugin\r
+ BotConfig.register BotConfigBooleanValue.new('salut.all_languages',\r
+ :default => true, \r
+ :desc => "Check for a salutation in all languages and not just in the one defined by core.language",\r
+ :on_change => Proc.new {|bot, v| bot.plugins['salut'].reload}\r
+ )\r
+\r
+ def initialize\r
+ @salutations = Hash.new\r
+ @match = nil\r
+ @main_lang_str = nil\r
+ @main_lang = nil\r
+ @all_langs = true\r
+ super\r
+ reload\r
+ end\r
+\r
+ def set_language(what)\r
+ reload\r
+ end\r
+\r
+ def create_match\r
+ @match = Hash.new\r
+ ar_in = Array.new\r
+ ar_out = Array.new\r
+ ar_both = Array.new\r
+ @salutations.each { |lang, hash|\r
+ hash.each { |situation, array|\r
+ case situation.to_s\r
+ when /in$/\r
+ ar_in += array\r
+ when /out$/\r
+ ar_out += array\r
+ else\r
+ ar_both += array\r
+ end\r
+ }\r
+ }\r
+ @match[:in] = Regexp.new("\\b(?:" + ar_in.uniq.map { |txt|\r
+ Regexp.escape(txt)\r
+ }.join('|') + ")\\b", Regexp::IGNORECASE) unless ar_in.empty?\r
+ @match[:out] = Regexp.new("\\b(?:" + ar_out.uniq.map { |txt|\r
+ Regexp.escape(txt)\r
+ }.join('|') + ")\\b", Regexp::IGNORECASE) unless ar_out.empty?\r
+ @match[:both] = Regexp.new("\\b(?:" + ar_both.uniq.map { |txt|\r
+ Regexp.escape(txt)\r
+ }.join('|') + ")\\b", Regexp::IGNORECASE) unless ar_both.empty?\r
+ debug "Matches: #{@match.inspect}"\r
+ end\r
+\r
+ def listen(m)\r
+ salut = nil\r
+ [:both, :in, :out].each { |k|\r
+ next unless @match[k]\r
+ debug "Checking salutations #{k} (#{@match[k].inspect})"\r
+ if m.message =~ /^#{@match[k]}/\r
+ salut = k\r
+ break\r
+ end\r
+ }\r
+ return unless salut\r
+ h = Time.new.hour\r
+ case h\r
+ when 4...12\r
+ salut_reply(m, salut, :morning)\r
+ when 12...18\r
+ salut_reply(m, salut, :afternoon)\r
+ else\r
+ salut_reply(m, salut, :evening)\r
+ end\r
+ end\r
+\r
+ def salut_reply(m, k, time)\r
+ debug "Replying to #{k} in the #{time}"\r
+ case k\r
+ when :both\r
+ sfx = ""\r
+ else\r
+ sfx = "-#{k}"\r
+ end\r
+ debug "Building array ..."\r
+ rep_ar = Array.new\r
+ rep_ar += @salutations[@main_lang].fetch("#{time}#{sfx}".to_sym, [])\r
+ rep_ar += @salutations[@main_lang].fetch("#{time}".to_sym, []) unless sfx.empty?\r
+ rep_ar += @salutations[@main_lang].fetch("generic#{sfx}".to_sym, [])\r
+ rep_ar += @salutations[@main_lang].fetch("generic".to_sym, []) unless sfx.empty?\r
+ debug "Choosing reply in #{rep_ar.inspect} ..."\r
+ if rep_ar.empty?\r
+ if m.public? and (m.address? or m =~ /#{Regexp.escape(@bot.nick)}/)\r
+ choice = @bot.lang.get("hello_X") % m.sourcenick\r
+ else\r
+ choice = @bot.lang.get("hello") % m.sourcenick\r
+ end\r
+ else\r
+ choice = rep_ar.pick_one\r
+ if m.public? and (m.address? or m.message =~ /#{Regexp.escape(@bot.nick)}/)\r
+ choice += "#{[',',''].pick_one} #{m.sourcenick}"\r
+ choice += [" :)", " :D", "!", "", "", ""].pick_one\r
+ end\r
+ end\r
+ debug "Replying #{choice}"\r
+ m.plainreply choice\r
+ end\r
+\r
+ def reload\r
+ save\r
+ @main_lang_str = @bot.config['core.language']\r
+ @main_lang = @main_lang_str.to_sym\r
+ @all_langs = @bot.config['salut.all_languages']\r
+ if @all_langs\r
+ # Get all available languages\r
+ langs = Dir.new("#{@bot.botclass}/salut").collect {|f|\r
+ f =~ /salut-([^.]+)/ ? $1 : nil\r
+ }.compact\r
+ langs.each { |lang|\r
+ @salutations[lang.to_sym] = load_lang(lang)\r
+ }\r
+ else\r
+ @salutations.clear\r
+ @salutations[@main_lang] = load_lang(@main_lang_str)\r
+ end\r
+ create_match\r
+ end\r
+\r
+ def load_lang(lang)\r
+ file = "#{@bot.botclass}/salut/salut-#{lang}"\r
+ if File.exist?(file)\r
+ begin\r
+ salutations = Hash.new\r
+ content = YAML::load_file(file)\r
+ content.each { |key, val|\r
+ salutations[key.to_sym] = val\r
+ }\r
+ return salutations\r
+ rescue\r
+ error "failed to read salutations in #{lang}: #{$!}"\r
+ end\r
+ end\r
+ return nil\r
+ end\r
+\r
+ def save\r
+ return if @salutations.empty?\r
+ @salutations.each { |lang, val|\r
+ l = lang.to_s\r
+ save_lang(lang, val)\r
+ }\r
+ end\r
+\r
+ def save_lang(lang, val)\r
+ file = "#{@bot.botclass}/salut/salut-#{lang}"\r
+ Utils.safe_save(file) { |file|\r
+ file.puts val.to_yaml\r
+ }\r
+ end\r
+\r
+end\r
+\r
+plugin = SalutPlugin.new\r
+\r