Permalink
Browse files

Introduce parser for new .co.za WHOIS

  • Loading branch information...
1 parent 2464082 commit 3d01c6b71974d87ddd97d29d7d3885e9c2347c8f @rorymckinley committed Jun 30, 2012
@@ -325,7 +325,7 @@
Whois::Server.define :tld, ".ye", nil, { :adapter => :none }
Whois::Server.define :tld, ".yt", "whois.nic.fr"
Whois::Server.define :tld, ".ac.za", "whois.ac.za"
-Whois::Server.define :tld, ".co.za", "whois.coza.net.za"
+Whois::Server.define :tld, ".co.za", "whois.registry.net.za"
Whois::Server.define :tld, ".gov.za", "whois.gov.za"
Whois::Server.define :tld, ".org.za", "whois.org.za"
Whois::Server.define :tld, ".za", nil, { :adapter => :none }
@@ -0,0 +1,157 @@
+require 'whois/record/parser/base'
+require 'whois/record/scanners/whois.registry.net.za'
+
+
+module Whois
+ class Record
+ class Parser
+ #--
+ # @note This parser is just a stub and provides only a few basic methods
+ # to check for domain availability and get domain status.
+ # Please consider to contribute implementing missing methods.
+ # ++
+ class WhoisRegistryNetZa < Base
+ include Scanners::Nodable
+
+ property_supported :available? do
+ node(:available)
+ end
+
+ property_supported :registered? do
+ !available?
+ end
+
+ property_supported :domain do
+ node(:domain_name)
+ end
+
+ property_supported :created_on do
+ parse_date(node(:registration_date))
+ end
+
+ property_supported :expires_on do
+ parse_date(node(:renewal_date))
+ end
+
+ property_supported :nameservers do
+ if registered?
+ node(:nameservers).map { |nameserver| Record::Nameserver.new(:name => nameserver) }
+ else
+ []
+ end
+ end
+
+ property_supported :registrar do
+ if node(:registrar_id)
+ Whois::Record::Registrar.new(:name => node(:registrar_name), :id => node(:registrar_id))
+ else
+ nil
+ end
+ end
+
+ # The response for this property gets wrapped in an array by Whois::Record::Parser::Base#handle_property
+ property_supported :registrant_contacts do
+ if registered?
+ build_registrant_contacts
+ else
+ []
+ end
+ end
+
+ property_supported :status do
+ node(:status)
+ end
+
+ property_supported :disclaimer do
+ node(:disclaimer)
+ end
+
+ property_not_supported :domain_id
+ property_not_supported :referral_whois
+ property_not_supported :referral_url
+ property_not_supported :updated_on
+ property_not_supported :admin_contacts
+ property_not_supported :technical_contacts
+
+ def parse
+ Scanners::WhoisRegistryNetZa.new(content_for_scanner).parse
+ end
+
+ private
+
+ def build_registrant_contacts
+ Whois::Record::Contact.new(
+ {:type => Whois::Record::Contact::TYPE_REGISTRANT}.merge(registrant_details).merge(registrant_address_details)
+ )
+ end
+
+ def registrant_details
+ if node(:registrant_name)
+ { :name => node(:registrant_name), :email => node(:registrant_email), :phone => node(:registrant_telephone), :fax => node(:registrant_fax)}
+ end
+ end
+
+ def registrant_address_details
+ { :address => node(:registrant_address) }
+ end
+
+ def parse_date(date_string)
+ if date_string
+ date_parts = date_string.split("-")
+ Time.new(*date_parts,nil,nil,nil,"+02:00")
+ else
+ nil
+ end
+ end
+
+ property_supported :registered? do
+ !available?
+ end
+
+ property_supported :nameservers do
+ if content_for_scanner =~ /Name Servers:\n((.+\n)+)\n/
+ $1.split("\n").map do |line|
+ Record::Nameserver.new(:name => line.strip)
+ end
+ end
+ end
+
+ property_supported :registrar do
+ if content_for_scanner =~ /Registrar:\n(.+)\[ ID = (.+) \]\s*\n/
+ Whois::Record::Registrar.new(:name => $1.strip, :id => $2.strip)
+ end
+ end
+
+ property_supported :registrant_contacts do
+ if content_for_scanner =~ /Registrant:\n((.+\n)+)\n/
+ reg_details = $1.split("\n")
+ name = reg_details[0].strip
+ email = get_email(reg_details[1])
+ telephone = get_telephone(reg_details[2])
+ fax = get_fax(reg_details[3])
+ end
+
+ if content_for_scanner =~ /Registrant's Address:\n((.+\n)+)\n/
+ address = ($1.split("\n").map { |part| part.strip }).join(" ")
+ end
+
+ [Whois::Record::Contact.new(:type => Whois::Record::Contact::TYPE_REGISTRANT, :name => name, :email => email, :phone => telephone, :fax => fax, :address => address)]
+ end
+
+ private
+
+ def get_email(email_candidate)
+ $1.strip if email_candidate.strip =~ /^Email: (.+)$/
+ end
+
+ def get_telephone(telephone_candidate)
+ $1.strip if telephone_candidate.strip =~ /^Tel: (.+)$/
+ end
+
+ def get_fax(fax_candidate)
+ $1.strip if fax_candidate.strip =~ /^Fax: (.+)$/
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,109 @@
+#--
+# Ruby Whois
+#
+# An intelligent pure Ruby WHOIS client and parser.
+#
+# Copyright (c) 2009-2012 Simone Carletti <weppos@weppos.net>
+#++
+
+require 'whois/record/scanners/base'
+
+module Whois
+ class Record
+ module Scanners
+
+ class WhoisRegistryNetZa < Base
+ self.tokenizers += [
+ :get_availability,
+ :get_domain_name,
+ :get_registrant_details,
+ :get_registrant_address,
+ :get_registrar_details,
+ :get_dates,
+ :get_status,
+ :get_pending_timer_events,
+ :get_nameservers,
+ :get_disclaimer
+ ]
+
+ tokenizer :get_availability do
+ if @input.scan_until(/^Available\n$/m)
+ @ast[:available] = true
+ end
+ end
+
+ tokenizer :get_domain_name do
+ if find_heading("Domain Name")
+ @ast[:domain_name] = content_in_category
+ end
+ end
+
+ tokenizer :get_registrant_details do
+ if find_heading("Registrant")
+ registrant_lines = content_in_category.split("\n")
+ @ast[:registrant_name] = registrant_lines.shift
+ [:registrant_email, :registrant_telephone, :registrant_fax].each do |contact_method|
+ @ast[contact_method] = registrant_lines.shift.split(":").last.strip
+ end
+ end
+ end
+
+ tokenizer :get_registrant_address do
+ if find_heading("Registrant's Address")
+ @ast[:registrant_address] = content_in_category.gsub(/\n\s+/, " ")
+ end
+ end
+
+ tokenizer :get_registrar_details do
+ if find_heading("Registrar")
+ content_in_category =~ /(.+) \[ ID = (.+) \]/
+ @ast[:registrar_name] = $1.strip
+ @ast[:registrar_id] = $2.strip
+ end
+ end
+
+ tokenizer :get_dates do
+ if find_heading("Relevant Dates")
+ dates = content_in_category.split("\n")
+ @ast[:registration_date] = dates.shift.split(":").last.strip
+ @ast[:renewal_date] = dates.shift.split(":").last.strip
+ end
+ end
+
+ tokenizer :get_status do
+ if find_heading("Domain Status")
+ statuses = content_in_category
+ @ast[:status] = statuses.split(", ")
+ end
+ end
+
+ tokenizer :get_pending_timer_events do
+ if find_heading("Pending Timer Events")
+ @ast[:pending_timer_events] = content_in_category
+ end
+ end
+
+ tokenizer :get_nameservers do
+ if find_heading("Name Servers")
+ @ast[:nameservers] = content_in_category.gsub(/\n\s+/, ",").split(",")
+ end
+ end
+
+ tokenizer :get_disclaimer do
+ @input.skip_until(/\n--\n/m)
+ @ast[:disclaimer] = @input.scan_until(/.*$/m)
+ end
+
+ private
+
+ def content_in_category
+ @input.scan_until(/(?=\n [A-Z])/).strip
+ end
+
+ def find_heading(heading_name)
+ @input.skip_until(/ #{heading_name}:\n/)
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,29 @@
+#available?
+ should: %s be_true
+
+#registered?
+ should: %s be_false
+
+#nameservers
+ should: %s be_empty
+
+#registrar
+ should: %s be_nil
+
+#registrant_contacts
+ should: %s be_empty
+
+#domain
+ should: %s be_nil
+
+#created_on
+ should: %s be_nil
+
+#status
+ should: %s be_nil
+
+#expires_on
+ should: %s be_nil
+
+#disclaimer
+ should: %s be_nil
@@ -0,0 +1,64 @@
+#available?
+ should: %s be_false
+
+#registered?
+ should: %s be_true
+
+#nameservers
+ should: %s CLASS(array)
+ should: %s SIZE(3)
+ should: %s[0] CLASS(nameserver)
+ should: %s[0].name == "ns2.host-h.net"
+ should: %s[1] CLASS(nameserver)
+ should: %s[1].name == "ns1.dns-h.com"
+ should: %s[2] CLASS(nameserver)
+ should: %s[2].name == "ns1.host-h.net"
+
+#registrar
+ should: %s CLASS(registrar)
+ should: %s.id == "epag"
+ should: %s.name == "EPAG Domainservices"
+
+#registrant_contacts
+ should: %s CLASS(array)
+ should: %s SIZE(1)
+ should: %s[0] CLASS(contact)
+ should: %s[0].type == Whois::Record::Contact::TYPE_REGISTRANT
+ should: %s[0].name == "Fred Flintstone"
+ should: %s[0].email == "someguy@somedomain.co.za"
+ should: %s[0].phone == "+27.219000000"
+ should: %s[0].fax == "+27.219001000"
+ should: %s[0].address == "30 Frazzita Business Park Durbanville Cape Town ZA 7550"
+
+#domain
+ should: %s == "broccoliwafflesareawesome.co.za"
+
+#created_on
+ should: %s == Time.new(2012,3,27,nil,nil,nil,"+02:00")
+
+#status
+ should: %s == ['ok', 'autorenew']
+
+#expires_on
+ should: %s == Time.new(2013,3,27,nil,nil,nil,"+02:00")
+
+#disclaimer
+ should: %s == "The use of this Whois facility is subject to the following terms and\nconditions. https://registry.net.za/whois_terms\nCopyright (c) UniForum SA 1995-2012\n"
+
+#domain_id
+ should: %s raise_error Whois::PropertyNotSupported
+
+#referral_whois
+ should: %s raise_error Whois::PropertyNotSupported
+
+#referral_url
+ should: %s raise_error Whois::PropertyNotSupported
+
+#updated_on
+ should: %s raise_error Whois::PropertyNotSupported
+
+#admin_contacts
+ should: %s raise_error Whois::PropertyNotSupported
+
+#technical_contacts
+ should: %s raise_error Whois::PropertyNotSupported
Oops, something went wrong.

0 comments on commit 3d01c6b

Please sign in to comment.