colossus 0.6.0 → 0.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1f7334b062d47a5404c341687249116596adef40
4
- data.tar.gz: 4b97e49786e4e8575f29947f033f3f91cf642460
3
+ metadata.gz: 7a1798af6e47665a55ac7d9140b00f2317c7cf9f
4
+ data.tar.gz: 1943594c8954d3cd1255f2b5626b6eee6d08fde1
5
5
  SHA512:
6
- metadata.gz: c97c78fb9c7fe9b5c5b9bc044b61295ea64c1fbffc4d2a18c3415e37578dfc65de9e82920988e64f48826ff253ba8e94032d0e9bfa7d0e137280fd607ffeea65
7
- data.tar.gz: 7cfc83075809b1a1ffdb6015760e58903703087087d05727771c421029cee681c0a9d872514d540ecbac90346b2ad90b9905a704f400b8737afc2be07985720b
6
+ metadata.gz: f08853ae51aa21a4526b33955717b903030ac681df09a3d86eb44a5b6a0c39ac92ca9711195450eced0c8918fc94dce7330e9c767581189542cac1a3558e8bda
7
+ data.tar.gz: 5e39feee2464f72cdbb66a4f2e8fc2d1bc860fae862d9b2b1600069c7b73b6a4a33796ae97d5182a2a1a6e8433f553323de86ccde79cec54650fb0f3c79321d5
@@ -2,14 +2,15 @@ require 'faye'
2
2
  require 'json'
3
3
  require 'openssl'
4
4
  require 'faraday'
5
+ require 'faraday_middleware'
5
6
  require 'observer'
6
7
  require 'em-synchrony'
7
8
  require 'securerandom'
8
9
 
9
10
  require 'colossus/configuration'
10
11
  require 'colossus/verifier'
11
- require 'colossus/writer_client'
12
- require 'colossus/simple_presence_getter'
12
+ require 'colossus/http_writer_client'
13
+ require 'colossus/simple_writer_server'
13
14
 
14
15
  require 'colossus/engines/memory/memory'
15
16
  require 'colossus/engines/memory/client_session'
@@ -65,7 +66,7 @@ class Colossus
65
66
  #
66
67
  # @param user_id [#to_s] The unique identifier of a user
67
68
  #
68
- # @return status [String]
69
+ # @return Hash{String => String} User_id key, status value
69
70
  def get(user_id)
70
71
  engine.get(user_id.to_s)
71
72
  end
@@ -76,7 +77,7 @@ class Colossus
76
77
  engine.get_multi(user_ids.map(&:to_s))
77
78
  end
78
79
 
79
- # @return Hash{String => String} User_id keys, statuses values
80
+ # (see #get)
80
81
  def get_all
81
82
  engine.get_all
82
83
  end
@@ -41,11 +41,17 @@ class Colossus
41
41
  end
42
42
 
43
43
  def get(user_id)
44
- client_sessions[user_id]
44
+ if client_sessions.has_key?(user_id)
45
+ { user_id => client_sessions[user_id].status }
46
+ else
47
+ { user_id => 'disconnected' }
48
+ end
45
49
  end
46
50
 
47
51
  def get_multi(*user_ids)
48
- user_ids.map { |user_id| get(user_id) }
52
+ statuses = {}
53
+ user_ids.each { |user_id| statuses[user_id] = get(user_id) }
54
+ statuses
49
55
  end
50
56
 
51
57
  def get_all
@@ -3,18 +3,14 @@ class Colossus
3
3
  # Faye extension implementing all the presence, authorization,
4
4
  # authentification and push logic.
5
5
  class Extension
6
- attr_reader :colossus, :faye, :faye_client
6
+ attr_reader :faye, :colossus
7
7
 
8
8
  VALID_STATUSES = %w(disconnected away active).freeze
9
9
 
10
10
  def initialize(faye, colossus = Colossus.new)
