Class: MonoVM::Whois::Parser::Record

Inherits:
Object
  • Object
show all
Defined in:
lib/monovm/whois/parser/record.rb

Overview

A registration, parsed into typed fields.

A library that hands back only the raw response leaves every caller that wants an expiry date writing its own regexp — once per registry format. This is that work done once.

#fields keeps every key/value the parser saw, so nothing is lost to the normalisation: if a registry emits something this class has no accessor for, it is still reachable.

Constant Summary collapse

REDACTIONS =

Values registries use to mean "withheld", mostly post-GDPR. Treated as absent rather than reported as a registrant literally named "REDACTED FOR PRIVACY", which would otherwise look like real data to a caller.

[
  "redacted for privacy", "redacted", "not disclosed", "data protected",
  "privacy protected", "withheld for privacy", "statutory masking enabled",
  "gdpr masked", "non-public data", "not available", "n/a", "none"
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(domain: nil, registry_id: nil, registrar: nil, registrar_whois_server: nil, registrar_url: nil, registrar_iana_id: nil, registrant: nil, statuses: [], nameservers: [], created_on: nil, updated_on: nil, expires_on: nil, dnssec: nil, contacts: {}, fields: {}, source: nil) ⇒ Record

Returns a new instance of Record.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/monovm/whois/parser/record.rb', line 32

def initialize(domain: nil, registry_id: nil, registrar: nil, registrar_whois_server: nil,
               registrar_url: nil, registrar_iana_id: nil, registrant: nil, statuses: [],
               nameservers: [], created_on: nil, updated_on: nil, expires_on: nil,
               dnssec: nil, contacts: {}, fields: {}, source: nil)
  @domain = clean(domain)
  @registry_id = clean(registry_id)
  @registrar = clean(registrar)
  @registrar_whois_server = clean(registrar_whois_server)&.downcase
  @registrar_url = clean(registrar_url)
  @registrar_iana_id = clean(registrar_iana_id)
  @registrant = clean(registrant)
  @statuses = normalise_list(statuses).freeze
  @nameservers = normalise_nameservers(nameservers).freeze
  @created_on = created_on
  @updated_on = updated_on
  @expires_on = expires_on
  @dnssec = dnssec
  @contacts = contacts.freeze
  @fields = fields.freeze
  @source = source
  freeze
end

Instance Attribute Details

#contactsObject (readonly)

Returns the value of attribute contacts.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def contacts
  @contacts
end

#created_onObject (readonly)

Returns the value of attribute created_on.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def created_on
  @created_on
end

#dnssecObject (readonly)

Returns the value of attribute dnssec.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def dnssec
  @dnssec
end

#domainObject (readonly)

Returns the value of attribute domain.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def domain
  @domain
end

#expires_onObject (readonly)

Returns the value of attribute expires_on.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def expires_on
  @expires_on
end

#fieldsObject (readonly)

Returns the value of attribute fields.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def fields
  @fields
end

#nameserversObject (readonly)

Returns the value of attribute nameservers.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def nameservers
  @nameservers
end

#registrantObject (readonly)

Returns the value of attribute registrant.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def registrant
  @registrant
end

#registrarObject (readonly)

Returns the value of attribute registrar.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def registrar
  @registrar
end

#registrar_iana_idObject (readonly)

Returns the value of attribute registrar_iana_id.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def registrar_iana_id
  @registrar_iana_id
end

#registrar_urlObject (readonly)

Returns the value of attribute registrar_url.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def registrar_url
  @registrar_url
end

#registrar_whois_serverObject (readonly)

Returns the value of attribute registrar_whois_server.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def registrar_whois_server
  @registrar_whois_server
end

#registry_idObject (readonly)

Returns the value of attribute registry_id.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def registry_id
  @registry_id
end

#sourceObject (readonly)

Returns the value of attribute source.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def source
  @source
end

#statusesObject (readonly)

Returns the value of attribute statuses.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def statuses
  @statuses
end

#updated_onObject (readonly)

Returns the value of attribute updated_on.



27
28
29
# File 'lib/monovm/whois/parser/record.rb', line 27

def updated_on
  @updated_on
end

Instance Method Details

#[](key) ⇒ Object

Look up a raw field by any of its names, case-insensitively.

record["Registry Expiry Date"]


109
110
111
112
113
# File 'lib/monovm/whois/parser/record.rb', line 109

def [](key)
  wanted = key.to_s.downcase.strip
  _, value = fields.find { |name, _| name.to_s.downcase.strip == wanted }
  value
end

#attributesHash

The constructor's arguments, as a Hash. Lets a record be rebuilt with a few fields changed — which is what merging a registry record with a registrar's amounts to — without naming all sixteen fields at every call site.

Returns:

  • (Hash)


60
61
62
63
64
65
66
67
68
69
# File 'lib/monovm/whois/parser/record.rb', line 60

def attributes
  {
    domain: domain, registry_id: registry_id, registrar: registrar,
    registrar_whois_server: registrar_whois_server, registrar_url: registrar_url,
    registrar_iana_id: registrar_iana_id, registrant: registrant,
    statuses: statuses, nameservers: nameservers, created_on: created_on,
    updated_on: updated_on, expires_on: expires_on, dnssec: dnssec,
    contacts: contacts, fields: fields, source: source
  }
end

#days_until_expiry(now: Time.now) ⇒ Object

Days until expiry, or nil when the record carries no expiry date. Negative when the date has passed.



100
101
102
103
104
# File 'lib/monovm/whois/parser/record.rb', line 100

def days_until_expiry(now: Time.now)
  return nil if expires_on.nil?

  ((expires_on - now) / 86_400).floor
end

#dnssec?Boolean

Returns:

  • (Boolean)


78
79
80
81
82
# File 'lib/monovm/whois/parser/record.rb', line 78

def dnssec?
  return false if dnssec.nil?

  !%w[unsigned unsigned delegation no false 0].include?(dnssec.to_s.downcase.strip)
end

#empty?Boolean

True when the parser found nothing worth reporting. A response can parse cleanly and still be empty — a not-found reply, for instance.

Returns:

  • (Boolean)


73
74
75
76
# File 'lib/monovm/whois/parser/record.rb', line 73

def empty?
  domain.nil? && registrar.nil? && nameservers.empty? && statuses.empty? &&
    created_on.nil? && expires_on.nil?
end

#expiring?Boolean

True for any status meaning the registration is winding down.

Returns:

  • (Boolean)


90
91
92
93
94
95
96
# File 'lib/monovm/whois/parser/record.rb', line 90

def expiring?
  statuses.any? do |status|
    normalised = status.downcase.delete(" ")
    normalised.include?("redemption") || normalised.include?("pendingdelete") ||
      normalised.include?("autorenewperiod")
  end
end

#inspectObject



135
136
137
138
# File 'lib/monovm/whois/parser/record.rb', line 135

def inspect
  "#<#{self.class.name} #{domain.inspect} registrar=#{registrar.inspect} " \
    "expires=#{expires_on&.iso8601.inspect}>"
end

#to_hObject



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/monovm/whois/parser/record.rb', line 115

def to_h
  {
    domain: domain,
    registry_id: registry_id,
    registrar: registrar,
    registrar_whois_server: registrar_whois_server,
    registrar_url: registrar_url,
    registrar_iana_id: registrar_iana_id,
    registrant: registrant,
    statuses: statuses,
    nameservers: nameservers,
    created_on: created_on&.iso8601,
    updated_on: updated_on&.iso8601,
    expires_on: expires_on&.iso8601,
    dnssec: dnssec,
    contacts: contacts.empty? ? nil : contacts,
    source: source
  }.compact
end

#transfer_prohibited?Boolean

True when the registry says this name is locked against transfer.

Returns:

  • (Boolean)


85
86
87
# File 'lib/monovm/whois/parser/record.rb', line 85

def transfer_prohibited?
  statuses.any? { |status| status.downcase.include?("transferprohibited") }
end