alula-ruby 2.6.3 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alula
4
+ # Base class for DCP command resources
5
+ class SingletonDcpCommandResource
6
+ attr_accessor :device_id, :values
7
+
8
+ BASE_PATH = '/dcp/v2/helix'
9
+
10
+ def initialize(device_id, attributes = nil)
11
+ @values = attributes || {}
12
+ construct_new_resource(device_id)
13
+ end
14
+
15
+ def model_name
16
+ self.class
17
+ end
18
+
19
+ def self.request(device_id:, http_method:, path: get_resource_path, payload: {}, opts: {})
20
+ if self == Alula::SingletonDcpCommandResource
21
+ raise NotImplementedError,
22
+ 'Alula::SingletonDcpCommandResource is an abstract class and cannot be instantiated.' \
23
+ ' You should perform actions on its subclasses (Synchronize, etc.)'
24
+ end
25
+ if payload.empty? && payload_required?
26
+ raise ArgumentError, 'Payload is empty. This will result in a useless request.'
27
+ end
28
+
29
+ path = "#{BASE_PATH}/#{device_id}/#{path}"
30
+ payload = payload_to_camelcase(payload)
31
+ response = Alula::Client.request(http_method, path, payload, opts)
32
+
33
+ unless response.ok?
34
+ error = Alula::AlulaError.for_response(response)
35
+
36
+ #
37
+ # Some error classifications are critical and should be raised for visibility
38
+ # These errors do not contain meaningful data that an end-user can use to correct
39
+ # the error.
40
+ raise error if [Alula::RateLimitError, Alula::BadRequestError, Alula::ForbiddenError,
41
+ Alula::UnknownError, Alula::InsufficientScopeError].include?(error.class)
42
+
43
+ return error
44
+ end
45
+
46
+ new(device_id, response.data)
47
+ end
48
+
49
+ def construct_new_resource(device_id)
50
+ self.device_id = device_id
51
+ instance_eval do
52
+ fields.each_key do |field|
53
+ camel_key = Util.camelize(field)
54
+ define_singleton_method(field) do
55
+ if @values.key?(camel_key)
56
+ @values[camel_key]
57
+ else
58
+ @values[field]
59
+ end
60
+ end
61
+ define_singleton_method("#{field}=") do |value|
62
+ if @values.key?(camel_key)
63
+ @values[camel_key] = value
64
+ else
65
+ @values[field] = value
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ def apply_attributes(attributes)
73
+ attributes.each do |key, value|
74
+ send("#{key}=", value)
75
+ end
76
+ end
77
+
78
+ def call
79
+ self.class.call(device_id: device_id, payload: @values)
80
+ end
81
+
82
+ def self.payload_to_camelcase(payload)
83
+ # recursively convert all keys to camelcase
84
+ payload.each_with_object({}) do |(key, value), hash|
85
+ hash[Util.camelize(key)] = if value.is_a?(Array)
86
+ value.map { |v| v.is_a?(Hash) ? payload_to_camelcase(v) : v }
87
+ else
88
+ value.is_a?(Hash) ? payload_to_camelcase(value) : value
89
+ end
90
+ end
91
+ end
92
+
93
+ def self.payload_required?
94
+ # return false unless the method is overridden
95
+ return false unless method_defined?(:payload_required?)
96
+
97
+ payload_required?
98
+ end
99
+ end
100
+ end
data/lib/alula/util.rb CHANGED
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Alula
4
+ # Utility methods for the Alula gem
2
5
  class Util
3
6
  class << self
4
7
  #
@@ -13,10 +16,11 @@ module Alula
13
16
  # activesupport/lib/active_support/inflector/methods.rb, line 90
14
17
  def underscore(camel_cased_word)
15
18
  return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
19
+
16
20
  word = camel_cased_word.to_s.gsub(/::/, '/')
17
- word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
18
- word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
19
- word.tr!("-", "_")
21
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
22
+ word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
23
+ word.tr!('-', '_')
20
24
  word.downcase!
21
25
  word
22
26
  end
@@ -28,21 +32,26 @@ module Alula
28
32
 
29
33
  def camelize(under_scored_word)
30
34
  return CAMELIZE_MAPPING[under_scored_word.to_s] if CAMELIZE_MAPPING.key?(under_scored_word.to_s)
35
+
31
36
  words = under_scored_word.to_s.split(/-|_/)
32
- words.each_with_index.map{ |el, i| i == 0 ? el.downcase : el.capitalize }.join
37
+ words.each_with_index.map { |el, i| i.zero? ? el.downcase : el.capitalize }.join
33
38
  end
34
39
 
35
40
  def upper_camelcase(under_scored_word)
36
41
  under_scored_word.to_s.split(/-|_/).map(&:capitalize).join
37
42
  end
38
43
 
39
- def split_on_word(string, separator_match = /-|_/, &block)
44
+ def upper_camelcase_from_camelcase(camel_cased_word)
45
+ camel_cased_word.split(/(?=[A-Z])/).map(&:capitalize).join
46
+ end
47
+
48
+ def split_on_word(string, separator_match = /-|_/, &_block)
40
49
  string.to_s.split(separator_match)
41
50
  end
42
51
 
43
52
  # https://stackoverflow.com/questions/9381553/ruby-merge-nested-hash
44
53
  def deep_merge(first, second)
45
- merger = proc do |key, v1, v2|
54
+ merger = proc do |_key, v1, v2|
46
55
  if Hash === v1 && Hash === v2
47
56
  v1.merge(v2, &merger)
48
57
  elsif Array === v1 && Array === v2
@@ -70,7 +79,7 @@ module Alula
70
79
 
