]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/commitdiff
salut plugin: handles multi-lingual salutations (hello/goodbye)
authorGiuseppe Bilotta <giuseppe.bilotta@gmail.com>
Tue, 17 Oct 2006 11:25:09 +0000 (11:25 +0000)
committerGiuseppe Bilotta <giuseppe.bilotta@gmail.com>
Tue, 17 Oct 2006 11:25:09 +0000 (11:25 +0000)
ChangeLog
data/rbot/plugins/salut.rb [new file with mode: 0644]
data/rbot/templates/salut/salut-english [new file with mode: 0644]
data/rbot/templates/salut/salut-italian [new file with mode: 0644]

index 5f1fa982bbf30af1571a7753ef741832e991bcf5..f04416fbea7d5689a3d9604b82f90d4eefde6988 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2006-10-17  Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
+
+       * Salut plugin: handles (multilingual) salutations (hello/goodbye)
+
 2006-10-15  Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
 
        * Language stuff: plugins can now handle language changes in a natural
@@ -5,6 +9,10 @@
        is not (yet) backwards compatible: the old larts/praises files from
        previous rbot setups have to be renamed manually
        * Language stuff: italian translations
+       * Utils.safe_save(filename): allows 'safe' saving of a file: it needs a
+       block, to which it will yield a temporary file on which operations can
+       be carried out. When the block returns, the tempfile will be renamed to
+       the given filename
 
 2006-09-21  Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
 
diff --git a/data/rbot/plugins/salut.rb b/data/rbot/plugins/salut.rb
new file mode 100644 (file)
index 0000000..1a301b4
--- /dev/null
@@ -0,0 +1,174 @@
+# 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
diff --git a/data/rbot/templates/salut/salut-english b/data/rbot/templates/salut/salut-english
new file mode 100644 (file)
index 0000000..f1c1dc4
--- /dev/null
@@ -0,0 +1,33 @@
+--- 
+:"generic-in": 
+- hello
+- howdy
+- hola
+- salut
+- sup
+- re
+- hey
+- hi
+- yo
+:"morning-in": 
+- good morning
+- goodmorning
+- morning
+- "'morgning"
+:"afternoon-in": 
+- good afternoon
+- goodafternoon
+- "'afternoon"
+:"generic-out": 
+- bye
+- cya
+- see you
+- see ya
+- g'bye
+- goodbye
+- later
+:"evening-in": 
+- good evening
+- goodevening
+- "'evening"
+- evening
diff --git a/data/rbot/templates/salut/salut-italian b/data/rbot/templates/salut/salut-italian
new file mode 100644 (file)
index 0000000..68632f0
--- /dev/null
@@ -0,0 +1,19 @@
+--- 
+:"generic-in": 
+- salve
+- ehila'
+- ola'
+- yo
+:"morning-in": 
+- buongiorno
+:"afternoon-in": 
+- buonasera
+:"generic-out": 
+- a dopo
+- ci vediamo
+- adios
+- se vedemio
+:"evening-in": 
+- buonasera
+:"generic":
+- ciao