PyFunceble-dev 4.3.0a21__py3-none-any.whl → 4.3.0a24__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- PyFunceble/checker/availability/base.py +7 -6
- PyFunceble/checker/availability/domain.py +18 -0
- PyFunceble/checker/availability/extras/base.py +4 -4
- PyFunceble/checker/availability/extras/dns.py +1 -1
- PyFunceble/checker/availability/extras/etoxic.py +3 -3
- PyFunceble/checker/availability/extras/parked.py +22 -20
- PyFunceble/checker/availability/extras/rules.py +5 -13
- PyFunceble/checker/availability/extras/subject_switch.py +4 -5
- PyFunceble/checker/availability/ip.py +18 -0
- PyFunceble/checker/availability/params.py +1 -1
- PyFunceble/checker/availability/status.py +9 -4
- PyFunceble/checker/availability/url.py +6 -0
- PyFunceble/checker/base.py +4 -0
- PyFunceble/checker/reputation/base.py +5 -2
- PyFunceble/checker/reputation/domain.py +11 -0
- PyFunceble/checker/reputation/ip.py +11 -0
- PyFunceble/checker/reputation/status.py +1 -1
- PyFunceble/checker/reputation/url.py +12 -1
- PyFunceble/checker/syntax/base.py +4 -1
- PyFunceble/checker/syntax/domain.py +4 -0
- PyFunceble/checker/syntax/ip.py +4 -0
- PyFunceble/checker/syntax/ipv4.py +10 -13
- PyFunceble/checker/syntax/ipv6.py +9 -11
- PyFunceble/checker/syntax/params.py +1 -1
- PyFunceble/checker/syntax/second_lvl_domain.py +3 -4
- PyFunceble/checker/syntax/subdomain.py +3 -4
- PyFunceble/checker/syntax/url.py +9 -6
- PyFunceble/checker/utils/whois.py +7 -11
- PyFunceble/cli/continuous_integration/base.py +14 -14
- PyFunceble/cli/credential_loader.py +4 -6
- PyFunceble/cli/entry_points/clean.py +0 -1
- PyFunceble/cli/entry_points/production.py +1 -1
- PyFunceble/cli/entry_points/pyfunceble/cli.py +11 -2
- PyFunceble/cli/execution_time.py +2 -2
- PyFunceble/cli/filesystem/cleanup.py +1 -3
- PyFunceble/cli/filesystem/dir_base.py +5 -1
- PyFunceble/cli/filesystem/dir_structure/backup.py +1 -2
- PyFunceble/cli/filesystem/dir_structure/base.py +0 -1
- PyFunceble/cli/filesystem/dir_structure/restore.py +5 -7
- PyFunceble/cli/filesystem/status_file.py +2 -3
- PyFunceble/cli/migrators/alembic.py +2 -4
- PyFunceble/cli/migrators/csv_file/inactive_source_delete.py +0 -1
- PyFunceble/cli/migrators/csv_file/whois_registrar_add.py +0 -1
- PyFunceble/cli/migrators/db_base.py +2 -2
- PyFunceble/cli/migrators/file_cleanup/base.py +3 -3
- PyFunceble/cli/migrators/file_cleanup/hashes_file.py +2 -3
- PyFunceble/cli/migrators/file_cleanup/mining_file.py +2 -3
- PyFunceble/cli/migrators/file_cleanup/production_config_file.py +2 -3
- PyFunceble/cli/migrators/mariadb/base.py +2 -4
- PyFunceble/cli/migrators/mariadb/file_and_status.py +1 -1
- PyFunceble/cli/migrators/mariadb/whois_record_idna_subject.py +0 -2
- PyFunceble/cli/processes/migrator.py +0 -1
- PyFunceble/cli/processes/workers/base.py +0 -1
- PyFunceble/cli/processes/workers/chancy_producer.py +1 -2
- PyFunceble/cli/processes/workers/dir_files_sorter.py +6 -14
- PyFunceble/cli/processes/workers/file_sorter.py +2 -9
- PyFunceble/cli/processes/workers/migrator.py +0 -1
- PyFunceble/cli/processes/workers/producer.py +2 -4
- PyFunceble/cli/processes/workers/tester.py +2 -3
- PyFunceble/cli/scripts/iana.py +14 -10
- PyFunceble/cli/scripts/production.py +2 -2
- PyFunceble/cli/scripts/public_suffix.py +2 -2
- PyFunceble/cli/system/integrator.py +1 -1
- PyFunceble/cli/system/launcher.py +14 -11
- PyFunceble/cli/utils/stdout.py +1 -1
- PyFunceble/cli/utils/testing.py +6 -16
- PyFunceble/config/compare.py +10 -9
- PyFunceble/config/loader.py +7 -4
- PyFunceble/converter/input_line2subject.py +2 -2
- PyFunceble/converter/internal_url.py +1 -1
- PyFunceble/converter/rpz_input_line2subject.py +2 -4
- PyFunceble/converter/subject2complements.py +4 -1
- PyFunceble/converter/url2netloc.py +3 -3
- PyFunceble/converter/wildcard2subject.py +3 -3
- PyFunceble/helpers/command.py +1 -1
- PyFunceble/helpers/dict.py +4 -4
- PyFunceble/helpers/file.py +2 -2
- PyFunceble/helpers/list.py +10 -7
- PyFunceble/helpers/merge.py +2 -2
- PyFunceble/helpers/regex.py +9 -11
- PyFunceble/query/dns/nameserver.py +9 -19
- PyFunceble/query/dns/query_tool.py +64 -205
- PyFunceble/query/dns/resolver.py +64 -51
- PyFunceble/query/netinfo/address.py +4 -6
- PyFunceble/query/netinfo/base.py +1 -1
- PyFunceble/query/netinfo/hostbyaddr.py +5 -8
- PyFunceble/query/requests/adapter/base.py +3 -3
- PyFunceble/query/requests/adapter/http.py +0 -1
- PyFunceble/query/requests/requester.py +6 -6
- PyFunceble/query/whois/converter/expiration_date.py +19 -8
- PyFunceble/query/whois/converter/month2unified.py +4 -6
- PyFunceble/query/whois/converter/registrar.py +18 -5
- PyFunceble/query/whois/query_tool.py +15 -18
- PyFunceble/storage.py +1 -1
- {pyfunceble_dev-4.3.0a21.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/METADATA +109 -108
- {pyfunceble_dev-4.3.0a21.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/RECORD +100 -100
- {pyfunceble_dev-4.3.0a21.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/WHEEL +1 -1
- {pyfunceble_dev-4.3.0a21.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/entry_points.txt +0 -0
- {pyfunceble_dev-4.3.0a21.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/licenses/LICENSE +0 -0
- {pyfunceble_dev-4.3.0a21.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/top_level.txt +0 -0
PyFunceble/query/dns/resolver.py
CHANGED
@@ -11,7 +11,7 @@ The tool to check the availability or syntax of domain, IP or URL.
|
|
11
11
|
██║ ██║ ██║ ╚██████╔╝██║ ╚████║╚██████╗███████╗██████╔╝███████╗███████╗
|
12
12
|
╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═════╝╚══════╝╚═════╝ ╚══════╝╚══════╝
|
13
13
|
|
14
|
-
Provides a way to
|
14
|
+
Provides a way to provide the nameserver to use.
|
15
15
|
|
16
16
|
Author:
|
17
17
|
Nissar Chababy, @funilrys, contactTATAfunilrysTODTODcom
|
@@ -50,7 +50,6 @@ License:
|
|
50
50
|
limitations under the License.
|
51
51
|
"""
|
52
52
|
|
53
|
-
import functools
|
54
53
|
from typing import List, Optional, Union
|
55
54
|
|
56
55
|
import dns.resolver
|
@@ -70,93 +69,123 @@ class Resolver:
|
|
70
69
|
|
71
70
|
STD_TIMEOUT: float = 5.0
|
72
71
|
|
73
|
-
|
72
|
+
_timeout: float = 3.0
|
74
73
|
|
75
|
-
|
76
|
-
|
74
|
+
_nameservers: Nameservers = None
|
75
|
+
_internal_resolver: Optional[dns.resolver.Resolver] = None
|
77
76
|
|
78
77
|
def __init__(
|
79
78
|
self, nameservers: Optional[List[str]] = None, timeout: Optional[float] = None
|
80
79
|
) -> None:
|
80
|
+
self._nameservers = Nameservers()
|
81
|
+
|
81
82
|
if nameservers is not None:
|
82
|
-
self.
|
83
|
+
self.nameservers = nameservers
|
83
84
|
else:
|
84
85
|
self.nameservers.guess_and_set_nameservers()
|
85
86
|
|
86
87
|
if timeout is not None:
|
87
|
-
self.
|
88
|
+
self.timeout = timeout
|
88
89
|
else:
|
89
90
|
self.guess_and_set_timeout()
|
90
91
|
|
91
|
-
|
92
|
+
@property
|
93
|
+
def resolver(self) -> dns.resolver.Resolver:
|
92
94
|
"""
|
93
|
-
|
95
|
+
Provides the resolver to work with.
|
94
96
|
"""
|
95
97
|
|
96
|
-
|
97
|
-
|
98
|
-
|
98
|
+
if not self._internal_resolver:
|
99
|
+
if self.get_raw_nameservers():
|
100
|
+
self._internal_resolver = dns.resolver.Resolver(configure=False)
|
101
|
+
else: # pragma: no cover ## I don't want to play with the default resolver.
|
102
|
+
self._internal_resolver = dns.resolver.Resolver()
|
103
|
+
|
104
|
+
self._internal_resolver.lifetime = self.timeout + 2.0
|
105
|
+
self._internal_resolver.timeout = self.timeout
|
106
|
+
self._internal_resolver.nameservers = self.get_raw_nameservers()
|
107
|
+
self._internal_resolver.nameserver_ports = self.get_raw_nameserver_ports()
|
99
108
|
|
100
|
-
|
101
|
-
self.internal_resolver.timeout = self.timeout
|
102
|
-
self.internal_resolver.nameservers = self.nameservers.get_nameservers()
|
103
|
-
self.internal_resolver.nameserver_ports = (
|
104
|
-
self.nameservers.get_nameserver_ports()
|
105
|
-
)
|
109
|
+
return self._internal_resolver
|
106
110
|
|
107
|
-
|
111
|
+
@property
|
112
|
+
def nameservers(self) -> Nameservers:
|
113
|
+
"""
|
114
|
+
Provides the nameservers to use.
|
115
|
+
"""
|
116
|
+
|
117
|
+
return self._nameservers
|
118
|
+
|
119
|
+
@nameservers.setter
|
120
|
+
def nameservers(self, value: List[str]) -> None:
|
121
|
+
"""
|
122
|
+
Sets the nameservers to use.
|
123
|
+
"""
|
108
124
|
|
109
|
-
|
125
|
+
self.nameservers.set_nameservers(value)
|
126
|
+
self._internal_resolver = None # Invalidate
|
110
127
|
|
111
128
|
def set_nameservers(self, value: List[str]) -> "Resolver":
|
112
129
|
"""
|
113
130
|
Sets the given nameserver.
|
114
131
|
"""
|
115
132
|
|
116
|
-
self.nameservers
|
133
|
+
self.nameservers = value
|
117
134
|
|
118
|
-
|
135
|
+
return self
|
136
|
+
|
137
|
+
@property
|
138
|
+
def timeout(self) -> float:
|
119
139
|
"""
|
120
|
-
|
140
|
+
Provides the timeout to use.
|
141
|
+
"""
|
142
|
+
|
143
|
+
return self._timeout
|
144
|
+
|
145
|
+
@timeout.setter
|
146
|
+
def timeout(self, value: float) -> None:
|
147
|
+
"""
|
148
|
+
Sets the timeout to use.
|
121
149
|
"""
|
122
150
|
|
123
151
|
if not isinstance(value, (float, int)):
|
124
152
|
raise TypeError(f"<value> should be {float}, {type(value)} given.")
|
125
153
|
|
126
|
-
self.
|
154
|
+
self._timeout = float(value)
|
155
|
+
self._internal_resolver = None # Invalidate
|
156
|
+
|
157
|
+
def set_timeout(self, value: Union[float, int]) -> "Resolver":
|
158
|
+
"""
|
159
|
+
Sets the timeout of a query.
|
160
|
+
"""
|
161
|
+
|
162
|
+
self.timeout = value
|
127
163
|
|
128
164
|
return self
|
129
165
|
|
130
|
-
def
|
166
|
+
def get_raw_nameservers(self) -> Optional[List[str]]:
|
131
167
|
"""
|
132
168
|
Provides the currently set list of nameserver.
|
133
169
|
"""
|
134
170
|
|
135
171
|
return self.nameservers.get_nameservers()
|
136
172
|
|
137
|
-
def
|
173
|
+
def get_raw_nameserver_ports(self) -> Optional[dict]:
|
138
174
|
"""
|
139
175
|
Provides the currently set list of nameserver ports.
|
140
176
|
"""
|
141
177
|
|
142
178
|
return self.nameservers.get_nameserver_ports()
|
143
179
|
|
144
|
-
def get_timeout(self) -> Optional[float]:
|
145
|
-
"""
|
146
|
-
Provides the currently set query timeout.
|
147
|
-
"""
|
148
|
-
|
149
|
-
return self.timeout
|
150
|
-
|
151
180
|
def guess_and_set_timeout(self) -> "Resolver":
|
152
181
|
"""
|
153
182
|
Tries to guess the the timeout from the configuration.
|
154
183
|
"""
|
155
184
|
|
156
185
|
if PyFunceble.facility.ConfigLoader.is_already_loaded():
|
157
|
-
self.
|
186
|
+
self.timeout = PyFunceble.storage.CONFIGURATION.lookup.timeout
|
158
187
|
else:
|
159
|
-
self.
|
188
|
+
self.timeout = self.STD_TIMEOUT
|
160
189
|
|
161
190
|
return self
|
162
191
|
|
@@ -176,19 +205,3 @@ class Resolver:
|
|
176
205
|
getattr(self, method)()
|
177
206
|
|
178
207
|
return self
|
179
|
-
|
180
|
-
@configure_resolver
|
181
|
-
def get_resolver(self) -> dns.resolver.Resolver:
|
182
|
-
"""
|
183
|
-
Provides the resolver to work with.
|
184
|
-
"""
|
185
|
-
|
186
|
-
if self.internal_resolver:
|
187
|
-
return self.internal_resolver
|
188
|
-
|
189
|
-
if self.nameservers.get_nameservers():
|
190
|
-
self.internal_resolver = dns.resolver.Resolver(configure=False)
|
191
|
-
else: # pragma: no cover ## I don't want to play with the default resolver.
|
192
|
-
self.internal_resolver = dns.resolver.Resolver()
|
193
|
-
|
194
|
-
return self.internal_resolver
|
@@ -51,7 +51,7 @@ License:
|
|
51
51
|
"""
|
52
52
|
|
53
53
|
import socket
|
54
|
-
from typing import List
|
54
|
+
from typing import List
|
55
55
|
|
56
56
|
from PyFunceble.query.netinfo.base import NetInfoBase
|
57
57
|
|
@@ -62,12 +62,12 @@ class AddressInfo(NetInfoBase):
|
|
62
62
|
"""
|
63
63
|
|
64
64
|
@NetInfoBase.ensure_subject_is_given
|
65
|
-
def get_info(self) ->
|
65
|
+
def get_info(self) -> List[str]:
|
66
66
|
"""
|
67
67
|
Fetch and provides the information of the given hosts.
|
68
68
|
|
69
69
|
:return:
|
70
|
-
A list of
|
70
|
+
A list of IP related to the given host.
|
71
71
|
"""
|
72
72
|
|
73
73
|
try:
|
@@ -76,6 +76,4 @@ class AddressInfo(NetInfoBase):
|
|
76
76
|
for x in socket.getaddrinfo(self.subject, 80, proto=socket.IPPROTO_TCP)
|
77
77
|
]
|
78
78
|
except (socket.gaierror, socket.herror, UnicodeError, OSError):
|
79
|
-
|
80
|
-
|
81
|
-
return []
|
79
|
+
return []
|
PyFunceble/query/netinfo/base.py
CHANGED
@@ -51,7 +51,6 @@ License:
|
|
51
51
|
"""
|
52
52
|
|
53
53
|
import socket
|
54
|
-
from typing import Optional
|
55
54
|
|
56
55
|
from PyFunceble.query.netinfo.base import NetInfoBase
|
57
56
|
|
@@ -62,13 +61,13 @@ class HostByAddrInfo(NetInfoBase):
|
|
62
61
|
"""
|
63
62
|
|
64
63
|
@NetInfoBase.ensure_subject_is_given
|
65
|
-
def get_info(self) ->
|
64
|
+
def get_info(self) -> dict:
|
66
65
|
"""
|
67
66
|
Fetch and provides the information of the given hosts.
|
68
67
|
|
69
68
|
:return:
|
70
|
-
A
|
71
|
-
was found.
|
69
|
+
A dictionary with the following format or an empty :py:class:`dict`
|
70
|
+
if nothing was found.
|
72
71
|
|
73
72
|
::
|
74
73
|
|
@@ -83,7 +82,5 @@ class HostByAddrInfo(NetInfoBase):
|
|
83
82
|
request = socket.gethostbyaddr(self.subject)
|
84
83
|
|
85
84
|
return {"hostname": request[0], "aliases": request[1], "ips": request[2]}
|
86
|
-
except (socket.gaierror, socket.herror):
|
87
|
-
|
88
|
-
|
89
|
-
return dict() # pylint: disable=use-dict-literal
|
85
|
+
except (socket.gaierror, socket.herror, UnicodeError, OSError):
|
86
|
+
return {}
|
@@ -63,7 +63,7 @@ from PyFunceble.query.dns.query_tool import DNSQueryTool
|
|
63
63
|
|
64
64
|
class RequestAdapterBase(requests.adapters.HTTPAdapter):
|
65
65
|
"""
|
66
|
-
Extends the built-in HTTP
|
66
|
+
Extends the built-in HTTP adapter and acts as a base for all our own
|
67
67
|
adapter.
|
68
68
|
"""
|
69
69
|
|
@@ -286,7 +286,7 @@ class RequestAdapterBase(requests.adapters.HTTPAdapter):
|
|
286
286
|
|
287
287
|
def resolve(self, hostname: str) -> Optional[str]:
|
288
288
|
"""
|
289
|
-
Resolves with the
|
289
|
+
Resolves with the preferred method.
|
290
290
|
"""
|
291
291
|
|
292
292
|
if hostname:
|
@@ -301,7 +301,7 @@ class RequestAdapterBase(requests.adapters.HTTPAdapter):
|
|
301
301
|
use our own ssl context - when given.
|
302
302
|
"""
|
303
303
|
|
304
|
-
|
304
|
+
pool_kwargs.pop("ssl_context", None)
|
305
305
|
|
306
306
|
return super().init_poolmanager(
|
307
307
|
connections, maxsize, block, ssl_context=self.ssl_context, **pool_kwargs
|
@@ -377,7 +377,7 @@ class Requester:
|
|
377
377
|
"""
|
378
378
|
|
379
379
|
if not isinstance(value, bool):
|
380
|
-
raise TypeError(f"<value>
|
380
|
+
raise TypeError(f"<value> should be {bool}, {type(value)} given.")
|
381
381
|
|
382
382
|
self._verify_certificate = value
|
383
383
|
|
@@ -429,11 +429,11 @@ class Requester:
|
|
429
429
|
When the given :code:`value` is not a :py:class`int` nor
|
430
430
|
:py:class:`float`.
|
431
431
|
:raise ValueError:
|
432
|
-
|
432
|
+
Went the given :code:`value` is less than `1`.
|
433
433
|
"""
|
434
434
|
|
435
435
|
if not isinstance(value, (int, float)):
|
436
|
-
raise TypeError(f"<value>
|
436
|
+
raise TypeError(f"<value> should be {int} or {float}, {type(value)} given.")
|
437
437
|
|
438
438
|
if value < 0:
|
439
439
|
raise ValueError("<value> should not be less than 0.")
|
@@ -489,7 +489,7 @@ class Requester:
|
|
489
489
|
"""
|
490
490
|
|
491
491
|
if not isinstance(value, dict):
|
492
|
-
raise TypeError(f"<value>
|
492
|
+
raise TypeError(f"<value> should be {dict}, {type(value)} given.")
|
493
493
|
|
494
494
|
self._proxy_pattern = value
|
495
495
|
|
@@ -544,7 +544,7 @@ class Requester:
|
|
544
544
|
|
545
545
|
def get_timeout(self) -> float:
|
546
546
|
"""
|
547
|
-
Provides the currently set
|
547
|
+
Provides the currently set timeout.
|
548
548
|
"""
|
549
549
|
|
550
550
|
return self.timeout
|
@@ -595,7 +595,7 @@ class Requester:
|
|
595
595
|
@request_factory("OPTIONS")
|
596
596
|
def options(self, *args, **kwargs) -> requests.Response:
|
597
597
|
"""
|
598
|
-
Sends
|
598
|
+
Sends an OPTIONS request and get its response.
|
599
599
|
"""
|
600
600
|
|
601
601
|
@request_factory("HEAD")
|
@@ -50,7 +50,7 @@ License:
|
|
50
50
|
limitations under the License.
|
51
51
|
"""
|
52
52
|
|
53
|
-
from typing import List, Optional
|
53
|
+
from typing import List, Optional
|
54
54
|
|
55
55
|
from PyFunceble.helpers.regex import RegexHelper
|
56
56
|
from PyFunceble.query.whois.converter.base import ConverterBase
|
@@ -226,7 +226,7 @@ class ExpirationDateExtractor(ConverterBase):
|
|
226
226
|
},
|
227
227
|
]
|
228
228
|
"""
|
229
|
-
Our parsing map. Indeed, we
|
229
|
+
Our parsing map. Indeed, we have a list of regex, but no way to know
|
230
230
|
how to parse them. Especially when the order (month, day, year) are
|
231
231
|
different from a format to another.
|
232
232
|
|
@@ -234,6 +234,19 @@ class ExpirationDateExtractor(ConverterBase):
|
|
234
234
|
created.
|
235
235
|
"""
|
236
236
|
|
237
|
+
_regex_helper: Optional[RegexHelper] = None
|
238
|
+
|
239
|
+
@property
|
240
|
+
def regex_helper(self) -> "RegexHelper":
|
241
|
+
"""
|
242
|
+
Provides the regex helper to use.
|
243
|
+
"""
|
244
|
+
|
245
|
+
if self._regex_helper is None:
|
246
|
+
self._regex_helper = RegexHelper()
|
247
|
+
|
248
|
+
return self._regex_helper
|
249
|
+
|
237
250
|
@ConverterBase.data_to_convert.setter
|
238
251
|
def data_to_convert(self, value: str) -> None:
|
239
252
|
"""
|
@@ -263,7 +276,7 @@ class ExpirationDateExtractor(ConverterBase):
|
|
263
276
|
"""
|
264
277
|
|
265
278
|
for regex in self.PATTERNS:
|
266
|
-
expiration_date_line =
|
279
|
+
expiration_date_line = self.regex_helper.set_regex(r"(?i)" + regex).match(
|
267
280
|
self.data_to_convert, return_match=True, rematch=True, group=0
|
268
281
|
)
|
269
282
|
|
@@ -273,15 +286,13 @@ class ExpirationDateExtractor(ConverterBase):
|
|
273
286
|
return expiration_date_line
|
274
287
|
return None
|
275
288
|
|
276
|
-
def __get_actual_expiration_date(
|
277
|
-
self, extracted: str
|
278
|
-
) -> Optional[Tuple[str, str, str]]:
|
289
|
+
def __get_actual_expiration_date(self, extracted: str) -> Optional[str]:
|
279
290
|
"""
|
280
291
|
Tries to extract the actual expiration date.
|
281
292
|
"""
|
282
293
|
|
283
294
|
for index, date_regex in self.MARKER2DATE_REGEX.items():
|
284
|
-
matched =
|
295
|
+
matched = self.regex_helper.set_regex(date_regex).match(
|
285
296
|
extracted, return_match=True, rematch=True
|
286
297
|
)
|
287
298
|
date_parts = tuple()
|
@@ -318,7 +329,7 @@ class ExpirationDateExtractor(ConverterBase):
|
|
318
329
|
if expiration_date_line:
|
319
330
|
expiration_date = expiration_date_line[0].strip()
|
320
331
|
|
321
|
-
if
|
332
|
+
if self.regex_helper.set_regex(self.REGEX_DIGITS).match(
|
322
333
|
expiration_date, return_match=False
|
323
334
|
):
|
324
335
|
return self.__get_actual_expiration_date(expiration_date)
|
@@ -75,10 +75,12 @@ class Month2Unified(ConverterBase):
|
|
75
75
|
"dec": [str(12), "dec", "december", "dec."],
|
76
76
|
}
|
77
77
|
|
78
|
+
REVERSE_MAP: Dict[str, str] = {z: x for x, y in MAP.items() for z in y}
|
79
|
+
|
78
80
|
@ConverterBase.data_to_convert.setter
|
79
81
|
def data_to_convert(self, value: Any) -> None:
|
80
82
|
"""
|
81
|
-
|
83
|
+
Overrides the default behavior.
|
82
84
|
|
83
85
|
:raise TypeError:
|
84
86
|
When the given data to convert is not :py:class:`str`
|
@@ -99,8 +101,4 @@ class Month2Unified(ConverterBase):
|
|
99
101
|
If no month is found, the given data is given as response.
|
100
102
|
"""
|
101
103
|
|
102
|
-
|
103
|
-
if self.data_to_convert.lower() in possibilities:
|
104
|
-
return to_return
|
105
|
-
|
106
|
-
return self.data_to_convert
|
104
|
+
return self.REVERSE_MAP.get(self.data_to_convert.lower(), self.data_to_convert)
|
@@ -11,7 +11,7 @@ The tool to check the availability or syntax of domain, IP or URL.
|
|
11
11
|
██║ ██║ ██║ ╚██████╔╝██║ ╚████║╚██████╗███████╗██████╔╝███████╗███████╗
|
12
12
|
╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═════╝╚══════╝╚═════╝ ╚══════╝╚══════╝
|
13
13
|
|
14
|
-
Provides our registrar
|
14
|
+
Provides our registrar extractor.
|
15
15
|
|
16
16
|
Author:
|
17
17
|
Nissar Chababy, @funilrys, contactTATAfunilrysTODTODcom
|
@@ -56,9 +56,9 @@ from PyFunceble.helpers.regex import RegexHelper
|
|
56
56
|
from PyFunceble.query.whois.converter.base import ConverterBase
|
57
57
|
|
58
58
|
|
59
|
-
class
|
59
|
+
class RegistrarExtractor(ConverterBase):
|
60
60
|
"""
|
61
|
-
Provides an interface for the
|
61
|
+
Provides an interface for the extraction of the registrar.
|
62
62
|
"""
|
63
63
|
|
64
64
|
PATTERNS: List[str] = [
|
@@ -73,6 +73,19 @@ class RegistarExtractor(ConverterBase):
|
|
73
73
|
r"sponsoring\s+registrar\s+organization(\s+|):(.*)",
|
74
74
|
]
|
75
75
|
|
76
|
+
_regex_helper: Optional[RegexHelper] = None
|
77
|
+
|
78
|
+
@property
|
79
|
+
def regex_helper(self) -> "RegexHelper":
|
80
|
+
"""
|
81
|
+
Provides the regex helper to use.
|
82
|
+
"""
|
83
|
+
|
84
|
+
if self._regex_helper is None:
|
85
|
+
self._regex_helper = RegexHelper()
|
86
|
+
|
87
|
+
return self._regex_helper
|
88
|
+
|
76
89
|
@ConverterBase.data_to_convert.setter
|
77
90
|
def data_to_convert(self, value: Any) -> None:
|
78
91
|
"""
|
@@ -94,7 +107,7 @@ class RegistarExtractor(ConverterBase):
|
|
94
107
|
raise ValueError("<value> should not be empty.")
|
95
108
|
|
96
109
|
# pylint: disable=no-member
|
97
|
-
super(
|
110
|
+
super(RegistrarExtractor, self.__class__).data_to_convert.fset(self, value)
|
98
111
|
|
99
112
|
def __get_line(self) -> Optional[str]:
|
100
113
|
"""
|
@@ -102,7 +115,7 @@ class RegistarExtractor(ConverterBase):
|
|
102
115
|
"""
|
103
116
|
|
104
117
|
for regex in self.PATTERNS:
|
105
|
-
registrar_line =
|
118
|
+
registrar_line = self.regex_helper.set_regex(r"(?i)" + regex).match(
|
106
119
|
self.data_to_convert, return_match=True, rematch=True, group=0
|
107
120
|
)
|
108
121
|
|
@@ -11,7 +11,7 @@ The tool to check the availability or syntax of domain, IP or URL.
|
|
11
11
|
██║ ██║ ██║ ╚██████╔╝██║ ╚████║╚██████╗███████╗██████╔╝███████╗███████╗
|
12
12
|
╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═════╝╚══════╝╚═════╝ ╚══════╝╚══════╝
|
13
13
|
|
14
|
-
Provides our interface for
|
14
|
+
Provides our interface for querying the WHOIS Record of a given subject.
|
15
15
|
|
16
16
|
Author:
|
17
17
|
Nissar Chababy, @funilrys, contactTATAfunilrysTODTODcom
|
@@ -57,7 +57,7 @@ from typing import Optional, Union
|
|
57
57
|
from PyFunceble.dataset.iana import IanaDataset
|
58
58
|
from PyFunceble.query.record.whois import WhoisQueryToolRecord
|
59
59
|
from PyFunceble.query.whois.converter.expiration_date import ExpirationDateExtractor
|
60
|
-
from PyFunceble.query.whois.converter.registrar import
|
60
|
+
from PyFunceble.query.whois.converter.registrar import RegistrarExtractor
|
61
61
|
|
62
62
|
# pylint: disable=protected-access
|
63
63
|
|
@@ -71,7 +71,7 @@ class WhoisQueryTool:
|
|
71
71
|
STD_PORT: int = 43
|
72
72
|
|
73
73
|
expiration_date_extractor: Optional[ExpirationDateExtractor] = None
|
74
|
-
registrar_extractor: Optional[
|
74
|
+
registrar_extractor: Optional[RegistrarExtractor] = None
|
75
75
|
iana_dataset: Optional[IanaDataset] = None
|
76
76
|
|
77
77
|
_subject: Optional[str] = None
|
@@ -90,7 +90,7 @@ class WhoisQueryTool:
|
|
90
90
|
server: Optional[str] = None,
|
91
91
|
query_timeout: Optional[float] = None,
|
92
92
|
) -> None:
|
93
|
-
self.registrar_extractor =
|
93
|
+
self.registrar_extractor = RegistrarExtractor()
|
94
94
|
self.expiration_date_extractor = ExpirationDateExtractor()
|
95
95
|
self.iana_dataset = IanaDataset()
|
96
96
|
|
@@ -297,7 +297,7 @@ class WhoisQueryTool:
|
|
297
297
|
raise TypeError(f"<value> should be {int} or {float}, {type(value)} given.")
|
298
298
|
|
299
299
|
if value < 0:
|
300
|
-
raise ValueError(f"<value> ({value!r}) should be less than 0.")
|
300
|
+
raise ValueError(f"<value> ({value!r}) should not be less than 0.")
|
301
301
|
|
302
302
|
self._query_timeout = float(value)
|
303
303
|
|
@@ -365,7 +365,7 @@ class WhoisQueryTool:
|
|
365
365
|
else:
|
366
366
|
extension = self.subject
|
367
367
|
|
368
|
-
extension = extension
|
368
|
+
extension = extension.rsplit(".", 1)[-1]
|
369
369
|
|
370
370
|
return self.iana_dataset.get_whois_server(extension)
|
371
371
|
|
@@ -419,24 +419,21 @@ class WhoisQueryTool:
|
|
419
419
|
if not data:
|
420
420
|
break
|
421
421
|
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
# decided to use `replace` in order to automatically replace
|
429
|
-
# all non utf-8 encoded characters.
|
430
|
-
self.lookup_record.record = self._record = response.decode(
|
431
|
-
"utf-8", "replace"
|
432
|
-
)
|
422
|
+
# Note: Because we don't want to deal with other issue, we
|
423
|
+
# decided to use `replace` in order to automatically replace
|
424
|
+
# all non utf-8 encoded characters.
|
425
|
+
self.lookup_record.record = self._record = response.decode(
|
426
|
+
"utf-8", "replace"
|
427
|
+
)
|
433
428
|
except socket.error:
|
434
429
|
pass
|
430
|
+
finally:
|
431
|
+
req.close()
|
435
432
|
|
436
433
|
if self.lookup_record.record is None or not self.lookup_record.record:
|
437
434
|
self.lookup_record.record = self._record = ""
|
438
435
|
self.lookup_record.expiration_date = self._expiration_date = ""
|
439
|
-
self.lookup_record.registrar = self.
|
436
|
+
self.lookup_record.registrar = self._registrar = ""
|
440
437
|
else:
|
441
438
|
self.lookup_record.expiration_date = self.expiration_date
|
442
439
|
self.lookup_record.registrar = self.registrar
|
PyFunceble/storage.py
CHANGED
@@ -60,7 +60,7 @@ from dotenv import load_dotenv
|
|
60
60
|
from PyFunceble.storage_facility import get_config_directory
|
61
61
|
|
62
62
|
PROJECT_NAME: str = "PyFunceble"
|
63
|
-
PROJECT_VERSION: str = "4.3.
|
63
|
+
PROJECT_VERSION: str = "4.3.0a24.dev (Blue Duckling: Tulip)"
|
64
64
|
|
65
65
|
DISTRIBUTED_CONFIGURATION_FILENAME: str = ".PyFunceble_production.yaml"
|
66
66
|
|