matrix_sdk 2.1.0 → 2.3.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.
@@ -122,6 +122,14 @@ module MatrixSdk
122
122
  Time.now - (since / 1000)
123
123
  end
124
124
 
125
+ # Gets a direct message room with the user if one exists
126
+ #
127
+ # @return [Room,nil] A direct message room if one exists
128
+ # @see MatrixSdk::Client#direct_room
129
+ def direct_room
130
+ client.direct_room(id)
131
+ end
132
+
125
133
  # Returns all the current device keys for the user, retrieving them if necessary
126
134
  def device_keys
127
135
  @device_keys ||= client.api.keys_query(device_keys: { id => [] }).yield_self do |resp|
@@ -1,91 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module URI
4
- # A mxc:// Matrix content URL
5
- class MATRIX < Generic
6
- def full_path
7
- select(:host, :port, :path, :query, :fragment)
8
- .reject(&:nil?)
9
- .join
10
- end
11
- end
12
-
13
- @@schemes['MXC'] = MATRIX
14
- end
15
-
16
- unless Object.respond_to? :yield_self
17
- class Object
18
- def yield_self
19
- yield(self)
20
- end
21
- end
22
- end
23
-
24
3
  module MatrixSdk
25
- module Extensions
26
- def events(*symbols)
27
- module_name = "#{name}Events"
28
-
29
- initializers = []
30
- readers = []
31
- methods = []
32
-
33
- symbols.each do |sym|
34
- name = sym.to_s
35
-
36
- initializers << "
37
- @on_#{name} = MatrixSdk::EventHandlerArray.new
38
- "
39
- readers << ":on_#{name}"
40
- methods << "
41
- def fire_#{name}(ev, filter = nil)
42
- @on_#{name}.fire(ev, filter)
43
- when_#{name}(ev) if !ev.handled?
44
- end
45
-
46
- def when_#{name}(ev); end
47
- "
48
- end
49
-
50
- class_eval "
51
- module #{module_name}
52
- attr_reader #{readers.join ', '}
53
-
54
- def event_initialize
55
- #{initializers.join}
56
- end
57
-
58
- #{methods.join}
59
- end
60
-
61
- include #{module_name}
62
- ", __FILE__, __LINE__ - 12
63
- end
64
-
65
- def ignore_inspect(*symbols)
66
- class_eval %*
67
- def inspect
68
- reentrant = caller_locations.any? { |l| l.absolute_path == __FILE__ && l.label == 'inspect' }
69
- "\#{to_s[0..-2]} \#{instance_variables
70
- .reject { |f| %i[#{symbols.map { |s| "@#{s}" }.join ' '}].include? f }
71
- .map { |f| "\#{f}=\#{reentrant ? instance_variable_get(f) : instance_variable_get(f).inspect}" }.join " " }}>"
72
- end
73
- *, __FILE__, __LINE__ - 7
74
- end
75
- end
76
-
77
- module Logging
78
- def logger
79
- return MatrixSdk.logger if MatrixSdk.global_logger?
80
-
81
- @logger ||= ::Logging.logger[self]
82
- end
83
-
84
- def logger=(logger)
85
- @logger = logger
86
- end
87
- end
88
-
89
4
  class EventHandlerArray < Hash
90
5
  include MatrixSdk::Logging
91
6
  attr_accessor :reraise_exceptions
@@ -154,6 +69,7 @@ module MatrixSdk
154
69
 
155
70
  class MatrixEvent < Event
156
71
  attr_accessor :event, :filter
72
+ alias data event
157
73
 
158
74
  ignore_inspect :sender
159
75
 
@@ -189,7 +105,9 @@ module MatrixSdk
189
105
  end
190
106
 
191
107
  def respond_to_missing?(method, *)
192
- event.key? method
108
+ return true if event.key? method
109
+
110
+ super
193
111
  end
194
112
  end
195
113
  end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+
