metal_archives 2.2.0 → 2.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +46 -0
  3. data/.github/workflows/release.yml +69 -0
  4. data/.gitignore +6 -6
  5. data/.overcommit.yml +35 -0
  6. data/.rspec +1 -0
  7. data/.rubocop.yml +54 -8
  8. data/.rubocop_todo.yml +92 -0
  9. data/CHANGELOG.md +22 -0
  10. data/Gemfile +1 -1
  11. data/LICENSE.md +1 -1
  12. data/README.md +35 -64
  13. data/Rakefile +8 -7
  14. data/bin/console +41 -0
  15. data/bin/setup +8 -0
  16. data/docker-compose.yml +14 -0
  17. data/lib/metal_archives.rb +48 -29
  18. data/lib/metal_archives/{utils/collection.rb → collection.rb} +0 -0
  19. data/lib/metal_archives/configuration.rb +9 -33
  20. data/lib/metal_archives/{error.rb → errors.rb} +0 -0
  21. data/lib/metal_archives/http_client.rb +13 -8
  22. data/lib/metal_archives/{utils/lru_cache.rb → lru_cache.rb} +0 -0
  23. data/lib/metal_archives/middleware/cache_check.rb +2 -4
  24. data/lib/metal_archives/middleware/encoding.rb +2 -2
  25. data/lib/metal_archives/middleware/headers.rb +5 -5
  26. data/lib/metal_archives/middleware/rewrite_endpoint.rb +2 -2
  27. data/lib/metal_archives/models/artist.rb +40 -24
  28. data/lib/metal_archives/models/band.rb +47 -29
  29. data/lib/metal_archives/models/base_model.rb +64 -61
  30. data/lib/metal_archives/models/label.rb +11 -11
  31. data/lib/metal_archives/models/release.rb +17 -15
  32. data/lib/metal_archives/{utils/nil_date.rb → nil_date.rb} +10 -18
  33. data/lib/metal_archives/parsers/artist.rb +62 -31
  34. data/lib/metal_archives/parsers/band.rb +97 -74
  35. data/lib/metal_archives/parsers/label.rb +21 -21
  36. data/lib/metal_archives/parsers/parser.rb +23 -8
  37. data/lib/metal_archives/parsers/release.rb +77 -72
  38. data/lib/metal_archives/{utils/range.rb → range.rb} +5 -2
  39. data/lib/metal_archives/version.rb +12 -1
  40. data/metal_archives.env.example +7 -0
  41. data/metal_archives.gemspec +40 -28
  42. data/nginx/default.conf +60 -0
  43. metadata +126 -65
  44. data/.travis.yml +0 -12
  45. data/spec/configuration_spec.rb +0 -96
  46. data/spec/factories/artist_factory.rb +0 -37
  47. data/spec/factories/band_factory.rb +0 -60
  48. data/spec/factories/nil_date_factory.rb +0 -9
  49. data/spec/factories/range_factory.rb +0 -8
  50. data/spec/models/artist_spec.rb +0 -138
  51. data/spec/models/band_spec.rb +0 -164
  52. data/spec/models/base_model_spec.rb +0 -219
  53. data/spec/models/release_spec.rb +0 -133
  54. data/spec/parser_spec.rb +0 -19
  55. data/spec/spec_helper.rb +0 -111
  56. data/spec/support/factory_girl.rb +0 -5
  57. data/spec/support/metal_archives.rb +0 -33
  58. data/spec/utils/collection_spec.rb +0 -72
  59. data/spec/utils/lru_cache_spec.rb +0 -53
  60. data/spec/utils/nil_date_spec.rb +0 -156
  61. data/spec/utils/range_spec.rb +0 -62
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'date'
4
- require 'countries'
3
+ require "date"
4
+ require "countries"
5
+ require "nokogiri"
5
6
 
6
7
  module MetalArchives
7
8
  ##
@@ -13,7 +14,7 @@ module MetalArchives
13
14
  #
14
15
  # Returns +Integer+
15
16
  #
16
- property :id, :type => Integer
17
+ property :id, type: Integer
17
18
 
18
19
  ##
19
20
  # :attr_reader: name
@@ -35,7 +36,7 @@ module MetalArchives
35
36
  # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
36
37
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
37
38
  #
38
- property :aliases, :multiple => true
39
+ property :aliases, multiple: true
39
40
 
40
41
  ##
41
42
  # :attr_reader: country
@@ -46,7 +47,7 @@ module MetalArchives
46
47
  # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
47
48
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
48
49
  #
49
- property :country, :type => ISO3166::Country
50
+ property :country, type: ISO3166::Country
50
51
 
