matrix_sdk 2.4.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|