Skip to content

Commit ee6bf57

Browse files
committed
add __lookup__ rdap/whois
1 parent 6e61371 commit ee6bf57

3 files changed

Lines changed: 5 additions & 298 deletions

File tree

whoisdomain/__init__.py

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ def q2(
208208
if dd.status:
209209
with_rdap_whois = True
210210
d: dict[str, Any] = wr.map_data_to_whoisdomain(dd.data, with_rdap_whois=with_rdap_whois)
211+
d['__lookup__'] = 'rdap'
211212

212213
rr = Domain(pc=pc, dc=dc)
213214
rr.from_whodap_dict(d)
@@ -293,20 +294,5 @@ def query(
293294
# Add get function to support return result in dictionary form
294295
get = _result2dict(query)
295296

296-
# CLAUDE: logging changes
297-
# Calling logging.basicConfig(level="DEBUG") inside library code mutates the application's root logger
298-
# and is widely considered bad library citizenship.
299-
# If the caller's app uses logging, you've just overridden their config.
300-
# Use a per-package logger and let the caller configure the level:
301-
# logging.getLogger("whoisdomain").setLevel("DEBUG"),
302-
# or document a setup_logging(verbose=) helper that callers can opt into.
303-
304-
# CLAUDE: memoryleak:
305-
# Three calls — gc.collect(0); gc.collect(1); gc.collect(2) — once on entry and once on exit.
306-
# gc.collect(2) already does generations 0 and 1, so the other two are redundant.
307-
# More importantly, manual GC in library code imposes work on callers who don't need it
308-
# (Python's GC is generational and usually correct without help).
309-
# The del spam right above isn't doing anything either
310-
# — locals are about to go out of scope.
297+
# CLAUDE: memoryleak:
311298
# If you're chasing a real leak, profile it with tracemalloc;
312-
# otherwise this is cargo-culted overhead.

whoisdomain/context/parameterContext.py

Lines changed: 0 additions & 279 deletions
Original file line numberDiff line numberDiff line change
@@ -95,285 +95,6 @@ def from_json(cls, s: str) -> "ParameterContext":
9595
return cls(**json.loads(s))
9696

9797

98-
ParamsStringJson: str = """
99-
{
100-
"ignore_returncode": {
101-
"type": "bool",
102-
"default": false,
103-
"optional": true,
104-
"help": "if the whois command fails with code 1 still process the data returned as normal."
105-
},
106-
"force": {
107-
"type": "bool",
108-
"default": false,
109-
"optional": true,
110-
"help": "Don't use cache."
111-
},
112-
"verbose": {
113-
"type": "bool",
114-
"default": false,
115-
"optional": true,
116-
"help": "print relevant information on steps taken to standard error"
117-
},
118-
"with_cleanup_results": {
119-
"type": "bool",
120-
"default": false,
121-
"optional": true,
122-
"help": "cleanup lines starting with % and REDACTED FOR PRIVACY"
123-
},
124-
"internationalized": {
125-
"type": "bool",
126-
"default": false,
127-
"optional": true,
128-
"help": "if true convert with internationalizedDomainNameToPunyCode()."
129-
},
130-
"include_raw_whois_text": {
131-
"type": "bool",
132-
"default": false,
133-
"optional": true,
134-
"help": "if reqested the full response is also returned."
135-
},
136-
"return_raw_text_for_unsupported_tld": {
137-
"type": "bool",
138-
"default": false,
139-
"optional": true,
140-
"help": ""
141-
},
142-
"parse_partial_response": {
143-
"type": "bool",
144-
"default": false,
145-
"optional": true,
146-
"help": "try to parse partial response when cmd timed out (stdbuf should be in PATH for best results)"
147-
},
148-
"simplistic": {
149-
"type": "bool",
150-
"default": false,
151-
"optional": true,
152-
"help": "when simplistic is true we return null for most exceptions and dont pass info why we have no data."
153-
},
154-
"withRedacted": {
155-
"type": "bool",
156-
"default": false,
157-
"optional": true,
158-
"help": "show redacted output default no redacted data is shown"
159-
},
160-
"cmd": {
161-
"type": "str",
162-
"optional": true,
163-
"default": "whois",
164-
"help": "specify the path to the cli whois you want to use."
165-
},
166-
"cache_file": {
167-
"type": "str",
168-
"optional": true,
169-
"default": null,
170-
"help": "Use file to store cache not only memory."
171-
},
172-
"server": {
173-
"type": "str",
174-
"optional": true,
175-
"default": null,
176-
"help": "use this whois server for making this query: Linux/Mac: 'whois -h <server> <domain>' Windows: 'whois.exe <domain> <server>'"
177-
},
178-
"cache_age": {
179-
"type": "int",
180-
"optional": true,
181-
"default": 172800,
182-
"help": "Cache expiration time for given domain in seconds 60*60*48 (48 hours)"
183-
},
184-
"slow_down": {
185-
"type": "int",
186-
"optional": true,
187-
"default": 0,
188-
"help": "Time [s] it will wait after you query WHOIS database."
189-
},
190-
"timeout": {
191-
"type": "float",
192-
"optional": true,
193-
"default": 30.0,
194-
"help": "timeout in seconds for the whois command to return a result."
195-
},
196-
"tryInstallMissingWhoisOnWindows": {
197-
"type": "bool",
198-
"default": false,
199-
"optional": true,
200-
"help": "allow auto install of sysinternals whois on windows if no whois found"
201-
},
202-
"shortResponseLen": {
203-
"type": "int",
204-
"optional": true,
205-
"default": 5,
206-
"help": "The number of lines we consider a short response."
207-
},
208-
"withPublicSuffix": {
209-
"type": "bool",
210-
"default": false,
211-
"optional": true,
212-
"help": "if lib 'tld' is installed add tld info based on get_tld(); fake the tld if needed"
213-
},
214-
"extractServers": {
215-
"type": "bool",
216-
"default": false,
217-
"optional": true,
218-
"help": "try to extract the whois servers from the whois output (uses --verbose)"
219-
},
220-
"stripHttpStatus": {
221-
"type": "bool",
222-
"default": false,
223-
"optional": true,
224-
"help": "strip https://icann.org/epp# from status response"
225-
},
226-
"noIgnoreWww": {
227-
"type": "bool",
228-
"default": false,
229-
"optional": true,
230-
"help": "if set to true we skip the strip www action"
231-
},
232-
"rdapOnly": {
233-
"type": "bool",
234-
"default": false,
235-
"optional": true,
236-
"help": "if set to true we only consult rdap"
237-
},
238-
"whoisOnly": {
239-
"type": "bool",
240-
"default": false,
241-
"optional": true,
242-
"help": "if set to true we only consult whois"
243-
}
244-
}
245-
"""
246-
247-
248-
class ParameterContext2:
249-
kt: dict[str, Any]
250-
value: dict[str, Any]
251-
params: dict[str, Any]
252-
253-
def __init__(
254-
self,
255-
**kwargs: Any,
256-
) -> None:
257-
self.kt: dict[str, Any] = {
258-
"int": int,
259-
"float": float,
260-
"str": str,
261-
"bool": bool,
262-
}
263-
self.value: dict[str, Any] = {}
264-
self.params: dict[str, Any] = json.loads(ParamsStringJson)
265-
266-
mandatory: list[str] = self._load_defaults()
267-
self._add_args(mandatory, **kwargs)
268-
self._validate_all_mandatory_known(mandatory)
269-
270-
def _load_defaults(self) -> list[str]:
271-
mandatory: list[str] = []
272-
for i, k in self.params.items():
273-
if "default" in k:
274-
self.value[i] = k["default"]
275-
else:
276-
mandatory.append(i) # params with no default become mandatory
277-
self.value[i] = None
278-
return mandatory
279-
280-
def _add_args(
281-
self,
282-
mandatory: list[str],
283-
**kwargs: Any,
284-
) -> None:
285-
for name, value in kwargs.items():
286-
if name not in self.params:
287-
msg = f"ignore parameter '{name}':you specified a parameter we do not currently know"
288-
raise TypeError(msg)
289-
290-
t = self.params[name].get("type")
291-
if t is None:
292-
msg = f"unknown type: {t} for {name}"
293-
raise TypeError(msg)
294-
295-
# we have a type and we still exist
296-
if value is not None:
297-
if not isinstance(value, self.kt[t]):
298-
msg = f"unknown type: {t} for {name}, {value}"
299-
raise TypeError(msg)
300-
301-
self.value[name] = value
302-
if name in mandatory:
303-
del mandatory[mandatory.index(name)]
304-
305-
@classmethod
306-
def _validate_all_mandatory_known(
307-
cls,
308-
mandatory: list[str],
309-
) -> None:
310-
if len(mandatory) != 0:
311-
msg = f"missing mandatory parametrs: {sorted(mandatory)}"
312-
raise ValueError(msg)
313-
314-
def __getattr__(
315-
self,
316-
name: str,
317-
) -> Any:
318-
if name in {"params", "value", "kt"}:
319-
raise AttributeError(name) # should never happen as they are resolved before __getattr__
320-
# getattr(self, name)
321-
322-
return self.value.get(name)
323-
324-
def __setattr__(
325-
self,
326-
name: str,
327-
value: Any,
328-
) -> None:
329-
if name in {"params", "value", "kt"}:
330-
super().__setattr__(name, value)
331-
return
332-
333-
self.set(name, value)
334-
335-
# -------------------------------------
336-
def get(
337-
self,
338-
name: str,
339-
) -> Any:
340-
return self.value.get(name)
341-
342-
def set(self, name: str, value: Any) -> None:
343-
if name not in self.params:
344-
msg = f"ignore parameter '{name}':you specified a parameter we do not currently know"
345-
raise TypeError(msg)
346-
347-
if name in self.params:
348-
t = self.params[name].get("type")
349-
if t is None:
350-
msg = f"unknown type: {t} for {name}"
351-
raise TypeError(msg)
352-
353-
if value is not None:
354-
if not isinstance(value, self.kt[t]):
355-
msg = f"unknown type: {t} for {name}, {value}"
356-
raise TypeError(msg)
357-
self.value[name] = value
358-
# leave the default
359-
360-
def toJson(
361-
self,
362-
) -> str:
363-
rr: dict[str, Any] = {}
364-
for k in self.params:
365-
rr[k] = self.get(k)
366-
return json.dumps(rr)
367-
368-
def fromJson(
369-
self,
370-
jstring: str,
371-
) -> None:
372-
zz = json.loads(jstring)
373-
for k, v in zz.items():
374-
self.set(k, v)
375-
376-
37798
if __name__ == "__main__":
37899
pc = ParameterContext()
379100
print(asdict(pc))

whoisdomain/domain.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
log = logging.getLogger(__name__)
1313

14-
1514
class Domain:
1615
def __init__(
1716
self,
@@ -37,12 +36,13 @@ def __init__(
3736

3837
self.dnssec: bool = False
3938

40-
self.last_updated: datetime.datetime | None = None
39+
# self.last_updated: datetime.datetime | None = None
4140
self.updated_date: datetime.datetime | None = None
4241
self.expiration_date: datetime.datetime | None = None
4342
self.creation_date: datetime.datetime | None = None
4443

4544
self._rdap_: dict[str, Any] = {}
45+
self.__lookup__ = "whois"
4646

4747
@classmethod
4848
def _cleanupArray(
@@ -170,7 +170,7 @@ def _parseData(
170170
self.creation_date = str_to_date(dc.data["creation_date"][0], tld=self.tld)
171171
self.expiration_date = str_to_date(dc.data["expiration_date"][0], tld=self.tld)
172172
self.updated_date = str_to_date(dc.data["updated_date"][0], tld=self.tld)
173-
self.last_updated = self.updated_date # keep old name for one release
173+
# self.last_updated = self.updated_date # keep old name for one release
174174

175175
self.dnssec = bool(dc.data["DNSSEC"])
176176
self._doStatus(pc, dc)

0 commit comments

Comments
 (0)