71
80
  # Error objects contain a bunch of info, but all the good stuff
72
81
  # is stored in a sub-object named meta
73
- #
82
+ #
74
83
  # meta looks something like this
75
84
  # {
76
85
  # fieldName: 'field error description',
@@ -103,6 +112,14 @@ module Alula
103
112
 
104
113
  error_object
105
114
  end
115
+
116
+ def model_errors_from_dcp_response(response)
117
+ return false unless response.data['error'] || response.data['message']
118
+
119
+ {
120
+ model: response.data['message']
121
+ }
122
+ end
106
123
  end
107
124
  end
108
125
  end
data/lib/alula/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alula
4
- VERSION = '2.6.3'
4
+ VERSION = '2.8.0'
5
5
  end
data/lib/alula.rb CHANGED
@@ -1,13 +1,25 @@
1
1
  require 'alula/version'
2
2
  require 'request_store'
3
3
  require 'forwardable'
4
+ require 'logger'
4
5
  require_relative 'alula/resource_attributes'
6
+ require_relative 'alula/dcp/resource_attributes'
5
7
  require_relative 'alula/relationship_attributes'
6
8
  require_relative 'alula/api_operations/list'
7
9
  require_relative 'alula/api_operations/request'
8
10
  require_relative 'alula/api_operations/save'
9
11
  require_relative 'alula/api_operations/delete'
10
12
  require_relative 'alula/api_resource'
13
+ require_relative 'alula/dcp/error_handler'
14
+ require_relative 'alula/dcp/list_object'
15
+ require_relative 'alula/dcp_operations/list'
16
+ require_relative 'alula/dcp_operations/request'
17
+ require_relative 'alula/dcp_operations/save'
18
+ require_relative 'alula/dcp_operations/delete'
19
+ require_relative 'alula/dcp_operations/delete_staged'
20
+ require_relative 'alula/dcp/meta'
21
+ require_relative 'alula/dcp_resource'
22
+ require_relative 'alula/singleton_dcp_command_resource'
11
23
  require_relative 'alula/rpc_resource'
12
24
  require_relative 'alula/rpc_response'
13
25
  require_relative 'alula/rest_resource'
@@ -67,6 +79,11 @@ require_relative 'alula/resources/feature_plan'
67
79
  require_relative 'alula/resources/feature_planvideo'
68
80
  require_relative 'alula/resources/feature_price'
69
81
  require_relative 'alula/resources/feature_bysubject'
82
+ require_relative 'alula/resources/dcp/base_resource'
83
+ require_relative 'alula/resources/dcp/users_data'
84
+ require_relative 'alula/resources/dcp/users_data/user'
85
+ require_relative 'alula/resources/dcp/users_data/installer_pin'
86
+ require_relative 'alula/resources/dcp/config/synchronize'
70
87
  require_relative 'alula/resources/video/base_resource'
71
88
  require_relative 'alula/resources/video/device'
72
89
  require_relative 'alula/procedures/device_cellular_history_proc'
@@ -162,7 +179,7 @@ module Alula
162
179
  end
163
180
 
164
181
  def self.logger
165
- @@logger ||= defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
182
+ @@logger ||= defined?(Rails) ? Rails.logger : Logger.new($stdout)
166
183
  end
167
184
 
168
185
  def self.logger=(logger)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alula-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.3
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Titus Johnson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-01-30 00:00:00.000000000 Z
11
+ date: 2025-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -207,6 +207,16 @@ files:
207
207
  - lib/alula/api_resource.rb
208
208
  - lib/alula/client.rb
209
209
  - lib/alula/client_configuration.rb
210
+ - lib/alula/dcp/error_handler.rb
211
+ - lib/alula/dcp/list_object.rb
212
+ - lib/alula/dcp/meta.rb
213
+ - lib/alula/dcp/resource_attributes.rb
214
+ - lib/alula/dcp_operations/delete.rb
215
+ - lib/alula/dcp_operations/delete_staged.rb
216
+ - lib/alula/dcp_operations/list.rb
217
+ - lib/alula/dcp_operations/request.rb
218
+ - lib/alula/dcp_operations/save.rb
219
+ - lib/alula/dcp_resource.rb
210
220
  - lib/alula/errors.rb
211
221
  - lib/alula/filter_builder.rb
212
222
  - lib/alula/helpers/device_helpers/attribute_translations_helper.rb
@@ -259,6 +269,12 @@ files:
259
269
  - lib/alula/relationship_attributes.rb
260
270
  - lib/alula/resource_attributes.rb
261
271
  - lib/alula/resources/billing_program.rb
272
+ - lib/alula/resources/dcp/base_resource.rb
273
+ - lib/alula/resources/dcp/config.rb
274
+ - lib/alula/resources/dcp/config/synchronize.rb
275
+ - lib/alula/resources/dcp/users_data.rb
276
+ - lib/alula/resources/dcp/users_data/installer_pin.rb
277
+ - lib/alula/resources/dcp/users_data/user.rb
262
278
  - lib/alula/resources/dealer.rb
263
279
  - lib/alula/resources/dealer_account_transfer.rb
264
280
  - lib/alula/resources/dealer_address.rb
@@ -304,6 +320,7 @@ files:
304
320
  - lib/alula/rest_resource.rb
305
321
  - lib/alula/rpc_resource.rb
306
322
  - lib/alula/rpc_response.rb
323
+ - lib/alula/singleton_dcp_command_resource.rb
307
324
  - lib/alula/singleton_rest_resource.rb
308
325
  - lib/alula/util.rb
309
326
  - lib/alula/version.rb