Class: Whois::Parsers::Base Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/whois/parsers/base.rb

Overview

This class is abstract.

Represents the abstract base parser class for all server-specific parser implementations.

NOTE. This class is for the most part auto-generated via meta programming. This is the reason why RDoc can’t detect and document all available methods.

Direct Known Subclasses

BaseAfilias, BaseAfilias2, BaseCocca, BaseCocca2, BaseIcannCompliant, BaseIisse, BaseNicFr, BaseShared1, BaseShared2, BaseShared3, BaseVerisign, BaseWhoisd, Blank, Example, KeroYachayPe, WhoisAedaNetAe, WhoisAmnicNet, WhoisAtiTn, WhoisAudnsNetAu, WhoisAx, WhoisBnnicBn, WhoisCat, WhoisCctldBy, WhoisCctldUz, WhoisCentralnicCom, WhoisCiraCa, WhoisCnnicCn, WhoisCoCa, WhoisCoPl, WhoisCoUg, WhoisComlaudeCom, WhoisDenicDe, WhoisDkHostmasterDk, WhoisDnsBe, WhoisDnsHr, WhoisDnsLu, WhoisDnsPl, WhoisDnsPt, WhoisDomainRegistryNl, WhoisDomainregistryIe, WhoisDomregLt, WhoisDotCf, WhoisDotTk, WhoisDotgovGov, WhoisEducauseEdu, WhoisEenetEe, WhoisEu, WhoisEuOrg, WhoisFi, WhoisGovZa, WhoisHkircHk, WhoisIanaOrg, WhoisInUa, WhoisIsnicIs, WhoisIsocOrgIl, WhoisJaNet, WhoisJprsJp, WhoisKenicOrKe, WhoisKg, WhoisKr, WhoisMonicMo, WhoisMuseum, WhoisMynicMy, WhoisNc, WhoisNicAi, WhoisNicAs, WhoisNicAt, WhoisNicBj, WhoisNicBo, WhoisNicCh, WhoisNicCi, WhoisNicCl, WhoisNicCoop, WhoisNicDz, WhoisNicEs, WhoisNicHu, WhoisNicIm, WhoisNicIr, WhoisNicIt, WhoisNicKz, WhoisNicLi, WhoisNicLk, WhoisNicLv, WhoisNicLy, WhoisNicMd, WhoisNicMx, WhoisNicName, WhoisNicNetSa, WhoisNicOrgUy, WhoisNicPr, WhoisNicPrivAt, WhoisNicSl, WhoisNicSm, WhoisNicSn, WhoisNicSo, WhoisNicSt, WhoisNicTm, WhoisNicTr, WhoisNicUk, WhoisNicVe, WhoisNoridNo, WhoisRegisterBg, WhoisRegisterSi, WhoisRegistreMa, WhoisRegistroBr, WhoisRegistryHm, WhoisRipeNet, WhoisRnidsRs, WhoisRotldRo, WhoisSgnicSg, WhoisSkNicSk, WhoisSmallregistryNet, WhoisSrsNetNz, WhoisSx, WhoisTcinetRu, WhoisThnicCoTh, WhoisTldEe, WhoisTonicTo, WhoisTwnicNetTw, WhoisUa, WhoisUspAcFj, WhoisWebsiteWs, WhoisYoursrsCom, WhoisZaNet, WhoisZaOrg

Instance Attribute Summary collapse

Methods collapse

Response collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(part) ⇒ Base

Initializes a new parser with given part.

Parameters:

  • part (Whois::Record::Part)


187
188
189
190
# File 'lib/whois/parsers/base.rb', line 187

def initialize(part)
  @part = part
  @cached_properties = {}
end

Instance Attribute Details

#partWhois::Record::Part (readonly)

Returns The part referenced by this parser.

Returns:

  • (Whois::Record::Part)

    The part referenced by this parser.



181
182
183
# File 'lib/whois/parsers/base.rb', line 181

def part
  @part
end

Class Method Details

.parse_time(timestamp) ⇒ Nil, Time

Parses a timestamp, returning nil for invalid input