11
- @colossus = colossus
12
11
  @faye = faye
12
+ @colossus = colossus
13
13
  faye.add_extension(self)
14
- @faye_client = faye.get_client
15
- colossus_faye_extension = Colossus::WriterClient::FayeExtension.
16
- new(colossus.verifier.writer_token)
17
- faye_client.add_extension(colossus_faye_extension)
18
14
  end
19
15
 
20
16
  def incoming(message, _request, callback)
@@ -26,18 +22,13 @@ class Colossus
26
22
  handle_user_action(message)
27
23
  message.delete('data')
28
24
  message.delete('ext')
29
- elsif message['ext']['writer_token']
30
- handle_server_action(message)
31
- message.delete('ext')
32
25
  end
33
26
 
34
27
  callback.call(message)
35
28
  end
36
29
 
37
30
  def acceptable?(message)
38
- message['ext'] &&
39
- (message['ext']['user_token'] ||
40
- message['ext']['writer_token'])
31
+ message['ext'] && message['ext']['user_token']
41
32
  end
42
33
 
43
34
  def handle_user_action(message)
@@ -54,60 +45,6 @@ class Colossus
54
45
  message
55
46
  end
56
47
 
57
- def handle_server_action(message)
58
- token = message['ext'] && message['ext']['writer_token']
59
-
60
- unless token && colossus.verifier.verify_writer_token(token)
61
- message['error'] = 'Invalid Token'
62
- message.delete('data')
63
- return message
64
- end
65
-
66
- if message['channel'].start_with?('/meta/')
67
- message.delete('data')
68
- message
69
- elsif message['channel'].start_with?('/presences/request/')
70
- handle_presence_request(message)
71
- elsif message['channel'].start_with?('/presences/response/')
72
- handle_presence_response(message)
73
- elsif message['channel'].start_with?('/users/')
74
- handle_publish(message)
75
- else
76
- message['error'] = 'Unknown Action'
77
- message.delete('data')
78
- end
79
-
80
- message
81
- end
82
-
83
- def handle_presence_request(message)
84
- user_ids = message['data'] && message['data']['user_ids']
85
- presence_id = message['channel'].partition('/presences/request/').last
86
-
87
- if user_ids && user_ids.is_a?(Array)
88
- statuses = colossus.get_multi(user_ids)
89
- message['data'].delete('user_ids')
90
- faye_client.publish("/presences/response/#{presence_id}", { 'statuses' => Hash[user_ids.zip(statuses)] })
91
- message
92
- elsif user_ids == nil
93
- statuses = colossus.get_all
94
- faye_client.publish("/presences/response/#{presence_id}", { 'statuses' => statuses })
95
- message
96
- else
97
- message.delete('data')
98
- message['error'] = 'Invalid user_ids data'
99
- message
100
- end
101
- end
102
-
103
- def handle_presence_response(message)
104
- message
105
- end
106
-
107
- def handle_publish(message)
108
- message
109
- end
110
-
111
48
  def handle_invalid_token(message)
112
49
  message['error'] = 'Invalid Token'
113
50
  message
