edmond-danthes 2.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c00bc2184b0c3d500760616b2ed8c1e09b77ecf73bec59e749b12e0478fcbc6c
4
+ data.tar.gz: 3826ce0b71a309ff0e2ac67cbee1b85f19c7a247234b49330b995f564943b5b7
5
+ SHA512:
6
+ metadata.gz: 6b5638531601eab5c8b4ac24d3d632c3129fe825066aab4359eb874bd39058628170c5144249a5ab9300e99678fd21c3502bae08ac49928d5164bdc07ef25e68
7
+ data.tar.gz: 776e9f3c7c4dbfb42aeb758a86667cfdfc559ac394e8a11fbcc47dd04d5ecb45701d257947c0304127a9d343075bf0a2593a173c8c97fd90e3eb9b648df3046f
@@ -0,0 +1,10 @@
1
+ *.swp
2
+ **/*.swp
3
+ **/*.log
4
+ *.gem
5
+ Gemfile.lock
6
+ .bundle
7
+ app/assets/javascripts/compiled
8
+ spec/coffeescripts/compiled
9
+ coverage
10
+ .idea
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,11 @@
1
+ AllCops:
2
+ Include:
3
+ - '**/Rakefile'
4
+ Exclude:
5
+ - 'spec/**/*'
6
+ Style/LineLength:
7
+ Max: 99
8
+ Style/FileName:
9
+ Enabled: false
10
+ Documentation:
11
+ Enabled: false
@@ -0,0 +1,10 @@
1
+ rvm:
2
+ - 2.1.7
3
+ - 2.2.1
4
+ - 2.2.2
5
+ - 2.2.3
6
+ - rbx-2
7
+ before_script:
8
+ - "export DISPLAY=:99.0"
9
+ - "sh -e /etc/init.d/xvfb start"
10
+ sudo: false
@@ -0,0 +1,84 @@
1
+ # d'Anthès
2
+
3
+ ## 2.0.1 (March 20 2015)
4
+
5
+ * Fix issue with websocket-driver >= 0.5.1
6
+
7
+ ## 2.0.0 (February 18 2015)
8
+
9
+ * Added ERB support in redis configuration file
10
+ * Fix generators for supporting only Rails 4.x
11
+ * Fix config loading in Rails 4.x
12
+ * Drop support of Rails 3.x
13
+
14
+ ## 1.0.5 (May 19 2014)
15
+
16
+ * Added ERB support in configuration files
17
+
18
+ ## 1.0.4 (February 25 2013)
19
+
20
+ * Added possibility to activate Faye's subscription later on subscribe call
21
+
22
+ ## 1.0.3 (September 26 2012)
23
+
24
+ * Fix IE support
25
+
26
+ ## 1.0.2 (September 7 2012)
27
+
28
+ * Subscription callback through sign call
29
+ * On subscription connect callback
30
+ * On subscription error callback
31
+ * Transport disabling
32
+
33
+ ## 1.0.1 (August 26 2012)
34
+
35
+ * Generator for redis config file
36
+ * Fixes for rackup file
37
+ * Fixes for full server url
38
+ * CoffeeScript class documentation
39
+
40
+ ## 1.0 (August 25 2012)
41
+
42
+ * initial release
43
+
44
+
45
+ # PrivatePub
46
+
47
+ ## 1.0.0 (January 25, 2012)
48
+
49
+ * Rails 3.2 compatibility with SecureRandom fix (thanks windigo) - issue #26
50
+
51
+ ## 1.0.0 (January 15, 2012)
52
+
53
+ * setting config defaults to nil so everything must be set in `private_pub.yml`
54
+
55
+ * Documentation improvements
56
+
57
+
58
+ ## 0.3.0 (January 14, 2012)
59
+
60
+ * adding `PrivatePub.publish_to` method for publishing from anywhere - issue #15
61
+
62
+ * rewriting `private_pub.js` so it is framework agnostic
63
+
64
+ * Rails 3.1 compatibility (thanks BinaryMuse) - issue #25
65
+
66
+ * adding faye gem dependency so it doesn't need to be installed separately
67
+
68
+ * renaming `faye.ru` to `private_pub.ru`
69
+
70
+ * truncate token for client for security (thanks jameshuynh) - issue #19
71
+
72
+
73
+ ## 0.2.0 (April 7, 2011)
74
+
75
+ * switched to YAML file for config. BACKWARDS INCOMPATIBLE: you will need to remove config/initializers/private_pub.rb
76
+
77
+ * moved view helpers into Railtie so helper file is no longer generated
78
+
79
+ * error out when signature has expired
80
+
81
+
82
+ ## 0.1.0 (April 4, 2011)
83
+
84
+ * initial release
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source 'http://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'faye-redis'
5
+
6
+ group :development, :test do
7
+ gem 'rake'
8
+ gem 'guard'
9
+ gem 'guard-coffeescript'
10
+ gem 'jasmine', '>= 2.0.0'
11
+ gem 'rspec', '>= 3.0.0'
12
+ gem 'rspec-mocks', '>= 3.0.0'
13
+ gem 'webmock'
14
+ gem 'coveralls', require: false
15
+ gem 'rails'
16
+ end
@@ -0,0 +1,7 @@
1
+ guard 'coffeescript', output: 'app/assets/javascripts/compiled' do
2
+ watch /^app\/assets\/javascripts\/(.*)\.coffee/
3
+ end
4
+
5
+ guard 'coffeescript', output: 'spec/coffeescripts/compiled' do
6
+ watch /^spec\/coffeescripts\/(.*)\.coffee/
7
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2020 Dmitry Zuev
2
+ Copyright (c) 2012 Alexander Simonov
3
+ Copyright (c) 2012 Ryan Bates
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,156 @@
1
+ # d'Anthès [![Build Status](https://secure.travis-ci.org/dotpromo/danthes.png?branch=master)](http://travis-ci.org/dotpromo/danthes)[![Code Climate](https://codeclimate.com/github/dotpromo/danthes.png)](https://codeclimate.com/github/dotpromo/danthes)[![Coverage Status](https://coveralls.io/repos/dotpromo/danthes/badge.png?branch=master)](https://coveralls.io/r/dotpromo/danthes)
2
+
3
+ This is a fork of [d'Anthès](https://github.com/amoniacou/danthes).
4
+
5
+ d'Anthès is a Ruby gem for use with Rails to publish and subscribe to messages through [Faye](http://faye.jcoglan.com/). It allows you to easily provide real-time updates through an open socket without tying up a Rails process. All channels are private so users can only listen to events you subscribe them to. Based on PrivatePub gem.
6
+
7
+ ## Docs
8
+
9
+ [Ruby](http://rubydoc.info/github/dotpromo/danthes/frames)
10
+
11
+ [CoffeeScript](https://github.com/dotpromo/danthes/wiki/CoffeeScript-documentation)
12
+
13
+ ## Setup
14
+
15
+ Add the gem to your Gemfile and run the `bundle` command to install it.
16
+
17
+ ```ruby
18
+ gem 'edmond-danthes'
19
+ ```
20
+
21
+ Run the generator to create the initial files.
22
+
23
+ ```
24
+ rails g danthes:install
25
+ ```
26
+
27
+ Next, start up Faye using the rackup file that was generated.
28
+
29
+ ```
30
+ rackup danthes.ru -s thin -E production
31
+ ```
32
+
33
+ **In Rails 3.1** add the JavaScript file to your application.js file manifest.
34
+
35
+ ```javascript
36
+ //= require danthes
37
+ ```
38
+
39
+ **NOTE**: On your local machine `secret_token` must be equal for all environments because danthes process working only in production mode.
40
+
41
+ It's not necessary to include faye's connect.js since that will be handled automatically for you.
42
+
43
+ ## Serving Faye over HTTPS (with Thin)
44
+
45
+ To serve Faye over HTTPS you could create a thin configuration file `config/danthes_thin.yml` similar to the following:
46
+
47
+ ```yaml
48
+ ---
49
+ port: 4443
50
+ ssl: true
51
+ ssl_key_file: /path/to/server.pem
52
+ ssl_cert_file: /path/to/certificate_chain.pem
53
+ environment: production
54
+ rackup: danthes.ru
55
+ ```
56
+
57
+ The `certificate_chain.pem` file should contain your signed certificate, followed by intermediate certificates (if any) and the root certificate of the CA that signed the key.
58
+
59
+ Next reconfigure the URL in `config/danthes.yml` to look like `https://your.hostname.com:4443/faye`
60
+
61
+ Finally start up Thin from the project root.
62
+
63
+ ```
64
+ thin -C config/danthes_thin.yml start
65
+ ```
66
+
67
+ ## Serving Faye with Redis engine
68
+
69
+ Run the generator to create the initial redis config file.
70
+
71
+ ```
72
+ rails g danthes:redis_install
73
+ ```
74
+
75
+ ## Usage
76
+
77
+ Use the `subscribe_to` helper method on any page to subscribe to a channel.
78
+
79
+ ```rhtml
80
+ <%= subscribe_to "/messages/new" %>
81
+ ```
82
+
83
+ Use the `publish_to` helper method to send JavaScript to that channel. This is usually done in a JavaScript AJAX template (such as a create.js.erb file).
84
+
85
+ ```rhtml
86
+ <% publish_to "/messages/new" do %>
87
+ $("#chat").append("<%= j render(@messages) %>");
88
+ <% end %>
89
+ ```
90
+
91
+ This JavaScript will be immediately evaluated on all clients who have subscribed to that channel. In this example they will see the new chat message appear in real-time without reloading the browser.
92
+
93
+
94
+ ## Alternative Usage
95
+
96
+ If you prefer to work through JSON instead of `.js.erb` templates, you can pass a hash to `publish_to` instead of a block and it will be converted `to_json` behind the scenes. This can be done anywhere (such as the controller).
97
+
98
+ ```ruby
99
+ Danthes.publish_to "/messages/new", :chat_message => "Hello, world!"
100
+ ```
101
+
102
+ And then handle this through JavaScript on the client side.
103
+
104
+ ```javascript
105
+ Danthes.subscribe("/messages/new", function(data, channel) {
106
+ $("#chat").append(data.chat_message);
107
+ });
108
+ ```
109
+
110
+ The Ruby `subscribe_to` helper call is still necessary with this approach to grant the user access to the channel. The JavaScript is just a callback for any custom behavior.
111
+
112
+ ## Debugging
113
+
114
+ To enable debugging for faye connection process set `debug` to true before first `sign` call.
115
+
116
+ ``` javascript
117
+ Danthes.debug = true
118
+ ```
119
+
120
+ ## Configuration
121
+
122
+ The configuration is set separately for each environment in the generated `config/danthes.yml` file. Here are the options.
123
+
124
+ * `server`: The URL to use for the Faye server such as `http://localhost:9292`.
125
+ * `mount`: The mount path for Faye
126
+ * `secret_token`: A secret hash to secure the server. Can be any string.
127
+ * `signature_expiration`: The length of time in seconds before a subscription signature expires. If this is not set there is no expiration. Note: if Faye is on a separate server from the Rails app, the system clocks must be in sync for the expiration to work properly.
128
+ * `adapter`: Adapter for the Rack application
129
+
130
+
131
+ ## How It Works
132
+
133
+ The `subscribe_to` helper will output the following script which subscribes the user to a specific channel and server.
134
+
135
+ ```html
136
+ <script type="text/javascript">
137
+ Danthes.sign({
138
+ channel: "/messages/new",
139
+ timestamp: 1302306682972,
140
+ signature: "dc1c71d3e959ebb6f49aa6af0c86304a0740088d",
141
+ server: "http://localhost:9292/faye"
142
+ });
143
+ </script>
144
+ ```
145
+
146
+ The signature and timestamp checked on the Faye server to ensure users are only able to access channels you subscribe them to. The signature will automatically expire after the time specified in the configuration.
147
+
148
+ The `publish_to` method will send a post request to the Faye server (using `Net::HTTP`) instructing it to send the given data back to the browser.
149
+
150
+ ## Development & Feedback
151
+
152
+ Questions or comments? Please use the [issue tracker](https://github.com/dotpromo/danthes/issues). Tests can be run with `bundle` and `rake` commands.
153
+
154
+ ## TODO
155
+
156
+ - Add support for faye subscribe callbacks
@@ -0,0 +1,31 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rspec/core/rake_task'
4
+ require 'yaml'
5
+ require 'jasmine'
6
+ require 'coffee-script'
7
+ require 'bundler/gem_tasks'
8
+ load 'jasmine/tasks/jasmine.rake'
9
+
10
+ desc 'Run RSpec'
11
+ RSpec::Core::RakeTask.new do |t|
12
+ t.verbose = false
13
+ end
14
+
15
+ task default: [:spec, 'compile_js', 'jasmine:ci']
16
+
17
+ def compile_coffee_script(file, path)
18
+ source = File.read File.expand_path("#{path}/#{file}.coffee", __FILE__)
19
+ compiled_path = File.expand_path("#{path}/compiled/", __FILE__)
20
+ unless File.exist?(compiled_path) && File.directory?(compiled_path)
21
+ Dir.mkdir compiled_path
22
+ end
23
+ destination = File.open File.join(compiled_path, file), 'w+'
24
+ destination.write CoffeeScript.compile(source)
25
+ end
26
+
27
+ desc 'Compile coffeescript'
28
+ task :compile_js do
29
+ compile_coffee_script('danthes.js', '../app/assets/javascripts')
30
+ compile_coffee_script('danthesSpec.js', '../spec/coffeescripts')
31
+ end
@@ -0,0 +1,174 @@
1
+ # Danthes Privat pub/sub Faye wrapper
2
+ #
3
+ # @example Howto enable debug
4
+ # Danthes.debug = true
5
+ # @example reset all internal data
6
+ # Danthes.reset()
7
+ # @example Howto sign and subscribe on channel with callback function
8
+ # Danthes.sign
9
+ # server: 'faye.example.com'
10
+ # channel: 'somechannel'
11
+ # signature: 'dc1c71d3e959ebb6f49aa6af0c86304a0740088d'
12
+ # timestamp: 1302306682972
13
+ # connect: (subscription) ->
14
+ # console.log(subscription)
15
+ # error: (subscription, error) ->
16
+ # console.log("error: #{error}")
17
+
18
+ window.Danthes = class Danthes
19
+
20
+ @debug: false
21
+
22
+ @debugMessage: (message) ->
23
+ console.log(message) if @debug
24
+
25
+ # Reset all
26
+ @reset: ->
27
+ @connecting = false
28
+ @fayeClient = null
29
+ @fayeCallbacks = []
30
+ @subscriptions = {}
31
+ @server = null
32
+ @disables = []
33
+ @connectionSettings =
34
+ timeout: 120
35
+ retry: 5
36
+ endpoints: {}
37
+
38
+ # Connect to faye
39
+ @faye: (callback) =>
40
+ if @fayeClient?
41
+ callback(@fayeClient)
42
+ else
43
+ @fayeCallbacks.push(callback)
44
+ if @server && !@connecting
45
+ @connecting = true
46
+ unless Faye?
47
+ script = document.createElement 'script'
48
+ script.type = 'text/javascript'
49
+ script.src = "#{@server}/client.js"
50
+ script.id = "faye-connection-script"
51
+ complete = false
52
+ script.onload = script.onreadystatechange = () =>
53
+ if !complete && (!script.readyState || script.readyState is "loaded" || script.readyState is "complete")
54
+ complete = true
55
+ script.onload = script.onreadystatechange = null
56
+ @debugMessage 'connect to faye after script loaded'
57
+ @connectToFaye()
58
+ @debugMessage 'faye script init'
59
+ document.documentElement.appendChild script
60
+ else
61
+ @debugMessage 'faye already inited'
62
+ @connectToFaye()
63
+
64
+ # Faye extension for incoming and outgoing messages
65
+ @fayeExtension:
66
+ incoming : (message, callback) =>
67
+ @debugMessage "incomming message #{JSON.stringify(message)}"
68
+ callback(message)
69
+ outgoing : (message, callback) =>
70
+ @debugMessage "outgoing message #{JSON.stringify(message)}"
71
+ if message.channel == "/meta/subscribe"
72
+ subscription = @subscriptions[message.subscription]['opts']
73
+ # Attach the signature and timestamp to subscription messages
74
+ message.ext = {} unless message.ext?
75
+ message.ext.danthes_signature = subscription.signature
76
+ message.ext.danthes_timestamp = subscription.timestamp
77
+ callback(message)
78
+
79
+ # Initialize Faye client
80
+ @connectToFaye: ->
81
+ if @server && Faye?
82
+ @debugMessage 'trying to connect faye'
83
+ @fayeClient = new Faye.Client(@server, @connectionSettings)
84
+ @fayeClient.addExtension(@fayeExtension)
85
+ # Disable any features what we want
86
+ @fayeClient.disable(key) for key in @disables
87
+ @debugMessage 'faye connected'
88
+ callback(@fayeClient) for callback in @fayeCallbacks
89
+
90
+ # Sign to channel
91
+ # @param [Object] options for signing
92
+ @sign: (options) ->
93
+ @debugMessage 'sign to faye'
94
+ @server = options.server unless @server
95
+ channel = options.channel
96
+ unless @subscriptions[channel]?
97
+ @subscriptions[channel] = {}
98
+ @subscriptions[channel]['callback'] = options['callback'] if options['callback']?
99
+ @subscriptions[channel]['opts'] =
100
+ signature: options['signature']
101
+ timestamp: options['timestamp']
102
+ # If we have 'connect' or 'error' option then force channel activation
103
+ if options['connect']? || options['error']?
104
+ @activateChannel channel, options
105
+
106
+ # Activating channel subscription
107
+ # @param channel [String] channel name
108
+ # @param options [Object] subscription callback options
109
+ @activateChannel: (channel, options = {}) ->
110
+ return true if @subscriptions[channel]['activated']
111
+ @faye (faye) =>
112
+ subscription = faye.subscribe channel, (message) => @handleResponse(message)
113
+ if subscription?
114
+ @subscriptions[channel]['sub'] = subscription
115
+ subscription.callback =>
116
+ options['connect']?(subscription)
117
+ @debugMessage "subscription for #{channel} is active now"
118
+ subscription.errback (error) =>
119
+ options['error']?(subscription, error)
120
+ @debugMessage "error for #{channel}: #{error.message}"
121
+ @subscriptions[channel]['activated'] = true
122
+
123
+ # Handle response from Faye
124
+ # @param [Object] message from Faye
125
+ @handleResponse: (message) ->
126
+ if message.eval
127
+ eval(message.eval)
128
+ channel = message.channel
129
+ return unless @subscriptions[channel]?
130
+ if callback = @subscriptions[channel]['callback']
131
+ callback(message.data, channel)
132
+
133
+ # Disable transports
134
+ # @param [String] name of transport
135
+ @disableTransport: (transport) ->
136
+ return unless transport in ['websocket', 'long-polling', 'callback-polling', 'in-process']
137
+ unless transport in @disables
138
+ @disables.push(transport)
139
+ @debugMessage "#{transport} faye transport will be disabled"
140
+ true
141
+
142
+ # Subscribe to channel with callback
143
+ # @param channel [String] Channel name
144
+ # @param callback [Function] Callback function
145
+ # @param options [Object] subscription callbacks options
146
+ @subscribe: (channel, callback, options = {}) ->
147
+ @debugMessage "subscribing to #{channel}"
148
+ if @subscriptions[channel]?
149
+ @activateChannel(channel, options)
150
+ # Changing callback on every call
151
+ @subscriptions[channel]['callback'] = callback
152
+ else
153
+ @debugMessage "Cannot subscribe on channel '#{channel}'. You need sign to channel first."
154
+ return false
155
+ true
156
+
157
+ # Unsubscribe from channel
158
+ # @param [String] Channel name
159
+ # @param [Boolean] Full unsubscribe
160
+ @unsubscribe: (channel, fullUnsubscribe = false) ->
161
+ @debugMessage "unsubscribing from #{channel}"
162
+ if @subscriptions[channel] && @subscriptions[channel]['activated']
163
+ @subscriptions[channel]['sub'].cancel()
164
+ if fullUnsubscribe
165
+ delete @subscriptions[channel]
166
+ else
167
+ delete @subscriptions[channel]['activated']
168
+ delete @subscriptions[channel]['sub']
169
+
170
+ # Unsubscribe from all channels
171
+ @unsubscribeAll: ->
172
+ @unsubscribe(channel) for channel, _ of @subscriptions
173
+
174
+ window.Danthes.reset()