51
52
  ##
52
53
  # :attr_reader: location
@@ -68,18 +69,18 @@ module MetalArchives
68
69
  # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
69
70
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
70
71
  #
71
- property :date_formed, :type => Date
72
+ property :date_formed, type: NilDate
72
73
 
73
74
  ##
74
75
  # :attr_reader: date_active
75
76
  #
76
- # Returns +Array+ of rdoc-ref:Range
77
+ # Returns +Array+ of rdoc-ref:Range containing rdoc-ref:NilDate
77
78
  #
78
79
  # [Raises]
79
80
  # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
80
81
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
81
82
  #
82
- property :date_active, :type => MetalArchives::Range, :multiple => true
83
+ property :date_active, type: MetalArchives::Range, multiple: true
83
84
 
84
85
  ##
85
86
  # :attr_reader: genres
@@ -90,7 +91,7 @@ module MetalArchives
90
91
  # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
91
92
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
92
93
  #
93
- property :genres, :multiple => true
94
+ property :genres, multiple: true
94
95
 
95
96
  ##
96
97
  # :attr_reader: lyrical_themes
@@ -101,7 +102,7 @@ module MetalArchives
101
102
  # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
102
103
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
103
104
  #
104
- property :lyrical_themes, :multiple => true
105
+ property :lyrical_themes, multiple: true
105
106
 
106
107
  ##
107
108
  # :attr_reader: label
@@ -112,7 +113,7 @@ module MetalArchives
112
113
  # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
113
114
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
114
115
  #
115
- property :label, :type => MetalArchives::Label
116
+ property :label, type: MetalArchives::Label
116
117
 
117
118
  ##
118
119
  # :attr_reader: independent
@@ -123,7 +124,7 @@ module MetalArchives
123
124
  # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
124
125
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
125
126
  #
126
- enum :independent, :values => [true, false]
127
+ enum :independent, values: [true, false]
127
128
 
128
129
  ##
129
130
  # :attr_reader: comment
@@ -145,9 +146,19 @@ module MetalArchives
145
146
  # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
146
147
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
147
148
  #
148
- enum :status, :values => %i[active split_up on_hold unknown changed_name disputed]
149
+ enum :status, values: %i(active split_up on_hold unknown changed_name disputed)
150
+
151
+ ##
152
+ # :attr_reader: releases
153
+ #
154
+ # Returns +Array+ of rdoc-ref:Release
155
+ #
156
+ # [Raises]
157
+ # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
158
+ # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
159
+ #
160
+ property :releases, type: MetalArchives::Release, multiple: true
149
161
 
150
- # TODO: releases
151
162
  # TODO: members
152
163
 
153
164
  ##
@@ -163,7 +174,7 @@ module MetalArchives
163
174
  # - +:band+: rdoc-ref:Band
164
175
  # - +:score+: +Integer+
165
176
  #
166
- property :similar, :type => Hash, :multiple => true
177
+ property :similar, type: Hash, multiple: true
167
178
 
168
179
  ##
169
180
  # :attr_reader: logo
@@ -196,12 +207,12 @@ module MetalArchives
196
207
  # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
197
208
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
198
209
  #
199
- # [+similar+]
210
+ # [+links+]
200
211
  # - +:url+: +String+
201
212
  # - +:type+: +Symbol+, either +:official+ or +:merchandise+
202
213
  # - +:title+: +String+
203
214
  #
204
- property :links, :multiple => true
215
+ property :links, multiple: true
205
216
 
206
217
  protected
207
218
 
@@ -237,6 +248,12 @@ module MetalArchives
237
248
 
238
249
  properties[:links] = Parsers::Band.parse_related_links_html response.body
239
250
 
251
+ ## Releases
252
+ url = "#{MetalArchives.config.default_endpoint}band/discography/id/#{id}/tab/all"
253
+ response = HTTPClient.get url
254
+
255
+ properties[:releases] = Parsers::Band.parse_releases_html response.body
256
+
240
257
  properties
241
258
  end
242
259
 
@@ -252,7 +269,7 @@ module MetalArchives
252
269
  def find(id)
253
270
  return cache[id] if cache.include? id
254
271
 
255
- Band.new :id => id
272
+ Band.new id: id
256
273
  end
257
274
 
258
275
  ##
@@ -292,7 +309,7 @@ module MetalArchives
292
309
  # - +:exact+: +Boolean+
293
310
  # - +:genre+: +String+
294
311
  # - +:country+: +ISO3166::Country+
