From 40e622c4ae1ccf8b9dfcec133d5f33f1d8b1217c Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Tue, 17 Oct 2006 11:25:09 +0000 Subject: [PATCH] salut plugin: handles multi-lingual salutations (hello/goodbye) --- ChangeLog | 8 ++ data/rbot/plugins/salut.rb | 174 ++++++++++++++++++++++++ data/rbot/templates/salut/salut-english | 33 +++++ data/rbot/templates/salut/salut-italian | 19 +++ 4 files changed, 234 insertions(+) create mode 100644 data/rbot/plugins/salut.rb create mode 100644 data/rbot/templates/salut/salut-english create mode 100644 data/rbot/templates/salut/salut-italian diff --git a/ChangeLog b/ChangeLog index 5f1fa982..f04416fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2006-10-17 Giuseppe Bilotta + + * Salut plugin: handles (multilingual) salutations (hello/goodbye) + 2006-10-15 Giuseppe Bilotta * 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 diff --git a/data/rbot/plugins/salut.rb b/data/rbot/plugins/salut.rb new file mode 100644 index 00000000..1a301b43 --- /dev/null +++ b/data/rbot/plugins/salut.rb @@ -0,0 +1,174 @@ +# vim: set sw=2 et: +# Salutations plugin: respond to salutations + +unless Array.respond_to?(:pick_one) + debug "Defining the pick_one method for Array" + class ::Array + def pick_one + return nil if self.empty? + self[rand(self.length)] + end + end +end + + +class SalutPlugin < Plugin + BotConfig.register BotConfigBooleanValue.new('salut.all_languages', + :default => true, + :desc => "Check for a salutation in all languages and not just in the one defined by core.language", + :on_change => Proc.new {|bot, v| bot.plugins['salut'].reload} + ) + + def initialize + @salutations = Hash.new + @match = nil + @main_lang_str = nil + @main_lang = nil + @all_langs = true + super + reload + end + + def set_language(what) + reload + end + + def create_match + @match = Hash.new + ar_in = Array.new + ar_out = Array.new + ar_both = Array.new + @salutations.each { |lang, hash| + hash.each { |situation, array| + case situation.to_s + when /in$/ + ar_in += array + when /out$/ + ar_out += array + else + ar_both += array + end + } + } + @match[:in] = Regexp.new("\\b(?:" + ar_in.uniq.map { |txt| + Regexp.escape(txt) + }.join('|') + ")\\b", Regexp::IGNORECASE) unless ar_in.empty? + @match[:out] = Regexp.new("\\b(?:" + ar_out.uniq.map { |txt| + Regexp.escape(txt) + }.join('|') + ")\\b", Regexp::IGNORECASE) unless ar_out.empty? + @match[:both] = Regexp.new("\\b(?:" + ar_both.uniq.map { |txt| + Regexp.escape(txt) + }.join('|') + ")\\b", Regexp::IGNORECASE) unless ar_both.empty? + debug "Matches: #{@match.inspect}" + end + + def listen(m) + salut = nil + [:both, :in, :out].each { |k| + next unless @match[k] + debug "Checking salutations #{k} (#{@match[k].inspect})" + if m.message =~ /^#{@match[k]}/ + salut = k + break + end + } + return unless salut + h = Time.new.hour + case h + when 4...12 + salut_reply(m, salut, :morning) + when 12...18 + salut_reply(m, salut, :afternoon) + else + salut_reply(m, salut, :evening) + end + end + + def salut_reply(m, k, time) + debug "Replying to #{k} in the #{time}" + case k + when :both + sfx = "" + else + sfx = "-#{k}" + end + debug "Building array ..." + rep_ar = Array.new + rep_ar += @salutations[@main_lang].fetch("#{time}#{sfx}".to_sym, []) + rep_ar += @salutations[@main_lang].fetch("#{time}".to_sym, []) unless sfx.empty? + rep_ar += @salutations[@main_lang].fetch("generic#{sfx}".to_sym, []) + rep_ar += @salutations[@main_lang].fetch("generic".to_sym, []) unless sfx.empty? + debug "Choosing reply in #{rep_ar.inspect} ..." + if rep_ar.empty? + if m.public? and (m.address? or m =~ /#{Regexp.escape(@bot.nick)}/) + choice = @bot.lang.get("hello_X") % m.sourcenick + else + choice = @bot.lang.get("hello") % m.sourcenick + end + else + choice = rep_ar.pick_one + if m.public? and (m.address? or m.message =~ /#{Regexp.escape(@bot.nick)}/) + choice += "#{[',',''].pick_one} #{m.sourcenick}" + choice += [" :)", " :D", "!", "", "", ""].pick_one + end + end + debug "Replying #{choice}" + m.plainreply choice + end + + def reload + save + @main_lang_str = @bot.config['core.language'] + @main_lang = @main_lang_str.to_sym + @all_langs = @bot.config['salut.all_languages'] + if @all_langs + # Get all available languages + langs = Dir.new("#{@bot.botclass}/salut").collect {|f| + f =~ /salut-([^.]+)/ ? $1 : nil + }.compact + langs.each { |lang| + @salutations[lang.to_sym] = load_lang(lang) + } + else + @salutations.clear + @salutations[@main_lang] = load_lang(@main_lang_str) + end + create_match + end + + def load_lang(lang) + file = "#{@bot.botclass}/salut/salut-#{lang}" + if File.exist?(file) + begin + salutations = Hash.new + content = YAML::load_file(file) + content.each { |key, val| + salutations[key.to_sym] = val + } + return salutations + rescue + error "failed to read salutations in #{lang}: #{$!}" + end + end + return nil + end + + def save + return if @salutations.empty? + @salutations.each { |lang, val| + l = lang.to_s + save_lang(lang, val) + } + end + + def save_lang(lang, val) + file = "#{@bot.botclass}/salut/salut-#{lang}" + Utils.safe_save(file) { |file| + file.puts val.to_yaml + } + end + +end + +plugin = SalutPlugin.new + diff --git a/data/rbot/templates/salut/salut-english b/data/rbot/templates/salut/salut-english new file mode 100644 index 00000000..f1c1dc43 --- /dev/null +++ b/data/rbot/templates/salut/salut-english @@ -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 index 00000000..68632f03 --- /dev/null +++ b/data/rbot/templates/salut/salut-italian @@ -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 -- 2.39.2