shove 0.52 → 1.0.1
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 +5 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +63 -0
- data/README.markdown +263 -0
- data/Rakefile +47 -0
- data/bin/shove +128 -106
- data/lib/shove/app.rb +78 -0
- data/lib/shove/app_directory.rb +104 -0
- data/lib/shove/client/callback.rb +24 -0
- data/lib/shove/client/channel.rb +81 -0
- data/lib/shove/client/connection.rb +167 -0
- data/lib/shove/http/channel_context.rb +60 -0
- data/lib/shove/http/client_context.rb +82 -0
- data/lib/shove/http/request.rb +94 -0
- data/lib/shove/http/response.rb +30 -0
- data/lib/shove/protocol.rb +53 -0
- data/lib/shove.rb +60 -78
- data/shove.gemspec +11 -20
- data/spec/app_directory_spec.rb +66 -0
- data/spec/cassettes/should_authorize_oneself.yml +24 -0
- data/spec/cassettes/should_be_able_to_authorize_with_the_server.yml +24 -0
- data/spec/cassettes/should_cancel_a_binding.yml +24 -0
- data/spec/cassettes/should_configure_the_default.yml +24 -0
- data/spec/cassettes/should_configure_the_from_the_previous_test.yml +24 -0
- data/spec/cassettes/should_create_a_channel_context.yml +24 -0
- data/spec/cassettes/should_deny_a_connection.yml +24 -0
- data/spec/cassettes/should_deny_a_control_to_a_client.yml +24 -0
- data/spec/cassettes/should_deny_a_publishing_to_a_client.yml +24 -0
- data/spec/cassettes/should_deny_a_subscriptions_to_a_client.yml +24 -0
- data/spec/cassettes/should_deny_publishing_on_a_channel_context.yml +24 -0
- data/spec/cassettes/should_deny_subscriptions_on_a_channel_context.yml +24 -0
- data/spec/cassettes/should_get_a_set_of_nodes_for_the_network.yml +24 -0
- data/spec/cassettes/should_get_a_subscribe_granted_event.yml +24 -0
- data/spec/cassettes/should_grant_a_connection.yml +24 -0
- data/spec/cassettes/should_grant_a_control_to_a_client.yml +24 -0
- data/spec/cassettes/should_grant_a_publishing_to_a_client.yml +24 -0
- data/spec/cassettes/should_grant_a_subscriptions_to_a_client.yml +24 -0
- data/spec/cassettes/should_grant_publishing_on_a_channel_context.yml +24 -0
- data/spec/cassettes/should_grant_subscriptions_on_a_channel_context.yml +24 -0
- data/spec/cassettes/should_publish.yml +24 -0
- data/spec/cassettes/should_publish_on_a_channel_context.yml +24 -0
- data/spec/cassettes/should_publish_to_a_client.yml +24 -0
- data/spec/cassettes/should_receive_an_unsubscribe_event.yml +24 -0
- data/spec/cassettes/should_receive_messages_on_a_channel.yml +24 -0
- data/spec/cassettes/should_send_a_connect_op.yml +24 -0
- data/spec/cassettes/should_send_a_connect_op_with_an_id.yml +24 -0
- data/spec/cassettes/should_spawn_a_client.yml +24 -0
- data/spec/cassettes/should_subscribe_to_a_channel.yml +24 -0
- data/spec/cassettes/should_trigger_a_connect_denied_event.yml +24 -0
- data/spec/cassettes/should_trigger_a_connect_event.yml +24 -0
- data/spec/cassettes/should_trigger_a_disconnect_event.yml +24 -0
- data/spec/cassettes/should_trigger_an_error_event.yml +24 -0
- data/spec/cassettes/should_unsubscribe_from_a_channel.yml +24 -0
- data/spec/cassettes/should_update_the_default_app.yml +24 -0
- data/spec/helper.rb +60 -0
- data/spec/shove_client_spec.rb +194 -0
- data/spec/shove_http_spec.rb +142 -0
- metadata +111 -81
- data/README.md +0 -71
- data/lib/shove/client.rb +0 -54
- data/lib/shove/request.rb +0 -80
- data/lib/shove/response.rb +0 -23
- data/spec/shove_spec.rb +0 -40
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# A sample Gemfile
|
2
|
+
source "http://rubygems.org"
|
3
|
+
|
4
|
+
group :development do
|
5
|
+
gem "rake"
|
6
|
+
gem "redcarpet"
|
7
|
+
gem "albino"
|
8
|
+
end
|
9
|
+
|
10
|
+
group :test do
|
11
|
+
gem "rspec"
|
12
|
+
gem "vcr", "2.0.0.rc1"
|
13
|
+
gem "webmock"
|
14
|
+
gem "net-http-spy"
|
15
|
+
end
|
16
|
+
|
17
|
+
gemspec
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
shove (1.0.1)
|
5
|
+
confstruct (>= 0.2.1)
|
6
|
+
em-http-request (>= 1.0.0)
|
7
|
+
em-ws-client (>= 0.1.1)
|
8
|
+
yajl-ruby (>= 1.1.0)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: http://rubygems.org/
|
12
|
+
specs:
|
13
|
+
addressable (2.2.6)
|
14
|
+
albino (1.3.3)
|
15
|
+
posix-spawn (>= 0.3.6)
|
16
|
+
confstruct (0.2.1)
|
17
|
+
cookiejar (0.3.0)
|
18
|
+
crack (0.3.1)
|
19
|
+
diff-lcs (1.1.3)
|
20
|
+
em-http-request (1.0.1)
|
21
|
+
addressable (>= 2.2.3)
|
22
|
+
cookiejar
|
23
|
+
em-socksify
|
24
|
+
eventmachine (>= 1.0.0.beta.4)
|
25
|
+
http_parser.rb (>= 0.5.3)
|
26
|
+
em-socksify (0.1.0)
|
27
|
+
eventmachine
|
28
|
+
em-ws-client (0.1.1)
|
29
|
+
eventmachine (~> 1.0.0.beta.3)
|
30
|
+
state_machine (~> 1.0.2)
|
31
|
+
eventmachine (1.0.0.beta.4)
|
32
|
+
http_parser.rb (0.5.3)
|
33
|
+
net-http-spy (0.2.1)
|
34
|
+
posix-spawn (0.3.6)
|
35
|
+
rake (0.9.2.2)
|
36
|
+
redcarpet (2.1.0)
|
37
|
+
rspec (2.8.0)
|
38
|
+
rspec-core (~> 2.8.0)
|
39
|
+
rspec-expectations (~> 2.8.0)
|
40
|
+
rspec-mocks (~> 2.8.0)
|
41
|
+
rspec-core (2.8.0)
|
42
|
+
rspec-expectations (2.8.0)
|
43
|
+
diff-lcs (~> 1.1.2)
|
44
|
+
rspec-mocks (2.8.0)
|
45
|
+
state_machine (1.0.3)
|
46
|
+
vcr (2.0.0.rc1)
|
47
|
+
webmock (1.7.10)
|
48
|
+
addressable (~> 2.2, > 2.2.5)
|
49
|
+
crack (>= 0.1.7)
|
50
|
+
yajl-ruby (1.1.0)
|
51
|
+
|
52
|
+
PLATFORMS
|
53
|
+
ruby
|
54
|
+
|
55
|
+
DEPENDENCIES
|
56
|
+
albino
|
57
|
+
net-http-spy
|
58
|
+
rake
|
59
|
+
redcarpet
|
60
|
+
rspec
|
61
|
+
shove!
|
62
|
+
vcr (= 2.0.0.rc1)
|
63
|
+
webmock
|
data/README.markdown
ADDED
@@ -0,0 +1,263 @@
|
|
1
|
+
shove ruby client
|
2
|
+
=================
|
3
|
+
Ruby client and CLI for the shove.io HTTP and WebSocket APIs
|
4
|
+
|
5
|
+
Installation
|
6
|
+
------------
|
7
|
+
|
8
|
+
```bash
|
9
|
+
gem install shove
|
10
|
+
```
|
11
|
+
|
12
|
+
Grab your App ID and App Key from shove at [https://shove.io/apps][0]
|
13
|
+
|
14
|
+
Configuring Shove
|
15
|
+
-----------------
|
16
|
+
|
17
|
+
If you are using a single shove app within your project, you can configure
|
18
|
+
shove though the Shove module:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
Shove.configure do
|
22
|
+
app_id "myappid"
|
23
|
+
app_key "myappkey"
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
If you want to work with different shove apps in one project, you can
|
28
|
+
create App objects
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
app = Shove::App.new do
|
32
|
+
app_id "myappid"
|
33
|
+
app_key "myappkey"
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
Using the HTTP Client
|
38
|
+
---------------------
|
39
|
+
The HTTP client gives publishing and access control capabilities without
|
40
|
+
a persistent WebSocket connection
|
41
|
+
|
42
|
+
Publish "Hello World!" to all connections on the notifications channel
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
Shove.channel("notifications").publish("Hello World!") do |response|
|
46
|
+
# handle response
|
47
|
+
end
|
48
|
+
```
|
49
|
+
|
50
|
+
Publish "Hey buddy" to the client with id buddy.
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
Shove.channel("direct:buddy").publish("Hey buddy") do |response|
|
54
|
+
# handle response
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
Apps, channels, and clients can be controlled from the HTTP API
|
59
|
+
|
60
|
+
Grant a connection to dan@shove.io
|
61
|
+
```ruby
|
62
|
+
Shove.grant_connect("dan@shove.io") do |response|
|
63
|
+
# handle response
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
Grant subscription on the notifications channel to client dan
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
Shove.channel("notifications").grant_subscribe("dan") do |response|
|
71
|
+
# handle response
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
Grant subscription on all channels to client dan
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
Shove.channel("*").grant_subscribe("dan@shove.io") do |response|
|
79
|
+
# handle response
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
Grant publishing on chat:client_22733 channel to client dan
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
Shove.channel("chat:client_22733").grant_publish("dan") do |response|
|
87
|
+
# handle response
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
Deny publishing on chat:client_22733 channel to dan
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
Shove.channel("chat:client_22733").deny_publish("dan") do |response|
|
95
|
+
# handle response
|
96
|
+
end
|
97
|
+
```
|
98
|
+
|
99
|
+
Using the WebSocket Client
|
100
|
+
--------------------------
|
101
|
+
|
102
|
+
Create a WebSocket client on the default app
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
client = Shove.app.connect
|
106
|
+
```
|
107
|
+
|
108
|
+
Or
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
app = Shove::App.new do
|
112
|
+
app_id "myappid"
|
113
|
+
end
|
114
|
+
client = app.connect
|
115
|
+
```
|
116
|
+
|
117
|
+
Create a client with a custom ID
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
client = Shove.app.connect("unique_id")
|
121
|
+
```
|
122
|
+
|
123
|
+
### Client events
|
124
|
+
|
125
|
+
Handle connect event
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
client.on("connect") do
|
129
|
+
# Connected!
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
Handle connect denies (private app)
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
client.on("connect_denied") do |id|
|
137
|
+
# Silly, but:
|
138
|
+
Shove.client(id).grant_connect do |response|
|
139
|
+
# At this point, the client should receive
|
140
|
+
# a connect event (through the shove app)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
```
|
144
|
+
|
145
|
+
And disconnect events
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
client.on("disconnect") do
|
149
|
+
end
|
150
|
+
```
|
151
|
+
|
152
|
+
If there is any kind of error, log it
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
client.on("error") do |error|
|
156
|
+
log.error "Shove error: #{error}"
|
157
|
+
end
|
158
|
+
```
|
159
|
+
|
160
|
+
### Clients and Channels
|
161
|
+
|
162
|
+
Subscribe to a channel or get a subscribed channel
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
channel = client.channel("channel")
|
166
|
+
```
|
167
|
+
|
168
|
+
Handle a message published on a channel
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
channel.on("message") do |msg|
|
172
|
+
widget.append msg
|
173
|
+
end
|
174
|
+
```
|
175
|
+
|
176
|
+
Handle the subscribe callback for a given channel
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
channel.on("subscribe") do
|
180
|
+
# channel is subscribed
|
181
|
+
end
|
182
|
+
```
|
183
|
+
|
184
|
+
If the app denies subscriptions by default, you should
|
185
|
+
handle the subscribe_denied event
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
channel.on("subscribe_denied") do
|
189
|
+
# Silly example
|
190
|
+
Shove.client(client.id).grant_subscribe(channel.name)
|
191
|
+
end
|
192
|
+
```
|
193
|
+
|
194
|
+
You can get the binding for a callback and cancel it
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
binding = channel.on("message") do |msg|
|
198
|
+
end
|
199
|
+
|
200
|
+
binding.cancel
|
201
|
+
```
|
202
|
+
|
203
|
+
Handle a direct message
|
204
|
+
|
205
|
+
```ruby
|
206
|
+
client.channel("direct").on("message") do |msg|
|
207
|
+
# handle direct message
|
208
|
+
end
|
209
|
+
```
|
210
|
+
|
211
|
+
Unsubscribe from a channel, optionally handle the event
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
channel.on("unsubscribe_complete") do
|
215
|
+
end
|
216
|
+
|
217
|
+
channel.unsubscribe
|
218
|
+
```
|
219
|
+
|
220
|
+
Publish a message from the WebSocket client
|
221
|
+
|
222
|
+
```ruby
|
223
|
+
channel.publish("hi!")
|
224
|
+
|
225
|
+
# publish json
|
226
|
+
channel.publish(obj.to_json)
|
227
|
+
```
|
228
|
+
|
229
|
+
Using the Command Line
|
230
|
+
----------------------
|
231
|
+
|
232
|
+
A CLI utility is included with the gem, run help to see options
|
233
|
+
|
234
|
+
```bash
|
235
|
+
shove help
|
236
|
+
```
|
237
|
+
|
238
|
+
Publish a message
|
239
|
+
|
240
|
+
```bash
|
241
|
+
shove publish -c channel1 -m "Hello world!"
|
242
|
+
```
|
243
|
+
|
244
|
+
Publish to a specific app
|
245
|
+
|
246
|
+
```bash
|
247
|
+
shove publish -a app_id -c chan1 -m "hi"
|
248
|
+
```
|
249
|
+
|
250
|
+
Set the default app for the CLI
|
251
|
+
|
252
|
+
```bash
|
253
|
+
shove apps:default -a app_id
|
254
|
+
```
|
255
|
+
|
256
|
+
Watch all activity on a channel
|
257
|
+
|
258
|
+
```bash
|
259
|
+
shove watch -c chan
|
260
|
+
```
|
261
|
+
|
262
|
+
[0]: https://shove.io/apps
|
263
|
+
[1]: http://shove.io/documentation/cli
|
data/Rakefile
CHANGED
@@ -4,3 +4,50 @@ RSpec::Core::RakeTask.new(:spec)
|
|
4
4
|
|
5
5
|
task :default => :spec
|
6
6
|
|
7
|
+
task :autospec => :spec do
|
8
|
+
require "eventmachine"
|
9
|
+
|
10
|
+
$time = Time.now
|
11
|
+
|
12
|
+
module Handler
|
13
|
+
def file_modified
|
14
|
+
if Time.now - $time > 1
|
15
|
+
$time = Time.now
|
16
|
+
Rake::Task["spec"].execute
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
EM.kqueue = true if EM.kqueue?
|
22
|
+
EM.run do
|
23
|
+
["spec","lib"].collect { |dir|
|
24
|
+
Dir.glob(File.dirname(__FILE__) + "/#{dir}/**/*.rb")
|
25
|
+
}.flatten.each do |file|
|
26
|
+
EM.watch_file file, Handler
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Generate the README HTML"
|
33
|
+
task :readme do
|
34
|
+
|
35
|
+
require "redcarpet"
|
36
|
+
require "albino"
|
37
|
+
|
38
|
+
# Create a custom renderer that uses albino to
|
39
|
+
# make pretty code
|
40
|
+
class Colorizer < Redcarpet::Render::HTML
|
41
|
+
def block_code(code, language)
|
42
|
+
Albino.colorize(code, language)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
content = Redcarpet::Markdown.new(Colorizer, :fenced_code_blocks => true)
|
47
|
+
.render(File.read("README.markdown"))
|
48
|
+
|
49
|
+
File.open("README.html", "w") do |f|
|
50
|
+
f << content
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/bin/shove
CHANGED
@@ -1,133 +1,155 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
$:.unshift File.dirname(__FILE__) + "/../lib"
|
4
|
+
|
5
|
+
require "optparse"
|
5
6
|
require "shove"
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
access[:network] = ask "Enter Network Id: "
|
21
|
-
access[:key] = ask "Enter Network Key: "
|
22
|
-
|
23
|
-
Shove.configure access
|
24
|
-
|
25
|
-
check = Shove.validate
|
26
|
-
if check.status >= 400
|
27
|
-
say "Unable to validate network settings. Error: #{check.message}"
|
28
|
-
else
|
29
|
-
break
|
30
|
-
end
|
31
|
-
|
8
|
+
action = ARGV[0]
|
9
|
+
channel = nil
|
10
|
+
client = nil
|
11
|
+
message = nil
|
12
|
+
app = nil
|
13
|
+
app_dir = Shove::AppDirectory.new
|
14
|
+
|
15
|
+
OptionParser.new do |o|
|
16
|
+
|
17
|
+
o.banner = "Usage: shove "
|
18
|
+
|
19
|
+
o.on("-h", "--help") do
|
20
|
+
action = "help"
|
32
21
|
end
|
33
22
|
|
34
|
-
|
35
|
-
|
23
|
+
o.on("-v", "--version") do
|
24
|
+
action = "version"
|
36
25
|
end
|
37
|
-
|
38
|
-
end
|
39
26
|
|
40
|
-
|
27
|
+
o.on("-l", "--list") do
|
28
|
+
action = "apps"
|
29
|
+
end
|
41
30
|
|
42
|
-
|
31
|
+
o.on("-a", "--app app", "the app to work with") do |arg|
|
32
|
+
app = arg
|
33
|
+
end
|
43
34
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
program :help, "Author", "Dan Simpson <dan@shove.io>"
|
48
|
-
program :formatter, :compact
|
35
|
+
o.on("-c", "--channel channel", "the channel to operate on") do |arg|
|
36
|
+
channel = arg
|
37
|
+
end
|
49
38
|
|
50
|
-
|
51
|
-
|
52
|
-
c.example "Streams the default channel", "shove stream default"
|
53
|
-
c.description = "Stream all data on a given channel to the console"
|
54
|
-
c.action do |args, opts|
|
55
|
-
if args.empty?
|
56
|
-
say_invalid c
|
57
|
-
else
|
58
|
-
EM.run do
|
59
|
-
Shove.stream(args.first) { |m|
|
60
|
-
puts m[:channel]
|
61
|
-
puts m[:event]
|
62
|
-
puts m[:to] # this will either be empty or self
|
63
|
-
puts m[:from] # message sender
|
64
|
-
puts m[:data] # the payload
|
65
|
-
puts "============"
|
66
|
-
}
|
67
|
-
end
|
68
|
-
end
|
39
|
+
o.on("-u", "--client client", "the client to operate on") do |arg|
|
40
|
+
client = arg
|
69
41
|
end
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
command :broadcast do |c|
|
74
|
-
c.syntax = "shove broadcast channel event data"
|
75
|
-
c.example "Broadcast x,y coordinates on the grid channel", "shove broadcast grid coords '1522,234'"
|
76
|
-
c.description = "Broadcast event and data to all subscribers of a given channel"
|
77
|
-
c.action do |args, opts|
|
78
|
-
if args.length != 3
|
79
|
-
say_invalid c
|
80
|
-
else
|
81
|
-
say "Broadcasting on channel #{args.first}"
|
82
|
-
Shove.broadcast(*args) do |response|
|
83
|
-
say response.message
|
84
|
-
end
|
85
|
-
end
|
42
|
+
|
43
|
+
o.on("-m", "--message message", "the message to publish") do |arg|
|
44
|
+
message = arg
|
86
45
|
end
|
46
|
+
|
47
|
+
o.parse!(ARGV)
|
87
48
|
end
|
88
49
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
50
|
+
begin
|
51
|
+
|
52
|
+
case action
|
53
|
+
when "version"
|
54
|
+
puts "shove version #{Shove::Version}"
|
55
|
+
when "apps"
|
56
|
+
|
57
|
+
apps = app_dir.apps
|
58
|
+
|
59
|
+
if apps.empty?
|
60
|
+
puts "No apps found. Run: shove apps:add"
|
96
61
|
else
|
97
|
-
|
98
|
-
|
99
|
-
|
62
|
+
puts "App Id\t\tApp Key"
|
63
|
+
puts "-----------------------"
|
64
|
+
apps.each_pair do |id,key|
|
65
|
+
puts "#{id}\t\t#{key}"
|
100
66
|
end
|
101
67
|
end
|
102
|
-
end
|
103
|
-
end
|
104
68
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
69
|
+
when "apps:add"
|
70
|
+
app_dir.get_config app
|
71
|
+
when "apps:default"
|
72
|
+
app_dir.default = app
|
73
|
+
when "hosts"
|
74
|
+
Shove.configure(app_dir.get_config(app))
|
75
|
+
|
76
|
+
Shove.hosts.each do |host|
|
77
|
+
puts host
|
78
|
+
end
|
79
|
+
|
80
|
+
when "publish"
|
81
|
+
|
82
|
+
Shove.configure(app_dir.get_config(app))
|
83
|
+
|
84
|
+
errors = []
|
85
|
+
errors << "channel not defined" unless channel
|
86
|
+
errors << "message not defined" unless message
|
87
|
+
|
88
|
+
if errors.empty?
|
89
|
+
Shove.channel(channel).publish(message) do |r|
|
90
|
+
if r.error?
|
91
|
+
puts "Error: #{r.message}"
|
92
|
+
else
|
93
|
+
puts "Published"
|
94
|
+
end
|
116
95
|
end
|
96
|
+
else
|
97
|
+
puts "Errors: #{errors.join(",")}"
|
117
98
|
end
|
118
|
-
end
|
119
|
-
end
|
120
99
|
|
100
|
+
when "watch"
|
121
101
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
102
|
+
Shove.configure(app_dir.get_config(app))
|
103
|
+
|
104
|
+
if channel
|
105
|
+
|
106
|
+
EM.run do
|
107
|
+
client = Shove.connect
|
108
|
+
client.authorize(app_dir.key(app))
|
109
|
+
|
110
|
+
client.on("error") do |error|
|
111
|
+
puts "Watch Error #{error}"
|
112
|
+
EM.stop
|
113
|
+
end
|
114
|
+
|
115
|
+
channel = client.channel(channel)
|
116
|
+
channel.on("message") do |msg|
|
117
|
+
puts "#{Time.now}: #{msg}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
else
|
122
|
+
puts "You must provide the channel with: -c channel_name"
|
130
123
|
end
|
124
|
+
|
125
|
+
else
|
126
|
+
puts File.read(__FILE__).split("__END__").last
|
131
127
|
end
|
128
|
+
|
129
|
+
|
130
|
+
rescue Exception => ex
|
131
|
+
|
132
|
+
puts ex.message
|
133
|
+
puts ex.backtrace
|
134
|
+
|
135
|
+
abort File.read(__FILE__).split("__END__").last
|
132
136
|
end
|
133
137
|
|
138
|
+
__END__
|
139
|
+
Usage: shove action [options]
|
140
|
+
|
141
|
+
|
142
|
+
Options
|
143
|
+
-h, --help
|
144
|
+
Show this message
|
145
|
+
|
146
|
+
Actions
|
147
|
+
publish publish a message to the app
|
148
|
+
example: shove publish -c chan -m "Hello"
|
149
|
+
|
150
|
+
hosts List available hosts for your app
|
151
|
+
watch Watch the messages on a given channel
|
152
|
+
|
153
|
+
apps List known apps
|
154
|
+
apps:default Use a particular app
|
155
|
+
apps:add Add a new app
|