295
- # - +:year_formation+: rdoc-ref:Range of rdoc-ref:NilDate
312
+ # - +:year_formation+: rdoc-ref:Range containing rdoc-ref:NilDate
296
313
  # - +:comment+: +String+
297
314
  # - +:status+: see rdoc-ref:Band.status
298
315
  # - +:lyrical_themes+: +String+
@@ -307,10 +324,10 @@ module MetalArchives
307
324
  response = HTTPClient.get url, params
308
325
  json = JSON.parse response.body
309
326
 
310
- return nil if json['aaData'].empty?
327
+ return nil if json["aaData"].empty?
311
328
 
312
- data = json['aaData'].first
313
- id = Nokogiri::HTML(data.first).xpath('//a/@href').first.value.delete('\\').split('/').last.gsub(/\D/, '').to_i
329
+ data = json["aaData"].first
330
+ id = Nokogiri::HTML(data.first).xpath("//a/@href").first.value.delete('\\').split("/").last.gsub(/\D/, "").to_i
314
331
 
315
332
  find id
316
333
  end
@@ -332,7 +349,7 @@ module MetalArchives
332
349
  # - +:exact+: +Boolean+
333
350
  # - +:genre+: +String+
334
351
  # - +:country+: +ISO3166::Country+
335
- # - +:year_formation+: rdoc-ref:Range of +Date+
352
+ # - +:year_formation+: rdoc-ref:Range containing rdoc-ref:NilDate
336
353
  # - +:comment+: +String+
337
354
  # - +:status+: see rdoc-ref:Band.status
338
355
  # - +:lyrical_themes+: +String+
@@ -364,7 +381,7 @@ module MetalArchives
364
381
  # - +:exact+: +Boolean+
365
382
  # - +:genre+: +String+
366
383
  # - +:country+: +ISO3166::Country+
367
- # - +:year_formation+: rdoc-ref:Range of +Date+
384
+ # - +:year_formation+: rdoc-ref:Range containing rdoc-ref:NilDate
368
385
  # - +:comment+: +String+
369
386
  # - +:status+: see rdoc-ref:Band.status
370
387
  # - +:lyrical_themes+: +String+
@@ -383,16 +400,16 @@ module MetalArchives
383
400
  if @max_items && @start >= @max_items
384
401
  []
385
402
  else
386
- response = HTTPClient.get url, params.merge(:iDisplayStart => @start)
403
+ response = HTTPClient.get url, params.merge(iDisplayStart: @start)
387
404
  json = JSON.parse response.body
388
405
 
389
- @max_items = json['iTotalRecords']
406
+ @max_items = json["iTotalRecords"]
390
407
 
391
408
  objects = []
392
409
 
393
- json['aaData'].each do |data|
410
+ json["aaData"].each do |data|
394
411
  # Create Band object for every ID in the results list
395
- id = Nokogiri::HTML(data.first).xpath('//a/@href').first.value.delete('\\').split('/').last.gsub(/\D/, '').to_i
412
+ id = Nokogiri::HTML(data.first).xpath("//a/@href").first.value.delete('\\').split("/").last.gsub(/\D/, "").to_i
396
413
  objects << Band.find(id)
397
414
  end
398
415
 
@@ -421,7 +438,8 @@ module MetalArchives
421
438
  #
422
439
  def search(name)
423
440
  raise MetalArchives::Errors::ArgumentError unless name.is_a? String
424
- search_by :name => name
441
+
442
+ search_by name: name
425
443
  end
426
444
 
427
445
  ##
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module MetalArchives
3
4
  ##
4
5
  # Abstract model class
@@ -8,7 +9,7 @@ module MetalArchives
8
9
  # Generic shallow copy constructor
9
10
  #
10
11
  def initialize(hash = {})
11
- raise Errors::NotImplementedError, 'no :id property in model' unless respond_to? :id?, true
12
+ raise Errors::NotImplementedError, "no :id property in model" unless respond_to? :id?, true
12
13
 
13
14
  hash.each do |property, value|
14
15
  instance_variable_set("@#{property}", value) if self.class.properties.include? property
@@ -19,7 +20,7 @@ module MetalArchives
19
20
  # Returns true if two objects have the same type and id
20
21
  #
21
22
  def ==(obj)
22
- obj.instance_of?(self.class) && id ==(obj.id)
23
+ obj.instance_of?(self.class) && id == obj.id
23
24
  end
24
25
 
25
26
  ##
@@ -30,7 +31,7 @@ module MetalArchives
30
31
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
31
32
  #
32
33
  def load!
33
- raise Errors::InvalidIDError, 'no id present' unless !!id
34
+ raise Errors::InvalidIDError, "no id present" unless id
34
35
 
