colossus 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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