### Home Classes Methods

### In Files

- lib/rbot/messagemapper.rb

### Parent

Object

### Methods

- ::new
- #inspect
- #items=
- #recognize
- #regexp=
- #requirements_for
- #set_auth_path

### Class/Module Index

Quicksearch

- Irc
- Irc::AsciiCasemap
- Irc::BanlistMessage
- Irc::BasicUserMessage
- Irc::Bot
- Irc::Bot::Auth
- Irc::Bot::Auth::BotOwnerClass
- Irc::Bot::Auth::BotUser
- Irc::Bot::Auth::Command
- Irc::Bot::Auth::DefaultBotUserClass
- Irc::Bot::Auth::InvalidPassword
- Irc::Bot::Auth::ManagerClass
- Irc::Bot::Auth::PermissionSet
- Irc::Bot::Config
- Irc::Bot::Config::ArrayValue
- Irc::Bot::Config::BooleanValue
- Irc::Bot::Config::EnumValue
- Irc::Bot::Config::FloatValue
- Irc::Bot::Config::IntegerValue
- Irc::Bot::Config::ManagerClass
- Irc::Bot::Config::StringValue
- Irc::Bot::Config::Value
- Irc::Bot::Config::Wizard
- Irc::Bot::DataFilter
- Irc::Bot::DataStream
- Irc::Bot::Language
- Irc::Bot::MessageMapper
- Irc::Bot::MessageMapper::Failure
- Irc::Bot::MessageMapper::FriendlyFailure
- Irc::Bot::MessageMapper::NoActionFailure
- Irc::Bot::MessageMapper::NoMatchFailure
- Irc::Bot::MessageMapper::NotPrivateFailure
- Irc::Bot::MessageMapper::NotPublicFailure
- Irc::Bot::MessageMapper::PartialMatchFailure
- Irc::Bot::MessageParameter
- Irc::Bot::MessageTemplate
- Irc::Bot::Plugins
- Irc::Bot::Plugins::BotModule
- Irc::Bot::Plugins::CoreBotModule
- Irc::Bot::Plugins::Plugin
- Irc::Bot::Plugins::PluginManagerClass
- Irc::Bot::Plugins::RecurseTooDeep
- Irc::Bot::Plugins::RemoteBotModule
- Irc::Bot::Plugins::RemoteCoreBotModule
- Irc::Bot::Plugins::RemotePlugin
- Irc::Bot::Registry
- Irc::Bot::Registry::Accessor
- Irc::Bot::RemoteDispatcher
- Irc::Bot::RemoteMessage
- Irc::Bot::RemoteObject
- Irc::Bot::Wordlist
- Irc::BotConfig
- Irc::Casemap
- Irc::Channel
- Irc::Channel::Mode
- Irc::Channel::ModeHash
- Irc::Channel::ModeTypeA
- Irc::Channel::ModeTypeB
- Irc::Channel::ModeTypeC
- Irc::Channel::ModeTypeD
- Irc::Channel::Topic
- Irc::Channel::UserMode
- Irc::ChannelList
- Irc::Client
- Irc::DBHash
- Irc::DBTree
- Irc::InviteMessage
- Irc::JoinMessage
- Irc::KickMessage
- Irc::MessageQueue
- Irc::ModeChangeMessage
- Irc::MotdMessage
- Irc::NamesMessage
- Irc::Netmask
- Irc::NetmaskDb
- Irc::NetmaskDb::Tree
- Irc::NetmaskList
- Irc::NickMessage
- Irc::NoSuchTargetMessage
- Irc::NoticeMessage
- Irc::PartMessage
- Irc::PrivMessage
- Irc::QueueRing
- Irc::QuitMessage
- Irc::RfcCasemap
- Irc::Server
- Irc::ServerOrCasemap
- Irc::Socket
- Irc::Socket::IdentityFilter
- Irc::StrictRfcCasemap
- Irc::TopicMessage
- Irc::UnknownMessage
- Irc::User
- Irc::UserList
- Irc::UserMessage
- Irc::Utils
- Irc::Utils::HttpUtil
- Irc::Utils::HttpUtil::CachedObject
- Irc::Utils::ParseTime
- Irc::WelcomeMessage
- Irc::WhoisMessage
- BDB
- BDB::CIBtree
- MonitorMixin
- MonitorMixin::ConditionVariable
- Net
- Net::HTTPResponse
- Regexp
- Regexp::Irc
- Singleton
- Singleton::SingletonClassMethods
- Timer
- Timer::Action
- TokyoCabinet
- TokyoCabinet::CIBDB
- UnicodePlugin
- UnicodePlugin::UnicodeFilter
- Array
- ArrayOf
- AuthModule
- BasicsModule
- ConditionVariable
- ConfigModule
- DottedIndex
- Enumerable
- Exception
- FiltersModule
- GetText
- GetTextVersionError
- HttpUtilPlugin
- IrcLogModule
- Module
- Numeric
- Object
- Range
- RemoteModule
- ServerError
- String
- Symbol
- UserDataModule
- WordlistModule
- YAML