35
36
  # Use constructor to set attributes
36
37
  initialize assemble
@@ -42,7 +43,7 @@ module MetalArchives
42
43
 
43
44
  @loaded = true
44
45
  self.class.cache[id] = self
45
- rescue => e
46
+ rescue StandardError => e
46
47
  # Don't cache invalid requests
47
48
  self.class.cache.delete id
48
49
  raise e
@@ -64,17 +65,17 @@ module MetalArchives
64
65
 
65
66
  protected
66
67
 
67
- ##
68
- # Fetch the data and assemble the model
69
- #
70
- # Override this method
71
- #
72
- # [Raises]
73
- # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
74
- # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
75
- #
68
+ ##
69
+ # Fetch the data and assemble the model
70
+ #
71
+ # Override this method
72
+ #
73
+ # [Raises]
74
+ # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
75
+ # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
76
+ #
76
77
  def assemble
77
- raise Errors::NotImplementedError, 'method :assemble not implemented'
78
+ raise Errors::NotImplementedError, "method :assemble not implemented"
78
79
  end
79
80
 
80
81
  class << self
@@ -92,37 +93,37 @@ module MetalArchives
92
93
 
93
94
  protected
94
95
 
95
- ##
96
- # Defines a model property.
97
- #
98
- # [+name+]
99
- # Name of the property
100
- #
101
- # [+opts+]
102
- # [+type+]
103
- # Data type of property (a constant)
104
- #
105
- # Default: +String+
106
- #
107
- # [+multiple+]
108
- # Whether or not the property has multiple values (which
109
- # turns it into an +Array+ of +type+)
110
- #
96
+ ##
97
+ # Defines a model property.
98
+ #
99
+ # [+name+]
100
+ # Name of the property
101
+ #
102
+ # [+opts+]
103
+ # [+type+]
104
+ # Data type of property (a constant)
105
+ #
106
+ # Default: +String+
107
+ #
108
+ # [+multiple+]
109
+ # Whether or not the property has multiple values (which
110
+ # turns it into an +Array+ of +type+)
111
+ #
111
112
  def property(name, opts = {})
112
113
  (@properties ||= []) << name
113
114
 
114
115
  # property
115
116
  define_method(name) do
116
- load! unless loaded? && instance_variable_defined?("@#{name}") || name ==(:id)
117
+ load! unless loaded? && instance_variable_defined?("@#{name}") || name == :id
117
118
  instance_variable_get("@#{name}")
118
119
  end
119
120
 
120
121
  # property?
121
122
  define_method("#{name}?") do
122
- load! unless loaded? && instance_variable_defined?("@#{name}") || name ==(:id)
123
+ load! unless loaded? && instance_variable_defined?("@#{name}") || name == :id
123
124
 
124
125
  property = instance_variable_get("@#{name}")
125
- property.respond_to?(:empty?) ? !property.empty? : !!property
126
+ property.respond_to?(:empty?) ? !property.empty? : !property.nil?
126
127
  end
127
128
 
128
129
  # property=
@@ -136,6 +137,7 @@ module MetalArchives
136
137
  type = opts[:type] || String
137
138
  if opts[:multiple]
138
139
  raise MetalArchives::Errors::TypeError, "invalid type #{value.class}, must be Array for #{name}" unless value.is_a? Array
140
+
139
141
  value.each do |val|
140
142
  raise MetalArchives::Errors::TypeError, "invalid type #{val.class}, must be #{type} for #{name}" unless val.is_a? type
141
143
  end
@@ -147,22 +149,22 @@ module MetalArchives
147
149
  end
148
150
  end
149
151
 
150
- ##
151
- # Defines a model enum property.
152
- #
153
- # [+name+]
154
- # Name of the property
155
- #
156
- # [+opts+]
157
- # [+values+]
158
- # Required. An array of possible values
159
- #
160
- # [+multiple+]
161
- # Whether or not the property has multiple values (which
162
- # turns it into an +Array+ of +type+)
163
- #
152
+ ##
153
+ # Defines a model enum property.
154
+ #
155
+ # [+name+]
156
+ # Name of the property
157
+ #
158
+ # [+opts+]
159
+ # [+values+]
160
+ # Required. An array of possible values
161
+ #
162
+ # [+multiple+]
163
+ # Whether or not the property has multiple values (which
164
+ # turns it into an +Array+ of +type+)
165
+ #
164
166
  def enum(name, opts)
165
- raise ArgumentError, 'opts[:values] is required' unless opts and opts[:values]
167
+ raise ArgumentError, "opts[:values] is required" unless opts && opts[:values]
166
168
 