@@ -0,0 +1,46 @@
1
+ class Colossus
2
+ class HTTPWriterClient
3
+ attr_reader :url, :writer_token, :time_out
4
+
5
+ def initialize(url,
6
+ writer_token = Colossus.config.writer_token,
7
+ time_out = 2)
8
+ @url = url
9
+ @writer_token = writer_token
10
+ @time_out = time_out
11
+ end
12
+
13
+ def presence(optional_user_ids = nil)
14
+ user_ids = Array(optional_user_ids) if optional_user_ids
15
+ connection.post('/presence_request') do |req|
16
+ req.body = { user_ids: user_ids, writer_token: writer_token }
17
+ end.body
18
+ end
19
+
20
+ def push(user_ids, message)
21
+ user_ids = Array(user_ids)
22
+ connection.post('/message') do |req|
23
+ req.body = { user_ids: user_ids, message: message, writer_token: writer_token}
24
+ end.body
25
+ end
26
+
27
+ private
28
+
29
+ def connection
30
+ Faraday.new(url, connection_options) do |conf|
31
+ conf.request :json
32
+ conf.response :json
33
+ conf.response :raise_error
34
+ conf.adapter Faraday.default_adapter
35
+ end
36
+ end
37
+
38
+ def connection_options
39
+ {request: {timeout: 2, open_timeout: 2}}
40
+ end
41
+
42
+ def base_url
43
+ @base_url ||= URI.parse(url).tap{ |u| u.path=('/') }
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,51 @@
1
+ class Colossus
2
+ class SimpleWriterServer
3
+ attr_reader :faye_extension
4
+
5
+ def initialize(faye_extension)
6
+ @faye_extension = faye_extension
7
+ end
8
+
9
+ def presence(writer_token, optional_user_ids = nil)
10
+ raise 'Invalid token' unless valid?(writer_token)
11
+
12
+ case optional_user_ids
13
+ when Array
14
+ colossus.get_multi(*optional_user_ids)
15
+ when String
16
+ colossus.get(optional_user_ids)
17
+ when NilClass
18
+ colossus.get_all
19
+ else
20
+ raise 'Invalid user_ids data'
21
+ end
22
+ end
23
+
24
+ def push(writer_token, user_ids, message)
25
+ raise 'Invalid token' unless valid?(writer_token)
26
+
27
+ case user_ids
28
+ when Array
29
+ user_ids.each do |user_id|
30
+ faye_client.publish("/users/#{user_id}", message)
31
+ end
32
+ when String
33
+ faye_client.publish("/users/#{user_ids}", message)
34
+ else
35
+ raise 'Invalid user_ids data'
36
+ end
37
+ end
38
+
39
+ def valid?(writer_token)
40
+ colossus.verifier.verify_writer_token(writer_token)
41
+ end
42
+
43
+ def faye_client
44
+ faye_extension.faye.get_client
45
+ end
46
+
47
+ def colossus
48
+ faye_extension.colossus
49
+ end
50
+ end
51
+ end
@@ -1,4 +1,4 @@
1
1
  # The Version
2
2
  class Colossus
3
- VERSION = '0.6.0'
3
+ VERSION = '0.7.0'
4
4
  end
metadata CHANGED
@@ -1,55 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: colossus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - antoinelyset
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-03 00:00:00.000000000 Z
11
+ date: 2014-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faye
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: em-synchrony
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: faraday
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: faraday_middleware
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
53
67
  - !ruby/object:Gem::Version
54
68
  version: '0'
55
69
  description: Colossus is a Push and Presence pure Ruby server. It uses Faye internally.
@@ -65,10 +79,10 @@ files:
65
79
  - lib/colossus/engines/memory/client_session_store.rb
66
80
  - lib/colossus/engines/memory/memory.rb
67
81
  - lib/colossus/faye/extension.rb
68
- - lib/colossus/simple_presence_getter.rb
82
+ - lib/colossus/http_writer_client.rb
83
+ - lib/colossus/simple_writer_server.rb
69
84
  - lib/colossus/verifier.rb
70
85
  - lib/colossus/version.rb
71
- - lib/colossus/writer_client.rb
72
86
  homepage: https://github.com/antoinelyset/colossus
73
87
  licenses:
74
88
  - MIT
@@ -79,17 +93,17 @@ require_paths:
79
93
  - lib
80
94
  required_ruby_version: !ruby/object:Gem::Requirement
81
95
  requirements:
82
- - - '>='
96
+ - - ">="
83
97
  - !ruby/object:Gem::Version
84
98
  version: '0'
85
99
  required_rubygems_version: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - '>='
101
+ - - ">="
88
102
  - !ruby/object:Gem::Version
89
103
  version: '0'
