metal_archives 2.2.0 → 3.1.1
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.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +93 -0
- data/.gitignore +6 -6
- data/.overcommit.yml +35 -0
- data/.rspec +2 -0
- data/.rubocop.yml +66 -6
- data/CHANGELOG.md +33 -0
- data/Gemfile +1 -1
- data/LICENSE.md +17 -4
- data/README.md +65 -86
- data/Rakefile +8 -7
- data/bin/console +38 -0
- data/bin/setup +8 -0
- data/config/inflections.rb +7 -0
- data/config/initializers/.keep +0 -0
- data/docker-compose.yml +23 -0
- data/lib/metal_archives.rb +82 -27
- data/lib/metal_archives/cache/base.rb +40 -0
- data/lib/metal_archives/cache/memory.rb +68 -0
- data/lib/metal_archives/cache/null.rb +22 -0
- data/lib/metal_archives/cache/redis.rb +49 -0
- data/lib/metal_archives/{utils/collection.rb → collection.rb} +3 -5
- data/lib/metal_archives/configuration.rb +33 -50
- data/lib/metal_archives/{error.rb → errors.rb} +9 -1
- data/lib/metal_archives/http_client.rb +45 -44
- data/lib/metal_archives/models/artist.rb +90 -45
- data/lib/metal_archives/models/band.rb +77 -52
- data/lib/metal_archives/models/base.rb +225 -0
- data/lib/metal_archives/models/label.rb +14 -15
- data/lib/metal_archives/models/release.rb +25 -29
- data/lib/metal_archives/parsers/artist.rb +86 -50
- data/lib/metal_archives/parsers/band.rb +155 -88
- data/lib/metal_archives/parsers/base.rb +14 -0
- data/lib/metal_archives/parsers/country.rb +21 -0
- data/lib/metal_archives/parsers/date.rb +31 -0
- data/lib/metal_archives/parsers/genre.rb +67 -0
- data/lib/metal_archives/parsers/label.rb +39 -31
- data/lib/metal_archives/parsers/parser.rb +18 -63
- data/lib/metal_archives/parsers/release.rb +98 -89
- data/lib/metal_archives/parsers/year.rb +31 -0
- data/lib/metal_archives/version.rb +12 -1
- data/metal_archives.env.example +10 -0
- data/metal_archives.gemspec +43 -28
- data/nginx/default.conf +60 -0
- metadata +179 -74
- data/.travis.yml +0 -12
- data/lib/metal_archives/middleware/cache_check.rb +0 -20
- data/lib/metal_archives/middleware/encoding.rb +0 -16
- data/lib/metal_archives/middleware/headers.rb +0 -38
- data/lib/metal_archives/middleware/rewrite_endpoint.rb +0 -38
- data/lib/metal_archives/models/base_model.rb +0 -215
- data/lib/metal_archives/utils/lru_cache.rb +0 -61
- data/lib/metal_archives/utils/nil_date.rb +0 -99
- data/lib/metal_archives/utils/range.rb +0 -66
- data/spec/configuration_spec.rb +0 -96
- data/spec/factories/artist_factory.rb +0 -37
- data/spec/factories/band_factory.rb +0 -60
- data/spec/factories/nil_date_factory.rb +0 -9
- data/spec/factories/range_factory.rb +0 -8
- data/spec/models/artist_spec.rb +0 -138
- data/spec/models/band_spec.rb +0 -164
- data/spec/models/base_model_spec.rb +0 -219
- data/spec/models/release_spec.rb +0 -133
- data/spec/parser_spec.rb +0 -19
- data/spec/spec_helper.rb +0 -111
- data/spec/support/factory_girl.rb +0 -5
- data/spec/support/metal_archives.rb +0 -33
- data/spec/utils/collection_spec.rb +0 -72
- data/spec/utils/lru_cache_spec.rb +0 -53
- data/spec/utils/nil_date_spec.rb +0 -156
- data/spec/utils/range_spec.rb +0 -62
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "countries"
|
4
|
+
|
5
|
+
module MetalArchives
|
6
|
+
module Parsers
|
7
|
+
##
|
8
|
+
# Country parser
|
9
|
+
#
|
10
|
+
class Country < Base
|
11
|
+
##
|
12
|
+
# Parse a country
|
13
|
+
#
|
14
|
+
# Returns +ISO3166::Country+
|
15
|
+
#
|
16
|
+
def self.parse(input)
|
17
|
+
ISO3166::Country.find_country_by_name(input)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetalArchives
|
4
|
+
module Parsers
|
5
|
+
##
|
6
|
+
# Date parser
|
7
|
+
#
|
8
|
+
class Date < Base
|
9
|
+
##
|
10
|
+
# Parse a date
|
11
|
+
#
|
12
|
+
# Returns +Date+
|
13
|
+
#
|
14
|
+
def self.parse(input)
|
15
|
+
::Date.parse(input)
|
16
|
+
rescue ::Date::Error
|
17
|
+
components = input
|
18
|
+
.split("-")
|
19
|
+
.map(&:to_i)
|
20
|
+
.reject(&:zero?)
|
21
|
+
.compact
|
22
|
+
|
23
|
+
return if components.empty?
|
24
|
+
|
25
|
+
::Date.new(*components)
|
26
|
+
rescue TypeError
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetalArchives
|
4
|
+
module Parsers
|
5
|
+
##
|
6
|
+
# Genre parser
|
7
|
+
#
|
8
|
+
class Genre < Base
|
9
|
+
SUFFIXES = %w((early) (later) metal).freeze
|
10
|
+
|
11
|
+
##
|
12
|
+
# Opinionated parsing of genres
|
13
|
+
#
|
14
|
+
# Returns an +Array+ of +String+
|
15
|
+
#
|
16
|
+
# The following components are omitted:
|
17
|
+
# - Metal
|
18
|
+
# - (early)
|
19
|
+
# - (later)
|
20
|
+
#
|
21
|
+
# All genres are capitalized.
|
22
|
+
#
|
23
|
+
# For examples on how genres are parsed, refer to +gnre_spec.rb+
|
24
|
+
#
|
25
|
+
def self.parse(input)
|
26
|
+
genres = []
|
27
|
+
# Split fields
|
28
|
+
input.split(/[,;]/).each do |genre|
|
29
|
+
##
|
30
|
+
# Start with a single empty genre string. Split the genre by spaces
|
31
|
+
# and process each component. If a component does not have a slash,
|
32
|
+
# concatenate it to all genre strings present in +temp+. If it does
|
33
|
+
# have a slash present, duplicate all genre strings, and concatenate
|
34
|
+
# the first component (before the slash) to the first half, and the
|
35
|
+
# last component to the last half. +temp+ now has an array of genre
|
36
|
+
# combinations.
|
37
|
+
#
|
38
|
+
# 'Traditional Heavy/Power Metal' => ['Traditional Heavy', 'Traditional Power']
|
39
|
+
# 'Traditional/Classical Heavy/Power Metal' => [
|
40
|
+
# 'Traditional Heavy', 'Traditional Power',
|
41
|
+
# 'Classical Heavy', 'Classical Power']
|
42
|
+
#
|
43
|
+
temp = [""]
|
44
|
+
|
45
|
+
genre.downcase.split.reject { |g| SUFFIXES.include? g }.each do |g|
|
46
|
+
if g.include? "/"
|
47
|
+
# Duplicate all WIP genres
|
48
|
+
temp2 = temp.dup
|
49
|
+
|
50
|
+
# Assign first and last components to temp and temp2 respectively
|
51
|
+
split = g.split "/"
|
52
|
+
temp.map! { |t| t.empty? ? split.first.capitalize : "#{t.capitalize} #{split.first.capitalize}" }
|
53
|
+
temp2.map! { |t| t.empty? ? split.last.capitalize : "#{t.capitalize} #{split.last.capitalize}" }
|
54
|
+
|
55
|
+
# Add both genre trees
|
56
|
+
temp += temp2
|
57
|
+
else
|
58
|
+
temp.map! { |t| t.empty? ? g.capitalize : "#{t.capitalize} #{g.capitalize}" }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
genres += temp
|
62
|
+
end
|
63
|
+
genres.uniq
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "date"
|
4
|
+
require "nokogiri"
|
5
5
|
|
6
6
|
module MetalArchives
|
7
7
|
module Parsers
|
@@ -11,53 +11,61 @@ module MetalArchives
|
|
11
11
|
class Label # :nodoc:
|
12
12
|
class << self
|
13
13
|
def find_endpoint(params)
|
14
|
-
"#{MetalArchives.config.
|
14
|
+
"#{MetalArchives.config.endpoint}labels/#{params[:name]}/#{params[:id]}"
|
15
15
|
end
|
16
16
|
|
17
17
|
def parse(response)
|
18
|
-
|
18
|
+
# Set default props
|
19
|
+
props = {
|
20
|
+
name: nil,
|
21
|
+
contact: [],
|
22
|
+
address: nil,
|
23
|
+
country: nil,
|
24
|
+
phone: nil,
|
25
|
+
status: nil,
|
26
|
+
specialization: [],
|
27
|
+
date_founded: nil,
|
28
|
+
|
29
|
+
online_shopping: nil,
|
30
|
+
}
|
31
|
+
|
19
32
|
doc = Nokogiri::HTML(response)
|
20
33
|
|
21
|
-
props[:name] = doc.css(
|
34
|
+
props[:name] = doc.css("#label_info .label_name").first.content
|
22
35
|
|
23
|
-
|
24
|
-
doc.css('#label_contact a').each do |contact|
|
36
|
+
doc.css("#label_contact a").each do |contact|
|
25
37
|
props[:contact] << {
|
26
|
-
:
|
27
|
-
:
|
38
|
+
title: contact.content,
|
39
|
+
content: contact.attr(:href),
|
28
40
|
}
|
29
41
|
end
|
30
42
|
|
31
|
-
doc.css(
|
32
|
-
dl.search(
|
43
|
+
doc.css("#label_info dl").each do |dl|
|
44
|
+
dl.search("dt").each do |dt|
|
33
45
|
content = sanitize(dt.next_element.content)
|
34
46
|
|
35
|
-
next if content ==
|
47
|
+
next if content == "N/A"
|
36
48
|
|
37
49
|
case sanitize(dt.content)
|
38
|
-
when
|
50
|
+
when "Address:"
|
39
51
|
props[:address] = content
|
40
|
-
when
|
41
|
-
props[:country] =
|
42
|
-
when
|
52
|
+
when "Country:"
|
53
|
+
props[:country] = Country.parse(css("a").first.content)
|
54
|
+
when "Phone number:"
|
43
55
|
props[:phone] = content
|
44
|
-
when
|
45
|
-
props[:status] = content.downcase.tr(
|
46
|
-
when
|
47
|
-
props[:specializations] =
|
48
|
-
when
|
49
|
-
|
50
|
-
|
51
|
-
props[:date_founded] = NilDate.new dof.year, dof.month, dof.day
|
52
|
-
rescue ArgumentError => e
|
53
|
-
props[:date_founded] = NilDate.parse content
|
54
|
-
end
|
55
|
-
when 'Sub-labels:'
|
56
|
+
when "Status:"
|
57
|
+
props[:status] = content.downcase.tr(" ", "_").to_sym
|
58
|
+
when "Specialised in:"
|
59
|
+
props[:specializations] = Parsers::Genre.parse(content)
|
60
|
+
when "Founding date :"
|
61
|
+
props[:date_founded] = Parsers::Date.parse(content)
|
62
|
+
when "Sub-labels:"
|
56
63
|
# TODO
|
57
|
-
when
|
58
|
-
|
64
|
+
when "Online shopping:"
|
65
|
+
case content
|
66
|
+
when "Yes"
|
59
67
|
props[:online_shopping] = true
|
60
|
-
|
68
|
+
when "No"
|
61
69
|
props[:online_shopping] = false
|
62
70
|
end
|
63
71
|
else
|
@@ -1,88 +1,43 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require 'countries'
|
3
|
+
require "date"
|
5
4
|
|
6
5
|
module MetalArchives
|
7
|
-
|
8
|
-
# Mapping layer from and to MA Web Service
|
9
|
-
#
|
10
|
-
module Parsers # :nodoc:
|
6
|
+
module Parsers
|
11
7
|
##
|
12
8
|
# Parser base class
|
13
9
|
#
|
14
10
|
class Parser
|
15
11
|
class << self
|
16
|
-
##
|
17
|
-
# Parse a country
|
18
|
-
#
|
19
|
-
# Returns +ISO3166::Country+
|
20
|
-
#
|
21
|
-
def parse_country(input)
|
22
|
-
ISO3166::Country.find_country_by_name input
|
23
|
-
end
|
24
|
-
|
25
12
|
##
|
26
13
|
# Sanitize a string
|
27
14
|
#
|
28
15
|
# Return +String+
|
29
16
|
#
|
30
17
|
def sanitize(input)
|
31
|
-
|
18
|
+
return if input.blank?
|
19
|
+
|
20
|
+
input
|
21
|
+
.gsub(/^"/, "")
|
22
|
+
.gsub(/"$/, "")
|
23
|
+
.gsub(/[[:space:]]/, " ")
|
24
|
+
.strip
|
32
25
|
end
|
33
26
|
|
34
27
|
##
|
35
|
-
#
|
36
|
-
#
|
37
|
-
# Returns an +Array+ of +String+
|
38
|
-
#
|
39
|
-
# The following components are omitted:
|
40
|
-
# - Metal
|
41
|
-
# - (early)
|
42
|
-
# - (later)
|
43
|
-
#
|
44
|
-
# All genres are capitalized.
|
28
|
+
# Rewrite a URL
|
45
29
|
#
|
46
|
-
#
|
30
|
+
# Return +URI+
|
47
31
|
#
|
48
|
-
def
|
49
|
-
|
50
|
-
# Split fields
|
51
|
-
input.split(',').each do |genre|
|
52
|
-
##
|
53
|
-
# Start with a single empty genre string. Split the genre by spaces
|
54
|
-
# and process each component. If a component does not have a slash,
|
55
|
-
# concatenate it to all genre strings present in +temp+. If it does
|
56
|
-
# have a slash present, duplicate all genre strings, and concatenate
|
57
|
-
# the first component (before the slash) to the first half, and the
|
58
|
-
# last component to the last half. +temp+ now has an array of genre
|
59
|
-
# combinations.
|
60
|
-
#
|
61
|
-
# 'Traditional Heavy/Power Metal' => ['Traditional Heavy', 'Traditional Power']
|
62
|
-
# 'Traditional/Classical Heavy/Power Metal' => [
|
63
|
-
# 'Traditional Heavy', 'Traditional Power',
|
64
|
-
# 'Classical Heavy', 'Classical Power']
|
65
|
-
#
|
66
|
-
temp = ['']
|
67
|
-
genre.downcase.split.reject { |g| ['(early)', '(later)', 'metal'].include? g }.each do |g|
|
68
|
-
if g.include? '/'
|
69
|
-
# Duplicate all WIP genres
|
70
|
-
temp2 = temp.dup
|
32
|
+
def rewrite(input)
|
33
|
+
return input unless MetalArchives.config.endpoint
|
71
34
|
|
72
|
-
|
73
|
-
split = g.split '/'
|
74
|
-
temp.map! { |t| t.empty? ? split.first.capitalize : "#{t.capitalize} #{split.first.capitalize}" }
|
75
|
-
temp2.map! { |t| t.empty? ? split.last.capitalize : "#{t.capitalize} #{split.last.capitalize}" }
|
35
|
+
endpoint = URI(MetalArchives.config.endpoint)
|
76
36
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
82
|
-
end
|
83
|
-
genres += temp
|
84
|
-
end
|
85
|
-
genres.uniq
|
37
|
+
URI(input)
|
38
|
+
.tap { |u| u.host = endpoint.host }
|
39
|
+
.tap { |u| u.scheme = endpoint.scheme }
|
40
|
+
.to_s
|
86
41
|
end
|
87
42
|
end
|
88
43
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "json"
|
4
|
+
require "date"
|
5
5
|
|
6
6
|
module MetalArchives
|
7
7
|
module Parsers
|
@@ -11,52 +11,56 @@ module MetalArchives
|
|
11
11
|
class Release < Parser # :nodoc:
|
12
12
|
class << self
|
13
13
|
TYPE_TO_QUERY = {
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
14
|
+
full_length: 1,
|
15
|
+
live: 2,
|
16
|
+
demo: 3,
|
17
|
+
single: 4,
|
18
|
+
ep: 5,
|
19
|
+
video: 6,
|
20
|
+
boxed_set: 7,
|
21
|
+
split: 8,
|
22
|
+
compilation: 10,
|
23
|
+
split_video: 12,
|
24
|
+
collaboration: 13,
|
25
25
|
}.freeze
|
26
26
|
|
27
27
|
TYPE_TO_SYM = {
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
28
|
+
"Full-length" => :full_length,
|
29
|
+
"Live album" => :live,
|
30
|
+
"Demo" => :demo,
|
31
|
+
"Single" => :single,
|
32
|
+
"EP" => :ep,
|
33
|
+
"Video" => :video,
|
34
|
+
"Boxed set" => :boxed_set,
|
35
|
+
"Split" => :split,
|
36
|
+
"Compilation" => :compilation,
|
37
|
+
"Split video" => :split_video,
|
38
|
+
"Collaboration" => :collaboration,
|
39
39
|
}.freeze
|
40
40
|
|
41
41
|
FORMAT_TO_QUERY = {
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
49
|
-
:
|
42
|
+
cd: "CD",
|
43
|
+
cassette: "Cassette",
|
44
|
+
vinyl: "Vinyl*",
|
45
|
+
vhs: "VHS",
|
46
|
+
dvd: "DVD",
|
47
|
+
"2dvd": "2DVD",
|
48
|
+
digital: "Digital",
|
49
|
+
blu_ray: "Blu-ray*",
|
50
|
+
other: "Other",
|
51
|
+
unknown: "Unknown",
|
50
52
|
}.freeze
|
51
53
|
|
52
54
|
FORMAT_TO_SYM = {
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
"CD" => :cd,
|
56
|
+
"Cassette" => :cassette,
|
57
|
+
"VHS" => :vhs,
|
58
|
+
"DVD" => :dvd,
|
59
|
+
"2DVD" => :"2dvd",
|
60
|
+
"Digital" => :digital,
|
61
|
+
"Other" => :other,
|
62
|
+
"Unknown" => :unknown,
|
63
|
+
}.freeze
|
60
64
|
|
61
65
|
##
|
62
66
|
# Map attributes to MA attributes
|
@@ -67,27 +71,25 @@ module MetalArchives
|
|
67
71
|
# +Hash+
|
68
72
|
#
|
69
73
|
def map_params(query)
|
70
|
-
|
71
|
-
:
|
72
|
-
:
|
73
|
-
:
|
74
|
-
:
|
75
|
-
:
|
76
|
-
:
|
77
|
-
:
|
78
|
-
:
|
79
|
-
:
|
80
|
-
:
|
81
|
-
:
|
82
|
-
:
|
83
|
-
:
|
84
|
-
:
|
85
|
-
:
|
86
|
-
:
|
87
|
-
:
|
74
|
+
{
|
75
|
+
bandName: query[:band_name] || "",
|
76
|
+
releaseTitle: query[:title] || "",
|
77
|
+
releaseYearFrom: query[:from_year] || "",
|
78
|
+
releaseMonthFrom: query[:from_month] || "",
|
79
|
+
releaseYearTo: query[:to_year] || "",
|
80
|
+
releaseMonthTo: query[:to_month] || "",
|
81
|
+
country: map_countries(query[:country]) || "",
|
82
|
+
location: query[:location] || "",
|
83
|
+
releaseLabelName: query[:label_name] || "",
|
84
|
+
releaseCatalogNumber: query[:catalog_id] || "",
|
85
|
+
releaseIdentifiers: query[:identifier] || "",
|
86
|
+
releaseRecordingInfo: query[:recording_info] || "",
|
87
|
+
releaseDescription: query[:version_description] || "",
|
88
|
+
releaseNotes: query[:notes] || "",
|
89
|
+
genre: query[:genre] || "",
|
90
|
+
releaseType: map_types(query[:types]),
|
91
|
+
releaseFormat: map_formats(query[:formats]),
|
88
92
|
}
|
89
|
-
|
90
|
-
params
|
91
93
|
end
|
92
94
|
|
93
95
|
##
|
@@ -99,50 +101,56 @@ module MetalArchives
|
|
99
101
|
# - rdoc-ref:MetalArchives::Errors::ParserError when parsing failed. Please report this error.
|
100
102
|
#
|
101
103
|
def parse_html(response)
|
102
|
-
|
104
|
+
# Set default props
|
105
|
+
props = {
|
106
|
+
title: nil,
|
107
|
+
type: nil,
|
108
|
+
date_released: nil,
|
109
|
+
catalog_id: nil,
|
110
|
+
identifier: nil,
|
111
|
+
version_description: nil,
|
112
|
+
format: nil,
|
113
|
+
limitation: nil,
|
114
|
+
}
|
115
|
+
|
103
116
|
doc = Nokogiri::HTML response
|
104
117
|
|
105
|
-
props[:title] = sanitize doc.css(
|
118
|
+
props[:title] = sanitize doc.css("#album_info .album_name a").first.content
|
106
119
|
|
107
|
-
doc.css(
|
108
|
-
dl.search(
|
120
|
+
doc.css("#album_info dl").each do |dl|
|
121
|
+
dl.search("dt").each do |dt|
|
109
122
|
content = sanitize dt.next_element.content
|
110
123
|
|
111
|
-
next if content ==
|
124
|
+
next if content == "N/A"
|
112
125
|
|
113
126
|
case sanitize(dt.content)
|
114
|
-
when
|
127
|
+
when "Type:"
|
115
128
|
props[:type] = map_type content
|
116
|
-
when
|
117
|
-
|
118
|
-
|
119
|
-
rescue MetalArchives::Errors::ArgumentError => e
|
120
|
-
dr = Date.parse content
|
121
|
-
props[:date_released] = NilDate.new dr.year, dr.month, dr.day
|
122
|
-
end
|
123
|
-
when 'Catalog ID:'
|
129
|
+
when "Release date:"
|
130
|
+
props[:date_released] = Parsers::Date.parse(content)
|
131
|
+
when "Catalog ID:"
|
124
132
|
props[:catalog_id] = content
|
125
|
-
when
|
133
|
+
when "Identifier:"
|
126
134
|
props[:identifier] = content
|
127
|
-
when
|
135
|
+
when "Version desc.:"
|
128
136
|
props[:version_description] = content
|
129
|
-
when
|
137
|
+
when "Label:"
|
130
138
|
# TODO: label
|
131
|
-
when
|
139
|
+
when "Format:"
|
132
140
|
props[:format] = map_format content
|
133
|
-
when
|
141
|
+
when "Limitation:"
|
134
142
|
props[:limitation] = content.to_i
|
135
|
-
when
|
136
|
-
next if content ==
|
143
|
+
when "Reviews:"
|
144
|
+
next if content == "None yet"
|
137
145
|
# TODO: reviews
|
138
146
|
else
|
139
|
-
raise
|
147
|
+
raise Errors::ParserError, "Unknown token: #{dt.content}"
|
140
148
|
end
|
141
149
|
end
|
142
150
|
end
|
143
151
|
|
144
152
|
props
|
145
|
-
rescue => e
|
153
|
+
rescue StandardError => e
|
146
154
|
e.backtrace.each { |b| MetalArchives.config.logger.error b }
|
147
155
|
raise Errors::ParserError, e
|
148
156
|
end
|
@@ -158,7 +166,7 @@ module MetalArchives
|
|
158
166
|
# +Array+ containing one or more +String+s
|
159
167
|
#
|
160
168
|
def map_countries(countries)
|
161
|
-
countries
|
169
|
+
countries&.map(&:alpha2)
|
162
170
|
end
|
163
171
|
|
164
172
|
##
|
@@ -174,7 +182,7 @@ module MetalArchives
|
|
174
182
|
|
175
183
|
types = []
|
176
184
|
type_syms.each do |type|
|
177
|
-
raise
|
185
|
+
raise Errors::ParserError, "Unknown type: #{type}" unless TYPE_TO_QUERY[type]
|
178
186
|
|
179
187
|
types << TYPE_TO_QUERY[type]
|
180
188
|
end
|
@@ -188,7 +196,7 @@ module MetalArchives
|
|
188
196
|
# Returns +Symbol+, see rdoc-ref:Release.type
|
189
197
|
#
|
190
198
|
def map_type(type)
|
191
|
-
raise
|
199
|
+
raise Errors::ParserError, "Unknown type: #{type}" unless TYPE_TO_SYM[type]
|
192
200
|
|
193
201
|
TYPE_TO_SYM[type]
|
194
202
|
end
|
@@ -206,7 +214,7 @@ module MetalArchives
|
|
206
214
|
|
207
215
|
formats = []
|
208
216
|
format_syms.each do |format|
|
209
|
-
raise
|
217
|
+
raise Errors::ParserError, "Unknown format: #{format}" unless FORMAT_TO_QUERY[format]
|
210
218
|
|
211
219
|
formats << FORMAT_TO_QUERY[format]
|
212
220
|
end
|
@@ -220,10 +228,11 @@ module MetalArchives
|
|
220
228
|
# Returns +Symbol+, see rdoc-ref:Release.format
|
221
229
|
#
|
222
230
|
def map_format(format)
|
223
|
-
return :
|
224
|
-
return :
|
231
|
+
return :cd if /CD/.match?(format)
|
232
|
+
return :vinyl if /[Vv]inyl/.match?(format)
|
233
|
+
return :blu_ray if /[Bb]lu.?[Rr]ay/.match?(format)
|
225
234
|
|
226
|
-
raise
|
235
|
+
raise Errors::ParserError, "Unknown format: #{format}" unless FORMAT_TO_SYM[format]
|
227
236
|
|
228
237
|
FORMAT_TO_SYM[format]
|
229
238
|
end
|