flamethrower 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/README.rdoc +5 -3
- data/VERSION +1 -1
- data/bin/flamethrower +6 -0
- data/flamethrower.gemspec +7 -2
- data/lib/flamethrower/campfire/message.rb +4 -1
- data/lib/flamethrower/campfire/room.rb +25 -1
- data/lib/flamethrower/irc/channel.rb +1 -1
- data/lib/flamethrower/server/event_server.rb +41 -2
- data/spec/fixtures/paste_message_with_pound.json +1 -0
- data/spec/fixtures/timestamp_message.json +1 -0
- data/spec/fixtures/upload_message.json +1 -0
- data/spec/fixtures/upload_url_sample +1 -0
- data/spec/fixtures/user.json +1 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/campfire/message_spec.rb +10 -0
- data/spec/unit/campfire/room_spec.rb +52 -36
- data/spec/unit/irc/channel_spec.rb +5 -0
- metadata +9 -4
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -16,15 +16,17 @@ in the MOTD message. /join anyone of these and start chatting.
|
|
16
16
|
|
17
17
|
You can also create a YAML file with domain and token specified like so:
|
18
18
|
|
19
|
-
domain: mydomain
|
20
|
-
token: aoeu1234
|
19
|
+
domain: mydomain
|
20
|
+
token: aoeu1234
|
21
21
|
|
22
22
|
Then start flamethrower like so:
|
23
23
|
|
24
|
-
flamethrower -c ~/myconfig.yml
|
24
|
+
flamethrower -c ~/myconfig.yml
|
25
25
|
|
26
26
|
=== A work in progress
|
27
27
|
|
28
|
+
TODO: Switch Net::HTTP sync calls to async EM::HttpRequest calls.
|
29
|
+
|
28
30
|
Flamethrower is a work in progress. Right now basic messaging works, but
|
29
31
|
it still needs a lot of love. If you find it useful and would like to see
|
30
32
|
it do something, please submit a patch (with tests please)!. Bug reports are
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/bin/flamethrower
CHANGED
@@ -56,4 +56,10 @@ end
|
|
56
56
|
FLAMETHROWER_LOGGER = Logger.new(options['logger'] || STDOUT)
|
57
57
|
|
58
58
|
server = Flamethrower::EventServer.new(options['host'], options['port'], options['domain'], options['token'])
|
59
|
+
|
60
|
+
trap("INT") do
|
61
|
+
FLAMETHROWER_LOGGER.info("Received shutdown signal, killing connections")
|
62
|
+
server.stop
|
63
|
+
end
|
64
|
+
|
59
65
|
server.start
|
data/flamethrower.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{flamethrower}
|
8
|
-
s.version = "0.0
|
8
|
+
s.version = "0.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Blake Smith"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2011-01-12}
|
13
13
|
s.default_executable = %q{flamethrower}
|
14
14
|
s.description = %q{Flamethrower gives you the power to use your awesome irc client to talk in your campfire rooms.}
|
15
15
|
s.email = %q{blakesmith0@gmail.com}
|
@@ -48,11 +48,16 @@ Gem::Specification.new do |s|
|
|
48
48
|
"spec/fixtures/leave_message.json",
|
49
49
|
"spec/fixtures/message.json",
|
50
50
|
"spec/fixtures/paste_message.json",
|
51
|
+
"spec/fixtures/paste_message_with_pound.json",
|
51
52
|
"spec/fixtures/room.json",
|
52
53
|
"spec/fixtures/room_update.json",
|
53
54
|
"spec/fixtures/rooms.json",
|
54
55
|
"spec/fixtures/speak_message.json",
|
55
56
|
"spec/fixtures/streaming_message.json",
|
57
|
+
"spec/fixtures/timestamp_message.json",
|
58
|
+
"spec/fixtures/upload_message.json",
|
59
|
+
"spec/fixtures/upload_url_sample",
|
60
|
+
"spec/fixtures/user.json",
|
56
61
|
"spec/spec_helper.rb",
|
57
62
|
"spec/unit/campfire/connection_spec.rb",
|
58
63
|
"spec/unit/campfire/message_spec.rb",
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Flamethrower
|
2
2
|
module Campfire
|
3
3
|
class Message
|
4
|
-
attr_accessor :body, :user, :room, :message_type, :status, :retry_at
|
4
|
+
attr_accessor :body, :user, :room, :message_type, :status, :retry_at, :user_id
|
5
5
|
|
6
6
|
RETRY_SECONDS = 15
|
7
7
|
|
@@ -9,6 +9,7 @@ module Flamethrower
|
|
9
9
|
@body = params['body']
|
10
10
|
@user = params['user']
|
11
11
|
@room = params['room']
|
12
|
+
@user_id = params['user_id']
|
12
13
|
@message_type = params['type']
|
13
14
|
@status = "pending"
|
14
15
|
end
|
@@ -34,6 +35,8 @@ module Flamethrower
|
|
34
35
|
irc_string = ":#{@user.to_irc.to_s} PART #{@room.to_irc.name}"
|
35
36
|
when "PasteMessage"
|
36
37
|
irc_string = ":#{@user.to_irc.to_s} PRIVMSG #{@room.to_irc.name} :#{@body}"
|
38
|
+
else
|
39
|
+
return
|
37
40
|
end
|
38
41
|
Flamethrower::Irc::Message.new(irc_string)
|
39
42
|
end
|
@@ -13,6 +13,7 @@ module Flamethrower
|
|
13
13
|
@token = token
|
14
14
|
@inbound_messages = Queue.new
|
15
15
|
@outbound_messages = Queue.new
|
16
|
+
@users_to_fetch = Queue.new
|
16
17
|
@failed_messages = []
|
17
18
|
@number = params['id']
|
18
19
|
@name = params['name']
|
@@ -52,6 +53,7 @@ module Flamethrower
|
|
52
53
|
fetch_messages
|
53
54
|
post_messages
|
54
55
|
requeue_failed_messages
|
56
|
+
fetch_users
|
55
57
|
messages_to_send = to_irc.retrieve_irc_messages
|
56
58
|
messages_to_send.each do |m|
|
57
59
|
::FLAMETHROWER_LOGGER.debug "Sending irc message #{m.to_s}"
|
@@ -91,7 +93,29 @@ module Flamethrower
|
|
91
93
|
::FLAMETHROWER_LOGGER.debug "Got json message #{params.inspect}"
|
92
94
|
params['user'] = @users.find {|u| u.number == params['user_id'] }
|
93
95
|
params['room'] = self
|
94
|
-
|
96
|
+
message = Flamethrower::Campfire::Message.new(params)
|
97
|
+
unless message.message_type == "TimestampMessage"
|
98
|
+
unless message.user
|
99
|
+
@users_to_fetch << message
|
100
|
+
else
|
101
|
+
@inbound_messages << message
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def fetch_users
|
108
|
+
until @users_to_fetch.empty?
|
109
|
+
message = @users_to_fetch.pop
|
110
|
+
response = campfire_get("/users/#{message.user_id}.json")
|
111
|
+
case response
|
112
|
+
when Net::HTTPOK
|
113
|
+
json = JSON.parse(response.body)
|
114
|
+
user = Flamethrower::Campfire::User.new(json['user'])
|
115
|
+
message.user = user
|
116
|
+
@users << user
|
117
|
+
@inbound_messages << message
|
118
|
+
end
|
95
119
|
end
|
96
120
|
end
|
97
121
|
|
@@ -3,26 +3,65 @@ module Flamethrower
|
|
3
3
|
include Flamethrower::Server
|
4
4
|
|
5
5
|
attr_accessor :server
|
6
|
+
|
7
|
+
def unbind
|
8
|
+
@server.connections.delete(self)
|
9
|
+
end
|
6
10
|
end
|
7
11
|
|
8
12
|
class EventServer
|
9
|
-
attr_reader :host, :port, :campfire_connection
|
13
|
+
attr_reader :host, :port, :campfire_connection, :connections
|
10
14
|
|
11
15
|
def initialize(host, port, domain, token)
|
12
16
|
@host = host || "0.0.0.0"
|
13
17
|
@port = port || 6667
|
14
18
|
@domain = domain
|
15
19
|
@token = token
|
20
|
+
@connections = []
|
16
21
|
end
|
17
22
|
|
18
23
|
def start
|
19
24
|
EventMachine::run do
|
20
25
|
FLAMETHROWER_LOGGER.info "Flamethrower started at #{@host}:#{@port} on domain #{@domain}"
|
21
|
-
EventMachine::start_server(@host, @port, EventConnection) do |connection|
|
26
|
+
@signature = EventMachine::start_server(@host, @port, EventConnection) do |connection|
|
27
|
+
@connections << connection
|
22
28
|
connection.server = self
|
23
29
|
connection.campfire_connection = Flamethrower::Campfire::Connection.new(@domain, @token, connection)
|
24
30
|
end
|
25
31
|
end
|
26
32
|
end
|
33
|
+
|
34
|
+
def stop
|
35
|
+
FLAMETHROWER_LOGGER.info("Killing room threads")
|
36
|
+
@connections.each do |connection|
|
37
|
+
connection.irc_channels.map do |channel|
|
38
|
+
channel.to_campfire.kill_thread!
|
39
|
+
end
|
40
|
+
end
|
41
|
+
EventMachine.stop_server(@signature)
|
42
|
+
die_safely
|
43
|
+
end
|
44
|
+
|
45
|
+
def die_safely
|
46
|
+
FLAMETHROWER_LOGGER.info("Waiting for streams and connections to die")
|
47
|
+
if streams_alive? && connections_alive?
|
48
|
+
EventMachine.add_periodic_timer(1) { die_safely }
|
49
|
+
else
|
50
|
+
FLAMETHROWER_LOGGER.info("Done.")
|
51
|
+
EventMachine.stop
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def streams_alive?
|
56
|
+
@connections.any? do |connection|
|
57
|
+
connection.irc_channels.any? do |channel|
|
58
|
+
channel.to_campfire.alive?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def connections_alive?
|
64
|
+
@connections.size <= 0
|
65
|
+
end
|
27
66
|
end
|
28
67
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"room_id":73541,"created_at":"2011/01/12 16:45:37 +0000","body":"#secure_asset_host: secure-assets-uat.example.com\nsecure_asset_host: assets1-uat.example.com","id":298515252,"user_id":627807,"type":"PasteMessage"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"room_id":73541,"created_at":"2010/12/14 20:09:23 +0000","body":null,"id":289361911,"user_id":489198,"type":"TimestampMessage"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"room_id":73541,"created_at":"2011/01/12 15:24:25 +0000","body":"Steak.jpeg","id":298466819,"user_id":786985,"type":"UploadMessage"}
|
@@ -0,0 +1 @@
|
|
1
|
+
The upload_message.json fixture generated this URL: https://thepoint.campfirenow.com/room/73541/uploads/1711244/Steak.jpeg
|
@@ -0,0 +1 @@
|
|
1
|
+
{"user":{"type":"Member","created_at":"2010/11/10 03:47:24 +0000","admin":true,"email_address":"bsmith@groupon.com","id":734581,"name":"blake"}}
|
data/spec/spec_helper.rb
CHANGED
@@ -27,6 +27,16 @@ describe Flamethrower::Campfire::Message do
|
|
27
27
|
@message.to_irc.to_s.should == ":#{@irc_user.to_s} PRIVMSG #{@channel.name} :thebody"
|
28
28
|
end
|
29
29
|
|
30
|
+
it "returns if the message type is unhandled" do
|
31
|
+
json = JSON.parse(json_fixture('enter_message'))
|
32
|
+
json['type'] = "BogusMessage"
|
33
|
+
message = Flamethrower::Campfire::Message.new(json)
|
34
|
+
message.user = @campfire_user
|
35
|
+
message.room = @room
|
36
|
+
Flamethrower::Irc::Message.should_not_receive(:new)
|
37
|
+
message.to_irc.should be_nil
|
38
|
+
end
|
39
|
+
|
30
40
|
it "converts a EnterMessage to a join irc message" do
|
31
41
|
json = JSON.parse(json_fixture('enter_message'))
|
32
42
|
message = Flamethrower::Campfire::Message.new(json)
|
@@ -57,7 +57,40 @@ describe Flamethrower::Campfire::Room do
|
|
57
57
|
@room.fetch_room_info
|
58
58
|
FakeWeb.last_request['authorization'].should == "Basic #{Base64::encode64("#{@room.token}:x").chomp}"
|
59
59
|
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#fetch_users" do
|
63
|
+
it "makes a call to the campfire api to fetch user information" do
|
64
|
+
FakeWeb.register_uri(:get, "https://mytoken:x@mydomain.campfirenow.com/users/734581.json", :body => json_fixture("user"), :status => ["200", "OK"])
|
65
|
+
@room.instance_variable_get("@users_to_fetch") << Flamethrower::Campfire::Message.new(JSON.parse(json_fixture("enter_message")))
|
66
|
+
@room.fetch_users
|
67
|
+
@room.users.map(&:name).should == ["blake"]
|
68
|
+
end
|
69
|
+
|
70
|
+
it "fetches using the 'user_id' field if a streaming message" do
|
71
|
+
FakeWeb.register_uri(:get, "https://mytoken:x@mydomain.campfirenow.com/users/734581.json", :body => json_fixture("user"), :status => ["200", "OK"])
|
72
|
+
@room.instance_variable_get("@users_to_fetch") << Flamethrower::Campfire::Message.new(JSON.parse(json_fixture("enter_message")))
|
73
|
+
@room.should_receive(:campfire_get).with("/users/734581.json")
|
74
|
+
@room.fetch_users
|
75
|
+
end
|
76
|
+
|
77
|
+
context "successfully get user info" do
|
78
|
+
it "enqueues an EnterMessage into @inbound_messages for displaying in irc" do
|
79
|
+
FakeWeb.register_uri(:get, "https://mytoken:x@mydomain.campfirenow.com/users/734581.json", :body => json_fixture("user"), :status => ["200", "OK"])
|
80
|
+
@room.instance_variable_get("@users_to_fetch") << Flamethrower::Campfire::Message.new(JSON.parse(json_fixture("enter_message")))
|
81
|
+
@room.fetch_users
|
82
|
+
message = @room.inbound_messages.pop.user.number.should == 734581
|
83
|
+
end
|
84
|
+
end
|
60
85
|
|
86
|
+
context "fails to get user info" do
|
87
|
+
it "doesn't enqueue an EnterMessage" do
|
88
|
+
FakeWeb.register_uri(:get, "https://mytoken:x@mydomain.campfirenow.com/users/734581.json", :status => ["400", "Bad Request"])
|
89
|
+
@room.instance_variable_get("@users_to_fetch") << Flamethrower::Campfire::Message.new(JSON.parse(json_fixture("enter_message")))
|
90
|
+
@room.fetch_users
|
91
|
+
message = @room.inbound_messages.size.should == 0
|
92
|
+
end
|
93
|
+
end
|
61
94
|
end
|
62
95
|
|
63
96
|
describe "#join" do
|
@@ -79,45 +112,13 @@ describe Flamethrower::Campfire::Room do
|
|
79
112
|
end
|
80
113
|
end
|
81
114
|
|
82
|
-
describe "#thread" do
|
83
|
-
before do
|
84
|
-
Kernel.stub(:sleep)
|
85
|
-
end
|
86
|
-
|
87
|
-
context "in a Thread" do
|
88
|
-
it "calls connect at the start of the thread" do
|
89
|
-
@room.stub(:fetch_messages)
|
90
|
-
@room.stub(:post_messages)
|
91
|
-
@room.should_receive(:connect).at_least(1).times
|
92
|
-
@room.start_thread
|
93
|
-
@room.kill_thread!
|
94
|
-
end
|
95
|
-
|
96
|
-
it "fetches messages from the stream" do
|
97
|
-
@room.stub(:connect)
|
98
|
-
@room.stub(:post_messages)
|
99
|
-
@room.should_receive(:fetch_messages).at_least(1).times
|
100
|
-
@room.start_thread
|
101
|
-
@room.kill_thread!
|
102
|
-
end
|
103
|
-
|
104
|
-
it "posts messages to the campfire API" do
|
105
|
-
@room.stub(:connect)
|
106
|
-
@room.stub(:fetch_messages)
|
107
|
-
@room.should_receive(:post_messages).at_least(1).times
|
108
|
-
@room.start_thread
|
109
|
-
@room.kill_thread!
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
115
|
describe "#fetch_messages" do
|
116
116
|
before do
|
117
117
|
Twitter::JSONStream.stub(:connect).and_return("stream")
|
118
|
-
item = json_fixture("streaming_message")
|
118
|
+
@item = json_fixture("streaming_message")
|
119
|
+
@room.users << @user
|
119
120
|
@room.connect
|
120
|
-
@room.stream.stub(:each_item).and_yield(item)
|
121
|
+
@room.stream.stub(:each_item).and_yield(@item)
|
121
122
|
end
|
122
123
|
|
123
124
|
it "iterates over each stream item and sends to the message queue" do
|
@@ -132,7 +133,6 @@ describe Flamethrower::Campfire::Room do
|
|
132
133
|
|
133
134
|
it "maps the message sender to the right user" do
|
134
135
|
@room.users << @user2
|
135
|
-
@room.users << @user
|
136
136
|
@room.fetch_messages
|
137
137
|
@room.inbound_messages.pop.user.should == @user
|
138
138
|
end
|
@@ -141,6 +141,22 @@ describe Flamethrower::Campfire::Room do
|
|
141
141
|
@room.fetch_messages
|
142
142
|
@room.inbound_messages.pop.room.should == @room
|
143
143
|
end
|
144
|
+
|
145
|
+
it "discards timestamp messages altogether" do
|
146
|
+
item = json_fixture("timestamp_message")
|
147
|
+
@room.stream.stub(:each_item).and_yield(item)
|
148
|
+
@room.fetch_messages
|
149
|
+
@room.instance_variable_get("@inbound_messages").size.should == 0
|
150
|
+
@room.instance_variable_get("@users_to_fetch").size.should == 0
|
151
|
+
end
|
152
|
+
|
153
|
+
it "puts messages that don't have an existing user into the users_to_fetch queue" do
|
154
|
+
enter_message = JSON.parse(json_fixture("streaming_message"))
|
155
|
+
enter_message['user_id'] = 98765
|
156
|
+
@room.stream.stub(:each_item).and_yield(enter_message.to_json)
|
157
|
+
@room.fetch_messages
|
158
|
+
@room.instance_variable_get("@users_to_fetch").size.should == 1
|
159
|
+
end
|
144
160
|
end
|
145
161
|
|
146
162
|
describe "#say" do
|
@@ -46,6 +46,11 @@ describe Flamethrower::Irc::Channel do
|
|
46
46
|
@channel.retrieve_irc_messages.should be_empty
|
47
47
|
end
|
48
48
|
|
49
|
+
it "doesn't add messages that return nil from to_irc" do
|
50
|
+
@room.inbound_messages << nil
|
51
|
+
@channel.retrieve_irc_messages.should be_empty
|
52
|
+
end
|
53
|
+
|
49
54
|
xit "doesn't send the message if the source is the current user" do
|
50
55
|
message = Flamethrower::Campfire::Message.new('body' => 'Hello there', 'user' => @campfire_user, 'room' => @room, 'type' => 'TextMessage')
|
51
56
|
@room.inbound_messages << message
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flamethrower
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
- 0
|
9
8
|
- 1
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Blake Smith
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2011-01-12 00:00:00 -06:00
|
19
19
|
default_executable: flamethrower
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -101,11 +101,16 @@ files:
|
|
101
101
|
- spec/fixtures/leave_message.json
|
102
102
|
- spec/fixtures/message.json
|
103
103
|
- spec/fixtures/paste_message.json
|
104
|
+
- spec/fixtures/paste_message_with_pound.json
|
104
105
|
- spec/fixtures/room.json
|
105
106
|
- spec/fixtures/room_update.json
|
106
107
|
- spec/fixtures/rooms.json
|
107
108
|
- spec/fixtures/speak_message.json
|
108
109
|
- spec/fixtures/streaming_message.json
|
110
|
+
- spec/fixtures/timestamp_message.json
|
111
|
+
- spec/fixtures/upload_message.json
|
112
|
+
- spec/fixtures/upload_url_sample
|
113
|
+
- spec/fixtures/user.json
|
109
114
|
- spec/spec_helper.rb
|
110
115
|
- spec/unit/campfire/connection_spec.rb
|
111
116
|
- spec/unit/campfire/message_spec.rb
|