5
+ module URI
6
+ # A mxc:// Matrix content URL
7
+ class MATRIX < Generic
8
+ def full_path
9
+ select(:host, :port, :path, :query, :fragment)
10
+ .reject(&:nil?)
11
+ .join
12
+ end
13
+ end
14
+
15
+ @@schemes['MXC'] = MATRIX
16
+ end
17
+
18
+ unless Object.respond_to? :yield_self
19
+ class Object
20
+ def yield_self
21
+ yield(self)
22
+ end
23
+ end
24
+ end
25
+
26
+ module MatrixSdk
27
+ module Extensions
28
+ def events(*symbols)
29
+ module_name = "#{name}Events"
30
+
31
+ initializers = []
32
+ readers = []
33
+ methods = []
34
+
35
+ symbols.each do |sym|
36
+ name = sym.to_s
37
+
38
+ initializers << "
39
+ @on_#{name} = MatrixSdk::EventHandlerArray.new
40
+ "
41
+ readers << ":on_#{name}"
42
+ methods << "
43
+ def fire_#{name}(ev, filter = nil)
44
+ @on_#{name}.fire(ev, filter)
45
+ when_#{name}(ev) if !ev.handled?
46
+ end
47
+
48
+ def when_#{name}(ev); end
49
+ "
50
+ end
51
+
52
+ class_eval "
53
+ module #{module_name}
54
+ attr_reader #{readers.join ', '}
55
+
56
+ def event_initialize
57
+ #{initializers.join}
58
+ end
59
+
60
+ #{methods.join}
61
+ end
62
+
63
+ include #{module_name}
64
+ ", __FILE__, __LINE__ - 12
65
+ end
66
+
67
+ def ignore_inspect(*symbols)
68
+ class_eval %*
69
+ def inspect
70
+ reentrant = caller_locations.any? { |l| l.absolute_path == __FILE__ && l.label == 'inspect' }
71
+ "\#{to_s[0..-2]} \#{instance_variables
72
+ .reject { |f| %i[#{symbols.map { |s| "@#{s}" }.join ' '}].include? f }
73
+ .map { |f| "\#{f}=\#{reentrant ? instance_variable_get(f) : instance_variable_get(f).inspect}" }.join " " }}>"
74
+ end
75
+ *, __FILE__, __LINE__ - 7
76
+ end
77
+ end
78
+
79
+ module Logging
80
+ def logger
81
+ return MatrixSdk.logger if MatrixSdk.global_logger?
82
+
83
+ @logger ||= ::Logging.logger[self]
84
+ end
85
+
86
+ def logger=(logger)
87
+ @logger = logger
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'matrix_sdk/util/tinycache_adapter'
4
+
5
+ module MatrixSdk::Util
6
+ module Tinycache
7
+ CACHE_LEVELS = {
8
+ none: 0,
9
+ some: 1,
10
+ all: 2
11
+ }.freeze
12
+
13
+ def self.adapter
14
+ @adapter ||= TinycacheAdapter
15
+ end
16
+
17
+ def self.adapter=(adapter)
18
+ @adapter = adapter
19
+ end
20
+
21
+ def self.extended(base)
22
+ helper_name = base.send(:cache_helper_module_name)
23
+ base.remove_const(helper_name) if base.const_defined?(helper_name)
24
+ base.prepend base.const_set(helper_name, Module.new)
25
+
26
+ base.include InstanceMethods
27
+ end
28
+
29
+ def cached(*methods, **opts)
30
+ methods.each { |method| build_cache_methods(method, **opts) }
31
+ end
32
+
33
+ module InstanceMethods
34
+ def tinycache_adapter
35
+ @tinycache_adapter ||= Tinycache.adapter.new.tap do |adapter|
36
+ adapter.config = self.class.tinycache_adapter_config if adapter.respond_to? :config=
37
+ adapter.client = client if respond_to?(:client) && adapter.respond_to?(:client=)
38
+ end
39
+ end
40
+ end
41
+
42
+ def tinycache_adapter_config
43
+ @tinycache_adapter_config ||= {}
44
+ end
45
+
46
+ private
47
+
48
+ def default_cache_key
49
+ proc do |method_name, _method_args|
50
+ method_name.to_sym
51
+ end
52
+ end
53
+
54
+ def cache_helper_module_name
55
+ class_name = name&.gsub(/:/, '') || to_s.gsub(/[^a-zA-Z_0-9]/, '')
56
+ "#{class_name}Tinycache"
57
+ end
58
+
59
+ def build_cache_methods(method_name, cache_key: default_cache_key, cache_level: :none, expires_in: nil, **opts)
60
+ raise ArgumentError, 'Cache key must be a three-arg proc' unless cache_key.is_a? Proc
61
+
62
+ method_names = build_method_names(method_name)
63
+ tinycache_adapter_config[method_name] = {
64
+ level: cache_level,
65
+ expires: expires_in || 1 * 365 * 24 * 60 * 60 # 1 year
66
+ }
67
+
68
+ const_get(cache_helper_module_name).class_eval do
69
+ define_method(method_names[:cache_key]) do |*args|
70
+ cache_key.call(method_name, args)
71
+ end
72
+
73
+ define_method(method_names[:with_cache]) do |*args|
74
+ tinycache_adapter.fetch(__send__(method_names[:cache_key], *args), expires_in: expires_in) do
75
+ __send__(method_names[:without_cache], *args)
76
+ end
77
+ end
78
+
79
+ define_method(method_names[:without_cache]) do |*args|
80
+ orig = method(method_name).super_method
81
+ orig.call(*args)
82
+ end
83
+
84
+ define_method(method_names[:clear_cache]) do |*args|
85
+ tinycache_adapter.delete(__send__(method_names[:cache_key], *args))
86
+ end
87
+
88
+ define_method(method_names[:cached]) do
89
+ true
90
+ end
91
+
92
+ define_method(method_name) do |*args|
93
+ unless_proc = opts[:unless].is_a?(Symbol) ? opts[:unless].to_proc : opts[:unless]
94
+
95
+ skip_cache = false
96
+ skip_cache ||= unless_proc&.call(self, method_name, args)
97
+ skip_cache ||= CACHE_LEVELS[client&.cache || :all] < CACHE_LEVELS[cache_level]
98
+
99
+ if skip_cache
100
+ __send__(method_names[:without_cache], *args)
101
+ else
102
+ __send__(method_names[:with_cache], *args)
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ def build_method_names(method)
109
+ # Clean up method name (split any suffix)
110
+ method_name = method.to_s.sub(/([?!=])$/, '')
111
+ punctuation = Regexp.last_match(-1)
112
+
113
+ {
114
+ cache_key: "#{method_name}_cache_key#{punctuation}",
115
+ with_cache: "#{method_name}_with_cache#{punctuation}",
116
+ without_cache: "#{method_name}_without_cache#{punctuation}",
117
+ clear_cache: "clear_#{method_name}_cache#{punctuation}",
118
+ cached: "#{method}_cached?"
119
+ }
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MatrixSdk::Util
4
+ class TinycacheAdapter
5
+ attr_accessor :config, :client
6
+
7
+ def initialize
8
+ @config = {}
9
+
10
+ clear
11
+ end
12
+
13
+ def read(key)
14
+ cache[key]&.value
15
+ end
16
+
17
+ def write(key, value, expires_in: nil, cache_level: nil)
18
+ expires_in ||= config.dig(key, :expires)
19
+ cache_level ||= client&.cache
20
+ cache_level ||= :all
21
+ cache_level = Tinycache::CACHE_LEVELS[cache_level] unless cache_level.is_a? Integer
22
+
23
+ return value if cache_level < Tinycache::CACHE_LEVELS[config.dig(key, :level) || :none]
24
+
25
+ cache[key] = Value.new(value, Time.now, Time.now + expires_in)
26
+ value
27
+ end
28
+
29
+ def exist?(key)
30
+ cache.key?(key)
31
+ end
32
+
33
+ def fetch(key, expires_in: nil, cache_level: nil, **_opts)
34
+ expires_in ||= config.dig(key, :expires)
35
+ cache_level ||= client&.cache
36
+ cache_level ||= :all
37
+ cache_level = Tinycache::CACHE_LEVELS[cache_level]
38
+
39
+ return read(key) if exist?(key) && !cache[key].expired?
40
+
41
+ value = yield
42
+ write(key, value, expires_in: expires_in, cache_level: cache_level)
43
+ end
44
+
45
+ def delete(key)
46
+ return false unless exist?(key)
47
+
48
+ cache.delete key
49
+ true
50
+ end
51
+
52
+ def clear
53
+ @cache = {}
54
+ end
55
+
56
+ def cleanup
57
+ @cache.delete_if { |_, v| v.expired? }
58
+ end
59
+
60
+ private
61
+
62
+ Value = Struct.new(:value, :timestamp, :expires_at) do
63
+ def expired?
64
+ return false if expires_at.nil?
65
+
66
+ Time.now > expires_at
67
+ end
68
+ end
69
+
70
+ attr_reader :cache
71
+ end
72
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MatrixSdk
4
- VERSION = '2.1.0'
4
+ VERSION = '2.3.0'
5
5
  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: 2.1.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Olofsson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-22 00:00:00.000000000 Z
