Class: Irc::Bot::MessageTemplate

Inherits:
Object
  • Object
show all
Defined in:
lib/rbot/messagemapper.rb

Overview

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(botmodule, template, hash = {}) ⇒ MessageTemplate

call-seq: initialize(botmodule, template, opts={})

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

Raises:

  • (ArgumentError)


411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
# 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

Instance Attribute Details

#botmoduleObject (readonly)

the BotModule that map()‘d this MessageTemplate



404
405
406
# File 'lib/rbot/messagemapper.rb', line 404

def botmodule
  @botmodule
end

#defaultsObject (readonly)

the defaults hash



399
400
401
# File 'lib/rbot/messagemapper.rb', line 399

def defaults
  @defaults
end

#itemsObject

the collection of dynamic and static items in the template



402
403
404
# File 'lib/rbot/messagemapper.rb', line 402

def items
  @items
end

#optionsObject (readonly)

the options hash



400
401
402
# File 'lib/rbot/messagemapper.rb', line 400

def options
  @options
end

#regexpObject

the Regexp corresponding to the template



403
404
405
# File 'lib/rbot/messagemapper.rb', line 403

def regexp
  @regexp
end

#templateObject (readonly)

the actual template string



401
402
403
# File 'lib/rbot/messagemapper.rb', line 401

def template
  @template
end

Instance Method Details

#inspectObject



645
646
647
648
649
# 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

#recognize(m) ⇒ Object

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



581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
# 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

#requirements_for(name) ⇒ Object



651
652
653
654
655
656
657
658
659
660
661
662
663
# 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) ⇒ Object



460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
# 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