diff options
author | Tom Gilbert <tom@linuxbrit.co.uk> | 2005-07-27 16:32:32 +0000 |
---|---|---|
committer | Tom Gilbert <tom@linuxbrit.co.uk> | 2005-07-27 16:32:32 +0000 |
commit | 2a96c9198c1f6e13407d0999083f6ce5e0bc06fa (patch) | |
tree | b3b9247d275d9b554665bc22884104d266d2e757 /rbot/messagemapper.rb | |
parent | 21949774b91eaec6ecde4eaa8ad121e2c0a36b87 (diff) |
move rbot into lib - still rearranging for packaging/installation
Diffstat (limited to 'rbot/messagemapper.rb')
-rw-r--r-- | rbot/messagemapper.rb | 168 |
1 files changed, 0 insertions, 168 deletions
diff --git a/rbot/messagemapper.rb b/rbot/messagemapper.rb deleted file mode 100644 index 42563d23..00000000 --- a/rbot/messagemapper.rb +++ /dev/null @@ -1,168 +0,0 @@ -module Irc - class MessageMapper - attr_writer :fallback - - def initialize(parent) - @parent = parent - @routes = Array.new - @fallback = 'usage' - end - - def map(*args) - @routes << Route.new(*args) - end - - def each - @routes.each {|route| yield route} - end - def last - @routes.last - end - - def handle(m) - return false if @routes.empty? - failures = [] - @routes.each do |route| - options, failure = route.recognize(m) - if options.nil? - failures << [route, failure] - else - action = route.options[:action] ? route.options[:action] : route.items[0] - next unless @parent.respond_to?(action) - auth = route.options[:auth] ? route.options[:auth] : action - if m.bot.auth.allow?(auth, m.source, m.replyto) - debug "route found and auth'd: #{action.inspect} #{options.inspect}" - @parent.send(action, m, options) - return true - end - # if it's just an auth failure but otherwise the match is good, - # don't try any more handlers - break - end - end - debug failures.inspect - debug "no handler found, trying fallback" - if @fallback != nil && @parent.respond_to?(@fallback) - if m.bot.auth.allow?(@fallback, m.source, m.replyto) - @parent.send(@fallback, m, {}) - return true - end - end - return false - end - - end - - class Route - attr_reader :defaults # The defaults hash - attr_reader :options # The options hash - attr_reader :items - def initialize(template, hash={}) - raise ArgumentError, "Second argument must be a hash!" unless hash.kind_of?(Hash) - @defaults = hash[:defaults].kind_of?(Hash) ? hash.delete(:defaults) : {} - @requirements = hash[:requirements].kind_of?(Hash) ? hash.delete(:requirements) : {} - self.items = template - @options = hash - end - def items=(str) - items = str.split(/\s+/).collect {|c| (/^(:|\*)(\w+)$/ =~ c) ? (($1 == ':' ) ? $2.intern : "*#{$2}".intern) : c} if str.kind_of?(String) # split and convert ':xyz' to symbols - items.shift if items.first == "" - items.pop if items.last == "" - @items = items - - if @items.first.kind_of? Symbol - raise ArgumentError, "Illegal template -- first component cannot be dynamic\n #{str.inspect}" - end - - # Verify uniqueness of each component. - @items.inject({}) do |seen, item| - if item.kind_of? Symbol - raise ArgumentError, "Illegal template -- duplicate item #{item}\n #{str.inspect}" if seen.key? item - seen[item] = true - end - seen - end - end - - # Recognize the provided string components, returning a hash of - # recognized values, or [nil, reason] if the string isn't recognized. - def recognize(m) - components = m.message.split(/\s+/) - options = {} - - @items.each do |item| - if /^\*/ =~ item.to_s - if components.empty? - value = @defaults.has_key?(item) ? @defaults[item].clone : [] - else - value = components.clone - end - components = [] - def value.to_s() self.join(' ') end - options[item.to_s.sub(/^\*/,"").intern] = value - elsif item.kind_of? Symbol - value = components.shift || @defaults[item] - if passes_requirements?(item, value) - options[item] = value - else - if @defaults.has_key?(item) - debug "item #{item} doesn't pass reqs but has a default of #{@defaults[item]}" - options[item] = @defaults[item].clone - # push the test-failed component back on the stack - components.unshift value - else - return nil, requirements_for(item) - end - end - else - return nil, "No value available for component #{item.inspect}" if components.empty? - component = components.shift - return nil, "Value for component #{item.inspect} doesn't match #{component}" if component != item - end - end - - return nil, "Unused components were left: #{components.join '/'}" unless components.empty? - - return nil, "route is not configured for private messages" if @options.has_key?(:private) && !@options[:private] && m.private? - return nil, "route is not configured for public messages" if @options.has_key?(:public) && !@options[:public] && !m.private? - - options.delete_if {|k, v| v.nil?} # Remove nil values. - return options, nil - end - - def inspect - when_str = @requirements.empty? ? "" : " when #{@requirements.inspect}" - default_str = @defaults.empty? ? "" : " || #{@defaults.inspect}" - "<#{self.class.to_s} #{@items.collect{|c| c.kind_of?(String) ? c : c.inspect}.join(' ').inspect}#{default_str}#{when_str}>" - end - - # Verify that the given value passes this route's requirements - def passes_requirements?(name, value) - return @defaults.key?(name) && @defaults[name].nil? if value.nil? # Make sure it's there if it should be - - case @requirements[name] - when nil then true - when Regexp then - value = value.to_s - match = @requirements[name].match(value) - match && match[0].length == value.length - else - @requirements[name] == value.to_s - end - end - - def requirements_for(name) - name = name.to_s.sub(/^\*/,"").intern if (/^\*/ =~ name.inspect) - presence = (@defaults.key?(name) && @defaults[name].nil?) - requirement = case @requirements[name] - when nil then nil - when Regexp then "match #{@requirements[name].inspect}" - else "be equal to #{@requirements[name].inspect}" - end - if presence && requirement then "#{name} must be present and #{requirement}" - elsif presence || requirement then "#{name} must #{requirement || 'be present'}" - else "#{name} has no requirements" - end - end - end -end |