AW: [Python-de] Klassen
Beate & Olaf Bee
bee_bee at t-online.de
Son Jan 4 17:49:05 CET 2004
Also hier ist der echte code.
-----Ursprüngliche Nachricht-----
Von: python-de-bounces at python.net [mailto:python-de-bounces at python.net]
Im Auftrag von Stefan J. Betz
Gesendet: Sonntag, 4. Januar 2004 17:27
An: Python-UG
Betreff: Re: [Python-de] Klassen
Am Sun, Jan 04, 2004 um 16:43:49 CET, beate & olaf bee schrieb:
> Hallo zusammen,
>
> erstmal Frohes Neues Jahr, ich bin der/ein Neuer.
Herzlich Willkommen :-)
> Ich versuch mich an der OO-Programierung und hin und wieder fehlt mal
> das Verständnis....
Ich denke so ziemlich jeder hatte da am Anfang mal so seine Probleme...
> >>> import rwhois
> >>> erg = DomainRecord("www.meineseite.de")
> >>> print erg.created
> None
>
> Eine Internet Verbindung ist im Hintergrund geöffnet, aber ich vermute
> das Python das nicht weiß?
Es wäre vielleicht sinnvoll den echten Code zu posten, oder zumindest
einen Teil davon, den mit dem Zeug das du beigelegt hast kann denke ich
keiner was anfangen :-(
mfg Betz Stefan
--
Das Telefonnetz... Unendliche Weiten... Dies sind die Abenteuer eines
genervten Internet-Surfers... Weit von zu Hause entfernt stößt er in
Bereiche des Systems vor, die vorher noch niemand gesehen hat...
##### rwhois.py Ver. 1.5 #####
#! /usr/bin/python --
"""
usage: %(progname)s [domain...]
Version: %(version)s
Contacts the apropriate whois database for each domain and displays
the result.
class WhoisRecord:
self.domain -- Domain Name
self.whoisserver -- Whoisserver associated with domain
self.page -- raw whois record data
public methods:
def WhoisRecord(domain=None)
Whois object constructor
def whois(domainname=None, server=None, cache=0)
Fetches whoisrecord and places result in self.page
Raises NoSuchDomain if the domain doesn't exist.
class DomainRecord(WhoisRecord):
self.domainid -- domainid for this domain
self.created -- date in which the domain was created
self.lastupdated -- date in which the domain was last
updated.
self.expires -- date in which the domain expires
self.databaseupdated -- date in which the database was last
updated.
self.servers -- list of (hostname, ip) pairs of the
nameservers.
self.registrant -- ContactRecord of domain owner.
self.contacts -- dictionary of contacts (ContactRecord
objects)
public methods:
def DomainRecord(domain=None)
Constructor for DomainRecord
def Parse()
Creates a parsed version of the information contained in
the whois record for domain from self.page
raises NoParser if a parser does not exist for a registry.
class Contact:
self.type -- Type of contact
self.organization -- Organization associated with contact.
self.person -- Person associated with contact.
self.handle -- NIC Handle
self.address -- Street address of contact
self.address2 --
self.address3 --
self.city -- city of addr
self.state -- address state
self.zip -- zipcode
self.country -- country
self.email -- Email address of contact
self.phone -- Phone Number
self.fax -- Fax Number
self.lastupdated -- Last update of contact record
"""
_version = "1.5"
import os, sys, string, time, getopt, socket, select, re, errno, copy,
signal
timeout=50
try:
signal.SIGALRM
HAS_ALARM = 1
except:
HAS_ALARM = 0
class WhoisRecord:
defaultserver='whois.verisign-grs.net'#'whois.networksolutions.com'
whoismap={ 'com' : 'whois.internic.net' , \
'org' : 'whois.pir.org' , \
'net' : 'whois.internic.net' , \
'edu' : 'whois.networksolutions.com' , \
'biz' : 'whois.biz' , \
'info': 'whois.afilias.info' , \
'us' : 'whois.nic.us', \
'de' : 'whois.denic.de' , \
'gov' : 'whois.nic.gov' , \
'name': 'whois.nic.name' , \
#??? 'pro': 'whois.nic.name' , \
'museum': 'whois.museum' , \
'int': 'whois.iana.org' , \
'aero': 'whois.information.aero' , \
'coop': 'whois.nic.coop' , \
# See http://www.nic.gov/cgi-bin/whois
'mil' : 'whois.nic.mil' , \
# See http://www.nic.mil/cgi-bin/whois
'ca' : 'whois.cdnnet.ca' , \
'uk' : 'whois.nic.uk' , \
'au' : 'whois.aunic.net' , \
'hu' : 'whois.nic.hu' , \
# All the following are unverified/checked.
'be' : 'whois.ripe.net',
'it' : 'whois.ripe.net' , \
# also whois.nic.it
'at' : 'whois.ripe.net' , \
# also www.nic.at, whois.aco.net
'dk' : 'whois.ripe.net' , \
'fo' : 'whois.ripe.net' , \
'lt' : 'whois.ripe.net' , \
'no' : 'whois.ripe.net' , \
'sj' : 'whois.ripe.net' , \
'sk' : 'whois.ripe.net' , \
'tr' : 'whois.ripe.net' , \
# also whois.metu.edu.tr
'il' : 'whois.ripe.net' , \
'bv' : 'whois.ripe.net' , \
'se' : 'whois.nic-se.se' , \
'br' : 'whois.nic.br' , \
# a.k.a. whois.fapesp.br?
'fr' : 'whois.nic.fr' , \
'sg' : 'whois.nic.net.sg' , \
'hm' : 'whois.registry.hm' , \
# see also whois.nic.hm
'nz' : 'domainz.waikato.ac.nz' , \
'nl' : 'whois.domain-registry.nl' , \
# RIPE also handles other countries
# See http://www.ripe.net/info/ncc/rir-areas.html
'ru' : 'whois.ripn.net' , \
'ch' : 'whois.nic.ch' , \
# see http://www.nic.ch/whois_readme.html
'jp' : 'whois.nic.ad.jp' , \
# (use DOM foo.jp/e for english; need to lookup !handles
separately)
'to' : 'whois.tonic.to' , \
'nu' : 'whois.nic.nu' , \
'fm' : 'www.dot.fm' , \
# http request http://www.dot.fm/search.html
'am' : 'whois.nic.am' , \
'nu' : 'www.nunames.nu' , \
# http request
# e.g.
http://www.nunames.nu/cgi-bin/drill.cfm?domainname=nunames.nu
#'cx' : 'whois.nic.cx' , \ # no response from this
server
'af' : 'whois.nic.af' , \
'as' : 'whois.nic.as' , \
'li' : 'whois.nic.li' , \
'lk' : 'whois.nic.lk' , \
'mx' : 'whois.nic.mx' , \
'pw' : 'whois.nic.pw' , \
'sh' : 'whois.nic.sh' , \
# consistently resets connection
'tj' : 'whois.nic.tj' , \
'tm' : 'whois.nic.tm' , \
'pt' : 'whois.dns.pt' , \
'kr' : 'whois.nic.or.kr' , \
# see also whois.krnic.net
'kz' : 'whois.nic.or.kr' , \
# see also whois.krnic.net
'al' : 'whois.ripe.net' , \
'az' : 'whois.ripe.net' , \
'ba' : 'whois.ripe.net' , \
'bg' : 'whois.ripe.net' , \
'by' : 'whois.ripe.net' , \
'cy' : 'whois.ripe.net' , \
'cz' : 'whois.ripe.net' , \
'dz' : 'whois.ripe.net' , \
'ee' : 'whois.ripe.net' , \
'eg' : 'whois.ripe.net' , \
'es' : 'whois.ripe.net' , \
'fi' : 'whois.ripe.net' , \
'gr' : 'whois.ripe.net' , \
'hr' : 'whois.ripe.net' , \
'lu' : 'whois.ripe.net' , \
'lv' : 'whois.ripe.net' , \
'ma' : 'whois.ripe.net' , \
'md' : 'whois.ripe.net' , \
'mk' : 'whois.ripe.net' , \
'mt' : 'whois.ripe.net' , \
'pl' : 'whois.ripe.net' , \
'ro' : 'whois.ripe.net' , \
'si' : 'whois.ripe.net' , \
'sm' : 'whois.ripe.net' , \
'su' : 'whois.ripe.net' , \
'tn' : 'whois.ripe.net' , \
'ua' : 'whois.ripe.net' , \
'va' : 'whois.ripe.net' , \
'yu' : 'whois.ripe.net' , \
# unchecked
'ac' : 'whois.nic.ac' , \
'cc' : 'whois.nic.cc' , \
#'cn' : 'whois.cnnic.cn' , \ # connection refused
'gs' : 'whois.adamsnames.tc' , \
'hk' : 'whois.apnic.net' , \
#'ie' : 'whois.ucd.ie' , \ # connection refused
#'is' : 'whois.isnet.is' , \# connection refused
#'mm' : 'whois.nic.mm' , \ # connection refused
'ms' : 'whois.adamsnames.tc' , \
'my' : 'whois.mynic.net' , \
#'pe' : 'whois.rcp.net.pe' , \ # connection refused
'st' : 'whois.nic.st' , \
'tc' : 'whois.adamsnames.tc' , \
'tf' : 'whois.adamsnames.tc' , \
'th' : 'whois.thnic.net' , \
'tw' : 'whois.twnic.net' , \
# 'us' : 'whois.isi.edu' , \
'vg' : 'whois.adamsnames.tc' , \
#'za' : 'whois.co.za' # connection refused
}
def __init__(self,domain=None):
self.domain=domain
self.whoisserver=None
self.page=None
def whois(self,domain=None, server=None, cache=0):
if domain is not None:
self.domain=domain
if server is not None:
self.whoisserver=server
if self.domain is None:
print "No Domain"
raise "No Domain"
if self.whoisserver is None:
self.chooseserver()
if self.whoisserver is None:
print "No Server"
raise "No Server"
if cache:
fn = "%s.dom" % domainname
if os.path.exists(fn):
return open(fn).read()
self.page=self._whois()
if cache:
open(fn, "w").write(page)
def chooseserver(self):
try:
toplevel = string.split(self.domain, ".")[-1]
self.whoisserver=WhoisRecord.whoismap.get(toplevel)
#print toplevel, "---", self.whoisserver
if self.whoisserver==None:
self.whoisserver=WhoisRecord.defaultserver
return
except:
self.whoisserver=WhoisRecord.defaultserver
return
if toplevel in ('com', 'org', 'net'):
tmp=self._whois()
m = re.search("Whois Server:(.+)", tmp)
if m:
self.whoisserver=string.strip(m.group(1))
#print "server 2:", self.whoisserver
return
self.whoisserver='whois.networksolutions.com'
tmp=self._whois()
m=re.search("Whois Server:(.+)",tmp)
if m:
self.whoisserver=string.strip(m.group(1))
#print "server 1:", self.whoisserver
return
#print "server 3:", self.whoisserver
def _whois(self):
def alrmhandler(signum,frame):
raise "TimedOut", "on connect"
s = None
## try until we timeout
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if HAS_ALARM:
s.setblocking(0)
signal.signal(signal.SIGALRM,alrmhandler)
signal.alarm(timeout)
while 1:
try:
s.connect((self.whoisserver, 43))
except socket.error, (ecode, reason):
if ecode==errno.EINPROGRESS:
continue
elif ecode==errno.EALREADY:
continue
else:
raise socket.error, (ecode, reason)
pass
break
if HAS_ALARM: signal.alarm(0)
ret = select.select ([s], [s], [], 30)
if len(ret[1])== 0 and len(ret[0]) == 0:
s.close()
raise TimedOut, "on data"
s.setblocking(1)
s.send("%s\n" % self.domain)
page = ""
while 1:
data = s.recv(8196)
if not data: break
page = page + data
pass
s.close()
if string.find(page, "No match for") != -1:
raise 'NoSuchDomain', self.domain
if string.find(page, "No entries found") != -1:
raise 'NoSuchDomain', self.domain
if string.find(page, "no domain specified") != -1:
raise 'NoSuchDomain', self.domain
if string.find(page, "NO MATCH:") != -1:
raise 'NoSuchDomain', self.domain
return page
##
##
----------------------------------------------------------------------
##
class ContactRecord:
def __init__(self):
self.type=None
self.organization=None
self.person=None
self.handle=None
self.address=None
self.address2=None
self.address3=None
self.city=None
self.country=None
self.state=None
self.zip=None
self.email=None
self.phone=None
self.fax=None
self.lastupdated=None
return
def __str__(self):
return "Type: %s\nOrganization: %s\nPerson: %s\nHandle:
%s\nAddress: %s\nAddress2: %s\nAddress3: %s\nCity: %s\nState: %s\nZip:
%s\nCountry: %s\nEmail: %s\nPhone: %s\nFax: %s\nLastupdate: %s\n" %
(self.type,self.organization,self.person,self.handle,self.address,
self.address2, self.address3, self.city, self.state, self.zip,
self.country, self.email,self.phone,self.fax,self.lastupdated)
class DomainRecord(WhoisRecord):
parsemap={ 'whois.networksolutions.com' :
'ParseWhois_NetworkSolutions' ,
'whois.opensrs.net' :
'ParseWhois_NetworkSolutions' , #needs to be customized!
'whois.register.com' : 'ParseWhois_RegisterCOM' ,
'whois.alldomains.com' :
'ParseWhois_AllDomainsCOM',
'whois.iana.org' : 'ParseWhois_INT',
'whois.nic.coop' : 'ParseWhois_COOP',
'whois.biz' : 'ParseWhois_BIZ' ,
'whois.nic.us' : 'ParseWhois_BIZ',
'whois.information.aero' : 'ParseWhois_INFO',
'whois.nic.name' : 'ParseWhois_INFO',
'whois.pir.org' : 'ParseWhois_INFO',
'whois.museum' : 'ParseWhois_INFO',
'whois.afilias.info' : 'ParseWhois_INFO' }
def __init__(self,domain=None):
WhoisRecord.__init__(self,domain)
self.domainid = None
self.created = None
self.lastupdated = None
self.expires = None
self.databaseupdated = None
self.servers = None
self.registrant = ContactRecord()
self.registrant.type='registrant'
self.contacts = {}
return
def __str__(self):
con=''
for (k,v) in self.contacts.items():
con=con + str(v) +'\n'
return "%s (%s):\nWhoisServer: %s\nCreated : %s\nLastupdated :
%s\nDatabaseupdated : %s\nExpires : %s\nServers : %s\nRegistrant
>>\n\n%s\nContacts >>\n\n%s\n" % (self.domain,
self.domainid,self.whoisserver,self.created, self.lastupdated,
self.databaseupdated, self.expires,self.servers, self.registrant, con)
def Parse(self):
self._ParseWhois()
return
def _ParseWhois(self):
m = re.search("Registrar Whois: (.*)", self.page)
if m:
self.whoisserver = m.group(1)
parser=DomainRecord.parsemap.get(self.whoisserver)
if parser==None:
raise 'NoParser for', self.whoisserver
#print "---> PARSER:", self.whoisserver, "-", parser
parser='self.'+parser+'()'
eval(parser)
return
##
##
----------------------------------------------------------------------
##
def _ParseContacts_RegisterCOM(self,page):
parts = re.split("((?:(?:Administrative|Billing|Technical|Zone)
Contact,?[ ]*)+:)\n", page)
contacttypes = None
for part in parts:
if string.find(part, "Contact:") != -1:
if part[-1] == ":": part = part[:-1]
contacttypes = string.split(part, ",")
continue
part = string.strip(part)
if not part: continue
contact=ContactRecord()
m = re.search("Email: (.+ at .+)", part)
if m:
contact.email=string.lower(string.strip(m.group(1)))
m = re.search("\s+Fax\.\.: (.+)", part)
if m:
contact.fax=string.lower(string.strip(m.group(1)))
m = re.search("\s+Phone: (.+)", part)
if m:
contact.phone=m.group(1)
end=m.start(0)
start=0
lines = string.split(part[start:end], "\n")
lines = map(string.strip,lines)
contact.organization = lines.pop(0)
contact.person = lines.pop(0)
contact.address=string.join(lines,'\n')
for contacttype in contacttypes:
contacttype = string.lower(string.strip(contacttype))
contacttype = string.replace(contacttype, " contact",
"")
contact.type=contacttype
self.contacts[contacttype] = copy.copy(contact)
def ParseWhois_NetworkSolutions(self):
m = re.search("Record last updated on (.+)\.", self.page)
if m: self.lastupdated = m.group(1)
m = re.search("Record created on (.+)\.", self.page)
if m: self.created = m.group(1)
m = re.search("Database last updated on (.+)\.", self.page)
if m: self.databaseupdated = m.group(1)
m = re.search("Record expires on (.+)\.",self.page)
if m: self.expires=m.group(1)
m = re.search("Registrant:(.+?)\n\n", self.page, re.S)
if m:
start= m.start(1)
end = m.end(1)
reg = string.strip(self.page[start:end])
reg = string.split(reg, "\n")
reg = map(string.strip,reg)
self.registrant.organization = reg[0]
self.registrant.address = string.join(reg[1:],'\n')
m = re.search("(.+) \((.+)\)", self.registrant.organization)
if m:
self.domainid = m.group(2)
m = re.search("Domain servers in listed order:\n\n", self.page)
if m:
i = m.end()
m = re.search("\n\n", self.page[i:])
j = m.start()
servers = string.strip(self.page[i:i+j])
lines = string.split(servers, "\n")
self.servers = []
for line in lines:
m=re.search("([\w|\.]+?)\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})",string.
strip(line))
if m:
self.servers.append((m.group(1), m.group(2)))
m = re.search("((?:(?:Administrative|Billing|Technical|Zone)
Contact,?[ ]*)+:)\n", self.page)
if m:
i = m.start()
m = re.search("Record expires on", self.page)
j = m.start()
contacts = string.strip(self.page[i:j])
self._ParseContacts_NetworkSolutions(contacts)
def ParseWhois_RegisterCOM(self):
m = re.search("Record last updated on.*: (.+)", self.page)
if m: self.lastupdated = m.group(1)
m = re.search("Created on.*: (.+)", self.page)
if m: self.created = m.group(1)
m = re.search("Expires on.*: (.+)", self.page)
if m: self.expires = m.group(1)
m = re.search("Phone: (.+)", self.page)
if m: self.registrant.phone=m.group(1)
m = re.search("Email: (.+ at .+)",self.page)
if m: self.registrant.email=m.group(1)
m = re.search("Fax\.\.: (.+ at .+)",self.page)
if m: self.registrant.fax=m.group(1)
m = re.search("Organization:(.+?)Phone:",self.page,re.S)
if m:
start=m.start(1)
end=m.end(1)
registrant = string.strip(self.page[start:end])
registrant = string.split(registrant, "\n")
registrant = map(string.strip,registrant)
self.registrant.organization = registrant[0]
self.registrant.person =registrant[1]
self.registrant.address = string.join(registrant[2:], "\n")
m = re.search("Domain servers in listed order:\n\n(.+?)\n\n",
self.page, re.S)
if m:
start = m.start(1)
end = m.end(1)
servers = string.strip(self.page[start:end])
lines = string.split(servers, "\n")
self.servers = []
for line in lines:
m=re.search("([\w|\.]+?)\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})",string.
strip(line))
if m:
self.servers.append((m.group(1), m.group(2)))
m = re.search("((?:(?:Administrative|Billing|Technical|Zone)
Contact,?[ ]*)+:)\n", self.page)
if m:
i = m.start()
m = re.search("Domain servers in listed order", self.page)
j = m.start()
contacts = string.strip(self.page[i:j])
self._ParseContacts_RegisterCOM(contacts)
def _ParseContacts_NetworkSolutions(self,page):
parts = re.split("((?:(?:Administrative|Billing|Technical|Zone)
Contact,?[ ]*)+:)\n", page)
contacttypes = None
for part in parts:
if string.find(part, "Contact:") != -1:
if part[-1] == ":": part = part[:-1]
contacttypes = string.split(part, ",")
continue
part = string.strip(part)
if not part: continue
record=ContactRecord()
lines = string.split(part, "\n")
m = re.search("(.+) \((.+)\) (.+ at .+)", lines.pop(0))
if m:
record.person = string.strip(m.group(1))
record.handle = string.strip(m.group(2))
record.email = string.lower(string.strip(m.group(3)))
pass
record.organization=string.strip(lines.pop(0))
flag = 0
addresslines = []
phonelines = []
phonelines.append(string.strip(lines.pop()))
for line in lines:
line = string.strip(line)
#m=re.search("^(\d|-|\+|\s)+$",line)
#if m: flag = 1
if flag == 0:
addresslines.append(line)
else:
phonelines.append(line)
pass
pass
record.phone = string.join(phonelines, "\n")
record.address = string.join(addresslines, "\n")
for contacttype in contacttypes:
contacttype = string.lower(string.strip(contacttype))
contacttype = string.replace(contacttype, " contact",
"")
record.type=contacttype
self.contacts.update({contacttype:copy.copy(record)})
return
def ParseWhois_AllDomainsCOM(self):
m = re.search("Record last updated on\.*: (.+)\.", self.page)
if m: self.lastupdated = m.group(1)
m = re.search("Created on\.*: (.+)\.", self.page)
if m: self.created = m.group(1)
m = re.search("Expires on\.*: (.+)\.",self.page)
if m: self.expires=m.group(1)
rawstr = r'Registrant:\n(?P<org>.*?)\s*\((?P<id>DOM-.*)\)'
m = re.search(rawstr, self.page)
if m:
self.registrant.organization = m.group('org')
idx = string.find(self.page, "\n\n", m.end(2))
self.registrant.address =
string.strip(self.page[m.end(2)+1:idx])
m = re.search("(.+) \((.+)\)", self.registrant.organization)
if m:
self.domainid = m.group('id')
m = re.search("Domain servers in listed order:\n\n", self.page)
if m:
i = m.end()
m = re.search("\n\n", self.page[i:])
j = m.start()
servers = string.strip(self.page[i:i+j])
lines = string.split(servers, "\n")
self.servers = []
for line in lines:
m=re.search("([\w|\.]+?)\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})",string.
strip(line))
if m:
self.servers.append((m.group(1), m.group(2)))
m = re.search("((?:(?:Administrative|Billing|Technical|Zone)
Contact,?[ ]*)+:)\n", self.page)
if m:
i = m.start()
m = re.search("Created on", self.page)
try:
j = m.start()
except:
j = len(self.page)
contacts = string.strip(self.page[i:j])
self._ParseContacts_AllDomainsCOM(contacts)
def _ParseContacts_AllDomainsCOM(self,page):
parts = re.split("((?:(?:Administrative|Billing|Technical|Zone)
Contact,?[ ]*)+:)\n", page)
contacttypes = None
for part in parts:
if string.find(part, "Contact:") != -1:
if part[-1] == ":": part = part[:-1]
contacttypes = string.split(part, ",")
continue
part = string.strip(part)
if not part: continue
record=ContactRecord()
rawstr =
r'(?P<person>.*?)\s*\((?P<handle>NIC-.*)\)\s*(?P<org>.*?)\n'
m = re.search(rawstr, part, re.DOTALL)
if m:
record.handle = m.group('handle')
record.organization = m.group('org')
record.person = m.group('person')
part = part[m.end('org'):]
rawstr =
r'.*\s(?P<email>.*?@.*?)\s(?P<phone>.*?)\sFAX-\s(?P<fax>.*)'
m = re.search(rawstr, part, re.IGNORECASE | re.DOTALL)
if m:
record.email = m.group('email')
record.phone = string.strip(m.group('phone'))
record.fax = m.group('fax')
part = part[:m.start('email')]
lines = string.split(part, "\n")
addresslines = map(string.strip, lines)
record.address = string.strip(string.join(addresslines,
"\n"))
for contacttype in contacttypes:
contacttype = string.lower(string.strip(contacttype))
contacttype = string.replace(contacttype, " contact",
"")
record.type=contacttype
self.contacts.update({contacttype:copy.copy(record)})
def ParseWhois_BIZ(self):
biz_contacts = (
{"page_field": "Administrative", "rec_field":
"administrative"},
{"page_field": "Billing", "rec_field": "billing"},
{"page_field": "Technical", "rec_field": "technical"},
{"page_field": "Registrant", "rec_field": "registrant"}
)
# map of each page field name to the corresponding field of a
ContactRecord()
# struct is a tuple of dicts where each dict has "page_field"
and "rec_field" key/vals
biz_contact_fields = (
{"page_field": "ID", "rec_field": "handle"},
{"page_field": "Organization", "rec_field":
"organization"},
{"page_field": "Name", "rec_field": "person"},
{"page_field": "Address1", "rec_field": "address"},
{"page_field": "City", "rec_field": "city"},
{"page_field": "State/Province", "rec_field": "state"},
{"page_field": "Postal Code", "rec_field": "zip"},
{"page_field": "Country", "rec_field": "country"},
{"page_field": "Phone Number", "rec_field": "phone"},
{"page_field": "Facsimile", "rec_field": "fax"},
{"page_field": "Email", "rec_field": "email"}
)
self._ParseContacts_Generic(biz_contacts, biz_contact_fields)
biz_fields = (
{'page_field': "Domain ID", "rec_field":
"domainid"},
{'page_field': "Domain Registration Date", "rec_field":
"created"},
{'page_field': "Domain Expiration Date", "rec_field":
"expires"},
{'page_field': "Name Server", "rec_field":
"servers"}
)
self._ParseWhois_Generic(biz_fields)
def ParseWhois_INFO(self):
info_contacts = (
{"page_field": "Admin", "rec_field":
"administrative"},
{"page_field": "Billing", "rec_field": "billing"},
{"page_field": "Tech", "rec_field": "technical"},
{"page_field": "Registrant", "rec_field": "registrant"}
)
# map of each page field name to the corresponding field of a
ContactRecord()
# struct is a tuple of dicts where each dict has "page_field"
and "rec_field" key/vals
info_contact_fields = (
{"page_field": "ID", "rec_field": "handle"},
{"page_field": "Organization", "rec_field":
"organization"},
{"page_field": "Name", "rec_field": "person"},
{"page_field": "Address", "rec_field": "address"}, #
for NAME
{"page_field": "Adress", "rec_field": "address"}, #
for MUSEUM (mispelled!)
{"page_field": "Street1", "rec_field": "address"}, #
for INFO
{"page_field": "Street2", "rec_field": "address2"},
{"page_field": "Street3", "rec_field": "address3"},
{"page_field": "City", "rec_field": "city"},
{"page_field": "State/Province", "rec_field": "state"},
{"page_field": "Postal Code", "rec_field": "zip"},
{"page_field": "Country", "rec_field": "country"},
{"page_field": "Phone", "rec_field": "phone"},
{"page_field": "Phone Number", "rec_field": "phone"}, #
for AERO, MUSEUM
{"page_field": "Facsimile", "rec_field": "fax"},
{"page_field": "Fax Number", "rec_field": "fax"}, # for
AERO, MUSEUM
{"page_field": "Email", "rec_field": "email"}
)
self._ParseContacts_Generic(info_contacts, info_contact_fields)
info_fields = (
{'page_field': "Domain ID", "rec_field":
"domainid"},
{'page_field': "Created On", "rec_field":
"created"},
{'page_field': "Creation Date", "rec_field":
"created"},
{'page_field': "Expires On", "rec_field":
"expires"}, #NAME
{'page_field': "Expiration Date", "rec_field":
"expires"}, #INFO. #AERO
{'page_field': "Last Updated", "rec_field":
"lastupdated"},
{'page_field': "Updated On", "rec_field":
"lastupdated"}, #MUSEUM
{'page_field': "Name Server", "rec_field":
"servers"}
)
self._ParseWhois_Generic(info_fields)
def ParseWhois_COOP(self):
coop_contacts = (
{"page_field": "domain:Admin-", "rec_field":
"administrative"},
{"page_field": "domain:Billing-", "rec_field":
"billing"},
{"page_field": "domain:Tech-", "rec_field":
"technical"},
{"page_field": "domain:Registrant-", "rec_field":
"registrant"}
)
# map of each page field name to the corresponding field of a
ContactRecord()
# struct is a tuple of dicts where each dict has "page_field"
and "rec_field" key/vals
coop_contact_fields = (
{"page_field": "ID", "rec_field":
"handle"},
{"page_field": "Organization", "rec_field":
"organization"},
{"page_field": "Name", "rec_field":
"person"},
{"page_field": "Address1", "rec_field":
"address"},
{"page_field": "Address2", "rec_field":
"address2"},
{"page_field": "City", "rec_field":
"city"},
{"page_field": "State/Province", "rec_field":
"state"},
{"page_field": "Postcode", "rec_field": "zip"},
{"page_field": "Country", "rec_field":
"country"},
{"page_field": "Phone-Number", "rec_field":
"phone"},
{"page_field": "Facsimile-Number", "rec_field": "fax"},
{"page_field": "Email", "rec_field":
"email"}
)
self._ParseContacts_Generic(coop_contacts, coop_contact_fields)
coop_fields = (
{'page_field': "domain:ID", "rec_field":
"domainid"},
{'page_field': "domain:Registration", "rec_field":
"created"},
{'page_field': "domain:Expiration", "rec_field":
"expires"},
{'page_field': "domain:Name-Server", "rec_field":
"servers"}
)
self._ParseWhois_Generic(coop_fields)
def _ParseWhois_Generic(self, fields):
for field in fields:
regex = "%s: *(.+)" % field['page_field']
#print regex
if field['rec_field'] == "servers":
self.servers = []
servers = re.findall(regex, self.page)
for server in servers:
try:
server = string.strip(server)
ip = socket.gethostbyname(server)
except:
ip = "?"
self.servers.append((server, ip))
else:
m = re.search(regex, self.page)
#if m: print m.group(1)
if m: setattr(self, field['rec_field'],
string.strip(m.group(1)))
def _ParseContacts_Generic(self, contacts, fields):
for contact in contacts:
if contact['rec_field'] == 'registrant':
self._ParseGenericContact(self.registrant,
contact['page_field'], fields)
else:
self.contacts[contact['rec_field']] = ContactRecord()
self.contacts[contact['rec_field']].type =
contact['rec_field']
self._ParseGenericContact(self.contacts[contact['rec_field']],
contact['page_field'], fields)
def _ParseGenericContact(self, contact_rec, contact, fields):
for field in fields:
m = re.search("%s *.*%s: *(.+)" % (contact,
field['page_field']), self.page)
if not m: continue
setattr(contact_rec, field['rec_field'],
string.strip(m.group(1)))
def ParseWhois_INT(self):
int_contacts = (
{"page_field": "Registrant", "rec_field": "registrant"},
{"page_field": "Administrative Contact", "rec_field":
"administrative"},
{"page_field": "Technical Contact", "rec_field":
"technical"})
page = string.replace(self.page, "\r\n", "\n")
for contact in int_contacts:
page_field = contact['page_field']
s = "%s:(.*)\n\W" % page_field
m = re.search(s, page, re.DOTALL)
#if m: print m.group(1)
print "-------------------"
##
##
----------------------------------------------------------------------
##
##
##
----------------------------------------------------------------------
##
def usage(progname):
version = _version
print __doc__ % vars()
def main(argv, stdout, environ):
progname = argv[0]
list, args = getopt.getopt(argv[1:], "", ["help", "version"])
for (field, val) in list:
if field == "--help":
usage(progname)
return
elif field == "--version":
print progname, _version
return
#rec=WhoisRecord()
#rec=DomainRecord()
for domain in args:
whoisserver=None
if string.find(domain,'@')!=-1:
(domain, whoisserver)=string.split(domain,'@')
try:
d = DomainRecord(domain)
d.whois(domain, whoisserver)
#print "---> PAGE:", d.page
d.Parse()
print str(d)
#print rec.page
except 'NoSuchDomain', reason:
print "ERROR: no such domain %s" % domain
# except socket.error, (ecode,reason):
print reason
except "TimedOut", reason:
print "Timed out", reason
if __name__ == "__main__":
main(sys.argv, sys.stdout, os.environ)