matrix_sdk 2.4.0 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +17 -2
- data/lib/matrix_sdk/api.rb +60 -18
- data/lib/matrix_sdk/bot/base.rb +843 -0
- data/lib/matrix_sdk/bot/main.rb +79 -0
- data/lib/matrix_sdk/bot.rb +4 -0
- data/lib/matrix_sdk/client.rb +44 -12
- data/lib/matrix_sdk/mxid.rb +3 -1
- data/lib/matrix_sdk/protocols/cs.rb +132 -106
- data/lib/matrix_sdk/protocols/msc.rb +5 -0
- data/lib/matrix_sdk/response.rb +2 -0
- data/lib/matrix_sdk/room.rb +140 -40
- data/lib/matrix_sdk/rooms/space.rb +3 -3
- data/lib/matrix_sdk/user.rb +25 -3
- data/lib/matrix_sdk/util/account_data_cache.rb +91 -0
- data/lib/matrix_sdk/util/extensions.rb +16 -6
- data/lib/matrix_sdk/util/tinycache.rb +20 -4
- data/lib/matrix_sdk/util/tinycache_adapter.rb +5 -1
- data/lib/matrix_sdk/util/uri.rb +16 -4
- data/lib/matrix_sdk/version.rb +1 -1
- data/lib/matrix_sdk.rb +11 -1
- metadata +7 -3
@@ -60,7 +60,9 @@ module MatrixSdk::Protocols::MSC
|
|
60
60
|
# rubocop:disable Metrics/BlockLength
|
61
61
|
thread = Thread.new(cancellation_token) do |ctx|
|
62
62
|
print_http(req)
|
63
|
+
@http_lock&.lock
|
63
64
|
http.request req do |response|
|
65
|
+
@http_lock&.unlock
|
64
66
|
break unless ctx[:run]
|
65
67
|
|
66
68
|
print_http(response, body: false)
|
@@ -134,8 +136,11 @@ module MatrixSdk::Protocols::MSC
|
|
134
136
|
break
|
135
137
|
end
|
136
138
|
end
|
139
|
+
|
137
140
|
break unless ctx[:run]
|
138
141
|
end
|
142
|
+
ensure
|
143
|
+
@http_lock.unlock if @http_lock&.owned?
|
139
144
|
end
|
140
145
|
# rubocop:enable Metrics/BlockLength
|
141
146
|
|
data/lib/matrix_sdk/response.rb
CHANGED
data/lib/matrix_sdk/room.rb
CHANGED
@@ -31,9 +31,11 @@ module MatrixSdk
|
|
31
31
|
ignore_inspect :client, :events, :prev_batch, :logger, :tinycache_adapter
|
32
32
|
|
33
33
|
# Requires heavy lookups, so they're cached for an hour
|
34
|
-
cached :joined_members,
|
35
|
-
|
36
|
-
|
34
|
+
cached :joined_members, cache_level: :all, expires_in: 60 * 60
|
35
|
+
|
36
|
+
# Only cache unfiltered requests for aliases and members
|
37
|
+
cached :aliases, unless: proc { |args| args.any? }, cache_level: :all, expires_in: 60 * 60
|
38
|
+
cached :all_members, unless: proc { |args| args.any? }, cache_level: :all, expires_in: 60 * 60
|
37
39
|
|
38
40
|
# Much simpler to look up, and lighter data-wise, so the cache is wider
|
39
41
|
cached :canonical_alias, :name, :avatar_url, :topic, :guest_access, :join_rule, :power_levels, cache_level: :some, expires_in: 15 * 60
|
@@ -53,7 +55,7 @@ module MatrixSdk
|
|
53
55
|
# @option data [String] :topic The current topic of the room
|
54
56
|
# @option data [String,MXID] :canonical_alias The canonical alias of the room
|
55
57
|
# @option data [Array(String,MXID)] :aliases All non-canonical aliases of the room
|
56
|
-
# @option data [:invite,:public] :join_rule The join rule for the room
|
58
|
+
# @option data [:invite,:public,:knock] :join_rule The join rule for the room
|
57
59
|
# @option data [:can_join,:forbidden] :guest_access The guest access setting for the room
|
58
60
|
# @option data [Boolean] :world_readable If the room is readable by the entire world
|
59
61
|
# @option data [Array(User)] :members The list of joined members
|
@@ -125,6 +127,12 @@ module MatrixSdk
|
|
125
127
|
ensure_room_handlers[:event]
|
126
128
|
end
|
127
129
|
|
130
|
+
# @!attribute [r] on_account_data
|
131
|
+
# @return [EventHandlerArray] The list of event handlers for account data changes
|
132
|
+
def on_account_data
|
133
|
+
ensure_room_handlers[:account_data]
|
134
|
+
end
|
135
|
+
|
128
136
|
# @!attribute [r] on_state_event
|
129
137
|
# @return [EventHandlerArray] The list of event handlers for only state events
|
130
138
|
def on_state_event
|
@@ -206,6 +214,32 @@ module MatrixSdk
|
|
206
214
|
nil
|
207
215
|
end
|
208
216
|
|
217
|
+
# Checks if the room is a direct message / 1:1 room
|
218
|
+
#
|
219
|
+
# @param members_only [Boolean] Should directness only care about member count?
|
220
|
+
# @return [Boolean]
|
221
|
+
def dm?(members_only: false)
|
222
|
+
return true if !members_only && client.direct_rooms.any? { |_uid, rooms| rooms.include? id.to_s }
|
223
|
+
|
224
|
+
joined_members.count <= 2
|
225
|
+
end
|
226
|
+
|
227
|
+
# Mark a room as a direct (1:1) message Room
|
228
|
+
def dm=(direct)
|
229
|
+
rooms = client.direct_rooms
|
230
|
+
dirty = false
|
231
|
+
list_for_room = (rooms[id.to_s] ||= [])
|
232
|
+
if direct && !list_for_room.include?(id.to_s)
|
233
|
+
list_for_room << id.to_s
|
234
|
+
dirty = true
|
235
|
+
elsif !direct && list_for_room.include?(id.to_s)
|
236
|
+
list_for_room.delete id.to_s
|
237
|
+
rooms.delete id.to_s if list_for_room.empty?
|
238
|
+
dirty = true
|
239
|
+
end
|
240
|
+
client.account_data['m.direct'] = rooms if dirty
|
241
|
+
end
|
242
|
+
|
209
243
|
# Gets the avatar url of the room - if any
|
210
244
|
#
|
211
245
|
# @return [String,nil] The avatar URL - if any
|
@@ -230,14 +264,14 @@ module MatrixSdk
|
|
230
264
|
#
|
231
265
|
# @return [:can_join,:forbidden] The current guest access right
|
232
266
|
def guest_access
|
233
|
-
client.api.get_room_guest_access(id)[:guest_access]
|
267
|
+
client.api.get_room_guest_access(id)[:guest_access]&.to_sym
|
234
268
|
end
|
235
269
|
|
236
270
|
# Gets the join rule for the room
|
237
271
|
#
|
238
272
|
# @return [:public,:knock,:invite,:private] The current join rule
|
239
273
|
def join_rule
|
240
|
-
client.api.get_room_join_rules(id)[:join_rule]
|
274
|
+
client.api.get_room_join_rules(id)[:join_rule]&.to_sym
|
241
275
|
end
|
242
276
|
|
243
277
|
# Checks if +guest_access+ is set to +:can_join+
|
@@ -250,11 +284,16 @@ module MatrixSdk
|
|
250
284
|
join_rule == :invite
|
251
285
|
end
|
252
286
|
|
287
|
+
# Checks if +join_rule+ is set to +:knock+
|
288
|
+
def knock_only?
|
289
|
+
join_rule == :knock
|
290
|
+
end
|
291
|
+
|
253
292
|
# Gets the history visibility of the room
|
254
293
|
#
|
255
294
|
# @return [:invited,:joined,:shared,:world_readable] The current history visibility for the room
|
256
295
|
def history_visibility
|
257
|
-
client.api.get_room_state(id, 'm.room.history_visibility')[:history_visibility]
|
296
|
+
client.api.get_room_state(id, 'm.room.history_visibility')[:history_visibility]&.to_sym
|
258
297
|
end
|
259
298
|
|
260
299
|
# Checks if the room history is world readable
|
@@ -267,15 +306,14 @@ module MatrixSdk
|
|
267
306
|
|
268
307
|
# Gets the room aliases
|
269
308
|
#
|
309
|
+
# @param canonical_only [Boolean] Should the list of aliases only contain the canonical ones
|
270
310
|
# @return [Array[String]] The assigned room aliases
|
271
|
-
def aliases
|
272
|
-
client.api.
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
.flatten
|
278
|
-
.compact
|
311
|
+
def aliases(canonical_only: true)
|
312
|
+
canonical = client.api.get_room_state(id, 'm.room.canonical_alias') rescue {}
|
313
|
+
aliases = ([canonical[:alias]].compact + (canonical[:alt_aliases] || [])).uniq.sort
|
314
|
+
return aliases if canonical_only
|
315
|
+
|
316
|
+
(aliases + client.api.get_room_aliases(id).aliases).uniq.sort
|
279
317
|
end
|
280
318
|
|
281
319
|
#
|
@@ -394,6 +432,31 @@ module MatrixSdk
|
|
394
432
|
client.api.send_content(id, url, name, 'm.audio', extra_information: audio_info)
|
395
433
|
end
|
396
434
|
|
435
|
+
# Sends a customized message to the Room
|
436
|
+
#
|
437
|
+
# @param body [String] The clear-text body of the message
|
438
|
+
# @param content [Hash] The custom content of the message
|
439
|
+
# @param msgtype [String] The type of the message, should be one of the known types (m.text, m.notice, m.emote, etc)
|
440
|
+
def send_custom_message(body, content = {}, msgtype: nil)
|
441
|
+
content.merge!(
|
442
|
+
body: body,
|
443
|
+
msgtype: msgtype || 'm.text'
|
444
|
+
)
|
445
|
+
|
446
|
+
client.api.send_message_event(id, 'm.room.message', content)
|
447
|
+
end
|
448
|
+
|
449
|
+
# Sends a custom timeline event to the Room
|
450
|
+
#
|
451
|
+
# @param type [String,Symbol] The type of the Event.
|
452
|
+
# For custom events, this should be written in reverse DNS format (e.g. com.example.event)
|
453
|
+
# @param content [Hash] The contents of the message, this will be the
|
454
|
+
# :content key of the resulting event object
|
455
|
+
# @see Protocols::CS#send_message_event
|
456
|
+
def send_event(type, content = {})
|
457
|
+
client.api.send_message_event(id, type, content)
|
458
|
+
end
|
459
|
+
|
397
460
|
# Redacts a message from the room
|
398
461
|
#
|
399
462
|
# @param event_id [String] the ID of the event to redact
|
@@ -490,12 +553,18 @@ module MatrixSdk
|
|
490
553
|
true
|
491
554
|
end
|
492
555
|
|
556
|
+
def account_data
|
557
|
+
return MatrixSdk::Util::AccountDataCache.new client, room: self if client.cache == :none
|
558
|
+
|
559
|
+
@account_data ||= MatrixSdk::Util::AccountDataCache.new client, room: self
|
560
|
+
end
|
561
|
+
|
493
562
|
# Retrieves a custom entry from the room-specific account data
|
494
563
|
#
|
495
564
|
# @param type [String] the data type to retrieve
|
496
565
|
# @return [Hash] the data that was stored under the given type
|
497
566
|
def get_account_data(type)
|
498
|
-
|
567
|
+
account_data[type]
|
499
568
|
end
|
500
569
|
|
501
570
|
# Stores a custom entry into the room-specific account data
|
@@ -503,7 +572,7 @@ module MatrixSdk
|
|
503
572
|
# @param type [String] the data type to store
|
504
573
|
# @param account_data [Hash] the data to store
|
505
574
|
def set_account_data(type, account_data)
|
506
|
-
|
575
|
+
self.account_data[type] = account_data
|
507
576
|
true
|
508
577
|
end
|
509
578
|
|
@@ -735,13 +804,27 @@ module MatrixSdk
|
|
735
804
|
def user_powerlevel(user, use_default: true)
|
736
805
|
user = user.id if user.is_a? User
|
737
806
|
user = MXID.new(user.to_s) unless user.is_a? MXID
|
738
|
-
raise ArgumentError, 'Must provide a valid
|
807
|
+
raise ArgumentError, 'Must provide a valid User or MXID' unless user.user?
|
739
808
|
|
740
|
-
level = power_levels
|
741
|
-
level
|
809
|
+
level = power_levels.dig(:users, user.to_s.to_sym)
|
810
|
+
level ||= power_levels[:users_default] || 0 if use_default
|
742
811
|
level
|
743
812
|
end
|
744
813
|
|
814
|
+
# Checks if a user can send a given event type in the room
|
815
|
+
#
|
816
|
+
# @param user [User,MXID,String] The user to check
|
817
|
+
# @param event [String,Symbol] The event type to check
|
818
|
+
# @param state [Boolean] If the given event is a state event or a message event
|
819
|
+
# @return [Boolean] If the given user is allowed to send an event of the given type
|
820
|
+
def user_can_send?(user, event, state: false)
|
821
|
+
user_pl = user_powerlevel(user)
|
822
|
+
event_pl = power_levels.dig(:events, event.to_s.to_sym)
|
823
|
+
event_pl ||= state ? (power_levels[:state_default] || 50) : (power_levels[:events_default] || 0)
|
824
|
+
|
825
|
+
user_pl >= event_pl
|
826
|
+
end
|
827
|
+
|
745
828
|
# Check if a user is an admin in the room
|
746
829
|
#
|
747
830
|
# @param user [User,MXID,String] The user to check for admin privileges
|
@@ -812,8 +895,17 @@ module MatrixSdk
|
|
812
895
|
|
813
896
|
if users
|
814
897
|
data[:users] = {} unless data.key? :users
|
815
|
-
|
816
|
-
|
898
|
+
users.each do |user, level|
|
899
|
+
user = user.id if user.is_a? User
|
900
|
+
user = MXID.new(user.to_s) unless user.is_a? MXID
|
901
|
+
raise ArgumentError, 'Must provide a valid user or MXID' unless user.user?
|
902
|
+
|
903
|
+
if level.nil?
|
904
|
+
data[:users].delete(user.to_s.to_sym)
|
905
|
+
else
|
906
|
+
data[:users][user.to_s.to_sym] = level
|
907
|
+
end
|
908
|
+
end
|
817
909
|
end
|
818
910
|
|
819
911
|
client.api.set_power_levels(id, data)
|
@@ -846,10 +938,14 @@ module MatrixSdk
|
|
846
938
|
private
|
847
939
|
|
848
940
|
def ensure_member(member)
|
941
|
+
return unless client.cache == :all
|
942
|
+
|
849
943
|
tinycache_adapter.write(:joined_members, []) unless tinycache_adapter.exist? :joined_members
|
850
944
|
|
851
945
|
members = tinycache_adapter.read(:joined_members) || []
|
852
946
|
members << member unless members.any? { |m| m.id == member.id }
|
947
|
+
|
948
|
+
tinycache_adapter.write(:joined_members, members)
|
853
949
|
end
|
854
950
|
|
855
951
|
def handle_power_levels(event)
|
@@ -857,27 +953,27 @@ module MatrixSdk
|
|
857
953
|
end
|
858
954
|
|
859
955
|
def handle_room_name(event)
|
860
|
-
tinycache_adapter.write(:name, event[
|
956
|
+
tinycache_adapter.write(:name, event.dig(*%i[content name]))
|
861
957
|
end
|
862
958
|
|
863
959
|
def handle_room_topic(event)
|
864
|
-
tinycache_adapter.write(:topic, event[
|
960
|
+
tinycache_adapter.write(:topic, event.dig(*%i[content topic]))
|
865
961
|
end
|
866
962
|
|
867
963
|
def handle_room_guest_access(event)
|
868
|
-
tinycache_adapter.write(:guest_access, event[
|
964
|
+
tinycache_adapter.write(:guest_access, event.dig(*%i[content guest_access])&.to_sym)
|
869
965
|
end
|
870
966
|
|
871
967
|
def handle_room_join_rules(event)
|
872
|
-
tinycache_adapter.write(:join_rule, event[
|
968
|
+
tinycache_adapter.write(:join_rule, event.dig(*%i[content join_rule])&.to_sym)
|
873
969
|
end
|
874
970
|
|
875
971
|
def handle_room_member(event)
|
876
972
|
return unless client.cache == :all
|
877
973
|
|
878
|
-
if event[
|
974
|
+
if event.dig(*%i[content membership]) == 'join'
|
879
975
|
ensure_member(client.get_user(event[:state_key]).dup.tap do |u|
|
880
|
-
u.instance_variable_set
|
976
|
+
u.instance_variable_set(:@display_name, event.dig(*%i[content displayname]))
|
881
977
|
end)
|
882
978
|
elsif tinycache_adapter.exist? :joined_members
|
883
979
|
members = tinycache_adapter.read(:joined_members)
|
@@ -886,20 +982,12 @@ module MatrixSdk
|
|
886
982
|
end
|
887
983
|
|
888
984
|
def handle_room_canonical_alias(event)
|
889
|
-
canonical_alias = tinycache_adapter.write
|
985
|
+
canonical_alias = tinycache_adapter.write(:canonical_alias, event.dig(*%i[content alias]))
|
890
986
|
|
891
987
|
data = tinycache_adapter.read(:aliases) || []
|
892
988
|
data << canonical_alias
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
def handle_room_aliases(event)
|
897
|
-
tinycache_adapter.write(:aliases, []) unless tinycache_adapter.exist? :aliases
|
898
|
-
|
899
|
-
aliases = tinycache_adapter.read(:aliases) || []
|
900
|
-
aliases.concat event[:content][:aliases]
|
901
|
-
|
902
|
-
tinycache_adapter.write(:aliases, aliases)
|
989
|
+
data += event.dig(*%i[content alt_aliases]) || []
|
990
|
+
tinycache_adapter.write(:aliases, data.uniq.sort)
|
903
991
|
end
|
904
992
|
|
905
993
|
def room_handlers?
|
@@ -908,6 +996,7 @@ module MatrixSdk
|
|
908
996
|
|
909
997
|
def ensure_room_handlers
|
910
998
|
client.instance_variable_get(:@room_handlers)[id] ||= {
|
999
|
+
account_data: MatrixSdk::EventHandlerArray.new,
|
911
1000
|
event: MatrixSdk::EventHandlerArray.new,
|
912
1001
|
state_event: MatrixSdk::EventHandlerArray.new,
|
913
1002
|
ephemeral_event: MatrixSdk::EventHandlerArray.new
|
@@ -915,7 +1004,6 @@ module MatrixSdk
|
|
915
1004
|
end
|
916
1005
|
|
917
1006
|
INTERNAL_HANDLERS = {
|
918
|
-
'm.room.aliases' => :handle_room_aliases,
|
919
1007
|
'm.room.canonical_alias' => :handle_room_canonical_alias,
|
920
1008
|
'm.room.guest_access' => :handle_room_guest_access,
|
921
1009
|
'm.room.join_rules' => :handle_room_join_rules,
|
@@ -924,6 +1012,7 @@ module MatrixSdk
|
|
924
1012
|
'm.room.power_levels' => :handle_power_levels,
|
925
1013
|
'm.room.topic' => :handle_room_topic
|
926
1014
|
}.freeze
|
1015
|
+
|
927
1016
|
def put_event(event)
|
928
1017
|
ensure_room_handlers[:event].fire(MatrixEvent.new(self, event), event[:type]) if room_handlers?
|
929
1018
|
|
@@ -931,6 +1020,17 @@ module MatrixSdk
|
|
931
1020
|
@events.shift if @events.length > @event_history_limit
|
932
1021
|
end
|
933
1022
|
|
1023
|
+
def put_account_data(event)
|
1024
|
+
if client.cache != :none
|
1025
|
+
adapter = account_data.tinycache_adapter
|
1026
|
+
adapter.write(event[:type], event[:content], expires_in: account_data.cache_time)
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
return unless room_handlers?
|
1030
|
+
|
1031
|
+
ensure_room_handlers[:account_data].fire(MatrixEvent.new(self, event))
|
1032
|
+
end
|
1033
|
+
|
934
1034
|
def put_ephemeral_event(event)
|
935
1035
|
return unless room_handlers?
|
936
1036
|
|
@@ -6,12 +6,12 @@ module MatrixSdk::Rooms
|
|
6
6
|
|
7
7
|
def tree(suggested_only: nil, max_rooms: nil)
|
8
8
|
begin
|
9
|
-
data = client.api.request :get, :
|
9
|
+
data = client.api.request :get, :client_r0, "/rooms/#{id}/spaces", query: {
|
10
10
|
suggested_only: suggested_only,
|
11
11
|
max_rooms_per_space: max_rooms
|
12
12
|
}.compact
|
13
|
-
rescue
|
14
|
-
data = client.api.request :get, :
|
13
|
+
rescue MatrixRequestError
|
14
|
+
data = client.api.request :get, :client_unstable, "/org.matrix.msc2946/rooms/#{id}/spaces", query: {
|
15
15
|
suggested_only: suggested_only,
|
16
16
|
max_rooms_per_space: max_rooms
|
17
17
|
}.compact
|
data/lib/matrix_sdk/user.rb
CHANGED
@@ -28,6 +28,12 @@ module MatrixSdk
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
def to_s
|
32
|
+
"#{display_name} (#{id})" if @display_name
|
33
|
+
|
34
|
+
@id.to_s
|
35
|
+
end
|
36
|
+
|
31
37
|
# @return [String] the display name
|
32
38
|
# @see MatrixSdk::Protocols::CS#get_display_name
|
33
39
|
def display_name
|
@@ -68,13 +74,29 @@ module MatrixSdk
|
|
68
74
|
@avatar_url = url
|
69
75
|
end
|
70
76
|
|
77
|
+
# Check if the user is an admin in a given room
|
78
|
+
#
|
79
|
+
# @param room [String,MXID] the room to check
|
80
|
+
# @return [Boolean] If the user is an admin (PL >= 100)
|
81
|
+
def admin?(room)
|
82
|
+
client.ensure_room(room).user_powerlevel(self) >= 100
|
83
|
+
end
|
84
|
+
|
85
|
+
# Check if the user is a moderator in a given room
|
86
|
+
#
|
87
|
+
# @param room [String,MXID] the room to check
|
88
|
+
# @return [Boolean] If the user is an admin (PL >= 50)
|
89
|
+
def moderator?(room)
|
90
|
+
client.ensure_room(room).user_powerlevel(self) >= 50
|
91
|
+
end
|
92
|
+
|
71
93
|
# Get the user's current presence status
|
72
94
|
#
|
73
95
|
# @return [Symbol] One of :online, :offline, :unavailable
|
74
96
|
# @see MatrixSdk::Protocols::CS#get_presence_status
|
75
97
|
# @note This information is not cached in the abstraction layer
|
76
98
|
def presence
|
77
|
-
raw_presence[:presence]
|
99
|
+
raw_presence[:presence]&.to_sym
|
78
100
|
end
|
79
101
|
|
80
102
|
# Sets the user's current presence status
|
@@ -132,8 +154,8 @@ module MatrixSdk
|
|
132
154
|
|
133
155
|
# Returns all the current device keys for the user, retrieving them if necessary
|
134
156
|
def device_keys
|
135
|
-
@device_keys ||= client.api.keys_query(device_keys: { id => [] }).yield_self do |resp|
|
136
|
-
resp
|
157
|
+
@device_keys ||= client.api.keys_query(device_keys: { id => [] }).yield_self do |resp| # rubocop:disable Style/ObjectThen # Keep Ruby 2.5 support a little longer
|
158
|
+
resp.dig(:device_keys, id.to_sym)
|
137
159
|
end
|
138
160
|
end
|
139
161
|
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MatrixSdk::Util
|
4
|
+
class AccountDataCache
|
5
|
+
extend MatrixSdk::Extensions
|
6
|
+
extend MatrixSdk::Util::Tinycache
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
attr_reader :client, :room
|
10
|
+
|
11
|
+
attr_accessor :cache_time
|
12
|
+
|
13
|
+
ignore_inspect :client, :room, :tinycache_adapter
|
14
|
+
|
15
|
+
def initialize(client, room: nil, cache_time: 1 * 60 * 60, **_params)
|
16
|
+
raise ArgumentError, 'Must be given a Client instance' unless client.is_a? MatrixSdk::Client
|
17
|
+
|
18
|
+
@client = client
|
19
|
+
@cache_time = cache_time
|
20
|
+
|
21
|
+
return unless room
|
22
|
+
|
23
|
+
@room = room
|
24
|
+
@room = client.ensure_room room unless @room.is_a? MatrixSdk::Room
|
25
|
+
end
|
26
|
+
|
27
|
+
def reload!
|
28
|
+
tinycache_adapter.clear
|
29
|
+
end
|
30
|
+
|
31
|
+
def keys
|
32
|
+
tinycache_adapter.send(:cache).keys
|
33
|
+
end
|
34
|
+
|
35
|
+
def values
|
36
|
+
keys.map { |key| tinycache_adapter.read(key) }
|
37
|
+
end
|
38
|
+
|
39
|
+
def size
|
40
|
+
keys.count
|
41
|
+
end
|
42
|
+
|
43
|
+
def key?(key)
|
44
|
+
keys.key?(key.to_s)
|
45
|
+
end
|
46
|
+
|
47
|
+
def each(live: false)
|
48
|
+
return to_enum(__method__, live: live) { keys.count } unless block_given?
|
49
|
+
|
50
|
+
keys.each do |key|
|
51
|
+
v = live ? self[key] : tinycache_adapter.read(key)
|
52
|
+
# hash = v.hash
|
53
|
+
yield key, v
|
54
|
+
# self[key] = v if hash != v.hash
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def delete(key)
|
59
|
+
key = key.to_s unless key.is_a? String
|
60
|
+
if room
|
61
|
+
client.api.set_room_account_data(client.mxid, room.id, key, {})
|
62
|
+
else
|
63
|
+
client.api.set_account_data(client.mxid, key, {})
|
64
|
+
end
|
65
|
+
tinycache_adapter.delete(key)
|
66
|
+
end
|
67
|
+
|
68
|
+
def [](key)
|
69
|
+
key = key.to_s unless key.is_a? String
|
70
|
+
tinycache_adapter.fetch(key, expires_in: @cache_time) do
|
71
|
+
if room
|
72
|
+
client.api.get_room_account_data(client.mxid, room.id, key)
|
73
|
+
else
|
74
|
+
client.api.get_account_data(client.mxid, key)
|
75
|
+
end
|
76
|
+
rescue MatrixSdk::MatrixNotFoundError
|
77
|
+
{}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def []=(key, value)
|
82
|
+
key = key.to_s unless key.is_a? String
|
83
|
+
if room
|
84
|
+
client.api.set_room_account_data(client.mxid, room.id, key, value)
|
85
|
+
else
|
86
|
+
client.api.set_account_data(client.mxid, key, value)
|
87
|
+
end
|
88
|
+
tinycache_adapter.write(key, value)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'pp'
|
4
|
+
|
3
5
|
unless Object.respond_to? :yield_self
|
4
6
|
class Object
|
5
7
|
def yield_self
|
@@ -51,21 +53,29 @@ module MatrixSdk
|
|
51
53
|
|
52
54
|
def ignore_inspect(*symbols)
|
53
55
|
class_eval %*
|
54
|
-
|
55
|
-
|
56
|
-
|
56
|
+
include PP::ObjectMixin
|
57
|
+
|
58
|
+
def pretty_print_instance_variables
|
59
|
+
instance_variables
|
57
60
|
.reject { |f| %i[#{symbols.map { |s| "@#{s}" }.join ' '}].include? f }
|
58
|
-
.
|
61
|
+
.sort
|
59
62
|
end
|
60
|
-
|
63
|
+
|
64
|
+
def pretty_print(pp)
|
65
|
+
pp.pp(self)
|
66
|
+
end
|
67
|
+
|
68
|
+
alias inspect pretty_print_inspect
|
69
|
+
*, __FILE__, __LINE__ - 14
|
61
70
|
end
|
62
71
|
end
|
63
72
|
|
64
73
|
module Logging
|
65
74
|
def logger
|
66
75
|
return MatrixSdk.logger if MatrixSdk.global_logger?
|
76
|
+
return @logger if instance_variable_defined?(:@logger) && @logger
|
67
77
|
|
68
|
-
|
78
|
+
::Logging.logger[self]
|
69
79
|
end
|
70
80
|
|
71
81
|
def logger=(logger)
|
@@ -62,7 +62,7 @@ module MatrixSdk::Util
|
|
62
62
|
method_names = build_method_names(method_name)
|
63
63
|
tinycache_adapter_config[method_name] = {
|
64
64
|
level: cache_level,
|
65
|
-
expires: expires_in || 1 * 365 * 24 * 60 * 60 # 1 year
|
65
|
+
expires: expires_in || (1 * 365 * 24 * 60 * 60) # 1 year
|
66
66
|
}
|
67
67
|
|
68
68
|
helper = const_get(cache_helper_module_name)
|
@@ -75,13 +75,25 @@ module MatrixSdk::Util
|
|
75
75
|
|
76
76
|
define_method(method_names[:with_cache]) do |*args|
|
77
77
|
tinycache_adapter.fetch(__send__(method_names[:cache_key], *args), expires_in: expires_in) do
|
78
|
-
|
78
|
+
named = args.delete_at(-1) if args.last.is_a? Hash
|
79
|
+
|
80
|
+
if named
|
81
|
+
__send__(method_names[:without_cache], *args, **named)
|
82
|
+
else
|
83
|
+
__send__(method_names[:without_cache], *args)
|
84
|
+
end
|
79
85
|
end
|
80
86
|
end
|
81
87
|
|
82
88
|
define_method(method_names[:without_cache]) do |*args|
|
83
89
|
orig = method(method_name).super_method
|
84
|
-
|
90
|
+
named = args.delete_at(-1) if args.last.is_a? Hash
|
91
|
+
|
92
|
+
if named
|
93
|
+
orig.call(*args, **named)
|
94
|
+
else
|
95
|
+
orig.call(*args)
|
96
|
+
end
|
85
97
|
end
|
86
98
|
|
87
99
|
define_method(method_names[:clear_cache]) do |*args|
|
@@ -99,8 +111,12 @@ module MatrixSdk::Util
|
|
99
111
|
define_method(method_name) do |*args|
|
100
112
|
unless_proc = opts[:unless].is_a?(Symbol) ? opts[:unless].to_proc : opts[:unless]
|
101
113
|
|
114
|
+
raise ArgumentError, 'Invalid proc provided (must have arity between 1..3)' if unless_proc && !(1..3).include?(unless_proc.arity)
|
115
|
+
|
102
116
|
skip_cache = false
|
103
|
-
skip_cache ||= unless_proc
|
117
|
+
skip_cache ||= unless_proc.call(self, method_name, args) if unless_proc&.arity == 3
|
118
|
+
skip_cache ||= unless_proc.call(method_name, args) if unless_proc&.arity == 2
|
119
|
+
skip_cache ||= unless_proc.call(args) if unless_proc&.arity == 1
|
104
120
|
skip_cache ||= CACHE_LEVELS[client&.cache || :all] < CACHE_LEVELS[cache_level]
|
105
121
|
|
106
122
|
if skip_cache
|
@@ -2,8 +2,12 @@
|
|
2
2
|
|
3
3
|
module MatrixSdk::Util
|
4
4
|
class TinycacheAdapter
|
5
|
+
extend MatrixSdk::Extensions
|
6
|
+
|
5
7
|
attr_accessor :config, :client
|
6
8
|
|
9
|
+
ignore_inspect :client
|
10
|
+
|
7
11
|
def initialize
|
8
12
|
@config = {}
|
9
13
|
|
@@ -59,7 +63,7 @@ module MatrixSdk::Util
|
|
59
63
|
end
|
60
64
|
|
61
65
|
def cleanup
|
62
|
-
@cache.
|
66
|
+
@cache.select { |_, v| v.expired? }.each { |_, v| v.value = nil }
|
63
67
|
end
|
64
68
|
|
65
69
|
private
|