matrix_sdk 2.1.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []