metal_archives 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 28427a784c317b61bcf01f503f193773f7ab8854
4
- data.tar.gz: 1fdafac6af5df82d1cd1de9c02a9e3357297a160
3
+ metadata.gz: 506a9d5605961addaadfe8c55a609c3d363bb087
4
+ data.tar.gz: 2f4e9daec3ad414a96ee970093e6e775420eaedf
5
5
  SHA512:
6
- metadata.gz: 41f50843c789d298d6b123c2571bae112d2f656d420d1db36bff4c9d4d64437800ff58d0332e207a605c9c07954881eec4faaa06a58454a0ef7325ecbc00fc13
7
- data.tar.gz: 581f8c2e7ebc7bacc8d687b9a7a69db25ac2e579518aa3c66c5fa4ff3c22a739f8b89d17b31ce70b4f949f13aae9b5b51a64257955b14346a067f6769a8c8d56
6
+ metadata.gz: c4e1ddea186668837f3dd74a1ef5190276fd319c4e710b51d859a92fa1b2f24590da01843d21890c298084adb33672974bb57e9996603d0952f04324e1e9e989
7
+ data.tar.gz: e80b21a2b3915bceda1258c6be7329b474d6c77974c29deea11422ca4b5769ba4941e19220c9718326c936bf73a1e49e59bb1406fff2ff11319a537978e2be04
data/README.md CHANGED
@@ -27,14 +27,13 @@ MetalArchives.configure do |c|
27
27
  c.app_version = "1.0"
28
28
  c.app_contact = "support@mymusicapp.com"
29
29
 
30
- # Cache config (optional)
31
- c.enable_cache = true
32
- c.cache_store = ActiveSupport::Cache.lookup_store(:file_store, '/tmp/metal_archives-cache')
33
-
34
30
  # Request throttling (optional, overrides defaults)
35
31
  c.request_rate = 1
36
32
  c.request_timeout = 3
37
33
 
34
+ # Custom cache size per object class (optional, overrides defaults)
35
+ c.cache_size = 100
36
+
38
37
  # Custom logger (optional)
39
38
  c.logger = Logger.new File.new('metal_archives.log')
40
39
  end
@@ -4,6 +4,7 @@ require 'metal_archives/error'
4
4
 
5
5
  require 'metal_archives/utils/range'
6
6
  require 'metal_archives/utils/collection'
7
+ require 'metal_archives/utils/lru_cache'
7
8
 
8
9
  require 'metal_archives/models/base_model'
9
10
  require 'metal_archives/models/label'
@@ -23,7 +23,6 @@ module MetalArchives
23
23
  raise MetalArchives::Errors::InvalidConfigurationError, 'app_name has not been configured' unless MetalArchives.config.app_name and not MetalArchives.config.app_name.empty?
24
24
  raise MetalArchives::Errors::InvalidConfigurationError, 'app_version has not been configured' unless MetalArchives.config.app_version and not MetalArchives.config.app_version.empty?
25
25
  raise MetalArchives::Errors::InvalidConfigurationError, 'app_contact has not been configured' unless MetalArchives.config.app_contact and not MetalArchives.config.app_contact.empty?
26
-
27
26
  end
28
27
  end
29
28
 
@@ -46,16 +45,6 @@ module MetalArchives
46
45
  #
47
46
  attr_accessor :app_contact
48
47
 
49
- ##
50
- # Whether to enable the cache
51
- #
52
- attr_accessor :enable_cache
53
-
54
- ##
55
- # ActiveSupport::Cache compatible store
56
- #
57
- attr_accessor :cache_store
58
-
59
48
  ##
60
49
  # Request throttling rate (in seconds per request per path)
61
50
  #
@@ -71,6 +60,11 @@ module MetalArchives
71
60
  #
72
61
  attr_accessor :logger
73
62
 
63
+ ##
64
+ # Cache size (per object class)
65
+ #
66
+ attr_accessor :cache_size
67
+
74
68
  ##
75
69
  # Default configuration values
