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.
@@ -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
 
@@ -31,6 +31,8 @@ module MatrixSdk
31
31
  return data
32
32
  end
33
33
 
34
+ return data if data.instance_variables.include? :@api
35
+
34
36
  raise ArgumentError, 'Input data was not a hash' unless data.is_a? Hash
35
37
 
36
38
  data.extend(Extensions)
@@ -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, :aliases, cache_level: :all, expires_in: 60 * 60
35
- # Only cache unfiltered requests for all members
36
- cached :all_members, unless: proc { |args| args.any? }, cache_level: :all, expires_in: 3600
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].to_sym
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].to_sym
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].to_sym
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.get_room_aliases(id).aliases
273
- rescue MatrixNotFoundError
274
- data = client.api.get_room_state_all(id)
275
- data.select { |chunk| chunk[:type] == 'm.room.aliases' && chunk.key?(:content) && chunk[:content].key?(:aliases) }
276
- .map { |chunk| chunk[:content][:aliases] }
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
- client.api.get_room_account_data(client.mxid, id, type)
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
- client.api.set_room_account_data(client.mxid, id, type, account_data)
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 user or MXID' unless user.user?
807
+ raise ArgumentError, 'Must provide a valid User or MXID' unless user.user?
739
808
 
740
- level = power_levels[:users][user.to_s.to_sym]
741
- level = power_levels[:users_default] || 0 if level.nil? && use_default
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
- data[:users].merge!(users)
816
- data[:users].delete_if { |_k, v| v.nil? }
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[:content][:name])
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[:content][:topic])
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[:content][:guest_access].to_sym)
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[:content][:join_rule].to_sym)
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[:content][:membership] == 'join'
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 :@display_name, event[:content][:displayname]
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 :canonical_alias, event[:content][:alias]
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
- tinycache_adapter.write(:aliases, data)
894
- end
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, :client_unstable, "/org.matrix.msc2946/rooms/#{id}/spaces", query: {
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, :client_r0, "/rooms/#{id}/spaces", query: {
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
@@ -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].to_sym
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[:device_keys][id.to_sym]
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
- def inspect
55
- reentrant = caller_locations.any? { |l| l.absolute_path == __FILE__ && l.label == 'inspect' }
56
- "\\\#<\#{self.class} \#{instance_variables
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
- .map { |f| "\#{f}=\#{reentrant ? instance_variable_get(f) : instance_variable_get(f).inspect}" }.join " " }}>"
61
+ .sort
59
62
  end
60
- *, __FILE__, __LINE__ - 7
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
- @logger ||= ::Logging.logger[self]
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
- __send__(method_names[:without_cache], *args)
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
- orig.call(*args)
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&.call(self, method_name, args)
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.delete_if { |_, v| v.expired? }
66
+ @cache.select { |_, v| v.expired? }.each { |_, v| v.value = nil }
63
67
  end
64
68
 
65
69
  private