shove 1.0.7 → 1.0.8

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.
Files changed (53) hide show
  1. data/Gemfile +1 -2
  2. data/README.markdown +57 -91
  3. data/Rakefile +0 -23
  4. data/lib/shove.rb +3 -70
  5. data/lib/shove/app.rb +40 -33
  6. data/lib/shove/client/channel.rb +4 -0
  7. data/lib/shove/client/connection.rb +32 -14
  8. data/lib/shove/http/request.rb +2 -2
  9. data/lib/shove/protocol.rb +3 -1
  10. data/shove.gemspec +1 -3
  11. data/spec/cassettes/should_be_able_to_authorize_with_the_server.yml +10 -6
  12. data/spec/cassettes/should_deny_a_connection.yml +10 -6
  13. data/spec/cassettes/should_deny_a_control_to_a_client.yml +10 -6
  14. data/spec/cassettes/should_deny_a_publishing_to_a_client.yml +10 -6
  15. data/spec/cassettes/should_deny_a_subscriptions_to_a_client.yml +10 -6
  16. data/spec/cassettes/should_deny_publishing_on_a_channel_context.yml +10 -6
  17. data/spec/cassettes/should_deny_subscriptions_on_a_channel_context.yml +10 -6
  18. data/spec/cassettes/should_get_a_set_of_nodes_for_the_network.yml +11 -7
  19. data/spec/cassettes/should_grant_a_connection.yml +10 -6
  20. data/spec/cassettes/should_grant_a_control_to_a_client.yml +11 -7
  21. data/spec/cassettes/should_grant_a_publishing_to_a_client.yml +10 -6
  22. data/spec/cassettes/should_grant_a_subscriptions_to_a_client.yml +10 -6
  23. data/spec/cassettes/should_grant_publishing_on_a_channel_context.yml +10 -6
  24. data/spec/cassettes/should_grant_subscriptions_on_a_channel_context.yml +10 -6
  25. data/spec/cassettes/should_publish_on_a_channel_context.yml +10 -6
  26. data/spec/cassettes/should_publish_to_a_client.yml +10 -6
  27. data/spec/helper.rb +0 -2
  28. data/spec/shove_client_spec.rb +39 -30
  29. data/spec/shove_http_spec.rb +27 -31
  30. metadata +20 -40
  31. data/bin/shove +0 -169
  32. data/lib/shove/app_directory.rb +0 -103
  33. data/spec/app_directory_spec.rb +0 -66
  34. data/spec/cassettes/should_authorize_on_a_channel.yml +0 -26
  35. data/spec/cassettes/should_authorize_oneself.yml +0 -24
  36. data/spec/cassettes/should_cancel_a_binding.yml +0 -24
  37. data/spec/cassettes/should_configure_the_default.yml +0 -24
  38. data/spec/cassettes/should_configure_the_from_the_previous_test.yml +0 -24
  39. data/spec/cassettes/should_create_a_channel_context.yml +0 -24
  40. data/spec/cassettes/should_get_a_subscribe_granted_event.yml +0 -24
  41. data/spec/cassettes/should_publish.yml +0 -24
  42. data/spec/cassettes/should_receive_an_unsubscribe_event.yml +0 -24
  43. data/spec/cassettes/should_receive_messages_on_a_channel.yml +0 -24
  44. data/spec/cassettes/should_send_a_connect_op.yml +0 -24
  45. data/spec/cassettes/should_send_a_connect_op_with_an_id.yml +0 -24
  46. data/spec/cassettes/should_spawn_a_client.yml +0 -24
  47. data/spec/cassettes/should_subscribe_to_a_channel.yml +0 -24
  48. data/spec/cassettes/should_trigger_a_connect_denied_event.yml +0 -24
  49. data/spec/cassettes/should_trigger_a_connect_event.yml +0 -24
  50. data/spec/cassettes/should_trigger_a_disconnect_event.yml +0 -24
  51. data/spec/cassettes/should_trigger_an_error_event.yml +0 -24
  52. data/spec/cassettes/should_unsubscribe_from_a_channel.yml +0 -24
  53. data/spec/cassettes/should_update_the_default_app.yml +0 -24
data/Gemfile CHANGED
@@ -16,5 +16,4 @@ end
16
16
 
17
17
  gem "em-http-request", ">= 1.0.0"
18
18
  gem "em-ws-client", ">= 0.2.0"
19
- gem "yajl-ruby", ">= 1.1.0"
20
- gem "confstruct", ">= 0.2.1"
19
+ gem "yajl-ruby", ">= 1.1.0"
@@ -1,6 +1,6 @@
1
- shove ruby client
2
- =================
3
- Ruby client and CLI for the shove.io HTTP and WebSocket APIs
1
+ shove
2
+ =====
3
+ HTTP and WebSocket clients for shove.io
4
4
 
