messed 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +8 -0
- data/README.rdoc +22 -0
- data/Rakefile +76 -0
- data/VERSION +1 -0
- data/application_spec/Rakefile +12 -0
- data/application_spec/app/runner.rb +3 -0
- data/application_spec/bin/runner +18 -0
- data/application_spec/bin/status +36 -0
- data/application_spec/bin/web +29 -0
- data/application_spec/config/environment.rb +8 -0
- data/application_spec/config/environments/development.rb +0 -0
- data/application_spec/log/development.log +6 -0
- data/application_spec/spec/application_spec.rb +12 -0
- data/application_spec/spec/spec.opts +7 -0
- data/application_spec/spec/spec_helper.rb +42 -0
- data/bin/messed +9 -0
- data/lib/messed/booter.rb +114 -0
- data/lib/messed/configuration.rb +94 -0
- data/lib/messed/controller/helper.rb +8 -0
- data/lib/messed/controller/processing.rb +22 -0
- data/lib/messed/controller/respond.rb +48 -0
- data/lib/messed/controller.rb +17 -0
- data/lib/messed/em_runner.rb +50 -0
- data/lib/messed/interface/adapter/sms.rb +4 -0
- data/lib/messed/interface/adapter/twitter_consumer.rb +35 -0
- data/lib/messed/interface/adapter/twitter_search.rb +111 -0
- data/lib/messed/interface/adapter/twitter_sender.rb +44 -0
- data/lib/messed/interface/adapter/twitter_streaming.rb +50 -0
- data/lib/messed/interface/adapter.rb +68 -0
- data/lib/messed/interface/runner.rb +20 -0
- data/lib/messed/interface.rb +74 -0
- data/lib/messed/logger.rb +50 -0
- data/lib/messed/matcher.rb +50 -0
- data/lib/messed/message/twitter.rb +23 -0
- data/lib/messed/message.rb +35 -0
- data/lib/messed/queue/beanstalk.rb +56 -0
- data/lib/messed/queue.rb +17 -0
- data/lib/messed/session/memcache.rb +40 -0
- data/lib/messed/session.rb +7 -0
- data/lib/messed/tasks/console.rb +70 -0
- data/lib/messed/tasks/generation.rb +12 -0
- data/lib/messed/tasks/runner.rb +50 -0
- data/lib/messed/tasks/status.rb +37 -0
- data/lib/messed/tasks.rb +9 -0
- data/lib/messed/util/remote_status.rb +45 -0
- data/lib/messed.rb +235 -0
- data/patterns/messed/Pattern +24 -0
- data/patterns/messed/Rakefile +12 -0
- data/patterns/messed/app/runner.rb +5 -0
- data/patterns/messed/bin/console +3 -0
- data/patterns/messed/bin/runner +3 -0
- data/patterns/messed/bin/status +3 -0
- data/patterns/messed/bin/web +13 -0
- data/patterns/messed/config/environment.rb +15 -0
- data/patterns/messed/config/environments/development.rb +2 -0
- data/patterns/messed/config/environments/production.rb +0 -0
- data/patterns/messed/config/environments/test.rb +0 -0
- data/patterns/messed/spec/application_spec.rb +12 -0
- data/patterns/messed/spec/spec.opts +7 -0
- data/patterns/messed/spec/spec_helper.rb +44 -0
- data/spec/adapter/applications/twitter_search/app/application.rb +3 -0
- data/spec/adapter/applications/twitter_search/app/runner.rb +7 -0
- data/spec/adapter/applications/twitter_search/bin/incoming +89 -0
- data/spec/adapter/applications/twitter_search/bin/runner +21 -0
- data/spec/adapter/applications/twitter_search/bin/status +36 -0
- data/spec/adapter/applications/twitter_search/config/environment.rb +11 -0
- data/spec/adapter/applications/twitter_search/config/environments/development.rb +0 -0
- data/spec/adapter/applications/twitter_search/log/development.log +1006 -0
- data/spec/adapter/applications/twitter_sender/app/application.rb +0 -0
- data/spec/adapter/applications/twitter_sender/app/runner.rb +0 -0
- data/spec/adapter/applications/twitter_sender/bin/incoming +89 -0
- data/spec/adapter/applications/twitter_sender/bin/runner +21 -0
- data/spec/adapter/applications/twitter_sender/bin/status +36 -0
- data/spec/adapter/applications/twitter_sender/config/environment.rb +11 -0
- data/spec/adapter/applications/twitter_sender/config/environments/development.rb +0 -0
- data/spec/adapter/applications/twitter_sender/log/development.log +146 -0
- data/spec/adapter/http/direct_message +0 -0
- data/spec/adapter/http/twitter_search +20 -0
- data/spec/adapter/http/update +0 -0
- data/spec/adapter/twitter_search_spec.rb +36 -0
- data/spec/adapter/twitter_sender_spec.rb +64 -0
- data/spec/booter_spec.rb +7 -0
- data/spec/fixtures/booter/app/application.rb +3 -0
- data/spec/fixtures/booter/app/runner.rb +7 -0
- data/spec/fixtures/booter/bin/incoming +89 -0
- data/spec/fixtures/booter/bin/runner +21 -0
- data/spec/fixtures/booter/bin/status +36 -0
- data/spec/fixtures/booter/config/environment.rb +15 -0
- data/spec/fixtures/booter/config/environments/development.rb +0 -0
- data/spec/fixtures/booter/log/development.log +11 -0
- data/spec/message_spec.rb +52 -0
- data/spec/session_spec.rb +34 -0
- data/spec/spec.opts +7 -0
- data/spec/spec_helper.rb +8 -0
- data/test/app/runner.rb +5 -0
- data/test/config/environment.rb +15 -0
- data/test/config/environments/development.rb +2 -0
- data/test/config/environments/production.rb +0 -0
- data/test/config/environments/test.rb +0 -0
- data/test/spec/application_spec.rb +12 -0
- data/test/spec/spec_helper.rb +44 -0
- metadata +291 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
class Messed
|
2
|
+
module Tasks
|
3
|
+
class Console
|
4
|
+
|
5
|
+
module KeyboardHandler
|
6
|
+
include EM::Protocols::LineText2
|
7
|
+
|
8
|
+
attr_accessor :root, :environment
|
9
|
+
|
10
|
+
def log_outgoing(responses)
|
11
|
+
if responses.empty?
|
12
|
+
puts "No responses"
|
13
|
+
else
|
14
|
+
puts "Responding ... #{responses.map{|r| "`#{r.body}'"}.join(', ')}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def prompt
|
19
|
+
$stdout << ">> "
|
20
|
+
$stdout.flush
|
21
|
+
end
|
22
|
+
|
23
|
+
def post_init
|
24
|
+
print_banner
|
25
|
+
prompt
|
26
|
+
end
|
27
|
+
|
28
|
+
def print_banner
|
29
|
+
puts "? help"
|
30
|
+
puts "!q quit"
|
31
|
+
puts "Eventhing else is a message"
|
32
|
+
end
|
33
|
+
|
34
|
+
def receive_line(data)
|
35
|
+
case data.strip
|
36
|
+
when '!q'
|
37
|
+
EM.stop_event_loop
|
38
|
+
exit
|
39
|
+
when '?'
|
40
|
+
print_banner
|
41
|
+
else
|
42
|
+
pid = EM.fork_reactor do
|
43
|
+
Booter.new(root, :environment => environment, :supress_banner => true) do |booter|
|
44
|
+
Messed::Logger.instance.setup_logger(::Logger.new(STDOUT), :debug)
|
45
|
+
log_outgoing(booter.application.process(booter.application.message_class.new(data.strip)))
|
46
|
+
EM.stop_event_loop
|
47
|
+
end
|
48
|
+
end
|
49
|
+
Process.wait(pid)
|
50
|
+
end
|
51
|
+
prompt
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.start
|
56
|
+
new.start
|
57
|
+
end
|
58
|
+
|
59
|
+
def start
|
60
|
+
EM.run do
|
61
|
+
EM.open_keyboard(KeyboardHandler) do |handler|
|
62
|
+
handler.root = $root
|
63
|
+
handler.environment = ARGV[0]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class Messed
|
2
|
+
module Tasks
|
3
|
+
class Runner < Thor
|
4
|
+
|
5
|
+
method_options %w( environment -e ) => "development"
|
6
|
+
method_options %w( detach -d ) => false
|
7
|
+
desc "interface [NAME] [CMD]", "starts an interface (start|stop)"
|
8
|
+
def interface(name, cmd)
|
9
|
+
case cmd
|
10
|
+
when 'start'
|
11
|
+
Messed::Booter.new($root, :detach => options.detach?, :environment => options.environment) do |booter|
|
12
|
+
interface = booter.interface_for(name.to_sym)
|
13
|
+
raise("unable to find an interface with name the `#{name}'") unless interface
|
14
|
+
interface.start
|
15
|
+
end
|
16
|
+
when 'stop'
|
17
|
+
Messed::Booter.new($root, :environment => options.environment).interface_for(name.to_sym).stop
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
method_options %w( environment -e ) => "development"
|
22
|
+
method_options %w( detach -d ) => false
|
23
|
+
desc "application [CMD]", "start the application (start|stop)"
|
24
|
+
def application(cmd)
|
25
|
+
case cmd
|
26
|
+
when 'start'
|
27
|
+
Messed::Booter.new($root, :detach => options.detach?, :environment => options.environment) do |booter|
|
28
|
+
application = booter.application
|
29
|
+
application.start
|
30
|
+
end
|
31
|
+
when 'stop'
|
32
|
+
Messed::Booter.new($root, :environment => options.environment).application.stop
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
method_options %w( environment -e ) => "development"
|
37
|
+
method_options %w( detach -d ) => false
|
38
|
+
desc "start all interfaces and application [NAME]", "starts all"
|
39
|
+
def all
|
40
|
+
Messed::Booter.new($root, :detach => options.detach?, :environment => options.environment) do |booter|
|
41
|
+
booter.configuration.interfaces.names.each do |name|
|
42
|
+
booter.interface_for(name.to_sym).start
|
43
|
+
end
|
44
|
+
booter.application.start
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Messed
|
2
|
+
module Tasks
|
3
|
+
class Status < Thor
|
4
|
+
|
5
|
+
desc "Status", "status"
|
6
|
+
method_options :environment => "development"
|
7
|
+
def status
|
8
|
+
booter = Messed::Booter.new($root, options.environment)
|
9
|
+
|
10
|
+
puts "=Queues"
|
11
|
+
puts "==Incoming"
|
12
|
+
booter.application.incoming.status.each {|k,v|
|
13
|
+
puts " %40s - %s" % [k, v]
|
14
|
+
}
|
15
|
+
|
16
|
+
puts "==Outgoing"
|
17
|
+
booter.application.outgoing.status.each {|k,v|
|
18
|
+
puts " %40s - %s" % [k, v]
|
19
|
+
}
|
20
|
+
|
21
|
+
puts "=Interfaces"
|
22
|
+
booter.interface_map.each {|name, interface|
|
23
|
+
puts "==#{interface.name}"
|
24
|
+
Messed::Util::RemoteStatus.new(interface.configuration.options['host'], interface.configuration.options['port']).status.each {|k,v|
|
25
|
+
puts " %40s - %s" % [k, v]
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
puts "=Application"
|
30
|
+
Messed::Util::RemoteStatus.new(booter.application.configuration['host'], booter.application.configuration['port']).status.each {|k,v|
|
31
|
+
puts " %40s - %s" % [k, v]
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/messed/tasks.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
class Messed
|
2
|
+
module Tasks
|
3
|
+
autoload :Generation, File.join('messed', 'tasks', 'generation')
|
4
|
+
autoload :Runner, File.join('messed', 'tasks', 'runner')
|
5
|
+
autoload :Status, File.join('messed', 'tasks', 'status')
|
6
|
+
autoload :Web, File.join('messed', 'tasks', 'web')
|
7
|
+
autoload :Console, File.join('messed', 'tasks', 'console')
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class Messed
|
2
|
+
module Util
|
3
|
+
class RemoteStatus
|
4
|
+
|
5
|
+
attr_reader :status
|
6
|
+
|
7
|
+
class StatusHandler < EM::Connection
|
8
|
+
|
9
|
+
attr_accessor :status
|
10
|
+
|
11
|
+
def post_init
|
12
|
+
puts "post..."
|
13
|
+
send_data "status\r\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
def receive_data(data)
|
17
|
+
JSON.parse(data).each do |key, value|
|
18
|
+
self.status[key] = status
|
19
|
+
end
|
20
|
+
EM.stop_event_loop
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(host, port)
|
25
|
+
host ||= '127.0.0.1'
|
26
|
+
@status = {}
|
27
|
+
EM.run do
|
28
|
+
EM.add_timer(5) {
|
29
|
+
@status['error'] = "timeout on connect"
|
30
|
+
EM.stop_event_loop
|
31
|
+
}
|
32
|
+
begin
|
33
|
+
EM.connect(host, port, StatusHandler) do |handler|
|
34
|
+
handler.status = @status
|
35
|
+
end
|
36
|
+
rescue
|
37
|
+
@status['error'] = "can't connect"
|
38
|
+
EM.stop_event_loop
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/messed.rb
ADDED
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'hashify'
|
2
|
+
require 'logger'
|
3
|
+
require 'time'
|
4
|
+
require 'eventmachine'
|
5
|
+
require 'em-http'
|
6
|
+
require 'em-beanstalk'
|
7
|
+
require 'hwia'
|
8
|
+
require 'active_support'
|
9
|
+
require 'dressmaker'
|
10
|
+
|
11
|
+
$LOAD_PATH << File.dirname(__FILE__)
|
12
|
+
|
13
|
+
class Messed
|
14
|
+
|
15
|
+
autoload :Booter, File.join('messed', 'booter')
|
16
|
+
autoload :Configuration, File.join('messed', 'configuration')
|
17
|
+
autoload :Controller, File.join('messed', 'controller')
|
18
|
+
autoload :EMRunner, File.join('messed', 'em_runner')
|
19
|
+
autoload :Interface, File.join('messed', 'interface')
|
20
|
+
autoload :Logger, File.join('messed', 'logger')
|
21
|
+
autoload :Matcher, File.join('messed', 'matcher')
|
22
|
+
autoload :Message, File.join('messed', 'message')
|
23
|
+
autoload :Queue, File.join('messed', 'queue')
|
24
|
+
autoload :Session, File.join('messed', 'session')
|
25
|
+
autoload :Tasks, File.join('messed', 'tasks')
|
26
|
+
autoload :Utils, File.join('messed', 'utils')
|
27
|
+
|
28
|
+
module Util
|
29
|
+
autoload :RemoteStatus, File.join('messed', 'util', 'remote_status')
|
30
|
+
end
|
31
|
+
|
32
|
+
include Logger::LoggingModule
|
33
|
+
include Controller::Helper
|
34
|
+
include Controller::Processing
|
35
|
+
include Controller::Respond
|
36
|
+
|
37
|
+
after_processing :reset!
|
38
|
+
|
39
|
+
attr_accessor :controller, :booter, :current_matcher
|
40
|
+
attr_reader :outgoing, :incoming, :matchers, :session_store, :type, :interface, :name,
|
41
|
+
:messages_received_count, :messages_sent_count, :last_message_received, :last_message_sent
|
42
|
+
|
43
|
+
def initialize(type = :twitter, &block)
|
44
|
+
@type = type
|
45
|
+
@matchers = []
|
46
|
+
@session_store = Session::Memcache.new
|
47
|
+
@messages_sent_count = 0
|
48
|
+
@messages_received_count = 0
|
49
|
+
|
50
|
+
@interface = self
|
51
|
+
@name = 'Application'
|
52
|
+
match(&block) if block
|
53
|
+
end
|
54
|
+
|
55
|
+
def match(&block)
|
56
|
+
instance_eval(&block)
|
57
|
+
end
|
58
|
+
|
59
|
+
def reset!
|
60
|
+
matchers.clear
|
61
|
+
end
|
62
|
+
|
63
|
+
def message_class
|
64
|
+
Message.class_for_type(type)
|
65
|
+
end
|
66
|
+
|
67
|
+
def incoming=(incoming)
|
68
|
+
@incoming = incoming
|
69
|
+
incoming.application = self
|
70
|
+
end
|
71
|
+
|
72
|
+
def outgoing=(outgoing)
|
73
|
+
@outgoing = outgoing
|
74
|
+
outgoing.application = self
|
75
|
+
end
|
76
|
+
|
77
|
+
def with(*args, &block)
|
78
|
+
matchers << if args.first.is_a?(Hash)
|
79
|
+
Matcher::Conditional.new(nil, args.first)
|
80
|
+
else
|
81
|
+
Matcher::Conditional.new(*args, &block)
|
82
|
+
end
|
83
|
+
matchers.last.destination = block
|
84
|
+
end
|
85
|
+
|
86
|
+
def otherwise(options = nil, &block)
|
87
|
+
matchers << Matcher::Always.new(&block)
|
88
|
+
matchers.last.destination = block
|
89
|
+
end
|
90
|
+
alias_method :always, :otherwise
|
91
|
+
|
92
|
+
def status_port
|
93
|
+
booter.configuration.application.status_port || 19191
|
94
|
+
end
|
95
|
+
|
96
|
+
def status_host
|
97
|
+
booter.configuration.application.status_address || '0.0.0.0'
|
98
|
+
end
|
99
|
+
|
100
|
+
def start(continue_forever = true)
|
101
|
+
if EM.reactor_running?
|
102
|
+
if booter
|
103
|
+
EM.start_server(status_host, status_port, EMRunner::StatusHandler) do |c|
|
104
|
+
c.interface = self
|
105
|
+
end
|
106
|
+
logger.info "Status handler for #{self.class} started on #{status_host}:#{status_port}"
|
107
|
+
booter.write_pid_file(booter.configuration.application.pid_file)
|
108
|
+
end
|
109
|
+
|
110
|
+
@connection = EM::Beanstalk.new
|
111
|
+
@connection.watch(incoming.tube) do
|
112
|
+
@connection.use(outgoing.tube) do
|
113
|
+
process_incoming(continue_forever)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
else
|
117
|
+
EM.run {
|
118
|
+
start(continue_forever)
|
119
|
+
}
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def stop
|
124
|
+
Process.kill("INT", booter.read_pid_file(booter.configuration.application.pid_file))
|
125
|
+
end
|
126
|
+
|
127
|
+
def process_incoming(continue_forever)
|
128
|
+
@connection.reserve(continue_forever ? nil : 0.5) { |job|
|
129
|
+
begin
|
130
|
+
message = message_class.from_json(job.body)
|
131
|
+
process_responses process(message)
|
132
|
+
job.delete do
|
133
|
+
process_incoming(continue_forever)
|
134
|
+
end
|
135
|
+
rescue JSON::ParserError
|
136
|
+
# unrecoverable
|
137
|
+
logger.error "message #{job.body.inspect} not in JSON format"
|
138
|
+
job.delete do
|
139
|
+
process_incoming(continue_forever)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
}.on_error { |message|
|
143
|
+
EM.stop_event_loop
|
144
|
+
}
|
145
|
+
end
|
146
|
+
|
147
|
+
def process(message)
|
148
|
+
logger.debug("Processing `#{message.body}'")
|
149
|
+
increment_messages_received!
|
150
|
+
responses = []
|
151
|
+
|
152
|
+
self.message = message
|
153
|
+
|
154
|
+
session_store.with(message.unique_id) do |session|
|
155
|
+
self.session = session
|
156
|
+
|
157
|
+
matchers.find do |matcher|
|
158
|
+
if matcher.match?(message)
|
159
|
+
self.current_matcher = matcher
|
160
|
+
controller = process_destination(matcher.destination)
|
161
|
+
responses.concat(controller.responses)
|
162
|
+
matcher.stop_processing?
|
163
|
+
else
|
164
|
+
false
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
controller.reset_processing! if controller.respond_to?(:reset_processing!)
|
169
|
+
reset_processing!
|
170
|
+
end
|
171
|
+
responses
|
172
|
+
end
|
173
|
+
|
174
|
+
def extract_destination(options, block)
|
175
|
+
block ||
|
176
|
+
{:controller => options.delete(:controller) || raise("you must supply a controller"), :action => options.delete(:action) || raise("you must supply an action")} ||
|
177
|
+
raise("you need to either supply options or a block")
|
178
|
+
end
|
179
|
+
protected :extract_destination
|
180
|
+
|
181
|
+
def reset!
|
182
|
+
self.controller = nil
|
183
|
+
self.message = nil
|
184
|
+
self.params = nil
|
185
|
+
self.session = nil
|
186
|
+
end
|
187
|
+
protected :reset!
|
188
|
+
|
189
|
+
def process_destination(destination)
|
190
|
+
if destination.respond_to?(:call)
|
191
|
+
instance_eval(&destination)
|
192
|
+
self
|
193
|
+
else
|
194
|
+
class_name = destination[:controller].to_s.split('_').map{|w| w.capitalize}.join
|
195
|
+
self.controller = Kernel.const_get(class_name.to_sym).new
|
196
|
+
self.controller.params = params if controller.respond_to?(:params=)
|
197
|
+
self.controller.message = message if controller.respond_to?(:message=)
|
198
|
+
self.controller.method(destination[:action].to_sym).call
|
199
|
+
self.controller
|
200
|
+
end
|
201
|
+
end
|
202
|
+
protected :process_destination
|
203
|
+
|
204
|
+
def process_responses(responses)
|
205
|
+
if responses && !responses.empty?
|
206
|
+
logger.debug("Putting response #{responses.first.body} onto outgoing queue")
|
207
|
+
@connection.put(responses.shift.to_json) do
|
208
|
+
increment_messages_sent!
|
209
|
+
process_responses(responses)
|
210
|
+
end
|
211
|
+
else
|
212
|
+
logger.debug("No response.")
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def status
|
217
|
+
{
|
218
|
+
:messages_received_count => messages_received_count,
|
219
|
+
:messages_sent_count => messages_sent_count,
|
220
|
+
:last_message_received => last_message_received,
|
221
|
+
:last_message_sent => last_message_sent
|
222
|
+
}
|
223
|
+
end
|
224
|
+
|
225
|
+
def increment_messages_sent!
|
226
|
+
@messages_sent_count += 1
|
227
|
+
@last_message_sent = Time.new
|
228
|
+
end
|
229
|
+
|
230
|
+
def increment_messages_received!
|
231
|
+
@messages_received_count += 1
|
232
|
+
@last_message_received = Time.new
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
desc "make executable"
|
2
|
+
directory.matches('/bin') do |dir|
|
3
|
+
dir.for('*') { |f|
|
4
|
+
f.append! <<-HERE_DOC
|
5
|
+
#!/usr/bin/env ruby
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
if ENV['MESSED_HOME']
|
9
|
+
require File.join(ENV['MESSED_HOME'], 'lib', 'messed')
|
10
|
+
else
|
11
|
+
require 'messed'
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'thor'
|
15
|
+
HERE_DOC
|
16
|
+
|
17
|
+
f.make_executable!
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "set application name to #{options[:app_name]}"
|
22
|
+
files.all do |f|
|
23
|
+
f.gsub!('__APP_NAME__', options[:app_name].inspect)
|
24
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require 'spec/rake/spectask'
|
3
|
+
task :spec => 'spec:all'
|
4
|
+
namespace(:spec) do
|
5
|
+
Spec::Rake::SpecTask.new(:all) do |t|
|
6
|
+
t.spec_opts ||= []
|
7
|
+
t.spec_opts << "-rubygems"
|
8
|
+
t.spec_opts << "--options" << "spec/spec.opts"
|
9
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
queues.incoming.host = '127.0.0.1'
|
2
|
+
queues.incoming.port = 11300
|
3
|
+
queues.incoming.tube = 'incoming-tube'
|
4
|
+
|
5
|
+
queues.outgoing.host = '127.0.0.1'
|
6
|
+
queues.outgoing.port = 11300
|
7
|
+
queues.outgoing.tube = 'outgoing-tube'
|
8
|
+
|
9
|
+
# interfaces.search.adapter = :twitter_search
|
10
|
+
# interfaces.search.options[:fetch] = {:query => {'q' => 'love'}, :host => 'search.twitter.com', :path => 'search.json'}
|
11
|
+
# interfaces.search.options[:interval] = 30
|
12
|
+
|
13
|
+
# interfaces.twitter_sender.adapter = :twitter_sender
|
14
|
+
# interfaces.twitter_sender.options[:username] = 'username'
|
15
|
+
# interfaces.twitter_sender.options[:password] = 'password'
|
File without changes
|
File without changes
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
begin
|
3
|
+
require 'messed'
|
4
|
+
rescue LoadError
|
5
|
+
if ENV['MESSED_HOME']
|
6
|
+
require File.join(ENV['MESSED_HOME'], 'lib', 'messed')
|
7
|
+
else
|
8
|
+
raise("no messed!")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class MessedSpecHolder
|
13
|
+
|
14
|
+
attr_accessor :booter, :outgoing_messages
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@booter = Messed::Booter.new(File.join(File.dirname(__FILE__), '..'))
|
18
|
+
end
|
19
|
+
|
20
|
+
def application
|
21
|
+
@booter.application
|
22
|
+
end
|
23
|
+
|
24
|
+
def process(message)
|
25
|
+
@outgoing_messages = application.process(application.message_class.new(message))
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
module MessedSpecHelper
|
33
|
+
|
34
|
+
Holder = MessedSpecHolder.new
|
35
|
+
|
36
|
+
def process(message)
|
37
|
+
Holder.process(message)
|
38
|
+
end
|
39
|
+
|
40
|
+
def outgoing_messages
|
41
|
+
Holder.outgoing_messages
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|