76
70
  #
@@ -78,6 +72,7 @@ module MetalArchives
78
72
  @throttle_rate = 1
79
73
  @throttle_wait = 3
80
74
  @logger = Logger.new STDOUT
75
+ @cache_size = 100
81
76
  end
82
77
  end
83
78
  end
@@ -31,5 +31,10 @@ module Errors
31
31
  # Error in backend response
32
32
  #
33
33
  class APIError < Error; end
34
+
35
+ ##
36
+ # Error in method argument
37
+ #
38
+ class ArgumentError < Error; end
34
39
  end
35
40
  end
@@ -1,5 +1,4 @@
1
1
  require 'faraday'
2
- require 'faraday-http-cache'
3
2
  require 'faraday_throttler'
4
3
 
5
4
  module MetalArchives
@@ -40,8 +39,6 @@ module MetalArchives
40
39
  f.response :logger, MetalArchives.config.logger
41
40
 
42
41
  f.use MetalArchives::Middleware
43
- f.use Faraday::HttpCache,
44
- :store => MetalArchives.config.cache_store if !!MetalArchives.config.enable_cache
45
42
  f.use :throttler,
46
43
  :rate => MetalArchives.config.request_rate,
47
44
  :wait => MetalArchives.config.request_timeout,
@@ -191,13 +191,15 @@ module MetalArchives
191
191
  # +Integer+
192
192
  #
193
193
  def find(id)
194
- Artist.new :id => id
194
+ cache[id] = Artist.new :id => id unless cache.include? id
195
+
196
+ cache[id]
195
197
  end
196
198
 
197
199
  ##
198
200
  # Find by ID (no lazy loading)
199
201
  #
200
- # Returns rdoc-ref:Band
202
+ # Returns rdoc-ref:Artist
201
203
  #
202
204
  # [Raises]
203
205
  # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
@@ -209,7 +211,7 @@ module MetalArchives
209
211
  #
210
212
  def find!(id)
211
213
  obj = find id
212
- obj.load!
214
+ obj.load! if obj
213
215
 
214
216
  obj
215
217
  end
@@ -222,12 +224,15 @@ module MetalArchives
222
224
  # [Raises]
223
225
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400
224
226
  # - rdoc-ref:MetalArchives::Errors::ParserError when parsing failed. Please report this error.
227
+ # - rdoc-ref:MetalArchives::Errors::ArgumentError when query contains no :name key
225
228
  #
226
229
  # [+query+]
227
230
  # Hash containing one or more of the following keys:
228
231
  # - +:name+: +String+
229
232
  #
230
233
  def find_by(query)
234
+ raise MetalArchives::Errors::ArgumentError unless query.include? :name
235
+
231
236
  url = 'http://www.metal-archives.com/search/ajax-artist-search/'
232
237
  params = Parsers::Artist.map_params query
233
238
 
@@ -239,7 +244,29 @@ module MetalArchives
239
244
  data = json['aaData'].first
240
245
  id = Nokogiri::HTML(data.first).xpath('//a/@href').first.value.gsub('\\', '').split('/').last.gsub(/\D/, '').to_i
241
246
 
242
- Artist.new :id => id
247
+ find id
248
+ end
249
+
250
+ ##
251
+ # Find by attributes (no lazy loading)
252
+ #
253
+ # Returns rdoc-ref:Artist or nil when no results
254
+ #
255
+ # [Raises]
256
+ # - rdoc-ref:MetalArchives::Errors::InvalidIDError when no or invalid id
257
+ # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400
258
+ # - rdoc-ref:MetalArchives::Errors::ParserError when parsing failed. Please report this error.
259
+ # - rdoc-ref:MetalArchives::Errors::ArgumentError when query contains no :name key
260
+ #
261
+ # [+query+]
262
+ # Hash containing one or more of the following keys:
263
+ # - +:name+: +String+
264
+ #
265
+ def find_by!(query)
266
+ obj = find_by query
267
+ obj.load! if obj
268
+
269
+ obj
243
270
  end