5
5
  <a name="installation"></a>
6
6
  Installation
@@ -11,53 +11,42 @@ gem install shove
11
11
  ```
12
12
 
13
13
  <a name="configuration"></a>
14
- Configuring Shove
15
- -----------------
14
+ Using Shove
15
+ -----------
16
16
 
17
- If you are using a single shove app within your project, you can configure
18
- shove though the Shove module:
17
+ To use shove, you must first create a Shove::App object.
19
18
 
20
19
  ```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
20
+ app = Shove::App.new(
21
+ app_id: "myappid",
22
+ app_key: "myappkey"
23
+ )
35
24
  ```
36
25
 
37
- Grab your App ID and App Key from shove: [https://shove.io][0]
26
+ Get your app_id, and app_key at [shove.io][0]
38
27
 
39
28
  <a name="http_client"></a>
40
29
  Using the HTTP Client
41
30
  ---------------------
42
31
  The HTTP client gives publishing and access control capabilities without
43
- a persistent WebSocket connection. The HTTP client does not act as a subscriber.
32
+ a persistent WebSocket connection. The HTTP client cannot act as a subscriber.
44
33
 
45
- Simple Publish
34
+ Publish to a channel
46
35
 
47
36
  ```ruby
48
- Shove.channel("notifications").publish("Hello World!")
37
+ app.channel("notifications").publish("Hello World!")
49
38
  ```
50
39
 
51
40
  Publish Direct
52
41
 
53
42
  ```ruby
54
- Shove.channel("direct:buddy").publish("Hey buddy")
43
+ app.channel("direct:buddy").publish("Hey buddy")
55
44
  ```
56
45
 
57
46
  Publish and handle the HTTP response
58
47
 
59
48
  ```ruby
60
- Shove.channel("notifications").publish("...") do |response|
49
+ app.channel("notifications").publish("...") do |response|
61
50
  if reponse.error?
62
51
  puts "#{response.status} - #{response.error}"
63
52
  end
@@ -70,25 +59,25 @@ granular security.
70
59
  Grant subscription on the notifications channel
71
60
 
72
61
  ```ruby
73
- Shove.channel("notifications").grant_subscribe("dan@shove.io")
62
+ app.channel("notifications").grant_subscribe("dan@shove.io")
74
63
  ```
75
64
 
76
65
  Grant subscription on all channels to client dan
77
66
 
78
67
  ```ruby
79
- Shove.channel("*").grant_subscribe("dan@shove.io")
68
+ app.channel("*").grant_subscribe("dan@shove.io")
80
69
  ```
81
70
 
82
71
  Grant publishing on chat:client_22733 channel to client dan
83
72
 
84
73
  ```ruby
85
- Shove.channel("chat:client_22733").grant_publish("dan")
74
+ app.channel("chat:client_22733").grant_publish("dan")
86
75
  ```
87
76
 
88
77
  Deny publishing on chat:client_22733 channel to dan
89
78
 
90
79
  ```ruby
91
- Shove.channel("chat:client_22733").deny_publish("dan")
80
+ app.channel("chat:client_22733").deny_publish("dan")
92
81
  ```
93
82
 
94
83
  Sometimes it's easier to give out an access key to a specific
@@ -98,37 +87,37 @@ channel, which is also an option.
98
87
  Channel Keys
99
88
  ------------
100
89
  You can generate channel keys which allow clients of
101
- your shove network to publish and subscribe to specific
90
+ your shove network to subscribe or publish to specific
102
91
  channels.
103
92
 
104
93
  Example: Create a key for the channel groups:788
105
94
 
106
95
  ```ruby
107
- key = Shove.channel_key "group:788"
96
+ key = app.channel_key "group:788"
108
97
  ```
109
98
 
110
- If it's for a particular App, use:
99
+ Subscribe only
111
100
 
112
101
  ```ruby
113
- key = app.channel_key "group:788"
102
+ key = app.subscribe_key "group:788"
114
103
  ```
115
104
 
116
105
  This functionality becomes useful when you want to give
117
- you site users access. A little haml for you:
106
+ you site users access. In your view:
118
107
 
119
- ```haml
120
- :javascript
121
- var channel = "#{@channel}";
122
- var key = "#{@shove.channel_key(@channel)}";
108
+ ```erb
109
+ var channel = "<%= @channel %>";
110
+ var key = "<%= @app.channel_key(@channel) %>";
123
111
  ```
124
112
 
125
- Note: Channel keys are based off the app key. So, in order for
126
- them to work, you must specify the app key:
113
+ Note: Channel keys are based off the app key (master key). So, in order for
114
+ them to work, you must specify the app key in your app.
127
115
 
128
116
  ```ruby