Parameters:

  • timestamp (String)

    The timestamp to parse

Returns:

  • (Nil)

    if the timestamp can’t be parsed

  • (Time)


172
173
174
175
176
177
178
# File 'lib/whois/parsers/base.rb', line 172

def self.parse_time(timestamp)
  return unless timestamp.is_a?(String) && !timestamp.empty?

  Time.parse(timestamp).change(usec: 0)
rescue ArgumentError
  nil
end

.property_not_implemented(property) ⇒ void

This method returns an undefined value.

Registers a property as “not implemented” and defines the corresponding private _property_PROPERTY method.

A “not implemented” property always raises a AttributeNotImplemented error when the property method is called.

Examples:

Defining a not implemented property

# Defines a not implemented property called :disclaimer.
property_not_implemented(:disclaimer)

Parameters:

  • property (Symbol)


100
101
102
103
104
105
106
107
108
109
110
# File 'lib/whois/parsers/base.rb', line 100

def self.property_not_implemented(property)
  property_register(property, Parser::PROPERTY_STATE_NOT_IMPLEMENTED)

  class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
    def _property_#{property}(*args)
      raise AttributeNotImplemented
    end

    private :_property_#{property}
  RUBY
end

.property_not_supported(property) ⇒ void

This method returns an undefined value.

Registers a property as “not supported” and defines the corresponding private _property_PROPERTY method.

A “not supported” property always raises a AttributeNotSupported error when the property method is called.

Examples:

Defining an unsupported property

# Defines an unsupported property called :disclaimer.
property_not_supported(:disclaimer)

Parameters:

  • property (Symbol)


125
126
127
128
129
130
131
132
133
134
135
# File 'lib/whois/parsers/base.rb', line 125

def self.property_not_supported(property)
  property_register(property, Parser::PROPERTY_STATE_NOT_SUPPORTED)

  class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
    def _property_#{property}(*args)
      raise AttributeNotSupported
    end

    private :_property_#{property}
  RUBY
end

.property_register(property, status) ⇒ void

This method returns an undefined value.

Registers a property in the registry.

Parameters:

  • property (Symbol)
  • status (Symbol)


82
83
84
# File 'lib/whois/parsers/base.rb', line 82

def self.property_register(property, status)
  self._properties = _properties.merge({ property => status })
end

.property_state(property) ⇒ Symbol?

Returns the status for the property passed as symbol.

Examples:

Undefined property

property_state(:disclaimer)
# => nil

Defined property

property_register(:disclaimer, Parser::PROPERTY_STATE_SUPPORTED) {}
property_state(:disclaimer)
# => :supported

Parameters:

  • property (Symbol)

Returns:

  • (Symbol, nil)


47
48
49
# File 'lib/whois/parsers/base.rb', line 47

def self.property_state(property)
  _properties[property]
end

.property_state?(property, status = :any) ⇒ Boolean

Check if the property passed as symbol is registered in the registry for current parser.

Examples:

Not-registered property

property_state?(:disclaimer)
# => false

Registered property

property_register(:disclaimer) {}
property_state?(:disclaimer)
# => true

Parameters:

  • property (Symbol)
  • status (Symbol) (defaults to: :any)

Returns:

  • (Boolean)


67
68
69
70
71
72
73
# File 'lib/whois/parsers/base.rb', line 67

def self.property_state?(property, status = :any)
  if status == :any
    _properties.key?(property)
  else
    _properties[property] == status
  end
end

.property_supported(property, &block) ⇒ void

This method returns an undefined value.

Registers a property as “supported” and defines the corresponding private _property_PROPERTY method.

Examples:

Defining a supported property

# Defines a supported property called :disclaimer.
property_supported(:disclaimer) do
  ...
end

Parameters:

  • property (Symbol)


149
150
151
152
153
154
# File 'lib/whois/parsers/base.rb', line 149

def self.property_supported(property, &block)
  property_register(property, Parser::PROPERTY_STATE_SUPPORTED)

  define_method("_property_#{property}", &block)
  private :"_property_#{property}"
end

Instance Method Details