244
271
 
245
272
  ##
@@ -250,11 +277,14 @@ module MetalArchives
250
277
  # [Raises]
251
278
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400
252
279
  # - rdoc-ref:MetalArchives::Errors::ParserError when parsing failed. Please report this error.
280
+ # - rdoc-ref:MetalArchives::Errors::ArgumentError when +name+ isn't a +String+
253
281
  #
254
282
  # [+name+]
255
283
  # +String+
256
284
  #
257
285
  def search(name)
286
+ raise MetalArchives::Errors::ArgumentError unless name.is_a? String
287
+
258
288
  url = 'http://www.metal-archives.com/search/ajax-artist-search/'
259
289
  query = { :name => name }
260
290
 
@@ -263,24 +293,26 @@ module MetalArchives
263
293
  l = lambda do
264
294
  @start ||= 0
265
295
 
266
- return [] if instance_variable_defined?('@max_items') and @start >= @max_items
296
+ if @max_items and @start >= @max_items
297
+ []
298
+ else
299
+ response = HTTPClient.get url, params.merge(:iDisplayStart => @start)
300
+ json = JSON.parse response.body
267
301
 
268
- response = HTTPClient.get url, params.merge(:iDisplayStart => @start)
269
- json = JSON.parse response.body
302
+ @max_items = json['iTotalRecords']
270
303
 
271
- @max_items = json['iTotalRecords']
304
+ objects = []
272
305
 
273
- objects = []
306
+ json['aaData'].each do |data|
307
+ # Create Artist object for every ID in the results list
308
+ id = Nokogiri::HTML(data.first).xpath('//a/@href').first.value.gsub('\\', '').split('/').last.gsub(/\D/, '').to_i
309
+ objects << Artist.find(id)
310
+ end
274
311
 
275
- json['aaData'].each do |data|
276
- # Create Artist object for every ID in the results list
277
- id = Nokogiri::HTML(data.first).xpath('//a/@href').first.value.gsub('\\', '').split('/').last.gsub(/\D/, '').to_i
278
- objects << Artist.new(:id => id)
279
- end
312
+ @start += 200
280
313
 
281
- @start += 200
282
-
283
- objects
314
+ objects
315
+ end
284
316
  end
285
317
 
286
318
  MetalArchives::Collection.new l
@@ -248,7 +248,9 @@ module MetalArchives
248
248
  # +Integer+
249
249
  #
250
250
  def find(id)
251
- Band.new :id => id
251
+ cache[id] = Band.new(:id => id) unless cache.include? id
252
+
253
+ cache[id]
252
254
  end
253
255
 
254
256
  ##
@@ -308,9 +310,39 @@ module MetalArchives
308
310
  data = json['aaData'].first
309
311
  id = Nokogiri::HTML(data.first).xpath('//a/@href').first.value.gsub('\\', '').split('/').last.gsub(/\D/, '').to_i
310
312
 
311
- Band.new :id => id
312
- rescue Errors::APIError
313
- nil
313
+ find id
314
+ end
315
+
316
+ ##
317
+ # Find by attributes (no lazy loading)
318
+ #
319
+ # Refer to {MA's FAQ}[http://www.metal-archives.com/content/help?index=3#tab_db] for search tips.
320
+ #
321
+ # Returns rdoc-ref:Band or nil when no results
322
+ #
323
+ # [Raises]
324
+ # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400
325
+ # - rdoc-ref:MetalArchives::Errors::ParserError when parsing failed. Please report this error.
326
+ #
327
+ # [+query+]
328
+ # Hash containing one or more of the following keys:
329
+ # - +:name+: +String+
330
+ # - +:exact+: +Boolean+
331
+ # - +:genre+: +String+
332
+ # - +:country+: +ISO366::Country+
333
+ # - +:year_formation+: rdoc-ref:Range of +Date+
334
+ # - +:comment+: +String+
335
+ # - +:status+: see rdoc-ref:Band.status
336
+ # - +:lyrical_themes+: +String+
337
+ # - +:location+: +String+
338
+ # - +:label+: rdoc-ref:Label
339
+ # - +:independent+: boolean
340
+ #
341
+ def find_by!(query)
342
+ obj = find_by query
343
+ obj.load! if obj
344
+
345
+ obj
314
346
  end