167
169
  (@properties ||= []) << name
168
170
 
@@ -177,7 +179,7 @@ module MetalArchives
177
179
  load! unless loaded? && instance_variable_defined?("@#{name}")
178
180
 
179
181
  property = instance_variable_get("@#{name}")
180
- property.respond_to?(:empty?) ? !property.empty? : !!property
182
+ property.respond_to?(:empty?) ? !property.empty? : !property.nil?
181
183
  end
182
184
 
183
185
  # property=
@@ -185,6 +187,7 @@ module MetalArchives
185
187
  # Check enum type
186
188
  if opts[:multiple]
187
189
  raise MetalArchives::Errors::TypeError, "invalid enum value #{value}, must be Array for #{name}" unless value.is_a? Array
190
+
188
191
  value.each do |val|
189
192
  raise MetalArchives::Errors::TypeError, "invalid enum value #{val} for #{name}" unless opts[:values].include? val
190
193
  end
@@ -196,19 +199,19 @@ module MetalArchives
196
199
  end
197
200
  end
198
201
 
199
- ##
200
- # Defines a model boolean property. This method is an alias for <tt>enum name, :values => [true, false]</tt>
201
- #
202
- # [+name+]
203
- # Name of the property
204
- #
205
- # [+opts+]
206
- # [+multiple+]
207
- # Whether or not the property has multiple values (which
208
- # turns it into an +Array+ of +type+)
209
- #
202
+ ##
203
+ # Defines a model boolean property. This method is an alias for <tt>enum name, :values => [true, false]</tt>
204
+ #
205
+ # [+name+]
206
+ # Name of the property
207
+ #
208
+ # [+opts+]
209
+ # [+multiple+]
210
+ # Whether or not the property has multiple values (which
211
+ # turns it into an +Array+ of +type+)
212
+ #
210
213
  def boolean(name, opts = {})
211
- enum name, opts.merge(:values => [true, false])
214
+ enum name, opts.merge(values: [true, false])
212
215
  end
213
216
  end
214
217
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'date'
4
- require 'countries'
3
+ require "date"
4
+ require "countries"
5
5
 
6
6
  module MetalArchives
7
7
  ##
@@ -13,7 +13,7 @@ module MetalArchives
13
13
  #
14
14
  # Returns +Integer+
15
15
  #
16
- property :id, :type => Integer
16
+ property :id, type: Integer
17
17
 
18
18
  ##
19
19
  # :attr_reader: name
@@ -46,7 +46,7 @@ module MetalArchives
46
46
  # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
47
47
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
48
48
  #
49
- property :country, :type => ISO3166::Country
49
+ property :country, type: ISO3166::Country
50
50
 
51
51
  ##
52
52
  # :attr_reader: phone
@@ -68,7 +68,7 @@ module MetalArchives
68
68
  # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
69
69
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
70
70
  #
71
- property :specializations, :multiple => true
71
+ property :specializations, multiple: true
72
72
 
73
73
  ##
74
74
  # :attr_reader: date_founded
@@ -79,14 +79,14 @@ module MetalArchives
79
79
  # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
80
80
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400 (except 404)
81
81
  #
82
- property :date_founded, :type => NilDate
82
+ property :date_founded, type: NilDate
83
83
 
84
84
  ##
85
85
  # :attr_reader: sub_labels
86
86
  #
87
87
  # Returns +Array+ of rdoc-ref:Label
88
88
  #
89
- property :sub_labels, :type => MetalArchives::Label, :multiple => true
89
+ property :sub_labels, type: MetalArchives::Label, multiple: true
90
90
 
91
91
  ##
92
92
  # :attr_reader: online_shopping
@@ -100,14 +100,14 @@ module MetalArchives
100
100
  #
101
101
  # Returns +Hash+ with the following keys: +title+, +content+
102
102
  #
103
- property :contact, :type => Hash, :multiple => true
103
+ property :contact, type: Hash, multiple: true
104
104
 
105
105
  ##
106
106
  # :attr_reader: status
107
107
  #
108
108
  # Returns +:active+, +:closed+ or +:unknown+
109
109
  #
110
- enum :status, :values => %i[active closed unknown]
110
+ enum :status, values: %i(active closed unknown)
111
111
 
112
112
  class << self
113
113
  ##
@@ -128,8 +128,8 @@ module MetalArchives
128
128
  def find_by_name(name, id)
129
129
  client.find_resource(
130
130
  :band,
131
- :name => name,
132
- :id => id
131
+ name: name,
132
+ id: id
133
133
  )
134
134
  end
135
135
  end