class Mobb::Base
Constants
- CALLERS_TO_IGNORE
- DEFAULT_CONDITIONS
Attributes
events[R]
filters[R]
matched[R]
Public Class Methods
add_filter(type, pattern = /.*/, **options, &block)
click to toggle source
# File lib/mobb/base.rb, line 218 def add_filter(type, pattern = /.*/, **options, &block) filters[type] << compile!(type, pattern, options, &block) end
after(pattern = /.*/, **options, &block)
click to toggle source
# File lib/mobb/base.rb, line 214 def after(pattern = /.*/, **options, &block) add_filter(:after, pattern, options, &block) end
before(pattern = /.*/, **options, &block)
click to toggle source
# File lib/mobb/base.rb, line 210 def before(pattern = /.*/, **options, &block) add_filter(:before, pattern, options, &block) end
clear(*options)
click to toggle source
# File lib/mobb/base.rb, line 388 def clear(*options) options.each { |option| set(option, nil) }; end
compile(pattern, options)
click to toggle source
# File lib/mobb/base.rb, line 268 def compile(pattern, options) Matcher.new(pattern, options); end
compile!(type, pattern, options, &block)
click to toggle source
# File lib/mobb/base.rb, line 241 def compile!(type, pattern, options, &block) at = options.delete(:at) defaults = DEFAULT_CONDITIONS[type] options = defaults ? defaults.merge(options) : options options.each_pair { |option, args| send(option, *args) } matcher = case type when :message compile(pattern, options) when :ticker compile_cron(pattern, at) when :trigger compile(pattern, options) else compile(pattern, options) end unbound_method = generate_method("#{type}", &block) source_conditions, @source_conditions = @source_conditions, [] dest_conditions, @dest_conditions = @dest_conditions, [] wrapper = block.arity != 0 ? proc { |instance, args| unbound_method.bind(instance).call(*args) } : proc { |instance, args| unbound_method.bind(instance).call } [ matcher, wrapper, source_conditions, dest_conditions ] end
compile_cron(time, at)
click to toggle source
# File lib/mobb/base.rb, line 270 def compile_cron(time, at) if String === time Matcher.new(CronParser.new(time)) else Matcher.new(CronParser.new(Whenever::Output::Cron.new(time, nil, at).time_in_cron_syntax)) end end
condition(name = "
click to toggle source
# File lib/mobb/base.rb, line 339 def condition(name = "#{caller.first[/`.*'/]} condition", &block) @source_conditions << generate_method(name, &block) end
Also aliased as: source_condition
cron(pattern, options = {}, &block)
click to toggle source
# File lib/mobb/base.rb, line 225 def cron(pattern, options = {}, &block) event(:ticker, pattern, options, &block); end
Also aliased as: every
dest_condition(name = "
click to toggle source
# File lib/mobb/base.rb, line 344 def dest_condition(name = "#{caller.first[/`.*'/]} condition", &block) @dest_conditions << generate_method(name) do |res| if String === res res = [res, {}] end block.call(res) res end end
dest_to(channel)
click to toggle source
# File lib/mobb/base.rb, line 380 def dest_to(channel) dest_condition do |res| res.last[:dest_channel] = channel end end
development?()
click to toggle source
# File lib/mobb/base.rb, line 299 def development?; environment == :development; end
disable(*options)
click to toggle source
# File lib/mobb/base.rb, line 387 def disable(*options) options.each { |option| set(option, false) }; end
enable(*options)
click to toggle source
# File lib/mobb/base.rb, line 386 def enable(*options) options.each { |option| set(option, true) }; end
event(type, pattern, options, &block)
click to toggle source
# File lib/mobb/base.rb, line 230 def event(type, pattern, options, &block) signature = compile!(type, pattern, options, &block) (@events[type] ||= []) << signature invoke_hook(:event_added, type, pattern, block) signature end
extensions()
click to toggle source
# File lib/mobb/base.rb, line 198 def extensions if superclass.respond_to?(:extensions) (@extensions + superclass.extensions).uniq else @extensions end end
generate_method(name, &block)
click to toggle source
# File lib/mobb/base.rb, line 278 def generate_method(name, &block) define_method(name, &block) method = instance_method(name) remove_method(name) method end
helpers(*extensions, &block)
click to toggle source
# File lib/mobb/base.rb, line 285 def helpers(*extensions, &block) class_eval(&block) if block_given? include(*extensions) if extensions.any? end
include_myself(cond)
click to toggle source
# File lib/mobb/base.rb, line 361 def include_myself(cond) source_condition do return true if !@env.respond_to?(:user) || cond @env.user.name != settings.name end end
invoke_hook(name, *args)
click to toggle source
# File lib/mobb/base.rb, line 237 def invoke_hook(name, *args) extensions.each { |e| e.send(name, *args) if e.respond_to?(name) } end
production?()
click to toggle source
# File lib/mobb/base.rb, line 300 def production?; environment == :production; end
quit!()
click to toggle source
# File lib/mobb/base.rb, line 408 def quit! return unless running? running_service.respond_to?(:stop!) ? running_service.stop! : running_service.stop $stderr.puts "== Great sound Mobb, thank you so much" clear :running_service, :handler_name end
react_to_bot(cond)
click to toggle source
# File lib/mobb/base.rb, line 354 def react_to_bot(cond) source_condition do return true if !@env.respond_to?(:bot?) || cond !@env.bot? end end
receive(pattern, options = {}, &block)
click to toggle source
# File lib/mobb/base.rb, line 222 def receive(pattern, options = {}, &block) event(:message, pattern, options, &block); end
Also aliased as: on
register(*extensions, &block)
click to toggle source
# File lib/mobb/base.rb, line 290 def register(*extensions, &block) extensions << Module.new(&block) if block_given? @extensions += extensions extensions.each do |extension| extend extension extension.registered(self) if extension.respond_to?(:registered) end end
reply_to_me(cond)
click to toggle source
# File lib/mobb/base.rb, line 368 def reply_to_me(cond) condition do @env.reply_to.include?(settings.name) == cond end end
reset!()
click to toggle source
# File lib/mobb/base.rb, line 190 def reset! @events = {} @filters = { before: [], after: [] } @source_conditions = [] @dest_conditions = [] @extensions = [] end
run!(options = {}, &block)
click to toggle source
# File lib/mobb/base.rb, line 390 def run!(options = {}, &block) return if running? set options handler = detect_repp_handler handler_name = handler.name.gsub(/.*::/, '') service_settings = settings.respond_to?(:service_settings) ? settings.service_settings : {} begin start_service(handler, service_settings, handler_name, &block) rescue => e $stderr.puts e.message $stderr.puts e.backtrace ensure quit! end end
running?()
click to toggle source
# File lib/mobb/base.rb, line 415 def running? running_service? end
set(option, value = (not_set = true), ignore_setter = false, &block)
click to toggle source
# File lib/mobb/base.rb, line 303 def set(option, value = (not_set = true), ignore_setter = false, &block) raise ArgumentError if block && !not_set value, not_set = block, false if block if not_set raise ArgumentError unless option.respond_to?(:each) option.each { |k,v| set(k,v) } return self end setter_name = "#{option}=" if respond_to?(setter_name) && ! ignore_setter return __send__(setter_name, value) end setter = proc { |val| set(option, val, true) } getter = proc { value } case value when Proc getter = value when Symbol, Integer, FalseClass, TrueClass, NilClass getter = value.inspect when Hash setter = proc do |val| val = value.merge(val) if Hash === val set(option, val, true) end end define_singleton(setter_name, setter) define_singleton(option, getter) define_singleton("#{option}?", "!!#{option}") unless method_defined?("#{option}?") self end
settings()
click to toggle source
# File lib/mobb/base.rb, line 206 def settings self end
silent(cond)
click to toggle source
# File lib/mobb/base.rb, line 374 def silent(cond) dest_condition do |res| res[0] = nil if cond end end
test?()
click to toggle source
# File lib/mobb/base.rb, line 301 def test?; environment == :test; end
trigger(name, options = {}, &block)
click to toggle source
# File lib/mobb/base.rb, line 228 def trigger(name, options = {}, &block) event(:trigger, name, options, &block); end
Private Class Methods
caller_files()
click to toggle source
# File lib/mobb/base.rb, line 466 def caller_files cleaned_caller(1).flatten end
cleaned_caller(keep = 3)
click to toggle source
# File lib/mobb/base.rb, line 470 def cleaned_caller(keep = 3) caller(1). map! { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }. reject { |file, *_| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } } end
define_singleton(name, content = Proc.new)
click to toggle source
# File lib/mobb/base.rb, line 459 def define_singleton(name, content = Proc.new) singleton_class.class_eval do undef_method(name) if method_defined?(name) String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content) end end
detect_repp_handler()
click to toggle source
# File lib/mobb/base.rb, line 448 def detect_repp_handler services = Array(service) services.each do |service_name| begin return Repp::Handler.get(service_name.to_s) rescue LoadError, NameError end end fail "Service handler (#{services.join(',')}) not found" end
inherited(subclass)
click to toggle source
Calls superclass method
# File lib/mobb/base.rb, line 476 def inherited(subclass) subclass.reset! subclass.set :app_file, caller_files.first unless subclass.app_file? super end
setup_traps()
click to toggle source
# File lib/mobb/base.rb, line 433 def setup_traps if traps? at_exit { quit! } [:INT, :TERM].each do |signal| old_handler = Signal.trap(signal) do quit! old_handler.respond_to?(:call) ? old_handler.call : exit end end disable :traps end end
start_service(handler, service_settings, handler_name) { |service| ... }
click to toggle source
# File lib/mobb/base.rb, line 421 def start_service(handler, service_settings, handler_name) handler.run(self, service_settings) do |service| $stderr.puts "== Mobb (v#{Mobb::VERSION}) is in da house with #{handler_name}. Make some noise!" setup_traps set running_service: service set handler_name: handler_name yield service if block_given? end end
Public Instance Methods
call(env)
click to toggle source
# File lib/mobb/base.rb, line 62 def call(env) dup.call!(env) end
call!(env)
click to toggle source
# File lib/mobb/base.rb, line 66 def call!(env) @env = env @body = nil @repp_options = {} @attachments = {} @matched = nil @silent = false invoke { dispatch! } @body = nil if @silent [@body, @repp_options, @attachments] end
chain(*args)
click to toggle source
# File lib/mobb/base.rb, line 155 def chain(*args) payload = args.last.instance_of?(Hash) ? args.pop : nil @repp_options[:trigger] = { names: args, payload: payload } end
dispatch!()
click to toggle source
# File lib/mobb/base.rb, line 79 def dispatch! # TODO: encode input messages invoke do filter! :before handle_event end ensure begin filter! :after rescue ::Exception => boom # TODO: invoke { handle_exception!(boom) } end end
event_eval() { || ... }
click to toggle source
# File lib/mobb/base.rb, line 153 def event_eval; throw :halt, yield; end
filter!(type, base = settings)
click to toggle source
# File lib/mobb/base.rb, line 109 def filter!(type, base = settings) filter! type, base.superclass if base.superclass.respond_to?(:filters) base.filters[type].each { |signature| # TODO: Refactor compile! and process_event to change conditions in a hash (e,g, { source_cond: [], dest_cond: [] }) pattern = signature.first source_conditions = signature[2] wrapper = signature[1] process_event(pattern, source_conditions, wrapper) } end
handle_event(base = settings, passed_block = nil)
click to toggle source
# File lib/mobb/base.rb, line 120 def handle_event(base = settings, passed_block = nil) if responds = base.events[@env.event_type] responds.each do |pattern, block, source_conditions, dest_conditions| process_event(pattern, source_conditions) do |*args| event_eval do res = block[*args] dest_conditions.inject(res) { |acc, c| c.bind(self).call(acc) } end end end end # TODO: Define respond missing if receive reply message nil end
invoke() { || ... }
click to toggle source
# File lib/mobb/base.rb, line 94 def invoke res = catch(:halt) { yield } return if res.nil? res = [res] if String === res if Array === res && String === res.first tmp = res.dup @body = tmp.shift @attachments = tmp.pop else @attachments = res end nil end
pass(&block)
click to toggle source
# File lib/mobb/base.rb, line 162 def pass(&block) throw :pass, block end
process_event(pattern, conditions, block = nil, values = []) { |self, captures| ... }
click to toggle source
# File lib/mobb/base.rb, line 136 def process_event(pattern, conditions, block = nil, values = []) res = pattern.match?(@env.body) catch(:pass) do conditions.each { |c| throw :pass unless c.bind(self).call } case res when ::Mobb::Matcher::Matched @matched = res.matched block ? block[self, res.captures] : yield(self, res.captures) when TrueClass block ? block[self] : yield(self) else nil end end end
say_nothing()
click to toggle source
# File lib/mobb/base.rb, line 160 def say_nothing; @silent = true; end
settings()
click to toggle source
# File lib/mobb/base.rb, line 166 def settings self.class.settings end