315
347
 
316
348
  ##
@@ -346,24 +378,26 @@ module MetalArchives
346
378
  l = lambda do
347
379
  @start ||= 0
348
380
 
349
- return [] if instance_variable_defined?('@max_items') and @start >= @max_items
350
-
351
- response = HTTPClient.get url, params.merge(:iDisplayStart => @start)
352
- json = JSON.parse response.body
381
+ if @max_items and @start >= @max_items
382
+ []
383
+ else
384
+ response = HTTPClient.get url, params.merge(:iDisplayStart => @start)
385
+ json = JSON.parse response.body
353
386
 
354
- @max_items = json['iTotalRecords']
387
+ @max_items = json['iTotalRecords']
355
388
 
356
- objects = []
389
+ objects = []
357
390
 
358
- json['aaData'].each do |data|
359
- # Create Band object for every ID in the results list
360
- id = Nokogiri::HTML(data.first).xpath('//a/@href').first.value.gsub('\\', '').split('/').last.gsub(/\D/, '').to_i
361
- objects << Band.new(:id => id)
362
- end
391
+ json['aaData'].each do |data|
392
+ # Create Band object for every ID in the results list
393
+ id = Nokogiri::HTML(data.first).xpath('//a/@href').first.value.gsub('\\', '').split('/').last.gsub(/\D/, '').to_i
394
+ objects << Band.find(id)
395
+ end
363
396
 
364
- @start += 200
397
+ @start += 200
365
398
 
366
- objects
399
+ objects
400
+ end
367
401
  end
368
402
 
369
403
  MetalArchives::Collection.new l
@@ -378,11 +412,13 @@ module MetalArchives
378
412
  #
379
413
  # [Raises]
380
414
  # - rdoc-ref:MetalArchives::Errors::APIError when receiving a status code >= 400
415
+ # - rdoc-ref:MetalArchives::Errors::ArgumentError when +name+ isn't a +String+
381
416
  #
382
417
  # [+name+]
383
418
  # +String+
384
419
  #
385
420
  def search(name)
421
+ raise MetalArchives::Errors::ArgumentError unless name.is_a? String
386
422
  search_by :name => name
387
423
  end
388
424
  end
@@ -55,6 +55,13 @@ module MetalArchives
55
55
  #
56
56
  attr_accessor :properties
57
57
 
58
+ ##
59
+ # Get class-level object cache
60
+ #
61
+ def cache
62
+ @cache ||= MetalArchives::LRUCache.new MetalArchives.config.cache_size
63
+ end
64
+
58
65
  protected
59
66
  ##
60
67
  # Defines a model property.
@@ -0,0 +1,54 @@
1
+ module MetalArchives
2
+ ##
3
+ # Generic LRU memory cache
4
+ #
5
+ class LRUCache
6
+ def initialize(size = 100)
7
+ @size = size
8
+
9
+ # Underlying data store
10
+ @cache = {}
11
+
12
+ # Array of keys in order of insertion
13
+ @keys = []
14
+ end
15
+
16
+ def []=(key, value)
17
+ @cache[key] = value
18
+
19
+ @keys.delete key if @keys.include? key
20
+
21
+ @keys << key
22
+
23
+ pop if @keys.size > @size
24
+ end
25
+
26
+ def [](key)
27
+ if @keys.include? key
28
+ MetalArchives.config.logger.debug "Cache hit for #{key}"
29
+ @keys.delete key
30
+ @keys << key
31
+ else
32
+ MetalArchives.config.logger.debug "Cache miss for #{key}"
33
+ end
34
+
35
+ @cache[key]
36
+ end
37
+
38
+ def clear
39
+ @cache.clear
40
+ @keys.clear
41
+ end
42
+
43
+ def include?(key)
44
+ @cache.include? key
45
+ end
46
+
47
+ private
48
+ def pop
49
+ to_remove = @keys.shift @keys.size - @size
50
+
51
+ to_remove.each { |key| @cache.delete key }
52
+ end
53
+ end
54
+ end
@@ -2,5 +2,5 @@ module MetalArchives
2
2
  ##