#changed?(other) ⇒ Boolean

Checks whether the content of this part is different than other.

Comparing a WHOIS response is not as trivial as you may think. WHOIS servers can inject into the WHOIS response strings that changes at every request, such as the timestamp the request was generated or the number of requests left for your current IP.

These strings causes a simple equal comparison to fail even if the registry data is the same.

This method should provide a bulletproof way to detect whether this record changed compared with other.

Parameters:

  • other (Base)

    The other parser instance to compare.

Returns:

  • (Boolean)

See Also:



291
292
293
# File 'lib/whois/parsers/base.rb', line 291

def changed?(other)
  !unchanged?(other)
end

#contactsArray<Parser::Contact>

Collects and returns all the available contacts.

Returns:

See Also:



260
261
262
263
264
265
# File 'lib/whois/parsers/base.rb', line 260

def contacts
  [:registrant_contacts, :admin_contacts, :technical_contacts].inject([]) do |contacts, property|
    contacts += send(property) if property_supported?(property)
    contacts
  end
end

#contentString

This is an internal method primary used as a common access point to get the content to be parsed as a string.

The main reason behind this method is because, in the past, the internal representation of the data to be parsed changed several times, and I always had to rewrite all single parsers in order to reflect these changes. Now, as far as the parser access the data via the content method, there’s no need to change each single implementation in case the content source changes.

That said, the only constraints about this method is to return the data to be parsed as string.

Returns:

  • (String)

    The part body.



208
209
210
# File 'lib/whois/parsers/base.rb', line 208

def content
  part.body
end

#is(symbol) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if the parser respond to symbol and calls the method if defined. The method referenced by the symbol is supposed to be a question? method and to return a boolean.

Examples:

is(:response_throttled?)
# => true

Parameters:

  • symbol (Symbol)

Returns:

  • (Boolean)


225
226
227
# File 'lib/whois/parsers/base.rb', line 225

def is(symbol)
  respond_to?(symbol) && send(symbol)
end

#property_supported?(property) ⇒ Boolean

Checks if the property passed as symbol is supported by the current parser.

Parameters:

  • property (Symbol)

    The name of the property to check.

Returns:

  • (Boolean)


162
163
164
# File 'lib/whois/parsers/base.rb', line 162

def property_supported?(property)
  self.class.property_state?(property, Parser::PROPERTY_STATE_SUPPORTED)
end

#response_incomplete?Boolean

This method is abstract.

This method is just a stub. Define it in your parser class.

Checks whether this is an incomplete response.

Returns:

  • (Boolean)

See Also:



323
324
# File 'lib/whois/parsers/base.rb', line 323

def response_incomplete?
end

#response_throttled?Boolean

This method is abstract.

This method is just a stub. Define it in your parser class.

Checks whether this is a throttle response.

Returns:

  • (Boolean)

See Also:



336
337
# File 'lib/whois/parsers/base.rb', line 336

def response_throttled?
end

#response_unavailable?Boolean

This method is abstract.

This method is just a stub. Define it in your parser class.

Checks whether this response contains a message that can be reconducted to a “WHOIS Server Unavailable” status.

Some WHOIS servers returns error messages when they are experiencing failures.

Returns:

  • (Boolean)

See Also:



353
354
# File 'lib/whois/parsers/base.rb', line 353

def response_unavailable?
end

#unchanged?(other) ⇒ Boolean

The opposite of #changed?.

Parameters:

  • other (Base)

    The other parser instance to compare.

Returns:

  • (Boolean)

See Also:



303
304
305
306
307
308
309
310
# File 'lib/whois/parsers/base.rb', line 303

def unchanged?(other)
  unless other.is_a?(self.class)
    raise(ArgumentError, "Can't compare `#{self.class}' with `#{other.class}'")
  end

  equal?(other) ||
  content_for_scanner == other.content_for_scanner
end

#validate!Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



230
231
232
233
# File 'lib/whois/parsers/base.rb', line 230

def validate!
  raise ResponseIsThrottled   if is(:response_throttled?)
  raise ResponseIsUnavailable if is(:response_unavailable?)
end