citadel-ruby-client 0.2.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0ad7287c5b5e735b97040f7b8f6bc0cda099dbec
4
+ data.tar.gz: 01f3a8bcfeca4b2fc1aacd75ad65a68dbf9a04aa
5
+ SHA512:
6
+ metadata.gz: 19cb0f9d33f06a25663e0a1dc58cbd5dd4faca6a5660c65e17654210dc4990da836231a8f25e77211ea2eacb1614f202b8f5768dadc29c7aa1f634ec0ea4cd84
7
+ data.tar.gz: 459dbb0a94e877a2ecab91cf0d1cff63c1f0b97ef02166e0acff20d85721c809a26e0fb5833c0898e6d32a5c5af760c1d095cfbc9314d701fef41f5337634d47
data/lib/citadel.rb ADDED
@@ -0,0 +1,194 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'http'
4
+ require 'json'
5
+ require 'citadel/authenticator'
6
+ require 'citadel/matrix_paths'
7
+ require 'citadel/matrix_interceptor'
8
+
9
+ module Citadel
10
+
11
+ DEFAULT_PUBLIC_ROOMS_LIMIT = 100
12
+
13
+ class << self
14
+ attr_accessor :tenant_url, :public_rooms_limit
15
+ end
16
+
17
+ class Client
18
+ def initialize(tenant_url, public_rooms_limit = DEFAULT_PUBLIC_ROOMS_LIMIT)
19
+ if tenant_url[-1,1] == '/'
20
+ Citadel.tenant_url = tenant_url[0,tenant_url.length-1]
21
+ else
22
+ Citadel.tenant_url = tenant_url
23
+ end
24
+ Citadel.public_rooms_limit = public_rooms_limit
25
+ end
26
+
27
+ #########
28
+ # AUTH #
29
+ #########
30
+
31
+ def auth_token
32
+ return @auth_token if defined? @auth_token
33
+ puts 'Citadel: You need to sign in'
34
+ return nil
35
+ end
36
+
37
+ def sign_in(login, password)
38
+ authenticator = Authenticator.new
39
+ @auth_token = 'Bearer ' + authenticator.get_token(login, password)
40
+ end
41
+
42
+ ##############
43
+ # LIST ROOMS #
44
+ ##############
45
+
46
+ def list_all_public_rooms
47
+ response = all_public_rooms_response
48
+ room_count = JSON.parse(response.body)['total_room_count_estimate'] - 2
49
+ result = []
50
+ (0..room_count).each do
51
+ result << JSON.parse(response.body)['chunk'][i]['room_id']
52
+ end
53
+ result
54
+ end
55
+
56
+ def list_all_joined_rooms
57
+ response = all_joined_rooms_response
58
+ rooms = JSON.parse(response.body)['joined_rooms']
59
+ rooms
60
+ end
61
+
62
+ def all_public_rooms_response
63
+ matrix_paths = MatrixPaths.new
64
+ url = matrix_paths.base_uri + matrix_paths.list_public_rooms_path
65
+ HTTP.auth(auth_token).get(url)
66
+ end
67
+
68
+ def all_joined_rooms_response
69
+ matrix_paths = MatrixPaths.new
70
+ url = matrix_paths.base_uri + matrix_paths.list_joined_rooms_path
71
+ HTTP.auth(auth_token).get(url)
72
+ end
73
+
74
+ #################
75
+ # ROOM CREATION #
76
+ #################
77
+
78
+ def create_room(room_name, topic)
79
+ matrix_paths = MatrixPaths.new
80
+ url = matrix_paths.base_uri + matrix_paths.create_room_path
81
+ room_name_alias = room_name.gsub!(' ','_')
82
+ data_hash = { creation_content: { 'm.federate': false },
83
+ name: room_name,
84
+ preset: 'public_chat',
85
+ visibility: 'public',
86
+ room_alias_name: room_name_alias,
87
+ topic: topic}
88
+ data = JSON.generate data_hash
89
+
90
+ response = HTTP.auth(auth_token).post(url, body: data)
91
+
92
+ matrix_interceptor = MatrixInterceptor.new
93
+ if matrix_interceptor.need_to_wait_and_retry(response)
94
+ response = HTTP.auth(auth_token).post(url, body: data)
95
+ end
96
+
97
+ JSON.parse(response.body)['room_id']
98
+ end
99
+
100
+ ########
101
+ # SEND #
102
+ ########
103
+
104
+ def send_message(room_id, message)
105
+
106
+ matrix_paths = MatrixPaths.new
107
+ randomizer = Random.new
108
+ txn = randomizer.rand(100)
109
+ url = matrix_paths.base_uri + matrix_paths.send_message_path(room_id) + txn.to_s
110
+
111
+ data_hash = { msgtype: 'm.text', body: message }
112
+ data = JSON.generate data_hash
113
+
114
+ response = HTTP.auth(auth_token).put(url, body: data)
115
+
116
+ matrix_interceptor = MatrixInterceptor.new
117
+ if matrix_interceptor.need_to_wait_and_retry(response)
118
+ response = HTTP.auth(auth_token).put(url, body: data)
119
+ end
120
+ end
121
+
122
+ ##########
123
+ # INVITE #
124
+ ##########
125
+
126
+ def invite_users_in_room(room_id, users)
127
+ users.each do |user|
128
+ invite_in_room(room_id, user)
129
+ end
130
+ end
131
+
132
+ def invite_in_room(room_id, user_id)
133
+
134
+ matrix_paths = MatrixPaths.new
135
+ url = matrix_paths.base_uri + matrix_paths.invite_in_room_path(room_id)
136
+ data_hash = { user_id: user_id }
137
+ data = JSON.generate data_hash
138
+
139
+ response = HTTP.auth(auth_token).post(url, body: data)
140
+
141
+ matrix_interceptor = MatrixInterceptor.new
142
+ if matrix_interceptor.need_to_wait_and_retry(response)
143
+ response = HTTP.auth(auth_token).post(url, body: data)
144
+ end
145
+ end
146
+
147
+ ###################
148
+ # ROOM MEMBERSHIP #
149
+ ###################
150
+
151
+ def join_room(room_id)
152
+ matrix_paths = MatrixPaths.new
153
+ url = matrix_paths.base_uri + matrix_paths.join_room_path(room_id)
154
+
155
+ response = HTTP.auth(auth_token).post(url)
156
+
157
+ matrix_interceptor = MatrixInterceptor.new
158
+ if matrix_interceptor.need_to_wait_and_retry(response)
159
+ response = HTTP.auth(auth_token).post(url)
160
+ end
161
+ end
162
+
163
+ def leave_room(room_id)
164
+ matrix_paths = MatrixPaths.new
165
+ url = matrix_paths.base_uri + matrix_paths.leave_room_path(room_id)
166
+
167
+ response = HTTP.auth(auth_token).post(url)
168
+
169
+ matrix_interceptor = MatrixInterceptor.new
170
+ if matrix_interceptor.need_to_wait_and_retry(response)
171
+ response = HTTP.auth(auth_token).post(url)
172
+ end
173
+ end
174
+
175
+ ###################
176
+ # ROOM MANAGEMENT #
177
+ ###################
178
+
179
+ def change_room_visibility(room_id, visibility)
180
+ matrix_paths = MatrixPaths.new
181
+ url = matrix_paths.base_uri + matrix_paths.change_room_visibility_path(room_id)
182
+
183
+ data_hash = { join_rule: visibility }
184
+ data = JSON.generate data_hash
185
+
186
+ response = HTTP.auth(auth_token).put(url, body: data)
187
+
188
+ matrix_interceptor = MatrixInterceptor.new
189
+ if matrix_interceptor.need_to_wait_and_retry(response)
190
+ response = HTTP.auth(auth_token).put(url)
191
+ end
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'matrix_paths'
4
+
5
+ module Citadel
6
+ class Authenticator
7
+ def get_token(login, password)
8
+ matrix_paths = MatrixPaths.new
9
+ url = matrix_paths.base_uri + matrix_paths.login_path
10
+ data_hash = { type: 'm.login.password', user: login, password: password }
11
+ data = JSON.generate data_hash
12
+ response = HTTP.post(url, body: data)
13
+ JSON.parse(response.body)['access_token']
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Citadel
4
+ class MatrixInterceptor
5
+ def need_to_wait_and_retry(response)
6
+ wait_time = JSON.parse(response.body)['retry_after_ms']
7
+ if wait_time
8
+ sleep((wait_time / 1000).ceil + 1)
9
+ return true
10
+ else
11
+ return false
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Citadel
4
+ class MatrixPaths
5
+
6
+ def base_uri
7
+ Citadel.tenant_url + '/_matrix/client/r0'
8
+ end
9
+
10
+ def login_path
11
+ '/login'
12
+ end
13
+
14
+ def create_room_path
15
+ '/createRoom'
16
+ end
17
+
18
+ def send_message_path(room_id)
19
+ '/rooms/' + room_id + '/send/m.room.message/'
20
+ end
21
+
22
+ def invite_in_room_path(room_id)
23
+ '/rooms/' + room_id + '/invite'
24
+ end
25
+
26
+ def list_public_rooms_path
27
+ '/publicRooms' + '?limit=' + Citadel.public_rooms_limit
28
+ end
29
+
30
+ def list_joined_rooms_path
31
+ '/joined_rooms'
32
+ end
33
+
34
+ def join_room_path(room_id)
35
+ '/rooms/' + room_id + '/join'
36
+ end
37
+
38
+ def leave_room_path(room_id)
39
+ '/rooms/' + room_id + '/leave'
40
+ end
41
+
42
+ def change_room_visibility_path(room_id)
43
+ '/rooms/' + room_id + '/state/m.room.join_rules'
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ module Citadel
2
+ VERSION = "0.2.1"
3
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: citadel-ruby-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Claire Dufetrelle
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-09-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: http
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.3'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: json
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.1'
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 1.8.3
79
+ type: :runtime
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - "~>"
84
+ - !ruby/object:Gem::Version
85
+ version: '2.1'
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 1.8.3
89
+ description: A simple way to publish messages on Citadel
90
+ email:
91
+ - claire.dufetrelle@fabernovel.com
92
+ executables: []
93
+ extensions: []
94
+ extra_rdoc_files: []
95
+ files:
96
+ - lib/citadel.rb
97
+ - lib/citadel/authenticator.rb
98
+ - lib/citadel/matrix_interceptor.rb
99
+ - lib/citadel/matrix_paths.rb
100
+ - lib/citadel/version.rb
101
+ homepage: http://rubygems.org/gems/citadel
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.5.2
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Citadel Ruby client
125
+ test_files: []