3
3
  # MetalArchives API version
4
4
  #
5
- VERSION = '0.5.0'
5
+ VERSION = '0.6.0'
6
6
  end
@@ -18,10 +18,8 @@ Gem::Specification.new do |gem|
18
18
  gem.add_development_dependency 'rake', '~> 11.0'
19
19
  gem.add_development_dependency 'rdoc', '~> 5.0'
20
20
  gem.add_development_dependency 'test-unit', '~> 3.0'
21
- gem.add_development_dependency 'activesupport', '~> 5.0'
22
21
 
23
22
  gem.add_dependency 'faraday', '~> 0.9'
24
- gem.add_dependency 'faraday-http-cache', '~> 2.0'
25
23
  gem.add_dependency 'faraday_throttler', '~> 0.0.3'
26
24
  gem.add_dependency 'nokogiri', '~> 1.6.8'
27
25
  gem.add_dependency 'countries', '~> 1.2.5'
@@ -29,7 +29,7 @@ class ArtistPropertyTest < Test::Unit::TestCase
29
29
  assert_equal 'Ian Fraser Kilmister', artist.name
30
30
  assert_equal ['Lemmy Kilmister'], artist.aliases
31
31
  assert_equal Date.new(2015, 12, 28), artist.date_of_death
32
- assert_equal 4, artist.links.length
32
+ assert_equal 5, artist.links.length
33
33
  assert_equal 1, artist.links.count { |l| l[:type] == :official }
34
34
  assert_equal 2, artist.links.count { |l| l[:type] == :unofficial }
35
35
  assert_equal 1, artist.links.count { |l| l[:type] == :unlisted_bands }
@@ -58,12 +58,22 @@ class ArtistQueryTest < Test::Unit::TestCase
58
58
  assert_nil artist
59
59
  end
60
60
 
61
+ def test_find_by!
62
+ artist = MetalArchives::Artist.find_by! :name => 'Alberto Rionda'
63
+
64
+ assert_instance_of MetalArchives::Artist, artist
65
+
66
+ artist = MetalArchives::Artist.find_by! :name => 'SomeNonExistantName'
67
+
68
+ assert_nil artist
69
+ end
70
+
61
71
  def test_search
62
72
  assert_instance_of MetalArchives::Collection, MetalArchives::Artist.search('Alberto Rionda')
63
73
  assert_equal 1, MetalArchives::Artist.search('Alberto Rionda').count
64
74
  assert_equal 9, MetalArchives::Artist.search('Name').count
65
75
  assert_equal 0, MetalArchives::Artist.search('SomeNonExistantName').count
66
- assert_equal 293, MetalArchives::Artist.search('Filip').count
76
+ assert_equal 296, MetalArchives::Artist.search('Filip').count
67
77
 
68
78
  assert !MetalArchives::Artist.search('SomeNonExistantName').any?
69
79
  end
@@ -71,6 +71,16 @@ class BandQueryTest < Test::Unit::TestCase
71
71
  assert_equal 3540361100, band.id
72
72
  end
73
73
 
74
+ def test_find_by!
75
+ band = MetalArchives::Band.find_by! :name => 'Falconer'
76
+
77
+ assert_instance_of MetalArchives::Band, band
78
+
79
+ band = MetalArchives::Band.find_by! :name => 'SomeNonExistantName'
80
+
81
+ assert_nil band
82
+ end
83
+
74
84
  def test_search_by
75
85
  assert_instance_of MetalArchives::Collection, MetalArchives::Band.search_by(:name => 'Alquimia')
76
86
 