90
104
  requirements: []
91
105
  rubyforge_project:
92
- rubygems_version: 2.0.14
106
+ rubygems_version: 2.2.2
93
107
  signing_key:
94
108
  specification_version: 4
95
109
  summary: Colossus, Web Push & Presence made easy.
@@ -1,25 +0,0 @@
1
- class Colossus
2
- class SimplePresenceGetter
3
- attr_reader :colossus
4
-
5
- def initialize(colossus)
6
- @colossus = colossus
7
- end
8
-
9
- def get_presences(writer_token, optional_user_ids = nil)
10
- raise 'Invalid token' unless valid?(writer_token)
11
- user_ids = Array(optional_user_ids) if optional_user_ids
12
- if user_ids && user_ids.is_a?(Array)
13
- Hash[user_ids.zip(colossus.get_multi(user_ids))]
14
- elsif user_ids == nil
15
- colossus.get_all
16
- else
17
- raise 'Invalid user_ids data'
18
- end
19
- end
20
-
21
- def valid?(writer_token)
22
- colossus.verifier.verify_writer_token(writer_token)
23
- end
24
- end
25
- end
@@ -1,82 +0,0 @@
1
- class Colossus
2
- class WriterClient
3
- attr_reader :url, :writer_token, :time_out
4
-
5
- def initialize(url,
6
- writer_token = Colossus.config.writer_token,
7
- time_out = 2)
8
- @url = url
9
- @writer_token = writer_token
10
- @time_out = time_out
11
- end
12
-
13
- def get_presences(optional_user_ids = nil)
14
- user_ids = Array(optional_user_ids) if optional_user_ids
15
- unique_token = generate_unique_token
16
- EM.synchrony do
17
- EM::Synchrony.add_timer(time_out) { raise 'Presence request timed out' }
18
- EM::Synchrony.sync(faye_client.subscribe("/presences/response/#{unique_token}") { |message| return message['statuses'] })
19
- EM::Synchrony.sync(faye_client.publish("/presences/request/#{unique_token}", user_ids))
20
- end
21
- end
22
-
23
- def get_presences_by_http(optional_user_ids = nil)
24
- user_ids = Array(optional_user_ids) if optional_user_ids
25
- # Custom Content-Type to indicate to the server
26
- # this is a simple http request
27
- conn = Faraday.new(url, headers: {'Content-Type' => 'application/vnd.http.json'}) do |conf|
28
- conf.adapter Faraday.default_adapter
29
- conf.response :raise_error
30
- end
31
-
32
- body = conn.post do |req|
33
- req.body = JSON.dump({ user_ids: user_ids, writer_token: writer_token})
34
- end.body
35
-
36
- response = JSON.parse(body)
37
- response['statuses']
38
- end
39
-
40
- def push_message(user_ids, message)
41
- user_ids = Array(user_ids)
42
- EM.synchrony do
43
- EM::Synchrony.add_timer(time_out) { raise 'Push message timed out' }
44
- user_ids.each do |user_id|
45
- EM::Synchrony.sync(faye_client.publish("/users/#{user_id}", message))
46
- end
47
- EM.stop
48
- end
49
- end
50
-
51
- private
52
-
53
- def faye_client
54
- faye_client = ::Faye::Client.new(url)
55
- faye_client.add_extension(FayeExtension.new(writer_token))
56
- faye_client
57
- end
58
-
59
- def generate_unique_token
60
- SecureRandom.hex(8)
61
- end
62
-
63
- class FayeExtension
64
- attr_reader :token
65
-
66
- def initialize(token)
67
- @token = token
68
- end
69
-
70
- def incoming(message, callback)
71
- callback.call(message)
72
- end
73
-
74
- def outgoing(message, callback)
75
- message['ext'] ||= {}
76
- message['ext']['writer_token'] = token
77
-
78
- callback.call(message)
79
- end
80
- end
81
- end
82
- end