129
- Shove.configure do
130
- app_key "key"
131
- end
117
+ app = Shove::App.new(
118
+ app_id: "myappid",
119
+ app_key: "myappkey"
120
+ )
132
121
  ```
133
122
 
134
123
  <a name="websocket_client"></a>
@@ -139,28 +128,15 @@ requires that you are running an EventMachine reactor.
139
128
 
140
129
  ```ruby
141
130
  EM.run do
142
- app = Shove::App.new do
143
- app_id "myapp"
144
- end
145
-
146
- app.connect
131
+ app = Shove::App.new(
132
+ app_id "myapp",
133
+ app_key: "myappkey"
134
+ )
147
135
 
148
- # alternatively, supply your user id
149
- client = app.connect "unique_id"
136
+ client = app.connect
150
137
  end
151
138
  ```
152
139
 
153
- ### Authorization
154
- The client is treated like any other websocket
155
- client and must be authorized to publish and subscribe.
156
-
157
- ```ruby
158
- client.authorize "app_key"
159
-
160
- # self authorize a particular channel
161
- client.channel("channel").authorize "channel_key"
162
- ```
163
-
164
140
  ### Client events
165
141
 
166
142
  Connect event:
@@ -195,7 +171,7 @@ client.on("connect_denied") do |id|
195
171
  end
196
172
  ```
197
173
 
198
- ### Publish and Subscribe
174
+ ### Channels & Publish and Subscribe
199
175
 
200
176
  Subscribe to a channel or get a subscribed channel
201
177
 
@@ -265,37 +241,27 @@ channel.publish("hi!")
265
241
  channel.publish(obj.to_json)
266
242
  ```
267
243
 
268
- Using the Command Line
269
- ----------------------
270
-
271
- A CLI utility is included with the gem, run help to see options
272
-
273
- ```bash
274
- shove help
275
- ```
276
-
277
- Publish a message
278
-
279
- ```bash
280
- shove publish -c channel1 -m "Hello world!"
281
- ```
282
-
283
- Publish to a specific app
284
-
285
- ```bash
286
- shove publish -a app_id -c chan1 -m "hi"
287
- ```
244
+ <a name="websocket_client"></a>
245
+ WebSocket Client without App Key
246
+ --------------------------------
247
+ If you are connecting to someone elses app
248
+ and have limited scope and access, you can get by.
288
249
 
289
- Set the default app for the CLI
250
+ ```ruby
251
+ EM.run do
252
+ app = Shove::App.new(
253
+ app_id "myapp"
254
+ )
290
255
 
291
- ```bash
292
- shove apps:default -a app_id
293
- ```
256
+ client = app.connect "connect-key"
294
257
 
295
- Watch all activity on a channel
258
+ channel = client.channel("channel")
259
+ channel.auth "channelkey"
296
260
 
297
- ```bash
298
- shove watch -c chan
261
+ channel.on("message") do |message|
262
+ puts message
263
+ end
264
+ end
299
265
  ```
300
266
 
301
267
  [0]: https://shove.io
data/Rakefile CHANGED
@@ -28,26 +28,3 @@ task :autospec => :spec do
28
28
  end
29
29
 
30
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
@@ -7,7 +7,6 @@ require "em-http-request"
7
7
  require "em-ws-client"
8
8
  require "yajl"
9
9
  require "yaml"
10
- require "confstruct"
11
10
  require "digest/sha1"
12
11
 
13
12
  ##
@@ -18,80 +17,14 @@ require "digest/sha1"
18
17
  # See https://github.com/shove/shove for js client documentation
19
18
  module Shove
20
19
 
21
- Version = "1.0.7"
22
-
23
- class ShoveException < Exception; end
24
-
25
- class << self
26
-
27
- attr_accessor :config, :app
28
-
29
- # configure shover
30
- # +settings+ the settings for the created client as
31
- # a string for a yaml file, or as a hash
32
- def configure params=nil, &block
33
-
34
- unless defined? @config
35
- @config = Confstruct::Configuration.new do
36
- api_url "https://api.shove.io"
37
- end
38
- end
39
-
40
- if params
41
- @config.configure params
42
- end
20
+ Version = "1.0.8"
43
21
 
