2 # Phrases plugin for CyBot.
3 # CiarĂ¡n Walsh 13/5/07
5 # Recognises patterns and responds with a stored phrase
7 class Phrases < PluginBase
9 @brief_help = 'Repeats stored phrases'
13 # Check a message against the phrase list
14 # Returns nil, or an array of the matching pattern and response text if one is found
15 def find_matching_phrase(msg)
16 return nil if msg[0] == ?$ # Ignore commands
17 @phrases.each do |(pattern, text)|
18 return [pattern, text.dup] if pattern === msg
23 # Called for all incoming channel messages
24 # Checks the message for a phrase match and replies
25 def hook_privmsg_chan(irc, msg)
26 pattern, text = find_matching_phrase(msg)
27 return unless pattern and text
29 # The hash of replacement variables that can be used in a response phrase
31 # Add the matches from the pattern to the replacement hash if applicable
32 if pattern.is_a? Regexp
33 pattern =~ msg # Why is this necessary??
34 Regexp.last_match.captures.each_with_index { |cap, index| vars['$' + (index+1).to_s] = cap }
36 vars['me'] = irc.server.nick
37 vars['you'] = irc.from.nick
39 vars.each_pair { |name, val| text.gsub!('[' + name + ']', val.to_s) }
40 irc.puts text#.gsub(/\[(.+?)\]/) { |match| vars.has_key?($1) ? vars[$1] : $1 }
43 # Checks whether the user is allowed to use this plugin
44 # Informs them and returns false if not
46 if !$user.caps(irc, 'phrases', 'op', 'owner').any?
47 irc.reply "You aren't allowed to use this command"
53 # Display a phrase for a given pattern
54 # Usage: $get <pattern>
55 def cmd_get(irc, phrase)
56 return unless authed?(irc)
58 if phrase.nil? or phrase.strip.empty?
59 irc.reply 'USAGE: get <phrase>'
62 pattern, text = find_matching_phrase(phrase)
65 irc.reply "#{pattern.inspect} => #{text}"
67 irc.reply "No phrase matched '#{phrase}'"
70 help :get, "Display a phrase for a given pattern. To set phrases use 'set'"
72 # Set the phrase for a pattern
73 # Usage: $set <pattern> => <phrase>
74 def cmd_set(irc, line)
75 return unless authed?(irc)
76 (pattern, text) = line.strip.split(/\s*=>\s*/, 2)
78 if !pattern || !text || pattern.empty? || text.empty?
79 irc.reply 'Usage: set <pattern> => <response phrase>'
80 irc.reply 'Pattern can be a constant phrase or a /rege/x'
81 irc.reply 'Response phrase can contain [variables]: me, you, $1+'
85 if pattern =~ %r{\A/(.*)/([imx]*)\z}
87 'i' => Regexp::IGNORECASE,
88 'x' => Regexp::EXTENDED,
91 ptrn, flags = $1, $2.split(//)
92 f = flags.inject(0) { |flags, letter| flags += transform[letter] if transform.has_key? letter }
93 re = Regexp.new(ptrn, f)
96 irc.reply "Error compiling pattern (note: only flags i & x are allowed)"
100 @phrases[pattern] = text
102 irc.puts 'Phrase stored'
104 help :set, "Set the phrase for a pattern.Usage: set <pattern> => <response phrase>. Pattern can be a constant phrase or a /rege/x./ Response phrase can contain [variables]: me, you, $1+."
106 def cmd_del(irc, pattern)
107 return unless authed?(irc)
109 if pattern.nil? or pattern.strip.empty?
110 irc.reply 'USAGE: del <pattern>'
114 if pattern =~ %r{\A/(.*)/([imx]*)\z}
116 'i' => Regexp::IGNORECASE,
117 'x' => Regexp::EXTENDED,
120 ptrn, flags = $1, $2.split(//)
121 f = flags.inject(0) { |flags, letter| flags += transform[letter] if transform.has_key? letter }
122 pattern = Regexp.new(ptrn, f)
124 irc.reply "Error compiling pattern (note: only flags i & x are allowed)"
128 if @phrases.delete(pattern)
129 irc.reply "Phrase #{pattern.inspect} deleted"
131 irc.reply "Phrase #{pattern.inspect} not found"
135 def cmd_reload(irc, line)
136 return unless authed?(irc)
138 irc.reply 'Phrases reloaded from disk'
140 help :reload, "Reloads all phrases from disk. Make sure to save any changes you've made first."
142 def cmd_save(irc, line)
143 return unless authed?(irc)
145 irc.reply 'Phrases saved to disk'
147 irc.reply "Couldn't write phrases to disk"
150 help :save, "Save phrases to disk."
152 # Load/save the phrases data
153 # These seem to be called automatically at (un)load
156 @phrases = YAML.load_file(file_name('phrases.yml'))
157 rescue Exception => e
160 @phrases = {} unless @phrases.is_a? Hash
164 open_file("phrases.yml", 'w') do |f|
165 f.puts "# CyBot phrases plugin"
166 YAML.dump(@phrases, f)
170 rescue Exception => e
172 $log.puts e.backtrace.join("\n")