Skip to content

Commit 991702e

Browse files
committed
test whoisdomain formatting with raw
1 parent fcbf21f commit 991702e

7 files changed

Lines changed: 204 additions & 66 deletions

File tree

Makefile

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,11 @@
11
# ==========================================================
2-
SHELL := /bin/bash -l
3-
export SHELL
4-
5-
VENV := ./vtmp/
6-
export VENV
7-
8-
# tested on 3.10-3.14
9-
MIN_PYTHON_VERSION := $(shell basename $$( ls /usr/bin/python3.[0-9][0-9] | awk '{print $0; exit}' ) )
10-
export MIN_PYTHON_VERSION
11-
12-
PIP_INSTALL := pip3 -q \
13-
--require-virtualenv \
14-
--disable-pip-version-check \
15-
--no-color install --no-cache-dir
16-
17-
# ==========================================
18-
# Code formatting and checks
19-
PY_FILES := *.py whoisdomain/
20-
21-
# LINE_LENGTH := 160
2+
include Makefile.inc
3+
# ==========================================================
224

235
MYPY_INSTALL := \
246
types-requests \
257
types-python-dateutil
268

27-
COMMON_VENV := rm -rf $(VENV); \
28-
$(MIN_PYTHON_VERSION) -m venv $(VENV); \
29-
source ./$(VENV)/bin/activate;
30-
31-
# --------------------------------------------------
32-
# reformat, lint and verify basics
33-
# --------------------------------------------------
349
prep: clean format check mypy
3510

3611
clean:

Makefile.docker

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
# ==========================================================
2-
SHELL := /bin/bash -l
3-
export SHELL
4-
5-
# tested on 3.10-3.14
6-
MIN_PYTHON_VERSION := $(shell basename $$( ls /usr/bin/python3.[0-9][0-9] | awk '{print $0; exit}' ) )
7-
export MIN_PYTHON_VERSION
2+
include Makefile.inc
3+
# ==========================================================
84

95
WHAT := whoisdomain
106
DOCKER_WHO := mbootgithub

Makefile.inc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
SHELL := /bin/bash -l
2+
export SHELL
3+
4+
VENV := ./vtmp/
5+
export VENV
6+
7+
MIN_PYTHON_VERSION := $(shell basename $$( ls /usr/bin/python3.[0-9][0-9] | awk '{print $0; exit}' ) )
8+
export MIN_PYTHON_VERSION
9+
10+
COMMON_VENV := rm -rf $(VENV); \
11+
$(MIN_PYTHON_VERSION) -m venv $(VENV); \
12+
source ./$(VENV)/bin/activate;
13+
14+
PIP_INSTALL := pip3 -q \
15+
--require-virtualenv \
16+
--disable-pip-version-check \
17+
--no-color install --no-cache-dir
18+
19+
# ==========================================
20+
# Code formatting and checks
21+
PY_FILES := *.py whoisdomain/

Makefile.pypi

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
# ==========================================================
22
# ==========================================================
3-
# https://docs.secure.software/cli
4-
5-
SHELL := /bin/bash -l
6-
export SHELL
7-
8-
# tested on 3.10-3.14
9-
MIN_PYTHON_VERSION := $(shell basename $$( ls /usr/bin/python3.[0-9][0-9] | awk '{print $0; exit}' ) )
10-
export MIN_PYTHON_VERSION
3+
include Makefile.inc
4+
# ==========================================================
115

126
run: pypiTest
137