No matching classes.

# Irc::Bot::MessageTemplate

MessageTemplate is the class that holds the actual message template map()'d by a BotModule and handled by a MessageMapper

### Attributes

botmodule[R]
defaults[R]
items[R]
options[R]
regexp[R]
template[R]

### Public Class Methods

initialize(botmodule, template, opts={}) click to toggle source

Create a new MessageTemplate associated to BotModule botmodule, with template template and options opts

    # File lib/rbot/messagemapper.rb, line 411
    def initialize(botmodule, template, hash={})
      raise ArgumentError, "Third 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) : {}
      @template = template
      case botmodule
      when String
        @botmodule = botmodule
      when Plugins::BotModule
        @botmodule = botmodule.name
      else
        raise ArgumentError, "#{botmodule.inspect} is not a botmodule nor a botmodule name"
      end

      self.items = template
      # @dyn_items is an array of MessageParameters, except for the first entry
      # which is the template
      @dyn_items = @items.collect { |it|
        if it.kind_of?(Symbol)
          i = it.to_s
          opt = MessageParameter.new(i)
          if i.sub!(/^\*/,"")
            opt.name = i
            opt.multi = true
          end
          opt.default = @defaults[opt.name]
          opt.collector = @requirements[opt.name]
          opt
        else
          nil
        end
      }
      @dyn_items.unshift(template).compact!
      debug "Items: #{@items.inspect}; dyn items: #{@dyn_items.inspect}"

      self.regexp = template
      debug "Command #{template.inspect} in #{@botmodule} will match using #{@regexp}"

      set_auth_path(hash)

      unless hash.has_key?(:action)
        hash[:action] = items[0]
      end

      @options = hash

      # debug "Create template #{self.inspect}"
    end

### Public Instance Methods

inspect() click to toggle source

    # File lib/rbot/messagemapper.rb, line 645
    def inspect
      when_str = @requirements.empty? ? "" : " when #{@requirements.inspect}"
      default_str = @defaults.empty? ? "" : " || #{@defaults.inspect}"
      "<#{self.class.to_s} #{@items.map { |c| c.inspect }.join(' ').inspect}#{default_str}#{when_str}>"
    end

items=(str) click to toggle source

    # File lib/rbot/messagemapper.rb, line 499
    def items=(str)
      raise ArgumentError, "template #{str.inspect} should be a String" unless str.kind_of?(String)

      # split and convert ':xyz' to symbols
      items = str.strip.split(/\]?\s+\[?|\]?$/).collect { |c|
        # there might be extra (non-alphanumeric) stuff (e.g. punctuation) after the symbol name
        if /^(:|\*)(\w+)(.*)/ =~ c
          sym = ($1 == ':' ) ? $2.intern : "*#{$2}".intern
          if $3.empty?
            sym
          else
            [sym, $3]
          end
        else
          c
        end
      }.flatten
      @items = items

      raise ArgumentError, "Illegal template -- first component cannot be dynamic: #{str.inspect}" if @items.first.kind_of? Symbol

      raise ArgumentError, "Illegal template -- first component cannot be optional: #{str.inspect}" if @items.first =~ /\[|\]/

      # Verify uniqueness of each component.
      @items.inject({}) do |seen, item|
        if item.kind_of? Symbol
          # We must remove the initial * when present,
          # because the parameters hash will intern both :item and *item as :item
          it = item.to_s.sub(/^\*/,"").intern
          raise ArgumentError, "Illegal template -- duplicate item #{it} in #{str.inspect}" if seen.key? it
          seen[it] = true
        end
        seen
      end
    end

recognize(m) click to toggle source

