4 # :title: Salutations plugin for rbot
\r
6 # Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
\r
7 # Copyright:: (C) 2006-2007 Giuseppe Bilotta
\r
10 # Salutations plugin: respond to salutations
\r
12 # TODO:: allow online editing of salutations
\r
14 # TODO:: *REMEMBER* to set @changed to true after edit or changes won't be saved
\r
16 class SalutPlugin < Plugin
\r
17 BotConfig.register BotConfigBooleanValue.new('salut.all_languages',
\r
19 :desc => "Check for a salutation in all languages and not just in the one defined by core.language",
\r
20 :on_change => Proc.new {|bot, v| bot.plugins['salut'].reload}
\r
22 BotConfig.register BotConfigBooleanValue.new('salut.address_only',
\r
24 :desc => "When set to true, the bot will only reply to salutations directed at him",
\r
25 :on_change => Proc.new {|bot, v| bot.plugins['salut'].reload}
\r
30 @salutations = Hash.new
\r
32 @match_langs = Array.new
\r
33 @main_lang_str = nil
\r
41 def set_language(what)
\r
51 @salutations.each { |lang, hash|
\r
56 hash.each { |situation, array|
\r
58 when /^generic-dest$/
\r
68 @match[lang] = Hash.new
\r
69 @match[lang][:in] = Regexp.new("\\b(?:" + ar_in.uniq.map { |txt|
\r
71 }.join('|') + ")\\b", Regexp::IGNORECASE) unless ar_in.empty?
\r
72 @match[lang][:out] = Regexp.new("\\b(?:" + ar_out.uniq.map { |txt|
\r
74 }.join('|') + ")\\b", Regexp::IGNORECASE) unless ar_out.empty?
\r
75 @match[lang][:both] = Regexp.new("\\b(?:" + ar_both.uniq.map { |txt|
\r
77 }.join('|') + ")\\b", Regexp::IGNORECASE) unless ar_both.empty?
\r
78 @match[lang][:dest] = Regexp.new("\\b(?:" + ar_dest.uniq.map { |txt|
\r
80 }.join('|') + ")\\b", Regexp::IGNORECASE) unless ar_dest.empty?
\r
82 @punct = /\s*[.,:!;?]?\s*/ # Punctuation
\r
84 # Languages to match for, in order
\r
86 @match_langs << @main_lang if @match.key?(@main_lang)
\r
87 @match_langs << :english if @match.key?(:english)
\r
88 @match.each_key { |key|
\r
95 return if @match.empty?
\r
96 return unless m.kind_of?(PrivMessage)
\r
97 return if m.address? and m.plugin == 'config'
\r
98 to_me = m.address? || m.message =~ /#{Regexp.escape(@bot.nick)}/i
\r
99 if @bot.config['salut.address_only']
\r
100 return unless to_me
\r
103 @match_langs.each { |lang|
\r
104 [:both, :in, :out].each { |k|
\r
105 next unless @match[lang][k]
\r
106 if m.message =~ @match[lang][k]
\r
107 salut = [@match[lang][k], lang, k]
\r
113 return unless salut
\r
114 # If the bot wasn't addressed, we continue only if the match was exact
\r
115 # (apart from space and punctuation) or if @match[:dest] matches too
\r
116 return unless to_me or m.message =~ /^#{@punct}#{salut.first}#{@punct}$/ or m.message =~ @match[salut[1]][:dest]
\r
120 salut_reply(m, salut, :morning)
\r
122 salut_reply(m, salut, :afternoon)
\r
124 salut_reply(m, salut, :evening)
\r
128 def salut_reply(m, salut, time)
\r
131 debug "Replying to #{salut.first} (#{lang} #{k}) in the #{time}"
\r
132 # salut_ar = @salutations[@main_lang].update @salutations[:english].update @salutations[lang]
\r
133 salut_ar = @salutations[lang]
\r
140 debug "Building array ..."
\r
142 rep_ar += salut_ar.fetch("#{time}#{sfx}".to_sym, [])
\r
143 rep_ar += salut_ar.fetch("#{time}".to_sym, []) unless sfx.empty?
\r
144 rep_ar += salut_ar.fetch("generic#{sfx}".to_sym, [])
\r
145 rep_ar += salut_ar.fetch("generic".to_sym, []) unless sfx.empty?
\r
146 debug "Choosing reply in #{rep_ar.inspect} ..."
\r
148 if m.public? # and (m.address? or m =~ /#{Regexp.escape(@bot.nick)}/)
\r
149 choice = @bot.lang.get("hello_X") % m.sourcenick
\r
151 choice = @bot.lang.get("hello") % m.sourcenick
\r
154 choice = rep_ar.pick_one
\r
155 if m.public? and (m.address? or m.message =~ /#{Regexp.escape(@bot.nick)}/)
\r
156 choice += "#{[',',''].pick_one} #{m.sourcenick}"
\r
157 choice += [" :)", " :D", "!", "", "", ""].pick_one
\r
160 debug "Replying #{choice}"
\r
161 m.plainreply choice
\r
166 @main_lang_str = @bot.config['core.language']
\r
167 @main_lang = @main_lang_str.to_sym
\r
168 @all_langs = @bot.config['salut.all_languages']
\r
170 # Get all available languages
\r
171 langs = Dir.new("#{@bot.botclass}/salut").collect {|f|
\r
172 f =~ /salut-([^.]+)/ ? $1 : nil
\r
174 langs.each { |lang|
\r
175 @salutations[lang.to_sym] = load_lang(lang)
\r
179 @salutations[@main_lang] = load_lang(@main_lang_str)
\r
185 def load_lang(lang)
\r
186 dir = "#{@bot.botclass}/salut"
\r
187 if not File.exist?(dir)
\r
190 file = "#{@bot.botclass}/salut/salut-#{lang}"
\r
191 if File.exist?(file)
\r
193 salutations = Hash.new
\r
194 content = YAML::load_file(file)
\r
195 content.each { |key, val|
\r
196 salutations[key.to_sym] = val
\r
200 error "failed to read salutations in #{lang}: #{$!}"
\r
207 return if @salutations.empty?
\r
208 return unless @changed
\r
209 @salutations.each { |lang, val|
\r
211 save_lang(lang, val)
\r
216 def save_lang(lang, val)
\r
217 fn = "#{@bot.botclass}/salut/salut-#{lang}"
\r
218 Utils.safe_save(fn) { |file|
\r
219 file.puts val.to_yaml
\r
225 plugin = SalutPlugin.new
\r