matrix_sdk 0.0.2 → 0.0.3
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 +4 -4
- data/.gitlab-ci.yml +33 -0
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +24 -0
- data/README.md +1 -0
- data/examples/simple_client.rb +17 -12
- data/lib/matrix_sdk/api.rb +233 -44
- data/lib/matrix_sdk/client.rb +43 -13
- data/lib/matrix_sdk/extensions.rb +39 -2
- data/lib/matrix_sdk/response.rb +41 -0
- data/lib/matrix_sdk/room.rb +46 -3
- data/lib/matrix_sdk/user.rb +16 -0
- data/lib/matrix_sdk/version.rb +1 -1
- data/lib/matrix_sdk.rb +3 -2
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc787a1c2e4bac79cf05357500571df2e7734464023a5182d08614b9e45e9aac
|
4
|
+
data.tar.gz: 465ea39af281892dcb299014b8a5b4bc0c869f6914974f40cb6fd21301090129
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a18893ee520aedfacc011cf5888b310875ee6929fa94967a0eeee01e91d592a56b19b190e6400e5e9338ccf477f9ac4cb1c480866fb720c1eecee7f0fb005a6f
|
7
|
+
data.tar.gz: ed1d6b9eaad9795147ffb8bf319c4fed25598147a2af2f97048eb0285684c32fc7809e36ad891917f3499105778eb11409d8577941258c9fb94cee84b4c41dbd
|
data/.gitlab-ci.yml
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
---
|
2
|
+
image: "ruby:2.4"
|
3
|
+
|
4
|
+
# Cache gems in between builds
|
5
|
+
cache:
|
6
|
+
paths:
|
7
|
+
- vendor/ruby
|
8
|
+
|
9
|
+
before_script:
|
10
|
+
- gem install bundler --no-ri --no-rdoc
|
11
|
+
- bundle install -j $(nproc) --path vendor
|
12
|
+
|
13
|
+
rubocop:
|
14
|
+
before_script: []
|
15
|
+
script:
|
16
|
+
- gem install rubocop --no-ri --no-rdoc
|
17
|
+
- rubocop
|
18
|
+
|
19
|
+
# rspec:
|
20
|
+
# script:
|
21
|
+
# - rspec spec
|
22
|
+
|
23
|
+
pages:
|
24
|
+
stage: deploy
|
25
|
+
before_script: []
|
26
|
+
script:
|
27
|
+
- gem install yard
|
28
|
+
- yard doc -o public/
|
29
|
+
artifacts:
|
30
|
+
paths:
|
31
|
+
- public/
|
32
|
+
only:
|
33
|
+
- master
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
## v0.0.3 - 2018-08-14
|
2
|
+
|
3
|
+
- Adds missing accessors for HTTP timeout
|
4
|
+
- Adds methods for checking auth status to client API
|
5
|
+
- Adds a wrapper class for API responses to ease use
|
6
|
+
- Adds option (and defaults) to store login details on registration
|
7
|
+
- Allows creating a MatrixSdk::Client off of an existing MatrixSdk::Api
|
8
|
+
- Extends event handling
|
9
|
+
|
10
|
+
- Fixes batch handling in sync
|
11
|
+
- Fixes event handling in the sample
|
12
|
+
- Removes unimplemented API methods to avoid confusion
|
13
|
+
|
14
|
+
- Plenty of documentation work
|
15
|
+
|
16
|
+
## v0.0.2 - 2018-05-11
|
17
|
+
|
18
|
+
- Fixes for multiple issues discovered after initial release
|
19
|
+
- Adds additional API methods
|
20
|
+
- Higher-level client API gets room and user abstractions
|
21
|
+
|
22
|
+
## v0.0.1 - 2018-05-06
|
23
|
+
|
24
|
+
Initial release
|
data/README.md
CHANGED
data/examples/simple_client.rb
CHANGED
@@ -11,7 +11,7 @@ class SimpleClient < MatrixSdk::Client
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def add_listener(room)
|
14
|
-
room.on_event { |ev| on_message(room, ev) }
|
14
|
+
room.on_event.add_handler { |ev| on_message(room, ev) }
|
15
15
|
end
|
16
16
|
|
17
17
|
def run
|
@@ -26,20 +26,22 @@ class SimpleClient < MatrixSdk::Client
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def on_message(room, event)
|
29
|
-
|
30
|
-
case ev[:type]
|
29
|
+
case event.type
|
31
30
|
when 'm.room.member'
|
32
|
-
puts "#{Time.now.strftime '%H:%M'} #{event[:content][:displayname]} joined." if event
|
31
|
+
puts "[#{Time.now.strftime '%H:%M'}] #{event[:content][:displayname]} joined." if event.membership == 'join'
|
33
32
|
when 'm.room.message'
|
34
|
-
user = get_user event
|
35
|
-
admin_level = get_user_level(room, user.id)
|
36
|
-
prefix =
|
37
|
-
if
|
38
|
-
|
33
|
+
user = get_user event.sender
|
34
|
+
admin_level = get_user_level(room, user.id) || 0
|
35
|
+
prefix = ' '
|
36
|
+
prefix = '+' if admin_level >= 50
|
37
|
+
prefix = '@' if admin_level >= 100
|
38
|
+
if %w[m.text m.notice].include? event.content[:msgtype]
|
39
|
+
notice = event.content[:msgtype] == 'm.notice'
|
40
|
+
puts "[#{Time.now.strftime '%H:%M'}] <#{prefix}#{user.display_name}> #{"\033[1;30m" if notice}#{event.content[:body]}#{"\033[0m" if notice}"
|
39
41
|
elsif event[:content][:msgtype] == 'm.emote'
|
40
|
-
puts "#{Time.now.strftime '%H:%M'} *#{prefix}#{user.display_name} #{event
|
42
|
+
puts "[#{Time.now.strftime '%H:%M'}] *#{prefix}#{user.display_name} #{event.content[:body]}"
|
41
43
|
else
|
42
|
-
puts "#{Time.now.strftime '%H:%M'} <#{prefix}#{user.display_name}>
|
44
|
+
puts "[#{Time.now.strftime '%H:%M'}] <#{prefix}#{user.display_name}> (#{event.content[:msgtype]}) #{event.content[:body]} - #{api.get_download_url event.content[:url]}"
|
43
45
|
end
|
44
46
|
end
|
45
47
|
end
|
@@ -54,6 +56,7 @@ if $PROGRAM_NAME == __FILE__
|
|
54
56
|
end
|
55
57
|
|
56
58
|
client = SimpleClient.new ARGV.first
|
59
|
+
ARGV.shift
|
57
60
|
|
58
61
|
print 'Username: '
|
59
62
|
user = STDIN.gets.strip
|
@@ -87,7 +90,9 @@ if $PROGRAM_NAME == __FILE__
|
|
87
90
|
room.send_text msg
|
88
91
|
end
|
89
92
|
end
|
93
|
+
rescue Interrupt
|
94
|
+
puts 'Interrupted, exiting...'
|
90
95
|
ensure
|
91
|
-
client.logout if client
|
96
|
+
client.logout if client && client.logged_in?
|
92
97
|
end
|
93
98
|
end
|
data/lib/matrix_sdk/api.rb
CHANGED
@@ -7,14 +7,31 @@ require 'uri'
|
|
7
7
|
|
8
8
|
module MatrixSdk
|
9
9
|
class Api
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
USER_AGENT = "Ruby Matrix SDK v#{MatrixSdk::VERSION}".freeze
|
11
|
+
DEFAULT_HEADERS = {
|
12
|
+
'accept' => 'application/json',
|
13
|
+
'user-agent' => USER_AGENT
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
attr_accessor :access_token, :device_id, :autoretry, :global_headers
|
17
|
+
attr_reader :homeserver, :validate_certificate, :read_timeout
|
18
|
+
|
19
|
+
ignore_inspect :access_token, :logger
|
20
|
+
|
21
|
+
# @param homeserver [String,URI] The URL to the Matrix homeserver, without the /_matrix/ part
|
22
|
+
# @param params [Hash] Additional parameters on creation
|
23
|
+
# @option params [String] :access_token The access token to use for the connection
|
24
|
+
# @option params [String] :device_id The ID of the logged in decide to use
|
25
|
+
# @option params [Boolean] :autoretry (true) Should requests automatically be retried in case of rate limits
|
26
|
+
# @option params [Boolean] :validate_certificate (false) Should the connection require valid SSL certificates
|
27
|
+
# @option params [Integer] :transaction_id (0) The starting ID for transactions
|
28
|
+
# @option params [Numeric] :backoff_time (5000) The request backoff time in milliseconds
|
29
|
+
# @option params [Numeric] :read_timeout (240) The timeout in seconds for reading responses
|
30
|
+
# @option params [Hash] :global_headers Additional headers to set for all requests
|
31
|
+
# @option params [Boolean] :skip_login Should the API skip logging in if the HS URL contains user information
|
15
32
|
def initialize(homeserver, params = {})
|
16
33
|
@homeserver = homeserver
|
17
|
-
@homeserver = URI.parse(@homeserver.
|
34
|
+
@homeserver = URI.parse("#{'https://' unless @homeserver.start_with? 'http'}#{@homeserver}") unless @homeserver.is_a? URI
|
18
35
|
if @homeserver.path.end_with? '_matrix/'
|
19
36
|
@homeserver.path = begin
|
20
37
|
split = @homeserver.path.rpartition '_matrix/'
|
@@ -26,24 +43,41 @@ module MatrixSdk
|
|
26
43
|
|
27
44
|
@access_token = params.fetch(:access_token, nil)
|
28
45
|
@device_id = params.fetch(:device_id, nil)
|
46
|
+
@autoretry = params.fetch(:autoretry, true)
|
29
47
|
@validate_certificate = params.fetch(:validate_certificate, false)
|
30
48
|
@transaction_id = params.fetch(:transaction_id, 0)
|
31
49
|
@backoff_time = params.fetch(:backoff_time, 5000)
|
50
|
+
@read_timeout = params.fetch(:read_timeout, 240)
|
51
|
+
@global_headers = DEFAULT_HEADERS.dup
|
52
|
+
@global_headers.merge!(params.fetch(:global_headers)) if params.key? :global_headers
|
32
53
|
|
33
54
|
login(user: @homeserver.user, password: @homeserver.password) if @homeserver.user && @homeserver.password && !@access_token && !params[:skip_login]
|
34
55
|
@homeserver.userinfo = '' unless params[:skip_login]
|
35
56
|
end
|
36
57
|
|
58
|
+
# Gets the logger for the API
|
59
|
+
# @return [Logging::Logger] The API-scope logger
|
37
60
|
def logger
|
38
|
-
@logger ||= Logging.logger[self
|
61
|
+
@logger ||= Logging.logger[self]
|
62
|
+
end
|
63
|
+
|
64
|
+
# @param seconds [Numeric]
|
65
|
+
# @return [Numeric]
|
66
|
+
def read_timeout=(seconds)
|
67
|
+
@http.finish if @http && @read_timeout != seconds
|
68
|
+
@read_timeout = seconds
|
39
69
|
end
|
40
70
|
|
71
|
+
# @param validate [Boolean]
|
72
|
+
# @return [Boolean]
|
41
73
|
def validate_certificate=(validate)
|
42
74
|
# The HTTP connection needs to be reopened if this changes
|
43
75
|
@http.finish if @http && validate != @validate_certificate
|
44
76
|
@validate_certificate = validate
|
45
77
|
end
|
46
78
|
|
79
|
+
# @param hs_info [URI]
|
80
|
+
# @return [URI]
|
47
81
|
def homeserver=(hs_info)
|
48
82
|
# TODO: DNS query for SRV information about HS?
|
49
83
|
return unless hs_info.is_a? URI
|
@@ -51,10 +85,34 @@ module MatrixSdk
|
|
51
85
|
@homeserver = hs_info
|
52
86
|
end
|
53
87
|
|
54
|
-
|
55
|
-
|
88
|
+
# Gets the available client API versions
|
89
|
+
# @return [Array]
|
90
|
+
def client_api_versions
|
91
|
+
@client_api_versions ||= request(:get, :client, '/versions').versions
|
92
|
+
end
|
93
|
+
|
94
|
+
# Gets the server version
|
95
|
+
# @note This uses the unstable federation/v1 API
|
96
|
+
def server_version
|
97
|
+
Response.new(self, request(:get, :federation_v1, '/version').server).tap do |resp|
|
98
|
+
resp.instance_eval <<-'CODE', __FILE__, __LINE__ - 1
|
99
|
+
def to_s
|
100
|
+
"#{name} #{version}"
|
101
|
+
end
|
102
|
+
CODE
|
103
|
+
end
|
56
104
|
end
|
57
105
|
|
106
|
+
# Runs the client API /sync method
|
107
|
+
# @param params [Hash] The sync options to use
|
108
|
+
# @option params [Numeric] :timeout (30.0) The timeout in seconds for the sync
|
109
|
+
# @option params :since The value of the batch token to base the sync from
|
110
|
+
# @option params [String,Hash] :filter The filter to use on the sync
|
111
|
+
# @option params [Boolean] :full_state Should the sync include the full state
|
112
|
+
# @option params [Boolean] :set_presence Should the sync set the user status to online
|
113
|
+
# @return [Response]
|
114
|
+
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#get-matrix-client-r0-sync
|
115
|
+
# For more information on the parameters and what they mean
|
58
116
|
def sync(params = {})
|
59
117
|
query = {
|
60
118
|
timeout: 30.0
|
@@ -68,29 +126,76 @@ module MatrixSdk
|
|
68
126
|
request(:get, :client_r0, '/sync', query: query)
|
69
127
|
end
|
70
128
|
|
129
|
+
# Registers a user using the client API /register endpoint
|
130
|
+
#
|
131
|
+
# @example Regular user registration and login
|
132
|
+
# api.register(username: 'example', password: 'NotARealPass')
|
133
|
+
# # => { user_id: '@example:matrix.org', access_token: '...', home_server: 'matrix.org', device_id: 'ABCD123' }
|
134
|
+
# api.whoami?
|
135
|
+
# # => { user_id: '@example:matrix.org' }
|
136
|
+
#
|
137
|
+
# @param params [Hash] The registration information, all not handled by Ruby will be passed as JSON in the body
|
138
|
+
# @option params [String,Symbol] :kind ('user') The kind of registration to use
|
139
|
+
# @option params [Boolean] :store_token (true) Should the resulting access token be stored for the API
|
140
|
+
# @option params [Boolean] :store_device_id (store_token value) Should the resulting device ID be stored for the API
|
141
|
+
# @return [Response]
|
142
|
+
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-register
|
143
|
+
# For options that are permitted in this call
|
71
144
|
def register(params = {})
|
72
145
|
kind = params.delete(:kind) { 'user' }
|
146
|
+
store_token = params.delete(:store_token) { true }
|
147
|
+
store_device_id = params.delete(:store_device_id) { store_token }
|
73
148
|
|
74
|
-
request(:post, :client_r0, '/register', body: params, query: { kind: kind })
|
149
|
+
request(:post, :client_r0, '/register', body: params, query: { kind: kind }).tap do |resp|
|
150
|
+
@access_token = resp.token if resp.key?(:token) && store_token
|
151
|
+
@device_id = resp.device_id if resp.key?(:device_id) && store_device_id
|
152
|
+
end
|
75
153
|
end
|
76
154
|
|
155
|
+
# Logs in using the client API /login endpoint, and optionally stores the resulting access for API usage
|
156
|
+
#
|
157
|
+
# @example Logging in with username and password
|
158
|
+
# api.login(user: 'example', password: 'NotARealPass')
|
159
|
+
# # => { user_id: '@example:matrix.org', access_token: '...', home_server: 'matrix.org', device_id: 'ABCD123' }
|
160
|
+
# api.whoami?
|
161
|
+
# # => { user_id: '@example:matrix.org' }
|
162
|
+
#
|
163
|
+
# @example Advanced login, without storing details
|
164
|
+
# api.whoami?
|
165
|
+
# # => { user_id: '@example:matrix.org' }
|
166
|
+
# api.login(medium: 'email', address: 'someone@somewhere.net', password: '...', store_token: false)
|
167
|
+
# # => { user_id: '@someone:matrix.org', access_token: ...
|
168
|
+
# api.whoami?.user_id
|
169
|
+
# # => '@example:matrix.org'
|
170
|
+
#
|
171
|
+
# @param params [Hash] The login information to use, along with options for said log in
|
172
|
+
# @option params [Boolean] :store_token (true) Should the resulting access token be stored for the API
|
173
|
+
# @option params [Boolean] :store_device_id (store_token value) Should the resulting device ID be stored for the API
|
174
|
+
# @option params [String] :login_type ('m.login.password') The type of login to attempt
|
175
|
+
# @option params [String] :initial_device_display_name (USER_AGENT) The device display name to specify for this login attempt
|
176
|
+
# @option params [String] :device_id The device ID to set on the login
|
177
|
+
# @return [Response] A response hash with the parameters :user_id, :access_token, :home_server, and :device_id.
|
178
|
+
# @see https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-login
|
179
|
+
# The Matrix Spec, for more information about the call and response
|
77
180
|
def login(params = {})
|
78
181
|
options = {}
|
79
182
|
options[:store_token] = params.delete(:store_token) { true }
|
80
|
-
options[:store_device_id] = params.delete(:store_device_id) {
|
183
|
+
options[:store_device_id] = params.delete(:store_device_id) { options[:store_token] }
|
81
184
|
|
82
185
|
data = {
|
83
186
|
type: params.delete(:login_type) { 'm.login.password' },
|
84
|
-
initial_device_display_name: params.delete(:initial_device_display_name) {
|
187
|
+
initial_device_display_name: params.delete(:initial_device_display_name) { USER_AGENT }
|
85
188
|
}.merge params
|
86
189
|
data[:device_id] = device_id if device_id
|
87
190
|
|
88
191
|
request(:post, :client_r0, '/login', body: data).tap do |resp|
|
89
|
-
@access_token = resp
|
90
|
-
@device_id = resp
|
192
|
+
@access_token = resp.token if resp.key?(:token) && options[:store_token]
|
193
|
+
@device_id = resp.device_id if resp.key?(:device_id) && options[:store_device_id]
|
91
194
|
end
|
92
195
|
end
|
93
196
|
|
197
|
+
# Logs out the currently logged in user
|
198
|
+
# @return [Response]
|
94
199
|
def logout
|
95
200
|
request(:post, :client_r0, '/logout')
|
96
201
|
end
|
@@ -106,14 +211,20 @@ module MatrixSdk
|
|
106
211
|
end
|
107
212
|
|
108
213
|
def join_room(id_or_alias)
|
109
|
-
|
214
|
+
id_or_alias = CGI.escape id_or_alias.to_s
|
215
|
+
|
216
|
+
request(:post, :client_r0, "/join/#{id_or_alias}")
|
110
217
|
end
|
111
218
|
|
112
219
|
def send_state_event(room_id, event_type, content, params = {})
|
113
220
|
query = {}
|
114
221
|
query[:ts] = params[:timestamp].to_i if params.key? :timestamp
|
115
222
|
|
116
|
-
|
223
|
+
room_id = CGI.escape room_id.to_s
|
224
|
+
event_type = CGI.escape event_type.to_s
|
225
|
+
state_key = CGI.escape params[:state_key].to_s if params.key? :state_key
|
226
|
+
|
227
|
+
request(:put, :client_r0, "/rooms/#{room_id}/state/#{event_type}#{"/#{state_key}" unless state_key.nil?}", body: content, query: query)
|
117
228
|
end
|
118
229
|
|
119
230
|
def send_message_event(room_id, event_type, content, params = {})
|
@@ -123,6 +234,10 @@ module MatrixSdk
|
|
123
234
|
txn_id = transaction_id
|
124
235
|
txn_id = params.fetch(:txn_id, "#{txn_id}#{Time.now.to_i}")
|
125
236
|
|
237
|
+
room_id = CGI.escape room_id.to_s
|
238
|
+
event_type = CGI.escape event_type.to_s
|
239
|
+
txn_id = CGI.escape txn_id.to_s
|
240
|
+
|
126
241
|
request(:put, :client_r0, "/rooms/#{room_id}/send/#{event_type}/#{txn_id}", body: content, query: query)
|
127
242
|
end
|
128
243
|
|
@@ -136,6 +251,10 @@ module MatrixSdk
|
|
136
251
|
txn_id = transaction_id
|
137
252
|
txn_id = params.fetch(:txn_id, "#{txn_id}#{Time.now.to_i}")
|
138
253
|
|
254
|
+
room_id = CGI.escape room_id.to_s
|
255
|
+
event_type = CGI.escape event_type.to_s
|
256
|
+
txn_id = CGI.escape txn_id.to_s
|
257
|
+
|
139
258
|
request(:put, :client_r0, "/rooms/#{room_id}/redact/#{event_type}/#{txn_id}", body: content, query: query)
|
140
259
|
end
|
141
260
|
|
@@ -195,11 +314,20 @@ module MatrixSdk
|
|
195
314
|
}
|
196
315
|
query[:to] = params[:to] if params.key? :to
|
197
316
|
|
317
|
+
room_id = CGI.escape room_id.to_s
|
318
|
+
|
198
319
|
request(:get, :client_r0, "/rooms/#{room_id}/messages", query: query)
|
199
320
|
end
|
200
321
|
|
322
|
+
def get_room_state(room_id, state_type)
|
323
|
+
room_id = CGI.escape room_id.to_s
|
324
|
+
state_type = CGI.escape state_type.to_s
|
325
|
+
|
326
|
+
request(:get, :client_r0, "/rooms/#{room_id}/state/#{state_type}")
|
327
|
+
end
|
328
|
+
|
201
329
|
def get_room_name(room_id)
|
202
|
-
|
330
|
+
get_room_state(room_id, 'm.room.name')
|
203
331
|
end
|
204
332
|
|
205
333
|
def set_room_name(room_id, name, params = {})
|
@@ -210,7 +338,7 @@ module MatrixSdk
|
|
210
338
|
end
|
211
339
|
|
212
340
|
def get_room_topic(room_id)
|
213
|
-
|
341
|
+
get_room_state(room_id, 'm.room.topic')
|
214
342
|
end
|
215
343
|
|
216
344
|
def set_room_topic(room_id, topic, params = {})
|
@@ -221,7 +349,7 @@ module MatrixSdk
|
|
221
349
|
end
|
222
350
|
|
223
351
|
def get_power_levels(room_id)
|
224
|
-
|
352
|
+
get_room_state(room_id, 'm.room.power_levels')
|
225
353
|
end
|
226
354
|
|
227
355
|
def set_power_levels(room_id, content)
|
@@ -230,10 +358,14 @@ module MatrixSdk
|
|
230
358
|
end
|
231
359
|
|
232
360
|
def leave_room(room_id)
|
361
|
+
room_id = CGI.escape room_id.to_s
|
362
|
+
|
233
363
|
request(:post, :client_r0, "/rooms/#{room_id}/leave")
|
234
364
|
end
|
235
365
|
|
236
366
|
def forget_room(room_id)
|
367
|
+
room_id = CGI.escape room_id.to_s
|
368
|
+
|
237
369
|
request(:post, :client_r0, "/rooms/#{room_id}/forget")
|
238
370
|
end
|
239
371
|
|
@@ -241,6 +373,9 @@ module MatrixSdk
|
|
241
373
|
content = {
|
242
374
|
user_id: user_id
|
243
375
|
}
|
376
|
+
|
377
|
+
room_id = CGI.escape room_id.to_s
|
378
|
+
|
244
379
|
request(:post, :client_r0, "/rooms/#{room_id}/invite", body: content)
|
245
380
|
end
|
246
381
|
|
@@ -249,6 +384,9 @@ module MatrixSdk
|
|
249
384
|
end
|
250
385
|
|
251
386
|
def get_membership(room_id, user_id)
|
387
|
+
room_id = CGI.escape room_id.to_s
|
388
|
+
user_id = CGI.escape user_id.to_s
|
389
|
+
|
252
390
|
request(:get, :client_r0, "/rooms/#{room_id}/state/m.room.member/#{user_id}")
|
253
391
|
end
|
254
392
|
|
@@ -268,6 +406,9 @@ module MatrixSdk
|
|
268
406
|
user_id: user_id,
|
269
407
|
reason: params[:reason] || ''
|
270
408
|
}
|
409
|
+
|
410
|
+
room_id = CGI.escape room_id.to_s
|
411
|
+
|
271
412
|
request(:post, :client_r0, "/rooms/#{room_id}/ban", body: content)
|
272
413
|
end
|
273
414
|
|
@@ -275,14 +416,24 @@ module MatrixSdk
|
|
275
416
|
content = {
|
276
417
|
user_id: user_id
|
277
418
|
}
|
419
|
+
|
420
|
+
room_id = CGI.escape room_id.to_s
|
421
|
+
|
278
422
|
request(:post, :client_r0, "/rooms/#{room_id}/unban", body: content)
|
279
423
|
end
|
280
424
|
|
281
425
|
def get_user_tags(user_id, room_id)
|
426
|
+
room_id = CGI.escape room_id.to_s
|
427
|
+
user_id = CGI.escape user_id.to_s
|
428
|
+
|
282
429
|
request(:get, :client_r0, "/user/#{user_id}/rooms/#{room_id}/tags")
|
283
430
|
end
|
284
431
|
|
285
432
|
def remove_user_tag(user_id, room_id, tag)
|
433
|
+
room_id = CGI.escape room_id.to_s
|
434
|
+
user_id = CGI.escape user_id.to_s
|
435
|
+
tag = CGI.escape tag.to_s
|
436
|
+
|
286
437
|
request(:delete, :client_r0, "/user/#{user_id}/rooms/#{room_id}/tags/#{tag}")
|
287
438
|
end
|
288
439
|
|
@@ -293,34 +444,47 @@ module MatrixSdk
|
|
293
444
|
content = {}
|
294
445
|
content[:order] = params[:order] if params.key? :order
|
295
446
|
end
|
447
|
+
|
448
|
+
room_id = CGI.escape room_id.to_s
|
449
|
+
user_id = CGI.escape user_id.to_s
|
450
|
+
tag = CGI.escape tag.to_s
|
451
|
+
|
296
452
|
request(:put, :client_r0, "/user/#{user_id}/rooms/#{room_id}/tags/#{tag}", body: content)
|
297
453
|
end
|
298
454
|
|
299
|
-
def get_account_data(user_id, type)
|
300
|
-
|
301
|
-
end
|
455
|
+
# def get_account_data(user_id, type)
|
456
|
+
# request(:get, :client_r0, "/user/#{user_id}/account_data/#{type}")
|
457
|
+
# end
|
302
458
|
|
303
|
-
def set_account_data(user_id,
|
304
|
-
|
305
|
-
|
459
|
+
def set_account_data(user_id, type_key, account_data)
|
460
|
+
user_id = CGI.escape user_id.to_s
|
461
|
+
type_key = CGI.escape type_key.to_s
|
306
462
|
|
307
|
-
|
308
|
-
request(:get, :client_r0, "/user/#{user_id}/rooms/#{room_id}/account_data/#{type}")
|
463
|
+
request(:put, :client_r0, "/user/#{user_id}/account_data/#{type_key}", body: account_data)
|
309
464
|
end
|
310
465
|
|
311
|
-
def
|
312
|
-
|
313
|
-
end
|
466
|
+
# def get_room_account_data(user_id, room_id, type)
|
467
|
+
# request(:get, :client_r0, "/user/#{user_id}/rooms/#{room_id}/account_data/#{type}")
|
468
|
+
# end
|
469
|
+
|
470
|
+
def set_room_account_data(user_id, room_id, type_key, account_data)
|
471
|
+
user_id = CGI.escape user_id.to_s
|
472
|
+
room_id = CGI.escape room_id.to_s
|
473
|
+
type_key = CGI.escape type_key.to_s
|
314
474
|
|
315
|
-
|
316
|
-
request(:get, :client_r0, "/rooms/#{room_id}/state")
|
475
|
+
request(:put, :client_r0, "/user/#{user_id}/rooms/#{room_id}/account_data/#{type_key}", body: account_data)
|
317
476
|
end
|
318
477
|
|
319
478
|
def get_filter(user_id, filter_id)
|
479
|
+
user_id = CGI.escape user_id.to_s
|
480
|
+
filter_id = CGI.escape filter_id.to_s
|
481
|
+
|
320
482
|
request(:get, :client_r0, "/user/#{user_id}/filter/#{filter_id}")
|
321
483
|
end
|
322
484
|
|
323
485
|
def create_filter(user_id, filter_params)
|
486
|
+
user_id = CGI.escape user_id.to_s
|
487
|
+
|
324
488
|
request(:post, :client_r0, "/user/#{user_id}/filter", body: filter_params)
|
325
489
|
end
|
326
490
|
|
@@ -329,17 +493,24 @@ module MatrixSdk
|
|
329
493
|
end
|
330
494
|
|
331
495
|
def get_display_name(user_id)
|
496
|
+
user_id = CGI.escape user_id.to_s
|
497
|
+
|
332
498
|
request(:get, :client_r0, "/profile/#{user_id}/displayname")
|
333
499
|
end
|
334
500
|
|
335
501
|
def set_display_name(user_id, display_name)
|
336
502
|
content = {
|
337
|
-
|
503
|
+
displayname: display_name
|
338
504
|
}
|
505
|
+
|
506
|
+
user_id = CGI.escape user_id.to_s
|
507
|
+
|
339
508
|
request(:put, :client_r0, "/profile/#{user_id}/displayname", body: content)
|
340
509
|
end
|
341
510
|
|
342
511
|
def get_avatar_url(user_id)
|
512
|
+
user_id = CGI.escape user_id.to_s
|
513
|
+
|
343
514
|
request(:get, :client_r0, "/profile/#{user_id}/avatar_url")
|
344
515
|
end
|
345
516
|
|
@@ -347,6 +518,9 @@ module MatrixSdk
|
|
347
518
|
content = {
|
348
519
|
avatar_url: url
|
349
520
|
}
|
521
|
+
|
522
|
+
user_id = CGI.escape user_id.to_s
|
523
|
+
|
350
524
|
request(:put, :client_r0, "/profile/#{user_id}/avatar_url", body: content)
|
351
525
|
end
|
352
526
|
|
@@ -355,11 +529,14 @@ module MatrixSdk
|
|
355
529
|
raise 'Not a mxc:// URL' unless mxcurl.is_a? URI::MATRIX
|
356
530
|
|
357
531
|
homeserver.dup.tap do |u|
|
358
|
-
|
532
|
+
full_path = CGI.escape mxcurl.full_path.to_s
|
533
|
+
u.path = "/_matrix/media/r0/download/#{full_path}"
|
359
534
|
end
|
360
535
|
end
|
361
536
|
|
362
537
|
def get_room_id(room_alias)
|
538
|
+
room_alias = CGI.escape room_alias.to_s
|
539
|
+
|
363
540
|
request(:get, :client_r0, "/directory/room/#{room_alias}")
|
364
541
|
end
|
365
542
|
|
@@ -367,14 +544,21 @@ module MatrixSdk
|
|
367
544
|
content = {
|
368
545
|
room_id: room_id
|
369
546
|
}
|
547
|
+
|
548
|
+
room_alias = CGI.escape room_alias.to_s
|
549
|
+
|
370
550
|
request(:put, :client_r0, "/directory/room/#{room_alias}", body: content)
|
371
551
|
end
|
372
552
|
|
373
553
|
def remove_room_alias(room_alias)
|
554
|
+
room_alias = CGI.escape room_alias.to_s
|
555
|
+
|
374
556
|
request(:delete, :client_r0, "/directory/room/#{room_alias}")
|
375
557
|
end
|
376
558
|
|
377
559
|
def get_room_members(room_id)
|
560
|
+
room_id = CGI.escape room_id.to_s
|
561
|
+
|
378
562
|
request(:get, :client_r0, "/rooms/#{room_id}/members")
|
379
563
|
end
|
380
564
|
|
@@ -382,6 +566,7 @@ module MatrixSdk
|
|
382
566
|
content = {
|
383
567
|
join_rule: join_rule
|
384
568
|
}
|
569
|
+
|
385
570
|
send_state_event(room_id, 'm.room.join_rules', content)
|
386
571
|
end
|
387
572
|
|
@@ -400,7 +585,7 @@ module MatrixSdk
|
|
400
585
|
def request(method, api, path, options = {})
|
401
586
|
url = homeserver.dup.tap do |u|
|
402
587
|
u.path = api_to_path(api) + path
|
403
|
-
u.query = [u.query, options
|
588
|
+
u.query = [u.query, URI.encode_www_form(options.fetch(:query))].flatten.compact.join('&') if options[:query]
|
404
589
|
u.query = nil if u.query.nil? || u.query.empty?
|
405
590
|
end
|
406
591
|
request = Net::HTTP.const_get(method.to_s.capitalize.to_sym).new url.request_uri
|
@@ -408,10 +593,13 @@ module MatrixSdk
|
|
408
593
|
request.body = request.body.to_json if options.key?(:body) && !request.body.is_a?(String)
|
409
594
|
request.body_stream = options[:body_stream] if options.key? :body_stream
|
410
595
|
|
411
|
-
|
596
|
+
global_headers.each { |h, v| request[h] = v }
|
597
|
+
if request.body || request.body_stream
|
598
|
+
request.content_type = 'application/json'
|
599
|
+
request.content_length = (request.body || request.body_stream).size
|
600
|
+
end
|
412
601
|
|
413
602
|
request['authorization'] = "Bearer #{access_token}" if access_token
|
414
|
-
request['user-agent'] = user_agent
|
415
603
|
if options.key? :headers
|
416
604
|
options[:headers].each do |h, v|
|
417
605
|
request[h.to_s.downcase] = v
|
@@ -428,13 +616,14 @@ module MatrixSdk
|
|
428
616
|
data = JSON.parse(response.body, symbolize_names: true) rescue nil
|
429
617
|
|
430
618
|
if response.is_a? Net::HTTPTooManyRequests
|
619
|
+
raise MatrixRequestError.new(data, response.code) unless autoretry
|
431
620
|
failures += 1
|
432
621
|
waittime = data[:retry_after_ms] || data[:error][:retry_after_ms] || @backoff_time
|
433
622
|
sleep(waittime.to_f / 1000.0)
|
434
623
|
next
|
435
624
|
end
|
436
625
|
|
437
|
-
return data if response.is_a? Net::HTTPSuccess
|
626
|
+
return MatrixSdk::Response.new self, data if response.is_a? Net::HTTPSuccess
|
438
627
|
raise MatrixRequestError.new(data, response.code) if data
|
439
628
|
raise MatrixConnectionError, response
|
440
629
|
end
|
@@ -443,6 +632,8 @@ module MatrixSdk
|
|
443
632
|
private
|
444
633
|
|
445
634
|
def print_http(http)
|
635
|
+
return unless logger.debug?
|
636
|
+
|
446
637
|
if http.is_a? Net::HTTPRequest
|
447
638
|
dir = '>'
|
448
639
|
logger.debug "#{dir} Sending a #{http.method} request to `#{http.path}`:"
|
@@ -450,11 +641,12 @@ module MatrixSdk
|
|
450
641
|
dir = '<'
|
451
642
|
logger.debug "#{dir} Received a #{http.code} #{http.message} response:"
|
452
643
|
end
|
453
|
-
http.to_hash.map { |k, v| "#{k}: #{k == 'authorization' ? '[
|
644
|
+
http.to_hash.map { |k, v| "#{k}: #{k == 'authorization' ? '[ REDACTED ]' : v.join(', ')}" }.each do |h|
|
454
645
|
logger.debug "#{dir} #{h}"
|
455
646
|
end
|
456
647
|
logger.debug dir
|
457
|
-
|
648
|
+
clean_body = JSON.parse(http.body).each { |k, v| v.replace('[ REDACTED ]') if %w[password access_token].include? k }.to_json if http.body
|
649
|
+
logger.debug "#{dir} #{clean_body.length < 200 ? clean_body : clean_body.slice(0..200) + "... [truncated, #{clean_body.length} Bytes]"}" if clean_body
|
458
650
|
end
|
459
651
|
|
460
652
|
def transaction_id
|
@@ -472,13 +664,10 @@ module MatrixSdk
|
|
472
664
|
@http ||= Net::HTTP.new homeserver.host, homeserver.port
|
473
665
|
return @http if @http.active?
|
474
666
|
|
667
|
+
@http.read_timeout = read_timeout
|
475
668
|
@http.use_ssl = homeserver.scheme == 'https'
|
476
669
|
@http.verify_mode = validate_certificate ? ::OpenSSL::SSL::VERIFY_NONE : nil
|
477
670
|
@http.start
|
478
671
|
end
|
479
|
-
|
480
|
-
def user_agent
|
481
|
-
"Ruby Matrix SDK v#{MatrixSdk::VERSION}"
|
482
|
-
end
|
483
672
|
end
|
484
673
|
end
|
data/lib/matrix_sdk/client.rb
CHANGED
@@ -7,13 +7,13 @@ module MatrixSdk
|
|
7
7
|
extend Forwardable
|
8
8
|
|
9
9
|
attr_reader :api
|
10
|
-
|
10
|
+
attr_writer :mxid
|
11
|
+
attr_accessor :cache, :sync_filter
|
11
12
|
|
12
13
|
events :event, :presence_event, :invite_event, :left_event, :ephemeral_event
|
13
14
|
ignore_inspect :api,
|
14
15
|
:on_event, :on_presence_event, :on_invite_event, :on_left_event, :on_ephemeral_event
|
15
16
|
|
16
|
-
alias user_id mxid
|
17
17
|
alias user_id= mxid=
|
18
18
|
|
19
19
|
def_delegators :@api,
|
@@ -23,19 +23,27 @@ module MatrixSdk
|
|
23
23
|
def initialize(hs_url, params = {})
|
24
24
|
event_initialize
|
25
25
|
|
26
|
-
params[:user_id]
|
27
|
-
raise ArgumentError, 'Must provide user_id with access_token' if params[:access_token] && !params[:user_id]
|
26
|
+
params[:user_id] ||= params[:mxid] if params[:mxid]
|
28
27
|
|
29
|
-
|
28
|
+
if hs_url.is_a? Api
|
29
|
+
@api = hs_url
|
30
|
+
params.each do |k, v|
|
31
|
+
api.instance_variable_set("@#{k}", v) if api.instance_variable_defined? "@#{k}"
|
32
|
+
end
|
33
|
+
else
|
34
|
+
@api = Api.new hs_url, params
|
35
|
+
end
|
30
36
|
|
31
37
|
@rooms = {}
|
32
|
-
@
|
38
|
+
@users = {}
|
39
|
+
@cache = params.fetch(:client_cache, :all)
|
33
40
|
|
34
41
|
@sync_token = nil
|
35
42
|
@sync_thread = nil
|
36
43
|
@sync_filter = { room: { timeline: { limit: params.fetch(:sync_filter_limit, 20) } } }
|
37
44
|
|
38
45
|
@should_listen = false
|
46
|
+
@next_batch = nil
|
39
47
|
|
40
48
|
@bad_sync_timeout_limit = 60 * 60
|
41
49
|
|
@@ -47,13 +55,20 @@ module MatrixSdk
|
|
47
55
|
|
48
56
|
return unless params[:user_id]
|
49
57
|
@mxid = params[:user_id]
|
50
|
-
sync
|
51
58
|
end
|
52
59
|
|
53
60
|
def logger
|
54
|
-
@logger ||= Logging.logger[self
|
61
|
+
@logger ||= Logging.logger[self]
|
62
|
+
end
|
63
|
+
|
64
|
+
def mxid
|
65
|
+
@mxid ||= begin
|
66
|
+
api.whoami?[:user_id] if api && api.access_token
|
67
|
+
end
|
55
68
|
end
|
56
69
|
|
70
|
+
alias user_id mxid
|
71
|
+
|
57
72
|
def rooms
|
58
73
|
@rooms.values
|
59
74
|
end
|
@@ -72,7 +87,7 @@ module MatrixSdk
|
|
72
87
|
data = api.login(user: username, password: password)
|
73
88
|
post_authentication(data)
|
74
89
|
|
75
|
-
sync(timeout: params.fetch(:sync_timeout, 15)) unless params[:no_sync]
|
90
|
+
sync(timeout: params.fetch(:sync_timeout, 15), full_state: params.fetch(:full_state, false)) unless params[:no_sync]
|
76
91
|
end
|
77
92
|
|
78
93
|
def logout
|
@@ -81,6 +96,10 @@ module MatrixSdk
|
|
81
96
|
@mxid = nil
|
82
97
|
end
|
83
98
|
|
99
|
+
def logged_in?
|
100
|
+
!(mxid.nil? || @api.access_token.nil?)
|
101
|
+
end
|
102
|
+
|
84
103
|
def create_room(room_alias = nil, params = {})
|
85
104
|
api.create_room(params.merge(room_alias: room_alias))
|
86
105
|
end
|
@@ -95,7 +114,11 @@ module MatrixSdk
|
|
95
114
|
end
|
96
115
|
|
97
116
|
def get_user(user_id)
|
98
|
-
|
117
|
+
if cache == :all
|
118
|
+
@users[user_id] ||= User.new(self, user_id)
|
119
|
+
else
|
120
|
+
User.new(self, user_id)
|
121
|
+
end
|
99
122
|
end
|
100
123
|
|
101
124
|
def remove_room_alias(room_alias)
|
@@ -108,8 +131,8 @@ module MatrixSdk
|
|
108
131
|
raise MatrixUnexpectedResponseError, 'Upload succeeded, but no media URI returned'
|
109
132
|
end
|
110
133
|
|
111
|
-
def listen_for_events(timeout = 30)
|
112
|
-
sync(timeout: timeout)
|
134
|
+
def listen_for_events(timeout = 30, arguments = {})
|
135
|
+
sync(arguments.merge(timeout: timeout))
|
113
136
|
end
|
114
137
|
|
115
138
|
def start_listener_thread(params = {})
|
@@ -131,12 +154,14 @@ module MatrixSdk
|
|
131
154
|
def listen_forever(params = {})
|
132
155
|
timeout = params.fetch(:timeout, 30)
|
133
156
|
params[:bad_sync_timeout] = params.fetch(:bad_sync_timeout, 5)
|
157
|
+
params[:sync_interval] = params.fetch(:sync_interval, 30)
|
134
158
|
|
135
159
|
bad_sync_timeout = params[:bad_sync_timeout]
|
136
160
|
while @should_listen
|
137
161
|
begin
|
138
162
|
sync(timeout: timeout)
|
139
163
|
bad_sync_timeout = params[:bad_sync_timeout]
|
164
|
+
sleep(params[:sync_interval]) if params[:sync_interval] > 0
|
140
165
|
rescue MatrixRequestError => ex
|
141
166
|
logger.warn("A #{ex.class} occurred during sync")
|
142
167
|
if ex.httpstatus >= 500
|
@@ -191,7 +216,12 @@ module MatrixSdk
|
|
191
216
|
end
|
192
217
|
|
193
218
|
def sync(params = {})
|
194
|
-
|
219
|
+
extra_params = {
|
220
|
+
filter: sync_filter.to_json
|
221
|
+
}
|
222
|
+
extra_params[:since] = @next_batch unless @next_batch.nil?
|
223
|
+
data = api.sync params.merge(extra_params)
|
224
|
+
@next_batch = data[:next_batch]
|
195
225
|
|
196
226
|
data[:presence][:events].each do |presence_update|
|
197
227
|
fire_presence_event(MatrixEvent.new(self, presence_update))
|
@@ -52,13 +52,23 @@ end
|
|
52
52
|
def ignore_inspect(*symbols)
|
53
53
|
class_eval %*
|
54
54
|
def inspect
|
55
|
-
"
|
55
|
+
"\#{to_s[0..-2]} \#{instance_variables
|
56
|
+
.reject { |f| %i[#{symbols.map { |s| "@#{s}" }.join ' '}].include? f }
|
57
|
+
.map { |f| "\#{f}=\#{instance_variable_get(f).inspect}" }.join " " }}>"
|
56
58
|
end
|
57
59
|
*, __FILE__, __LINE__ - 4
|
58
60
|
end
|
59
61
|
|
60
62
|
module MatrixSdk
|
61
63
|
class EventHandlerArray < Hash
|
64
|
+
attr_accessor :reraise_exceptions
|
65
|
+
|
66
|
+
def initialize(*args)
|
67
|
+
@reraise_exceptions = false
|
68
|
+
|
69
|
+
super(*args)
|
70
|
+
end
|
71
|
+
|
62
72
|
def add_handler(filter = nil, id = nil, &block)
|
63
73
|
id ||= block.hash
|
64
74
|
self[id] = { filter: filter, id: id, block: block }
|
@@ -70,9 +80,19 @@ module MatrixSdk
|
|
70
80
|
|
71
81
|
def fire(event, filter = nil)
|
72
82
|
reverse_each do |_k, h|
|
73
|
-
|
83
|
+
begin
|
84
|
+
h[:block].call(event) if event.matches?(h[:filter], filter)
|
85
|
+
rescue StandardError => ex
|
86
|
+
logger.error "#{ex.class.name} occurred when firing event (#{event})\n#{ex}"
|
87
|
+
|
88
|
+
raise ex if @reraise_exceptions
|
89
|
+
end
|
74
90
|
end
|
75
91
|
end
|
92
|
+
|
93
|
+
def logger
|
94
|
+
@logger ||= Logging.logger[self]
|
95
|
+
end
|
76
96
|
end
|
77
97
|
|
78
98
|
class Event
|
@@ -115,5 +135,22 @@ module MatrixSdk
|
|
115
135
|
to_match == filter
|
116
136
|
end
|
117
137
|
end
|
138
|
+
|
139
|
+
def [](key)
|
140
|
+
event[key]
|
141
|
+
end
|
142
|
+
|
143
|
+
def to_s
|
144
|
+
"#{event[:type]}: #{event.reject { |k, _v| k == :type }.to_json}"
|
145
|
+
end
|
146
|
+
|
147
|
+
def method_missing(method, *args)
|
148
|
+
return event[method] if event.key? method
|
149
|
+
super
|
150
|
+
end
|
151
|
+
|
152
|
+
def respond_to_missing?(method)
|
153
|
+
event.key? method
|
154
|
+
end
|
118
155
|
end
|
119
156
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module MatrixSdk
|
2
|
+
# An usability wrapper for API responses as an extended [Hash]
|
3
|
+
# All results can be read as both hash keys and as read-only methods on the key
|
4
|
+
#
|
5
|
+
# @example Simple usage of the response wrapper to get the avatar URL
|
6
|
+
# resp = api.get_avatar_url(api.whoami?.user_id)
|
7
|
+
# # => { avatar_url: 'mxc://matrix.org/SDGdghriugerRg' }
|
8
|
+
# resp.is_a? Hash
|
9
|
+
# # => true
|
10
|
+
# resp.key? :avatar_url
|
11
|
+
# # => true
|
12
|
+
# resp.avatar_url
|
13
|
+
# # => 'mxc://matrix.org/SDGdghriugerRg'
|
14
|
+
# resp.api.set_avatar_url(...)
|
15
|
+
# # => {}
|
16
|
+
#
|
17
|
+
# @since 0.0.3
|
18
|
+
# @see Hash
|
19
|
+
# @!attribute [r] api
|
20
|
+
# @return [Api] The API connection that returned the response
|
21
|
+
module Response
|
22
|
+
def self.new(api, data)
|
23
|
+
data.extend(Extensions)
|
24
|
+
data.instance_variable_set(:@api, api)
|
25
|
+
data
|
26
|
+
end
|
27
|
+
|
28
|
+
module Extensions
|
29
|
+
attr_reader :api
|
30
|
+
|
31
|
+
def respond_to_missing?(name, *_args)
|
32
|
+
key? name
|
33
|
+
end
|
34
|
+
|
35
|
+
def method_missing(name, *args)
|
36
|
+
return fetch(name) if key?(name) && args.empty?
|
37
|
+
super
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/matrix_sdk/room.rb
CHANGED
@@ -78,7 +78,7 @@ module MatrixSdk
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def logger
|
81
|
-
Logging.logger[self
|
81
|
+
@logger ||= Logging.logger[self]
|
82
82
|
end
|
83
83
|
|
84
84
|
#
|
@@ -261,34 +261,54 @@ module MatrixSdk
|
|
261
261
|
# User Management
|
262
262
|
#
|
263
263
|
|
264
|
+
# Invites a user into the room
|
265
|
+
# @param user_id [String,User] the MXID of the user
|
266
|
+
# @return [Boolean] wether the action succeeded
|
264
267
|
def invite_user(user_id)
|
268
|
+
user_id = user_id.id if user_id.is_a? MatrixSdk::User
|
265
269
|
client.api.invite_user(id, user_id)
|
266
270
|
true
|
267
271
|
rescue MatrixError
|
268
272
|
false
|
269
273
|
end
|
270
274
|
|
275
|
+
# Kicks a user from the room
|
276
|
+
# @param user_id [String,User] the MXID of the user
|
277
|
+
# @param reason [String] the reason for the kick
|
278
|
+
# @return [Boolean] wether the action succeeded
|
271
279
|
def kick_user(user_id, reason = '')
|
280
|
+
user_id = user_id.id if user_id.is_a? MatrixSdk::User
|
272
281
|
client.api.kick_user(id, user_id, reason: reason)
|
273
282
|
true
|
274
283
|
rescue MatrixError
|
275
284
|
false
|
276
285
|
end
|
277
286
|
|
287
|
+
# Bans a user from the room
|
288
|
+
# @param user_id [String,User] the MXID of the user
|
289
|
+
# @param reason [String] the reason for the ban
|
290
|
+
# @return [Boolean] wether the action succeeded
|
278
291
|
def ban_user(user_id, reason = '')
|
292
|
+
user_id = user_id.id if user_id.is_a? MatrixSdk::User
|
279
293
|
client.api.ban_user(id, user_id, reason: reason)
|
280
294
|
true
|
281
295
|
rescue MatrixError
|
282
296
|
false
|
283
297
|
end
|
284
298
|
|
299
|
+
# Unbans a user from the room
|
300
|
+
# @param user_id [String,User] the MXID of the user
|
301
|
+
# @return [Boolean] wether the action succeeded
|
285
302
|
def unban_user(user_id)
|
303
|
+
user_id = user_id.id if user_id.is_a? MatrixSdk::User
|
286
304
|
client.api.unban_user(id, user_id)
|
287
305
|
true
|
288
306
|
rescue MatrixError
|
289
307
|
false
|
290
308
|
end
|
291
309
|
|
310
|
+
# Requests to be removed from the room
|
311
|
+
# @return [Boolean] wether the request succeeded
|
292
312
|
def leave
|
293
313
|
client.api.leave_room(id)
|
294
314
|
client.rooms.delete id
|
@@ -297,14 +317,25 @@ module MatrixSdk
|
|
297
317
|
false
|
298
318
|
end
|
299
319
|
|
320
|
+
# Retrieves a custom entry from the room-specific account data
|
321
|
+
# @param type [String] the data type to retrieve
|
322
|
+
# @return [Hash] the data that was stored under the given type
|
300
323
|
def get_account_data(type)
|
301
324
|
client.api.get_room_account_data(client.mxid, id, type)
|
302
325
|
end
|
303
326
|
|
327
|
+
# Stores a custom entry into the room-specific account data
|
328
|
+
# @param type [String] the data type to store
|
329
|
+
# @param account_data [Hash] the data to store
|
304
330
|
def set_account_data(type, account_data)
|
305
331
|
client.api.set_room_account_data(client.mxid, id, type, account_data)
|
306
332
|
end
|
307
333
|
|
334
|
+
# Changes the room-specific user profile
|
335
|
+
# @param params [Hash] the user profile changes to apply
|
336
|
+
# @option params [String] :display_name the new display name to use in the room
|
337
|
+
# @option params [String,URI] :avatar_url the new avatar URL to use in the room
|
338
|
+
# @note the avatar URL should be a mxc:// URI
|
308
339
|
def set_user_profile(params = {})
|
309
340
|
return nil unless params[:display_name] || params[:avatar_url]
|
310
341
|
data = client.api.get_membership(id, client.mxid)
|
@@ -339,6 +370,8 @@ module MatrixSdk
|
|
339
370
|
nil
|
340
371
|
end
|
341
372
|
|
373
|
+
# Reloads the name of the room
|
374
|
+
# @return [Boolean] if the name was changed or not
|
342
375
|
def reload_name!
|
343
376
|
data = client.api.get_room_name(id)
|
344
377
|
changed = data[:name] != name
|
@@ -355,6 +388,8 @@ module MatrixSdk
|
|
355
388
|
nil
|
356
389
|
end
|
357
390
|
|
391
|
+
# Reloads the topic of the room
|
392
|
+
# @return [Boolean] if the topic was changed or not
|
358
393
|
def reload_topic!
|
359
394
|
data = client.api.get_room_topic(id)
|
360
395
|
changed = data[:topic] != topic
|
@@ -395,7 +430,7 @@ module MatrixSdk
|
|
395
430
|
|
396
431
|
def invite_only=(invite_only)
|
397
432
|
self.join_rule = invite_only ? :invite : :public
|
398
|
-
@join_rule == :invite
|
433
|
+
@join_rule == :invite
|
399
434
|
end
|
400
435
|
|
401
436
|
def join_rule=(join_rule)
|
@@ -407,7 +442,7 @@ module MatrixSdk
|
|
407
442
|
|
408
443
|
def allow_guests=(allow_guests)
|
409
444
|
self.guest_access = (allow_guests ? :can_join : :forbidden)
|
410
|
-
@guest_access == :can_join
|
445
|
+
@guest_access == :can_join
|
411
446
|
end
|
412
447
|
|
413
448
|
def guest_access=(guest_access)
|
@@ -417,6 +452,10 @@ module MatrixSdk
|
|
417
452
|
nil
|
418
453
|
end
|
419
454
|
|
455
|
+
# Modifies the power levels of the room
|
456
|
+
# @param users [Hash] the user-specific power levels to set or remove
|
457
|
+
# @param users_default [Hash] the default user power levels to set
|
458
|
+
# @return [Boolean] if the change was successful
|
420
459
|
def modify_user_power_levels(users = nil, users_default = nil)
|
421
460
|
return false if users.nil? && users_default.nil?
|
422
461
|
data = client.api.get_power_levels(id)
|
@@ -434,6 +473,10 @@ module MatrixSdk
|
|
434
473
|
false
|
435
474
|
end
|
436
475
|
|
476
|
+
# Modifies the required power levels for actions in the room
|
477
|
+
# @param events [Hash] the event-specific power levels to change
|
478
|
+
# @param params [Hash] other power-level params to change
|
479
|
+
# @return [Boolean] if the change was successful
|
437
480
|
def modify_required_power_levels(events = nil, params = {})
|
438
481
|
return false if events.nil? && (params.nil? || params.empty?)
|
439
482
|
data = client.api.get_power_levels(id)
|
data/lib/matrix_sdk/user.rb
CHANGED
@@ -3,9 +3,17 @@ require 'matrix_sdk'
|
|
3
3
|
module MatrixSdk
|
4
4
|
# A class for tracking information about a user on Matrix
|
5
5
|
class User
|
6
|
+
# @!attribute [r] id
|
7
|
+
# @return [String] the MXID of the user
|
8
|
+
# @!attribute [r] client
|
9
|
+
# @return [Client] the client for the user
|
6
10
|
attr_reader :id, :client
|
7
11
|
alias user_id :id
|
8
12
|
|
13
|
+
# @!method inspect
|
14
|
+
# An inspect method that skips a handful of instance variables to avoid
|
15
|
+
# flooding the terminal with debug data.
|
16
|
+
# @return [String] a regular inspect string without the data for some variables
|
9
17
|
ignore_inspect :client
|
10
18
|
|
11
19
|
def initialize(client, id, data = {})
|
@@ -20,10 +28,14 @@ module MatrixSdk
|
|
20
28
|
end
|
21
29
|
end
|
22
30
|
|
31
|
+
# @!attribute [r] display_name
|
32
|
+
# @return [String] the display name
|
23
33
|
def display_name
|
24
34
|
@display_name ||= client.api.get_display_name(id)[:displayname]
|
25
35
|
end
|
26
36
|
|
37
|
+
# @!attribute [w] display_name
|
38
|
+
# @param name [String] the display name to set
|
27
39
|
def display_name=(name)
|
28
40
|
client.api.set_display_name(id, name)
|
29
41
|
@display_name = name
|
@@ -31,14 +43,18 @@ module MatrixSdk
|
|
31
43
|
nil
|
32
44
|
end
|
33
45
|
|
46
|
+
# Gets a friendly name of the user
|
47
|
+
# @return [String] either the display name or MXID if unset
|
34
48
|
def friendly_name
|
35
49
|
display_name || id
|
36
50
|
end
|
37
51
|
|
52
|
+
# @!attribute [r] avatar_url
|
38
53
|
def avatar_url
|
39
54
|
@avatar_url ||= client.api.get_avatar_url(id)[:avatar_url]
|
40
55
|
end
|
41
56
|
|
57
|
+
# @!attribute [w] avatar_url
|
42
58
|
def avatar_url=(url)
|
43
59
|
client.api.set_avatar_url(id, url)
|
44
60
|
@avatar_url = url
|
data/lib/matrix_sdk/version.rb
CHANGED
data/lib/matrix_sdk.rb
CHANGED
@@ -6,6 +6,7 @@ autoload :Logging, 'logging'
|
|
6
6
|
module MatrixSdk
|
7
7
|
autoload :Api, 'matrix_sdk/api'
|
8
8
|
autoload :Client, 'matrix_sdk/client'
|
9
|
+
autoload :Response, 'matrix_sdk/response'
|
9
10
|
autoload :Room, 'matrix_sdk/room'
|
10
11
|
autoload :User, 'matrix_sdk/user'
|
11
12
|
|
@@ -19,9 +20,9 @@ module MatrixSdk
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def self.logger
|
22
|
-
@logger ||= Logging.logger[
|
23
|
+
@logger ||= Logging.logger[self].tap do |logger|
|
23
24
|
logger.add_appenders Logging.appenders.stdout
|
24
|
-
logger.level = :
|
25
|
+
logger.level = :info
|
25
26
|
end
|
26
27
|
end
|
27
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: matrix_sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Olofsson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logging
|
@@ -74,8 +74,10 @@ extensions: []
|
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
76
|
- ".gitignore"
|
77
|
+
- ".gitlab-ci.yml"
|
77
78
|
- ".rubocop.yml"
|
78
79
|
- ".travis.yml"
|
80
|
+
- CHANGELOG.md
|
79
81
|
- Gemfile
|
80
82
|
- LICENSE.txt
|
81
83
|
- README.md
|
@@ -86,6 +88,7 @@ files:
|
|
86
88
|
- lib/matrix_sdk/client.rb
|
87
89
|
- lib/matrix_sdk/errors.rb
|
88
90
|
- lib/matrix_sdk/extensions.rb
|
91
|
+
- lib/matrix_sdk/response.rb
|
89
92
|
- lib/matrix_sdk/room.rb
|
90
93
|
- lib/matrix_sdk/user.rb
|
91
94
|
- lib/matrix_sdk/version.rb
|