11
+ date: 2021-03-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mocha
@@ -95,10 +95,8 @@ files:
95
95
  - README.md
96
96
  - lib/matrix_sdk.rb
97
97
  - lib/matrix_sdk/api.rb
98
- - lib/matrix_sdk/application_service.rb
99
98
  - lib/matrix_sdk/client.rb
100
99
  - lib/matrix_sdk/errors.rb
101
- - lib/matrix_sdk/extensions.rb
102
100
  - lib/matrix_sdk/mxid.rb
103
101
  - lib/matrix_sdk/protocols/as.rb
104
102
  - lib/matrix_sdk/protocols/cs.rb
@@ -108,12 +106,16 @@ files:
108
106
  - lib/matrix_sdk/response.rb
109
107
  - lib/matrix_sdk/room.rb
110
108
  - lib/matrix_sdk/user.rb
109
+ - lib/matrix_sdk/util/events.rb
110
+ - lib/matrix_sdk/util/extensions.rb
111
+ - lib/matrix_sdk/util/tinycache.rb
112
+ - lib/matrix_sdk/util/tinycache_adapter.rb
111
113
  - lib/matrix_sdk/version.rb
112
114
  homepage: https://github.com/ananace/ruby-matrix-sdk
113
115
  licenses:
114
116
  - MIT
115
117
  metadata: {}
116
- post_install_message:
118
+ post_install_message:
117
119
  rdoc_options: []
118
120
  require_paths:
119
121
  - lib
@@ -128,8 +130,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
130
  - !ruby/object:Gem::Version
129
131
  version: '0'
130
132
  requirements: []
131
- rubygems_version: 3.1.2
132
- signing_key:
133
+ rubygems_version: 3.2.11
134
+ signing_key:
133
135
  specification_version: 4
134
136
  summary: SDK for applications using the Matrix protocol
135
137
  test_files: []