@@ -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
47146def 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
71173xmain ()
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