@@ -106,7 +116,7 @@ class BandQueryTest < Test::Unit::TestCase
106
116
  assert_equal 0, MetalArchives::Band.search_by(:name => 'SomeNonExistantName').count
107
117
  assert !MetalArchives::Band.search_by(:name => 'SomeNonExistantName').any?
108
118
 
109
- assert_equal 274, MetalArchives::Band.search_by(:country => ISO3166::Country['CN']).count
119
+ assert_equal 279, MetalArchives::Band.search_by(:country => ISO3166::Country['CN']).count
110
120
  end
111
121
 
112
122
  def test_errors
data/test/test_helper.rb CHANGED
@@ -13,9 +13,8 @@ MetalArchives.configure do |c|
13
13
  c.app_version = MetalArchives::VERSION
14
14
  c.app_contact = `git config user.email`.chomp || 'user@example.com'
15
15
 
16
- # Cache config (optional)
17
- c.enable_cache = false
18
- # c.cache_store = ActiveSupport::Cache.lookup_store(:file_store, '/tmp/metal_archives-cache')
16
+ # Custom cache size per object class (optional, overrides defaults)
17
+ c.cache_size = 1
19
18
 
20
19
  # Request throttling (optional, overrides defaults)
21
20
  c.request_rate = 1
@@ -0,0 +1,22 @@
1
+ require_relative '../test_helper'
2
+
3
+ class LruCacheTest < Test::Unit::TestCase
4
+ def test_lru
5
+ cache = MetalArchives::LRUCache.new 3
6
+
7
+ cache[:a] = 'one'
8
+ cache[:b] = 'two'
9
+ cache[:c] = 'three'
10
+
11
+ assert_equal 3, cache.instance_variable_get('@size')
12
+
13
+ cache[:d] = 'four'
14
+
15
+ assert_equal 3, cache.instance_variable_get('@size')
16
+
17
+ assert_equal 'two', cache[:b]
18
+ assert_equal 'three', cache[:c]
19
+ assert_equal 'four', cache[:d]
20
+ assert_equal nil, cache[:a]
21
+ end
22
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metal_archives
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Dejonckheere
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-07 00:00:00.000000000 Z
11
+ date: 2017-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: byebug
@@ -66,20 +66,6 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
- - !ruby/object:Gem::Dependency
70
- name: activesupport
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '5.0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '5.0'
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: faraday
85
71
  requirement: !ruby/object:Gem::Requirement
@@ -94,20 +80,6 @@ dependencies:
94
80
  - - "~>"
95
81
  - !ruby/object:Gem::Version
96
82
  version: '0.9'
97
- - !ruby/object:Gem::Dependency
98
- name: faraday-http-cache
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '2.0'
104
- type: :runtime
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '2.0'
111
83
  - !ruby/object:Gem::Dependency
112
84
  name: faraday_throttler
113
85
  requirement: !ruby/object:Gem::Requirement
@@ -176,6 +148,7 @@ files:
176
148
  - lib/metal_archives/parsers/label.rb
177
149
  - lib/metal_archives/parsers/parser.rb
178
150
  - lib/metal_archives/utils/collection.rb
151
+ - lib/metal_archives/utils/lru_cache.rb
179
152
  - lib/metal_archives/utils/range.rb
180
153
  - lib/metal_archives/version.rb
181
154
  - metal_archives.gemspec
@@ -188,6 +161,7 @@ files:
188
161
  - test/query/band_query_test.rb
189
162
  - test/test_helper.rb
190
163
  - test/utils/collection_test.rb
164
+ - test/utils/lru_cache_test.rb
191
165
  - test/utils/range_test.rb
192
166
  homepage: http://github.com/floriandejonckheere/metal_archives
193
167
  licenses:
@@ -209,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
209
183
  version: '0'
210
184
  requirements: []
211
185
  rubyforge_project:
212
- rubygems_version: 2.5.2
186
+ rubygems_version: 2.6.8
213
187
  signing_key:
214
188
  specification_version: 4
215
189
  summary: Metal Archives Ruby API