Recognize the provided string components, returning a hash of recognized values, or [nil, reason] if the string isn't recognized.

    # File lib/rbot/messagemapper.rb, line 581
    def recognize(m)

      debug "Testing #{m.message.inspect} against #{self.inspect}"

      matching = @regexp.match(m.message)
      return MessageMapper::NoMatchFailure.new(self, m) unless matching
      return MessageMapper::PartialMatchFailure.new(self, m) unless matching[0] == m.message

      return MessageMapper::NotPrivateFailure.new(self, m) if @options.has_key?(:private) && !@options[:private] && m.private?
      return MessageMapper::NotPublicFailure.new(self, m) if @options.has_key?(:public) && !@options[:public] && !m.private?

      debug_match = matching[1..-1].collect{ |d| d.inspect}.join(', ')
      debug "#{m.message.inspect} matched #{@regexp} with #{debug_match}"
      debug "Associating #{debug_match} with dyn items #{@dyn_items.join(', ')}"

      options = @defaults.dup

      @dyn_items.each_with_index { |it, i|
        next if i == 0
        item = it.name
        debug "dyn item #{item} (multi-word: #{it.multi?.inspect})"
        if it.multi?
          if matching[i].nil?
            default = it.default
            case default
            when Array
              value = default.clone
            when String
              value = default.strip.split
            when nil, false, []
              value = []
            else
              warning "Unmanageable default #{default} detected for :*#{item.to_s}, using []"
              value = []
            end
            case default
            when String
              value.instance_variable_set(:@string_value, default)
            else
              value.instance_variable_set(:@string_value, value.join(' '))
            end
          else
            value = matching[i].split
            value.instance_variable_set(:@string_value, matching[i])
          end
          def value.to_s
            @string_value
          end
        else
          if matching[i].nil?
            warning "No default value for option #{item.inspect} specified" unless @defaults.has_key?(item)
            value = it.default
          else
            value = it.collect(matching[i])
          end
        end
        options[item] = value
        debug "set #{item} to #{options[item].inspect}"
      }

      options.delete_if {|k, v| v.nil?} # Remove nil values.
      return options
    end

regexp=(str) click to toggle source

    # File lib/rbot/messagemapper.rb, line 535
    def regexp=(str)
      # debug "Original string: #{str.inspect}"
      rx = Regexp.escape(str)
      # debug "Escaped: #{rx.inspect}"
      rx.gsub!(/((?:\\ )*)(:|\\\*)(\w+)/) { |m|
        whites = $1
        is_single = $2 == ":"
        name = $3.intern

        not_needed = @defaults.has_key?(name)

        has_req = @requirements[name]
        debug "Requirements for #{name}: #{has_req.inspect}"
        case has_req
        when nil
          sub = is_single ? "\\S+" : ".*?"
        when Regexp
          # Remove captures and the ^ and $ that are sometimes placed in requirement regexps
          sub = has_req.mm_cleanup
        when String
          sub = Regexp.escape(has_req)
        when Array
          sub = has_req[0].mm_cleanup
        when Hash
          sub = has_req[:regexp].mm_cleanup
        else
          warning "Odd requirement #{has_req.inspect} of class #{has_req.class} for parameter '#{name}'"
          sub = Regexp.escape(has_req.to_s) rescue "\\S+"
        end
        debug "Regexp for #{name}: #{sub.inspect}"
        s = "#{not_needed ? "(?:" : ""}#{whites}(#{sub})#{ not_needed ? ")?" : ""}"
      }
      # debug "Replaced dyns: #{rx.inspect}"
      rx.gsub!(/((?:\\ )*)((?:\\\[)+)/, '\2\1')
      # debug "Corrected optionals spacing: #{rx.inspect}"
      rx.gsub!(/\\\[/, "(?:")
      rx.gsub!(/\\\]/, ")?")
      # debug "Delimited optionals: #{rx.inspect}"
      rx.gsub!(/(?:\\ )+/, "\\s+")
      # debug "Corrected spaces: #{rx.inspect}"
      # Created message (such as by fake_message) can contain multiple lines
      @regexp = /\A#{rx}\z/
    end

requirements_for(name) click to toggle source

    # File lib/rbot/messagemapper.rb, line 651
    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

set_auth_path(hash) click to toggle source

    # File lib/rbot/messagemapper.rb, line 460
    def set_auth_path(hash)
      if hash.has_key?(:auth)
        warning "Command #{@template.inspect} in #{@botmodule} uses old :auth syntax, please upgrade"
      end
      if hash.has_key?(:full_auth_path)
        warning "Command #{@template.inspect} in #{@botmodule} sets :full_auth_path, please don't do this"
      else
        pre = @botmodule
        words = items.reject{ |x|
          x == pre || x.kind_of?(Symbol) || x =~ /\[|\]/
        }
        if words.empty?
          post = nil
        else
          post = words.first
        end
        if hash.has_key?(:auth_path)
          extra = hash[:auth_path]
          if extra.sub!(/^:/, "")
            pre += "::" + post
            post = nil
          end
          if extra.sub!(/:$/, "")
            if words.length > 1
              post = [post,words[1]].compact.join("::")
            end
          end
          pre = nil if extra.sub!(/^!/, "")
          post = nil if extra.sub!(/!$/, "")
          extra = nil if extra.empty?
        else
          extra = nil
        end
        hash[:full_auth_path] = [pre,extra,post].compact.join("::")
        debug "Command #{@template} in #{botmodule} will use authPath #{hash[:full_auth_path]}"
        # TODO check if the full_auth_path is sane
      end
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.