2018-08-02 00:09:29 +02:00
|
|
|
# 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 "null_logger"
|
|
|
|
require_relative "../response"
|
|
|
|
require_relative "../errors"
|
|
|
|
require_relative "entry_builder"
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
def get_field!(name, after: -1, value: nil)
|
|
|
|
fields.detect { |field|
|
|
|
|
field.index > after &&
|
|
|
|
field.name == name &&
|
|
|
|
(value.nil? || field.value == value)
|
|
|
|
} || fail(FieldNotFoundError, "Field `#{name}` not found, after index #{after}")
|
|
|
|
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
|