44
- if block
45
- @config.configure(&block)
46
- end
47
-
48
- unless defined? @app
49
- @app = App.new(@config)
50
- else
51
-
52
- end
53
- end
54
-
55
- # fetch a channel by name
56
- # +name+ the name of the channel
57
- def channel name
58
- @app.channel(name)
59
- end
60
-
61
- # fetch a client by id
62
- def client id
63
- @app.client(id)
64
- end
65
-
66
- # validate network settings
67
- # used for the CLI
68
- def valid?
69
- @app.valid?
70
- end
71
-
72
- # fetch the available stream nodes
73
- # for this network.
74
- def hosts
75
- @app.hosts
76
- end
77
-
78
- # Connect to the default app with a
79
- # WebSocket connection
80
- def connect
81
- @app.connect
82
- end
83
-
84
- # Create a channel key
85
- # +channel+ the name of the channel
86
- def channel_key channel
87
- @app.channel_key channel
88
- end
22
+ # Exception class for all shove exception
23
+ class ShoveException < Exception; end
89
24
 
90
- end
91
25
  end
92
26
 
93
27
  require "shove/app"
94
- require "shove/app_directory"
95
28
  require "shove/protocol"
96
29
  require "shove/client/connection"
97
30
  require "shove/client/channel"
@@ -1,38 +1,24 @@
1
1
  module Shove
2
2
  class App
3
3
 
4
- attr_accessor :config
4
+ attr_accessor :app_key, :app_id, :api_url, :ws_url
5
5
 
6
6
  # create an API client
7
7
  # +config+ optional Confstruct
8
8
  # +&block+ config block
9
9
  # Example:
10
- # Shove::App.new do
11
- # app_id "myappid"
12
- # app_key "myappkey"
13
- # end
14
- def initialize config=Confstruct::Configuration.new, &block
15
- @config = config
16
- configure(&block)
17
- end
18
-
19
- def configure params={}, &block
20
-
21
- @config.configure do
22
- api_url Shove.config.api_url || "https://api.shove.io"
23
- end
10
+ # Shove::App.new(
11
+ # app_id: "myappid"
12
+ # app_key: "myappkey"
13
+ # )
14
+ def initialize config={}
15
+ @config = config
16
+ @app_id = config[:app_id]
17
+ @app_key = config[:app_key]
18
+ @api_url = config[:api_url] || "https://api.shove.io"
19
+ @ws_url = config[:ws_url]
24
20
 
25
- if params
26
- @config.configure params
27
- end
28
-
29
- if block
30
- @config.configure(&block)
31
- end
32
-
33
- unless @config.app_id
34
- raise ShoveException.new("App ID required")
35
- end
21
+ raise ShoveException.new("App ID required") unless @app_id
36
22
  end
37
23
 
38
24
  # is the app valid?
@@ -43,7 +29,7 @@ module Shove
43
29
 
44
30
  # get a list of websocket hosts
45
31
  def hosts
46
- request("hosts").exec_sync(:get).parse
32
+ @hosts ||= request("hosts").exec_sync(:get).parse
47
33
  end
48
34
 
49
35
  # create a channel context for acting on a channel
@@ -60,29 +46,50 @@ module Shove
60
46
 
61
47
  # the base URL based on the settings
62
48
  def url
63
- "#{@config.api_url}/apps/#{@config.app_id}"
49
+ "#{@api_url}/apps/#{@app_id}"
64
50
  end
65
51
 
66
52
  # Create a default request object with the base URL
67
53
  # +path+ extra path info
68
54
  def request path
69
- Http::Request.new("#{url}/#{path}", @config)
55
+ Http::Request.new("#{url}/#{path}", self)
70
56
  end
71
57
 
72
58
  # Generate a channel key for a client to self authorize
73
59
  # publish and subscribe actions.
74
60
  # +channel+ the name of the channel
75
61
  def channel_key channel
76
- Digest::SHA1.hexdigest "#{@config.app_key}-#{channel}"
62
+ Digest::SHA1.hexdigest "#{@app_key}-#{channel}!"
63
+ end
64
+
65
+ # Generate a channel key for a client to self authorize
66
+ # publish and subscribe actions.
67
+ # +channel+ the name of the channel
68
+ def publish_key channel
69
+ channel_key channel
70
+ end
71
+
72
+ # Generate a channel key for a client to self authorize
73
+ # subscribe actions.
74
+ # +channel+ the name of the channel
75
+ def subscribe_key channel
76
+ Digest::SHA1.hexdigest "#{@app_key}-#{channel}"
77
+ end
78
+
79
+ # Generate a connect key for a client to self authorize
80
+ # publish and subscribe actions.
81
+ # +channel+ the name of the channel
82
+ def connect_key
83
+ Digest::SHA1.hexdigest "#{@app_key}-connect"
77
84
  end
78
85
 
79
86
  ####
80
87
 
81
88
  # Connect to shove as a client in the current process
82
89
  # +id+ optional shove id to supply
83
- def connect id=nil
84
- client = Client::Connection.new(self, id)
85
- client.connect
90
+ def connect connect_key=nil
91
+ client = Client::Connection.new(self)
92
+ client.connect connect_key
86
93
  client
87
94
  end
88
95