Makefile.tests

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,6 @@
1-
# Makefile
2-
3-
SHELL := /bin/bash -l
4-
export SHELL
5-
6-
VENV := ./vtmp/
7-
export VENV
8-
9-
# tested on 3.10-3.14
10-
MIN_PYTHON_VERSION := $(shell basename $$( ls /usr/bin/python3.[0-9][0-9] | awk '{print $0; exit}' ) )
11-
export MIN_PYTHON_VERSION
12-
13-
# ==========================================
14-
# Code formatting and checks
15-
PY_FILES := *.py bin/*.py whoisdomain/
16-
17-
LINE_LENGTH := 160
1+
# ==========================================================
2+
include Makefile.inc
3+
# ==========================================================
184

195
TEST_OPTIONS_ALL = \
206
--withPublicSuffix \

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ On January 19, 2023, ICANN opened voting on a global amendment to all its regist
3030
* the second item will be YYYYMMDD,
3131
* the third item will start from 1 and be only used if more than one update will have to be done in one day.
3232

33-
Versions `1.x.x` will keep the output compatible with Danny Cork until 2024-02-03 (February 2024)
33+
Versions `1.x.x` will keep the output compatible with Danny Cork.
34+
Versions `2.x.x` will add a dependency on whodap and use rdab based whois data before consulting historical whois.
3435

3536
## Releases
3637

t2.py

Lines changed: 172 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,27 +28,126 @@ class WhoisRdap:
2828
def __init__(self) -> None:
2929
self.dnsc = whodap.DNSClient.new_client() # make sure we cache the primary looup for the tld rdap servers
3030

31-
def fld(self, domain: str) -> str:
31+
def fld(self, domain: str) -> str | None:
3232
return tld.get_fld(domain, fix_protocol=True, fail_silently=True)
3333

3434
def do_one_domain(self, domain: str) -> DataResponse:
3535
try:
36-
xfld = self.fld(domain)
36+
xfld = str(self.fld(domain))
3737
a = xfld.split(".")
3838
dom = ".".join(a[:-1])
3939
xtld = a[-1]
4040
resp = self.dnsc.lookup(dom, xtld)
4141
return DataResponse(status=True, data=resp.to_whois_dict())
4242
except Exception as e:
4343
print(f"Exception: {e}", file=sys.stderr)
44-
return DataResponse(status=False, message=e)
44+
return DataResponse(status=False, message=str(e))
45+
46+
@classmethod
47+
def get_registrant(cls, data: dict[str, Any]) -> tuple[str, str]:
48+
registrant = ""
49+
registrant_country = ""
50+
51+
ll = [
52+
"registrant_email",
53+
"registrant_organization",
54+
"registrant_name",
55+
]
56+
for k in ll:
57+
if not registrant and data[k]:
58+
registrant = data[k]
59+
break
60+
61+
mm = [
62+
"registrant_address",
63+
"registrant_phone",
64+
]
65+
for k in mm:
66+
if not registrant_country and data[k]:
67+
registrant_country = data[k]
68+
break
69+
70+
return registrant, registrant_country
71+
72+
@classmethod
73+
def get_registrar(cls, data: dict[str, Any]) -> str:
74+
ll = [
75+
"registrar_email",
76+
"registrar_name",
77+
"registrar_phone",
78+
]
79+
for k in ll:
80+
if data[k]:
81+
return str(data[k])
82+
83+
return ""
84+
85+
@classmethod
86+
def get_emails(cls, data: dict[str, Any]) -> list[str]:
87+
r: list[str] = []
88+
email_fields: list[str] = [
89+
"abuse_email",
90+
"admin_email",
91+
"billing_email",
92+
"registrant_email",
93+
"registrar_email",
94+
"technical_email",
95+
]
96+
for k in email_fields:
97+
if data[k] and "@" in data[k]:
98+
email = str(data[k])
99+
if email not in r:
100+
r.append(email)
101+
102+
return r
103+
104+
@classmethod
105+
def map_data_to_whoisdomain(
106+
cls,
107+
data: dict[str, Any],
108+
*,
109+
with_rdap_whois: bool = False,
110+
) -> dict[str, Any]:
111+
rr: dict[str, Any] = {}
112+
rr["name"] = data["domain_name"]
113+
rr["dnssec"] = data["dnssec"] == "signed"
114+
if data["abuse_email"]:
115+
rr["abuse_contact"] = data["abuse_email"]
116+
if data["admin_email"]:
117+
rr["admin"] = data["admin_email"]
118+
if data["nameservers"]:
119+
rr["name_servers"] = data["nameservers"]
120+
121+
if data["created_date"]:
122+
rr["creation_date"] = data["created_date"]
123+
if data["updated_date"]:
124+
rr["updated_date"] = data["updated_date"]
125+
if data["expires_date"]:
126+
rr["expiration_date"] = data["expires_date"]
127+
128+
rr["statuses"] = []
129+
rr["status"] = ""
130+
if data["status"]:
131+
rr["statuses"] = data["status"]
132+
if len(rr["statuses"]):
133+
rr["status"] = rr["statuses"][0]
134+
135+
rr["emails"] = cls.get_emails(data)
136+
137+
rr["registrant"], rr["registrant_country"] = cls.get_registrant(data)
138+
rr["registrar"] = cls.get_registrar(data)
139+
140+
if with_rdap_whois:
141+
rr["_rdap_"] = data
142+
143+
return rr
45144

46145

47146
def xmain() -> None:
48147
rr = {}
49148

50149
wr = WhoisRdap()
51-
for k, v in whoisdomain.tldDb.tld_regexpr.ZZ.items():
150+
for k, v in whoisdomain.ZZ.items():
52151
server = v.get("_server")
53152
test = v.get("_test")
54153
if not server:
@@ -61,11 +160,77 @@ def xmain() -> None:
61160
dd = wr.do_one_domain(server)
62161
rr[xfld] = dd.data if dd.status else dd.message
63162
if rr[xfld]:
64-
print("Server:", xfld, rr[xfld])
65-
66-
if test:
163+
print("Server:", server, xfld, rr[xfld])
164+
if dd.status:
165+
print(wr.map_data_to_whoisdomain(dd.data, with_raw=True))
166+
if test and test != xfld:
67167
dd = wr.do_one_domain(test)
68168
print("Test:", test, dd.data if dd.status else dd.message)
169+
if dd.status:
170+
print(wr.map_data_to_whoisdomain(dd.data, with_rdap_whois=True))
69171

70172

71173
xmain()
174+
175+
"""
176+
#
177+
domain_name -> name
178+
179+
abuse_contact
180+
181+
admin
182+
owner
183+
reseller
184+
185+
registrant
186+
registrant_country
187+
registrar
188+
189+
status -> statuses[0] if len(statuses) > 0 else ""
190+
statuses []
191+
name_servers []
192+
emails []
193+
194+
creation_date
195+
expiration_date
196+
updated_date
197+
198+
dnssec: bool
199+
200+
{
201+
'name': 'google.com', # actual domain used (www.google.com -> google.com)
202+
'tld': 'com',
203+
'fld': '', # new
204+
'registrar': 'MarkMonitor, Inc.',
205+
'registrant': 'Google LLC',
206+
'registrant_country': 'US',
207+
208+
'creation_date': datetime.datetime(1997, 9, 15, 9, 0),
209+
'expiration_date': datetime.datetime(2028, 9, 13, 9, 0),
210+
'last_updated': datetime.datetime(2019, 9, 9, 17, 39, 4),
211+
212+
'status': 'clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)', # statuses[0] if exists.
213+
'statuses': [
214+
'clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)',
215+
'clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)',
216+
'clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)',
217+
'serverDeleteProhibited (https://www.icann.org/epp#serverDeleteProhibited)',
218+
'serverTransferProhibited (https://www.icann.org/epp#serverTransferProhibited)',
219+
'serverUpdateProhibited (https://www.icann.org/epp#serverUpdateProhibited)'
220+
],
221+
222+
'dnssec': False,
223+
224+
'name_servers': [
225+
'ns1.google.com',
226+
'ns2.google.com',
227+
'ns3.google.com',
228+
'ns4.google.com'
229+
],
230+
231+
'emails': [
232+
'abusecomplaints@markmonitor.com',
233+
'whoisrequest@markmonitor.com'
234+
]
235+
}
236+
"""

0 commit comments

Comments
 (0)