21
1
Fork 0
mirror of https://github.com/Evolix/chexpire.git synced 2024-04-29 07:20:50 +02:00
chexpire/app/services/whois/parser/base.rb

103 lines
2.5 KiB
Ruby
Raw Normal View History

# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
# License: GNU AGPL-3+ (see full text in LICENSE file)
2018-05-30 12:04:07 +02:00
require_relative "../response"
module Whois
module Parser
class Base
extend DomainHelper
attr_reader :domain
attr_reader :logger
attr_reader :response
attr_reader :entries
attr_reader :date_format
def initialize(domain, logger: NullLogger.new)
@domain = domain
@logger = logger
@response = Response.new(domain)
@date_format = nil
end
def parse(raw)
@entries = build_entries(raw)
do_parse
2018-05-30 16:51:24 +02:00
logger.log :parsed_response, response
2018-05-30 12:04:07 +02:00
response
2018-06-05 15:25:19 +02:00
rescue ParserError => ex
2018-05-30 16:51:24 +02:00
logger.log :parser_error, ex
2018-05-30 18:15:20 +02:00
raise
2018-05-30 12:04:07 +02:00
end
protected
2019-02-28 00:15:03 +01:00
def get_field(name, after: -1, value: nil)
2018-05-30 12:04:07 +02:00
fields.detect { |field|
field.index > after &&
field.name == name &&
(value.nil? || field.value == value)
2019-02-28 00:15:03 +01:00
}
end
2019-02-28 23:43:21 +01:00
2019-02-28 00:15:03 +01:00
def get_field!(name, after: -1, value: nil)
2019-02-28 23:43:21 +01:00
get_field(name, after: after, value: value) \
|| fail(FieldNotFoundError, "Field `#{name}` not found, after index #{after}")
2018-05-30 12:04:07 +02:00
end
def get_value!(name, after: -1)
get_field!(name, after: after).value
end
def parse_date(str)
2018-06-05 16:39:08 +02:00
date_format.nil? ? Time.parse(str) : Time.strptime(str, date_format)
rescue ArgumentError
msg = if date_format.nil?
"Date `#{str}` is not parsable without specifying a date format"
else
"Date `#{str}` does not match format #{date_format}"
2018-05-30 12:04:07 +02:00
end
2018-06-05 16:39:08 +02:00
raise InvalidDateError, msg
2018-05-30 12:04:07 +02:00
end
2018-05-30 18:15:20 +02:00
def comment_include?(str)
entries.any? { |e|
e.comment? && e.text? && e.text.include?(str)
}
end
2018-06-05 16:39:08 +02:00
def text_include?(str)
entries.any? { |e|
e.text? && e.text.include?(str)
}
end
2018-05-30 18:15:20 +02:00
def raise_not_found
fail DomainNotFoundError, "Domain #{domain} not found in the registry database."
end
2018-05-30 12:04:07 +02:00
private
def build_entries(raw)
builder = EntryBuilder.new(
field_regex: self.class::FIELD_REGEX,
comment_regex: self.class::COMMENT_REGEX,
)
raw.split("\n").map.each_with_index { |line, index|
builder.build_from_line(line, index)
}.sort_by(&:index)
end
def fields
@fields ||= entries.select(&:field?)
end
end
end
end