whois-0.7/0000755000175000017500000000000012043550320013235 5ustar ddarkoddarko00000000000000whois-0.7/README0000644000175000017500000000175011772311776014142 0ustar ddarkoddarko00000000000000WHOIS ============= Python module/library for retrieving WHOIS information of domains. By DDarko http://ddarko.org/ Features ============= * Python wrapper for Linux "whois" command * simple interface to access parsed WHOIS data for a given domain * able to extract data for all the popular TLDs (com, org, net, biz, info, pl, jp, uk, nz, ...) * query a WHOIS server directly instead of going through an intermediate web service like many others do * works with Python 2.4+ and Python 3.x * all dates as datetime objects * possibility to cache results Usage example ============= >>> import whois >>> domain = whois.query('google.com') >>> print(domain.__dict__) { 'expiration_date': datetime.datetime(2020, 9, 14, 0, 0), 'last_updated': datetime.datetime(2011, 7, 20, 0, 0), 'registrar': 'MARKMONITOR INC.', 'name': 'google.com', 'creation_date': datetime.datetime(1997, 9, 15, 0, 0) } >>> print(domain.name) google.com >>> print(domain.expiration_date) 2020-09-14 00:00:00 whois-0.7/PKG-INFO0000644000175000017500000000441312043550320014334 0ustar ddarkoddarko00000000000000Metadata-Version: 1.1 Name: whois Version: 0.7 Summary: Python module/library for retrieving WHOIS information of domains. Home-page: http://code.google.com/p/python-whois/ Author: DDarko.org Author-email: ddarko@ddarko.org License: MIT http://www.opensource.org/licenses/mit-license.php Description: WHOIS ============= Python module/library for retrieving WHOIS information of domains. By DDarko http://ddarko.org/ Features ============= * Python wrapper for Linux "whois" command * simple interface to access parsed WHOIS data for a given domain * able to extract data for all the popular TLDs (com, org, net, biz, info, pl, jp, uk, nz, ...) * query a WHOIS server directly instead of going through an intermediate web service like many others do * works with Python 2.4+ and Python 3.x * all dates as datetime objects * possibility to cache results Usage example ============= >>> import whois >>> domain = whois.query('google.com') >>> print(domain.__dict__) { 'expiration_date': datetime.datetime(2020, 9, 14, 0, 0), 'last_updated': datetime.datetime(2011, 7, 20, 0, 0), 'registrar': 'MARKMONITOR INC.', 'name': 'google.com', 'creation_date': datetime.datetime(1997, 9, 15, 0, 0) } >>> print(domain.name) google.com >>> print(domain.expiration_date) 2020-09-14 00:00:00 Keywords: Python,WHOIS,TLD,domain,expiration,registrar Platform: any Classifier: License :: OSI Approved :: MIT License Classifier: Intended Audience :: Developers Classifier: Environment :: Console Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.5 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.0 Classifier: Programming Language :: Python :: 3.1 Classifier: Programming Language :: Python :: 3.2 Classifier: Topic :: Internet Classifier: Topic :: Software Development :: Libraries :: Python Modules whois-0.7/setup.py0000644000175000017500000000214712043550314014756 0ustar ddarkoddarko00000000000000from distutils.core import setup setup( name='whois', version='0.7', description='Python module/library for retrieving WHOIS information of domains.', long_description = open('README').read(), author='DDarko.org', author_email='ddarko@ddarko.org', license='MIT http://www.opensource.org/licenses/mit-license.php', url='http://code.google.com/p/python-whois/', platforms = ['any'], packages=['whois'], keywords=['Python','WHOIS','TLD','domain','expiration','registrar'], classifiers=[ 'License :: OSI Approved :: MIT License', 'Intended Audience :: Developers', 'Environment :: Console', 'Programming Language :: Python', 'Programming Language :: Python :: 2.5', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.0', 'Programming Language :: Python :: 3.1', 'Programming Language :: Python :: 3.2', 'Topic :: Internet', 'Topic :: Software Development :: Libraries :: Python Modules', ], ) ''' test_suite='testsuite', entry_points=""" [console_scripts] cmd = package:main """, '''whois-0.7/whois/0000755000175000017500000000000012043550320014366 5ustar ddarkoddarko00000000000000whois-0.7/whois/_3_adjust.py0000644000175000017500000000471212043546116016627 0ustar ddarkoddarko00000000000000import re import sys import datetime PYTHON_VERSION = sys.version_info[0] class Domain: def __init__(self, data): self.name = data['domain_name'][0].strip().lower() self.registrar = data['registrar'][0].strip() self.creation_date = str_to_date(data['creation_date'][0]) self.expiration_date = str_to_date(data['expiration_date'][0]) self.last_updated = str_to_date(data['updated_date'][0]) #---------------------------------- # name_servers tmp = [] for x in data['name_servers']: if isinstance(x, str): tmp.append(x) else: for y in x: tmp.append(y) self.name_servers = set() for x in tmp: x = x.strip(' .') if x: if ' ' in x: x, _ = x.split(' ', 1) x = x.strip(' .') self.name_servers.add(x.lower()) #---------------------------------- # http://docs.python.org/library/datetime.html#strftime-strptime-behavior DATE_FORMATS = [ '%d-%b-%Y', # 02-jan-2000 '%d.%m.%Y', # 02.02.2000 '%d/%m/%Y', # 01/06/2011 '%Y-%m-%d', # 2000-01-02 '%Y.%m.%d', # 2000.01.02 '%Y/%m/%d', # 2005/05/30 '%Y.%m.%d %H:%M:%S', # 2002.09.19 13:00:00 '%Y%m%d %H:%M:%S', # 20110908 14:44:51 '%Y-%m-%d %H:%M:%S', # 2011-09-08 14:44:51 '%d.%m.%Y %H:%M:%S', # 19.09.2002 13:00:00 '%d-%b-%Y %H:%M:%S %Z', # 24-Jul-2009 13:20:03 UTC '%Y/%m/%d %H:%M:%S (%z)', # 2011/06/01 01:05:01 (+0900) '%Y/%m/%d %H:%M:%S', # 2011/06/01 01:05:01 '%a %b %d %H:%M:%S %Z %Y', # Tue Jun 21 23:59:59 GMT 2011 '%a %b %d %Y', # Tue Dec 12 2000 '%Y-%m-%dT%H:%M:%S', # 2007-01-26T19:10:31 '%Y-%m-%dT%H:%M:%SZ', # 2007-01-26T19:10:31Z '%Y-%m-%dT%H:%M:%S%z', # 2011-03-30T19:36:27+0200 '%Y-%m-%dT%H:%M:%S.%f%z', # 2011-09-08T14:44:51.622265+03:00 '%Y-%m-%dt%H:%M:%S.%f', # 2011-09-08t14:44:51.622265 ] def str_to_date(s): s = s.strip().lower() if not s or s == 'not defined': return s = s.replace('(jst)', '(+0900)') s = re.sub('(\+[0-9]{2}):([0-9]{2})', '\\1\\2', s) if PYTHON_VERSION < 3: return str_to_date_py2(s) for format in DATE_FORMATS: try: return datetime.datetime.strptime(s, format) except ValueError as e: pass raise ValueError("Unknown date format: '%s'" % s) def str_to_date_py2(s): tmp = re.findall('\+([0-9]{2})00', s) if tmp: tz = int(tmp[0]) else: tz = 0 for format in DATE_FORMATS: try: return datetime.datetime.strptime(s, format) + datetime.timedelta(hours=tz) except ValueError as e: pass raise ValueError("Unknown date format: '%s'" % s) whois-0.7/whois/tld_regexpr.py0000644000175000017500000001167712043546071017303 0ustar ddarkoddarko00000000000000com = { 'extend': None, 'domain_name': r'Domain Name:\s?(.+)', 'registrar': r'Registrar:\s?(.+)', 'registrant': None, 'creation_date': r'Creation Date:\s?(.+)', 'expiration_date': r'Expiration Date:\s?(.+)', 'updated_date': r'Updated Date:\s?(.+)', 'name_servers': r'Name Server:\s*(.+)\s*', 'status': r'Status:\s?(.+)', 'emails': r'[\w.-]+@[\w.-]+\.[\w]{2,4}', } net = { 'extend': 'com', } org = { 'extend': 'com', 'creation_date': r'\nCreated On:\s?(.+)', 'updated_date': r'\nLast Updated On:\s?(.+)', 'name_servers': r'Name Server:\s?(.+)\s*', } uk = { 'extend': 'com', 'registrant': r'Registrant:\n\s*(.+)', 'creation_date': r'Registered on:\s*(.+)', 'expiration_date': r'Renewal date:\s*(.+)', 'updated_date': r'Last updated:\s*(.+)', 'name_servers': r'Name Servers:\s*(.+)\s*', 'status': r'Registration status:\n\s*(.+)', } pl = { 'extend': 'uk', 'creation_date': r'\ncreated:\s*(.+)\n', 'updated_date': r'\nlast modified:\s*(.+)\n', 'name_servers': r'\nnameservers:\s*(.+)\n\s*(.+)\n', 'status': r'\nStatus:\n\s*(.+)', } ru = { 'extend': 'com', 'domain_name': r'\ndomain:\s*(.+)', 'creation_date': r'\ncreated:\s*(.+)', 'expiration_date': r'\npaid-till:\s*(.+)', 'name_servers': r'\nnserver:\s*(.+)', 'status': r'\nstate:\s*(.+)', } lv = { 'extend': 'ru', 'creation_date': r'Registered:\s*(.+)\n', 'updated_date': r'Changed:\s*(.+)\n', 'status': r'Status:\s?(.+)', } jp = { 'domain_name': r'\[Domain Name\]\s?(.+)', 'registrar': None, 'registrant': r'\[Registrant\]\s?(.+)', 'creation_date': r'\[Created on\]\s?(.+)', 'expiration_date': r'\[Expires on\]\s?(.+)', 'updated_date': r'\[Last Updated\]\s?(.+)', 'name_servers': r'\[Name Server\]\s*(.+)', 'status': r'\[Status\]\s?(.+)', 'emails': r'[\w.-]+@[\w.-]+\.[\w]{2,4}', } co_jp = { 'extend': 'jp', 'creation_date': r'\[Registered Date\]\s?(.+)', 'expiration_date': r'\[State\].+\((.+)\)', 'updated_date': r'\[Last Update\]\s?(.+)', } de = { 'extend': 'com', 'domain_name': r'\ndomain:\s*(.+)', 'updated_date': r'\nChanged:\s?(.+)', 'name_servers': r'Nserver:\s*(.+)', } at = { 'extend': 'com', 'domain_name': r'domain:\s?(.+)', 'updated_date': r'changed:\s?(.+)', 'name_servers': r'nserver:\s*(.+)', } eu = { 'extend': 'com', 'domain_name': r'\ndomain:\s*(.+)', 'registrar': r'Name:\s?(.+)', } biz = { 'extend': 'com', 'registrar': r'Sponsoring Registrar:\s?(.+)', 'registrant': r'Registrant Organization:\s?(.+)', 'creation_date': r'Domain Registration Date:\s?(.+)', 'expiration_date': r'Domain Expiration Date:\s?(.+)', 'updated_date': r'Domain Last Updated Date:\s?(.+)', 'status': None, } info = { 'extend': 'biz', 'creation_date': r'Created On:\s?(.+)', 'expiration_date': r'Expiration Date:\s?(.+)', 'updated_date': r'Last Updated On:\s?(.+)', 'status': r'Status:\s?(.+)', } name = { 'extend': 'com', 'status': r'Domain Status:\s?(.+)', } us = { 'extend': 'name', } co = { 'extend': 'biz', 'status': r'Status:\s?(.+)', } me = { 'extend': 'biz', 'creation_date': r'Domain Create Date:\s?(.+)', 'expiration_date': r'Domain Expiration Date:\s?(.+)', 'updated_date': r'Domain Last Updated Date:\s?(.+)', 'name_servers': r'Nameservers:\s?(.+)', 'status': r'Domain Status:\s?(.+)', } be = { 'extend': 'pl', 'domain_name': r'\nDomain:\s*(.+)', 'registrar': r'Company Name:\n?(.+)', 'creation_date': r'Registered:\s*(.+)\n', 'status': r'Status:\s?(.+)', } nz = { 'extend': None, 'domain_name': r'domain_name:\s?(.+)', 'registrar': r'registrar_name:\s?(.+)', 'registrant': r'registrant_contact_name:\s?(.+)', 'creation_date': r'domain_dateregistered:\s?(.+)', 'expiration_date': r'domain_datebilleduntil:\s?(.+)', 'updated_date': r'domain_datelastmodified:\s?(.+)', 'name_servers': r'ns_name_[0-9]{2}:\s?(.+)', 'status': r'query_status:\s?(.+)', 'emails': r'[\w.-]+@[\w.-]+\.[\w]{2,4}', } cz = { 'extend': 'com', 'domain_name': r'Domain:\s?(.+)', 'registrar': r'registrar:\s?(.+)', 'registrant': r'registrant:\s?(.+)', 'creation_date': r'registered:\s?(.+)', 'expiration_date': r'expire:\s?(.+)', 'updated_date': r'changed:\s?(.+)', 'name_servers': r'nserver:\s*(.+) ', } it = { 'extend': 'com', 'domain_name': r'Domain:\s?(.+)', 'registrar': r'Registrar:\s*Organization:\s*(.+)', 'registrant': r'Registrant:\s?Name:\s?(.+)', 'creation_date': r'Created:\s?(.+)', 'expiration_date': r'Expire Date:\s?(.+)', 'updated_date': r'Last Update:\s?(.+)', 'name_servers': r'Nameservers:\s?(.+)\s?(.+)\s?(.+)\s?(.+)', 'status': r'Status:\s?(.+)', } fr = { 'extend': 'com', 'domain_name': r'domain:\s?(.+)', 'registrar': r'registrar:\s*(.+)', 'registrant': r'contact:\s?(.+)', 'creation_date': r'created:\s?(.+)', 'expiration_date': None, 'updated_date': r'last-update:\s?(.+)', 'name_servers': r'nserver:\s*(.+)', 'status': r'status:\s?(.+)', }whois-0.7/whois/_1_query.py0000644000175000017500000000271412043532574016503 0ustar ddarkoddarko00000000000000import subprocess import time import sys import os PYTHON_VERSION = sys.version_info[0] CACHE = {} CACHE_MAX_AGE = 60*60*48 # 48h try: import json except: import simplejson as json def cache_load(cf): if not os.path.isfile(cf): return global CACHE f = open(cf, 'r') try: CACHE = json.load(f) except: pass f.close() def cache_save(cf): global CACHE f = open(cf, 'w') json.dump(CACHE, f) f.close() def do_query(dl, force=0, cache_file=None, slow_down=0, ignore_returncode=0): k = '.'.join(dl) if cache_file: cache_load(cache_file) if force or k not in CACHE or CACHE[k][0] < time.time() - CACHE_MAX_AGE: CACHE[k] = ( int(time.time()), _do_whois_query(dl, ignore_returncode), ) if cache_file: cache_save(cache_file) if slow_down: time.sleep(slow_down) return CACHE[k][1] def _do_whois_query(dl, ignore_returncode): """ Linux 'whois' command wrapper """ p = subprocess.Popen(['whois', '.'.join(dl)], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) r = p.communicate()[0] r = r.decode() if PYTHON_VERSION == 3 else r if not ignore_returncode and p.returncode != 0: raise Exception(r) return r """ import socket def _do_whois_query(dl): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((('%s.whois-servers.net' % dl[-1], 43))) s.send(("%s\r\n" % '.'.join(dl)).encode()) response = [] while 1: t = s.recv(4096) response.append(t) if t == b'': break s.close() return b''.join(response).decode() """whois-0.7/whois/__init__.py0000644000175000017500000000335412043545163016515 0ustar ddarkoddarko00000000000000""" Python module/library for retrieving WHOIS information of domains. By DDarko.org ddarko@ddarko.org http://ddarko.org/ License MIT http://www.opensource.org/licenses/mit-license.php Usage example >>> import whois >>> domain = whois.query('google.com') >>> print(domain.__dict__) {'expiration_date': datetime.datetime(2020, 9, 14, 0, 0), 'last_updated': datetime.datetime(2011, 7, 20, 0, 0), 'registrar': 'MARKMONITOR INC.', 'name': 'google.com', 'creation_date': datetime.datetime(1997, 9, 15, 0, 0)} >>> print(domain.name) google.com >>> print(domain.expiration_date) 2020-09-14 00:00:00 """ from ._1_query import do_query from ._2_parse import do_parse, TLD_RE from ._3_adjust import Domain CACHE_FILE = None SLOW_DOWN = 0 def query(domain, force=0, cache_file=None, slow_down=0, ignore_returncode=0): """ force=1 Don't use cache. cache_file= Use file to store cache not only memory. slow_down=0 Time [s] it will wait after you query WHOIS database. This is useful when there is a limit to the number of requests at a time. """ assert isinstance(domain, str), Exception('`domain` - must be ') cache_file = cache_file or CACHE_FILE slow_down = slow_down or SLOW_DOWN domain = domain.lower().strip() d = domain.split('.') if d[0] == 'www': d = d[1:] if len(d) == 1: return None if domain.endswith('.co.jp'): tld = 'co_jp' else: tld = d[-1] if tld not in TLD_RE.keys(): raise Exception('Unknown TLD: %s\n(all known TLD: %s)' % (tld, list(TLD_RE.keys()))) while 1: pd = do_parse(do_query(d, force, cache_file, slow_down, ignore_returncode), tld) if (not pd or not pd['domain_name'][0]) and len(d) > 2: d = d[1:] else: break return Domain(pd) if pd['domain_name'][0] else None whois-0.7/whois/_2_parse.py0000644000175000017500000000174512043544556016457 0ustar ddarkoddarko00000000000000from . import tld_regexpr import re TLD_RE = {} def get_tld_re(tld): if tld in TLD_RE: return TLD_RE[tld] v = getattr(tld_regexpr, tld) extend = v.get('extend') if extend: e = get_tld_re(extend) tmp = e.copy() tmp.update(v) else: tmp = v if 'extend' in tmp: del tmp['extend'] TLD_RE[tld] = dict((k, re.compile(v, re.IGNORECASE) if isinstance(v, str) else v) for k, v in tmp.items()) return TLD_RE[tld] [get_tld_re(tld) for tld in dir(tld_regexpr) if tld[0] != '_'] #from pprint import pprint def do_parse(whois_str, tld): r = {} if whois_str.count('\n') < 5: s = whois_str.strip().lower() if s == 'not found': return if s.count('error'): return raise Exception(whois_str) sn = re.findall(r'Server Name:\s?(.+)', whois_str, re.IGNORECASE) if sn: whois_str = whois_str[whois_str.find('Domain Name:'):] for k, v in TLD_RE.get(tld, TLD_RE['com']).items(): if v is None: r[k] = [''] else: r[k] = v.findall(whois_str) or [''] #pprint(r) return r