metal_archives 2.2.0 → 3.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|