Class: Mobb::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/mobb/base.rb

Direct Known Subclasses

Application

Constant Summary collapse

CALLERS_TO_IGNORE =
[
  /\/mobb(\/(base|main|show_exceptions))?\.rb$/,   # all sinatra code
  /^\(.*\)$/,                                         # generated code
  /rubygems\/(custom|core_ext\/kernel)_require\.rb$/, # rubygems require hacks
  /active_support/,                                   # active_support require hacks
  /bundler(\/runtime)?\.rb/,                          # bundler require hacks
  /<internal:/,                                       # internal in ruby >= 1.9.2
  /src\/kernel\/bootstrap\/[A-Z]/                     # maglev kernel files
]

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Attribute Details

.eventsObject (readonly)

Returns the value of attribute events.



139
140
141
# File 'lib/mobb/base.rb', line 139

def events
  @events
end

Class Method Details

.clear(*options) ⇒ Object



244
# File 'lib/mobb/base.rb', line 244

def clear(*options) options.each { |option| set(option, nil) }; end

.compile(pattern, options) ⇒ Object



172
# File 'lib/mobb/base.rb', line 172

def compile(pattern, options) Matcher.new(pattern, options); end

.compile!(type, pattern, options, &block) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/mobb/base.rb', line 159

def compile!(type, pattern, options, &block)
  options.each_pair { |option, args| send(option, *args) }

  matcher = compile(pattern, options)
  unbound_method = generate_method("#{type}", &block)
  conditions, @conditions = @conditions, []
  wrapper = block.arity != 0 ?
    proc { |instance, args| unbound_method.bind(instance).call(*args) } :
    proc { |instance, args| unbound_method.bind(instance).call }

  [ matcher, wrapper, conditions ]
end

.condition(name = "#{caller.first[/`.*'/]} condition", &block) ⇒ Object



226
227
228
# File 'lib/mobb/base.rb', line 226

def condition(name = "#{caller.first[/`.*'/]} condition", &block)
  @conditions << generate_method(name, &block)
end

.development?Boolean

Returns:

  • (Boolean)


186
# File 'lib/mobb/base.rb', line 186

def development?; environment == :development; end

.disable(*options) ⇒ Object



243
# File 'lib/mobb/base.rb', line 243

def disable(*options) options.each { |option| set(option, false) }; end

.enable(*options) ⇒ Object



242
# File 'lib/mobb/base.rb', line 242

def enable(*options) options.each { |option| set(option, true) }; end

.event(type, pattern, options, &block) ⇒ Object

def every(pattern, options = {}, &block) event(:cron, pattern, options, &block); end



155
156
157
# File 'lib/mobb/base.rb', line 155

def event(type, pattern, options, &block)
  (@events[type] ||= []) << compile!(type, pattern, options, &block)
end

.generate_method(name, &block) ⇒ Object



174
175
176
177
178
179
# File 'lib/mobb/base.rb', line 174

def generate_method(name, &block)
  define_method(name, &block)
  method = instance_method(name)
  remove_method(name)
  method
end

.helpers(*extensions, &block) ⇒ Object



181
182
183
184
# File 'lib/mobb/base.rb', line 181

def helpers(*extensions, &block)
  class_eval(&block)   if block_given?
  include(*extensions) if extensions.any?
end

.ignore_bot(cond) ⇒ Object



230
231
232
233
234
# File 'lib/mobb/base.rb', line 230

def ignore_bot(cond)
  condition do
    @env.bot? != cond
  end
end

.production?Boolean

Returns:

  • (Boolean)


187
# File 'lib/mobb/base.rb', line 187

def production?; environment == :production; end

.quit!Object



264
265
266
267
268
269
# File 'lib/mobb/base.rb', line 264

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

.receive(pattern, options = {}, &block) ⇒ Object Also known as: on



150
# File 'lib/mobb/base.rb', line 150

def receive(pattern, options = {}, &block) event(:message, pattern, options, &block); end

.reply_to_me(cond) ⇒ Object



236
237
238
239
240
# File 'lib/mobb/base.rb', line 236

def reply_to_me(cond)
  condition do
    @env.reply_to.include?(settings.name) == cond
  end
end

.reset!Object



141
142
143
144
# File 'lib/mobb/base.rb', line 141

def reset!
  @events = {}
  @conditions = []
end

.run!(options = {}, &block) ⇒ Object



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/mobb/base.rb', line 246

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?Boolean

Returns:

  • (Boolean)


271
272
273
# File 'lib/mobb/base.rb', line 271

def running?
  running_service?
end

.set(option, value = (not_set = true), ignore_setter = false, &block) ⇒ Object

Raises:

  • (ArgumentError)


190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/mobb/base.rb', line 190

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

.settingsObject



146
147
148
# File 'lib/mobb/base.rb', line 146

def settings
  self
end

.test?Boolean

Returns:

  • (Boolean)


188
# File 'lib/mobb/base.rb', line 188

def test?; environment == :test; end

Instance Method Details

#call(env) ⇒ Object



49
50
51
# File 'lib/mobb/base.rb', line 49

def call(env)
  dup.call!(env)
end

#call!(env) ⇒ Object



57
58
59
60
61
# File 'lib/mobb/base.rb', line 57

def call!(env)
  @env = env
  invoke { dispatch! }
  [@body, @attachments]
end

#dispatch!Object



67
68
69
70
71
72
73
74
75
76
# File 'lib/mobb/base.rb', line 67

def dispatch!
  # TODO: encode input messages

  invoke do
    # TODO: before filters
    handle_event
  end
ensure
  # TODO: after fillters
end

#event_evalObject



122
# File 'lib/mobb/base.rb', line 122

def event_eval; throw :halt, yield; end

#handle_event(base = settings, passed_block = nil) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/mobb/base.rb', line 93

def handle_event(base = settings, passed_block = nil)
  if responds = base.events[@env.event_type]
    responds.each do |pattern, block, conditions|
      process_event(pattern, conditions) do |*args|
        event_eval { block[*args] }
      end
    end
  end

  # TODO: Define respond missing if receive reply message
  nil
end

#invokeObject



78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/mobb/base.rb', line 78

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

#process_event(pattern, conditions, block = nil, values = []) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/mobb/base.rb', line 106

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
      yield(self, *(res.matched))
    when TrueClass
      yield self
    else
      nil
    end
  end
end

#settingsObject



124
125
126
# File 'lib/mobb/base.rb', line 124

def settings
  self.class.settings
end

#tick(env) ⇒ Object



53
54
55
# File 'lib/mobb/base.rb', line 53

def tick(env)
  dup.tick!(env)
end

#tick!(env) ⇒ Object



63
64
65
# File 'lib/mobb/base.rb', line 63

def tick!(env)
  fail # TODO: write logic here
end