PyFunceble-dev 4.3.0a9__py3-none-any.whl → 4.3.0a11__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 +0 -1
- PyFunceble/checker/availability/domain.py +0 -1
- PyFunceble/checker/availability/extras/base.py +18 -18
- PyFunceble/checker/availability/extras/etoxic.py +0 -1
- PyFunceble/checker/availability/extras/parked.py +1 -2
- PyFunceble/checker/availability/extras/rules.py +64 -5
- PyFunceble/checker/availability/extras/subject_switch.py +1 -1
- PyFunceble/checker/availability/ip.py +0 -1
- PyFunceble/checker/availability/url.py +0 -1
- PyFunceble/checker/reputation/base.py +0 -1
- PyFunceble/cli/entry_points/pyfunceble/cli.py +19 -0
- PyFunceble/cli/filesystem/printer/base.py +19 -6
- PyFunceble/cli/processes/migrator.py +0 -1
- PyFunceble/cli/processes/workers/base.py +5 -3
- PyFunceble/cli/processes/workers/dir_files_sorter.py +0 -1
- PyFunceble/cli/processes/workers/file_sorter.py +0 -1
- PyFunceble/cli/processes/workers/file_sorter_base.py +0 -1
- PyFunceble/cli/processes/workers/migrator.py +0 -1
- PyFunceble/cli/processes/workers/miner.py +7 -9
- PyFunceble/cli/processes/workers/producer.py +15 -2
- PyFunceble/cli/processes/workers/tester.py +2 -6
- PyFunceble/cli/scripts/iana.py +11 -1
- PyFunceble/cli/scripts/public_suffix.py +14 -1
- PyFunceble/cli/system/launcher.py +10 -1
- PyFunceble/cli/utils/version.py +27 -15
- PyFunceble/config/loader.py +43 -12
- PyFunceble/data/infrastructure/.PyFunceble_production.yaml +14 -0
- PyFunceble/downloader/base.py +13 -3
- PyFunceble/helpers/download.py +147 -20
- PyFunceble/helpers/hash.py +10 -18
- PyFunceble/query/dns/nameserver.py +12 -6
- PyFunceble/query/dns/query_tool.py +3 -1
- PyFunceble/query/http_status_code.py +9 -7
- PyFunceble/query/requests/adapter/base.py +36 -4
- PyFunceble/query/requests/adapter/http.py +2 -3
- PyFunceble/query/requests/adapter/https.py +2 -2
- PyFunceble/query/requests/requester.py +70 -41
- PyFunceble/storage.py +1 -4
- {PyFunceble_dev-4.3.0a9.dist-info → PyFunceble_dev-4.3.0a11.dist-info}/METADATA +143 -150
- {PyFunceble_dev-4.3.0a9.dist-info → PyFunceble_dev-4.3.0a11.dist-info}/RECORD +44 -44
- {PyFunceble_dev-4.3.0a9.dist-info → PyFunceble_dev-4.3.0a11.dist-info}/WHEEL +1 -1
- {PyFunceble_dev-4.3.0a9.dist-info → PyFunceble_dev-4.3.0a11.dist-info}/LICENSE +0 -0
- {PyFunceble_dev-4.3.0a9.dist-info → PyFunceble_dev-4.3.0a11.dist-info}/entry_points.txt +0 -0
- {PyFunceble_dev-4.3.0a9.dist-info → PyFunceble_dev-4.3.0a11.dist-info}/top_level.txt +0 -0
PyFunceble/cli/utils/version.py
CHANGED
@@ -55,6 +55,7 @@ import sys
|
|
55
55
|
from datetime import datetime, timezone
|
56
56
|
|
57
57
|
import colorama
|
58
|
+
import requests
|
58
59
|
from box import Box
|
59
60
|
|
60
61
|
import PyFunceble.cli.storage
|
@@ -72,14 +73,24 @@ def get_upstream_version() -> Box:
|
|
72
73
|
Provides the state of the upstream version.
|
73
74
|
"""
|
74
75
|
|
76
|
+
try:
|
77
|
+
response = DownloadHelper(
|
78
|
+
InternalUrlConverter(
|
79
|
+
PyFunceble.cli.storage.VERSION_DUMP_LINK,
|
80
|
+
).get_converted(),
|
81
|
+
own_proxy_handler=True,
|
82
|
+
proxies=PyFunceble.storage.PROXY,
|
83
|
+
certificate_validation=(
|
84
|
+
PyFunceble.storage.CONFIGURATION.verify_ssl_certificate
|
85
|
+
if PyFunceble.storage.CONFIGURATION
|
86
|
+
else True
|
87
|
+
),
|
88
|
+
).download_text()
|
89
|
+
except requests.exceptions.RequestException:
|
90
|
+
response = "{}"
|
91
|
+
|
75
92
|
return Box(
|
76
|
-
DictHelper().from_yaml(
|
77
|
-
DownloadHelper(
|
78
|
-
InternalUrlConverter(
|
79
|
-
PyFunceble.cli.storage.VERSION_DUMP_LINK
|
80
|
-
).get_converted()
|
81
|
-
).download_text()
|
82
|
-
),
|
93
|
+
DictHelper().from_yaml(response),
|
83
94
|
frozen_box=True,
|
84
95
|
)
|
85
96
|
|
@@ -346,16 +357,17 @@ def print_central_messages(check_force_update: bool = False) -> None:
|
|
346
357
|
|
347
358
|
upstream_version = get_upstream_version()
|
348
359
|
|
349
|
-
if
|
350
|
-
|
360
|
+
if upstream_version:
|
361
|
+
if check_force_update:
|
362
|
+
handle_force_update(upstream_version)
|
351
363
|
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
364
|
+
_ = (
|
365
|
+
not handle_deprecated_version(upstream_version)
|
366
|
+
and not handle_greater_version(upstream_version)
|
367
|
+
and not handle_older_version(upstream_version)
|
368
|
+
)
|
357
369
|
|
358
|
-
|
370
|
+
handle_messages(upstream_version)
|
359
371
|
|
360
372
|
prefix = " - " if len(PyFunceble.cli.storage.EXTRA_MESSAGES) > 1 else ""
|
361
373
|
|
PyFunceble/config/loader.py
CHANGED
@@ -66,6 +66,7 @@ from yaml.error import MarkedYAMLError
|
|
66
66
|
import PyFunceble.cli.storage
|
67
67
|
import PyFunceble.storage
|
68
68
|
from PyFunceble.config.compare import ConfigComparison
|
69
|
+
from PyFunceble.dataset.user_agent import UserAgentDataset
|
69
70
|
from PyFunceble.downloader.iana import IANADownloader
|
70
71
|
from PyFunceble.downloader.public_suffix import PublicSuffixDownloader
|
71
72
|
from PyFunceble.downloader.user_agents import UserAgentsDownloader
|
@@ -438,19 +439,20 @@ class ConfigLoader:
|
|
438
439
|
else:
|
439
440
|
destination = dest
|
440
441
|
|
441
|
-
DownloadHelper(
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
442
|
+
DownloadHelper(
|
443
|
+
src,
|
444
|
+
certificate_validation=(
|
445
|
+
PyFunceble.storage.CONFIGURATION.verify_ssl_certificate
|
446
|
+
if PyFunceble.storage.CONFIGURATION
|
447
|
+
else True
|
448
|
+
),
|
449
|
+
own_proxy_handler=True,
|
450
|
+
proxies=config["proxies"],
|
451
|
+
).download_text(destination=destination)
|
450
452
|
|
451
453
|
try:
|
452
454
|
config = self.dict_helper.from_yaml_file(self.path_to_config)
|
453
|
-
except MarkedYAMLError:
|
455
|
+
except (MarkedYAMLError, FileNotFoundError):
|
454
456
|
self.file_helper.set_path(self.path_to_default_config).copy(
|
455
457
|
self.path_to_config
|
456
458
|
)
|
@@ -474,6 +476,32 @@ class ConfigLoader:
|
|
474
476
|
|
475
477
|
self.dict_helper.set_subject(config).to_yaml_file(self.path_to_config)
|
476
478
|
|
479
|
+
if self.file_helper.set_path(self.path_to_overwrite_config).exists():
|
480
|
+
# Early load of the overwrite configuration to allow usage of defined
|
481
|
+
# proxy settings.
|
482
|
+
overwrite_data = self.dict_helper.from_yaml_file(
|
483
|
+
self.path_to_overwrite_config
|
484
|
+
)
|
485
|
+
|
486
|
+
if isinstance(overwrite_data, dict):
|
487
|
+
config = Merge(overwrite_data).into(config)
|
488
|
+
else: # pragma: no cover ## Just make it visible to end-user.
|
489
|
+
self.file_helper.write("")
|
490
|
+
|
491
|
+
# Now we preset the storage to enforce the usage of the configuration
|
492
|
+
# in any downloads.
|
493
|
+
PyFunceble.storage.CONFIGURATION = Box(
|
494
|
+
config,
|
495
|
+
)
|
496
|
+
|
497
|
+
if not self.is_already_loaded():
|
498
|
+
self.install_missing_infrastructure_files()
|
499
|
+
self.download_dynamic_infrastructure_files()
|
500
|
+
download_remote_config(
|
501
|
+
self.remote_config_location, self.path_to_remote_config
|
502
|
+
)
|
503
|
+
download_remote_config(self.path_to_config)
|
504
|
+
|
477
505
|
if (
|
478
506
|
self.path_to_remote_config
|
479
507
|
and self.file_helper.set_path(self.path_to_remote_config).exists()
|
@@ -484,14 +512,14 @@ class ConfigLoader:
|
|
484
512
|
config = Merge(remote_data).into(config)
|
485
513
|
|
486
514
|
if self.file_helper.set_path(self.path_to_overwrite_config).exists():
|
515
|
+
# Load the overwrite configuration again to ensure that user defined
|
516
|
+
# settings are always applied - last one wins.
|
487
517
|
overwrite_data = self.dict_helper.from_yaml_file(
|
488
518
|
self.path_to_overwrite_config
|
489
519
|
)
|
490
520
|
|
491
521
|
if isinstance(overwrite_data, dict):
|
492
522
|
config = Merge(overwrite_data).into(config)
|
493
|
-
else: # pragma: no cover ## Just make it visible to end-user.
|
494
|
-
self.file_helper.write("")
|
495
523
|
|
496
524
|
return config
|
497
525
|
|
@@ -562,6 +590,9 @@ class ConfigLoader:
|
|
562
590
|
if "proxy" in config and config["proxy"]:
|
563
591
|
PyFunceble.storage.PROXY = Box(config["proxy"])
|
564
592
|
|
593
|
+
# Early load user agents to allow usage of defined user agents.
|
594
|
+
UserAgentDataset().get_latest()
|
595
|
+
|
565
596
|
return self
|
566
597
|
|
567
598
|
def destroy(self, keep_custom: bool = False) -> "ConfigLoader":
|
@@ -377,6 +377,20 @@ cli_testing:
|
|
377
377
|
# CLI Argument: --max-registrar
|
378
378
|
max_registrar: 15
|
379
379
|
|
380
|
+
# Enable/Disable the printing of the datetime of the test.
|
381
|
+
#
|
382
|
+
# CLI Argument: --display-datetime
|
383
|
+
datetime: no
|
384
|
+
|
385
|
+
# The format to use when displaying the datetime of the test.
|
386
|
+
#
|
387
|
+
# WARNING:
|
388
|
+
# This parameter is only taken into consideration when `datetime` is set
|
389
|
+
# to `yes`.
|
390
|
+
#
|
391
|
+
# CLI Argument: --display-datetime-fmt
|
392
|
+
datetime_format: "%Y-%m-%d %H:%M:%S"
|
393
|
+
|
380
394
|
testing_mode:
|
381
395
|
# Provides and select the testing mode.
|
382
396
|
#
|
PyFunceble/downloader/base.py
CHANGED
@@ -107,6 +107,7 @@ class DownloaderBase:
|
|
107
107
|
_config_dir: Optional[str] = None
|
108
108
|
_destination: Optional[str] = None
|
109
109
|
_download_link: Optional[str] = None
|
110
|
+
_download_helper: Optional[DownloadHelper] = None
|
110
111
|
|
111
112
|
dict_helper: Optional[DictHelper] = None
|
112
113
|
|
@@ -130,6 +131,17 @@ class DownloaderBase:
|
|
130
131
|
if self.DEFAULT_FILENAME is not None:
|
131
132
|
self.destination = os.path.join(self.config_dir, self.DEFAULT_FILENAME)
|
132
133
|
|
134
|
+
self._download_helper = DownloadHelper(
|
135
|
+
self.download_link,
|
136
|
+
own_proxy_handler=True,
|
137
|
+
proxies=PyFunceble.storage.PROXY,
|
138
|
+
certificate_validation=(
|
139
|
+
PyFunceble.storage.CONFIGURATION.verify_ssl_certificate
|
140
|
+
if PyFunceble.storage.CONFIGURATION
|
141
|
+
else True
|
142
|
+
),
|
143
|
+
)
|
144
|
+
|
133
145
|
@property
|
134
146
|
def authorized(self) -> bool:
|
135
147
|
"""
|
@@ -343,8 +355,6 @@ class DownloaderBase:
|
|
343
355
|
if not hasattr(self, "download_link") or not self.download_link:
|
344
356
|
raise PyFunceble.downloader.exceptions.NoDownloadLinkGiven()
|
345
357
|
|
346
|
-
if
|
347
|
-
destination=self.destination
|
348
|
-
):
|
358
|
+
if self._download_helper.download_text(destination=self.destination):
|
349
359
|
self.set_current_downtime()
|
350
360
|
self.save_all_downtimes()
|
PyFunceble/helpers/download.py
CHANGED
@@ -65,13 +65,29 @@ class DownloadHelper:
|
|
65
65
|
Simplification of the downloads.
|
66
66
|
|
67
67
|
:param str url:
|
68
|
-
:param int
|
68
|
+
:param int retries:
|
69
69
|
The number of time we have to retry before raising an exception.
|
70
|
+
:param bool certificate_validation:
|
71
|
+
The state of the certificate validation.
|
72
|
+
:param bool own_proxy_handler:
|
73
|
+
Whether we should use our own proxy handler or not.
|
74
|
+
:param dict proxies:
|
75
|
+
The proxy to use.
|
76
|
+
|
77
|
+
When :code:`own_proxy_handler` is set to :code:`True`, the proxies
|
78
|
+
are expected to come from the global configuration.
|
79
|
+
Otherwise, the proxies are expected to be a dictionary as defined
|
80
|
+
by the requests library.
|
70
81
|
"""
|
71
82
|
|
72
83
|
_url: Optional[str] = None
|
73
84
|
_certificate_validation: bool = True
|
74
85
|
_retries: int = 3
|
86
|
+
_proxies: Optional[dict] = None
|
87
|
+
|
88
|
+
_session = None
|
89
|
+
_own_proxy_handler: Optional[bool] = True
|
90
|
+
_proxies: Optional[dict] = None
|
75
91
|
|
76
92
|
def __init__(
|
77
93
|
self,
|
@@ -79,15 +95,42 @@ class DownloadHelper:
|
|
79
95
|
*,
|
80
96
|
certificate_validation: bool = True,
|
81
97
|
retries: int = 3,
|
98
|
+
own_proxy_handler: Optional[bool] = True,
|
99
|
+
proxies: Optional[dict] = None,
|
82
100
|
) -> None:
|
83
|
-
if url:
|
101
|
+
if url is not None:
|
84
102
|
self.url = url
|
85
103
|
|
86
|
-
if
|
87
|
-
self.
|
104
|
+
if proxies is not None:
|
105
|
+
self.proxies = proxies
|
88
106
|
|
89
|
-
|
90
|
-
|
107
|
+
self.retries = retries
|
108
|
+
self.certificate_validation = bool(certificate_validation)
|
109
|
+
self.own_proxy_handler = own_proxy_handler
|
110
|
+
|
111
|
+
@property
|
112
|
+
def session(self) -> requests.Session:
|
113
|
+
"""
|
114
|
+
Provides the current state of the :code:`_session` attribute.
|
115
|
+
"""
|
116
|
+
|
117
|
+
if not self._session:
|
118
|
+
if self.own_proxy_handler:
|
119
|
+
# pylint: disable=import-outside-toplevel
|
120
|
+
from PyFunceble.query.requests.requester import Requester
|
121
|
+
|
122
|
+
self._session = Requester(proxy_pattern=self.proxies)
|
123
|
+
else:
|
124
|
+
self._session = requests.Session()
|
125
|
+
self._session.proxies = self.proxies
|
126
|
+
|
127
|
+
retries = Retry(total=self.retries, backoff_factor=3)
|
128
|
+
adapter = HTTPAdapter(max_retries=retries)
|
129
|
+
|
130
|
+
self._session.mount("http://", adapter)
|
131
|
+
self._session.mount("https://", adapter)
|
132
|
+
|
133
|
+
return self._session
|
91
134
|
|
92
135
|
@property
|
93
136
|
def url(self) -> Optional[str]:
|
@@ -208,7 +251,103 @@ class DownloadHelper:
|
|
208
251
|
|
209
252
|
return self
|
210
253
|
|
211
|
-
|
254
|
+
@property
|
255
|
+
def own_proxy_handler(self) -> Optional[bool]:
|
256
|
+
"""
|
257
|
+
Provides the current state of the :code:`own_proxy_handler` attribute.
|
258
|
+
"""
|
259
|
+
|
260
|
+
return self._own_proxy_handler
|
261
|
+
|
262
|
+
@own_proxy_handler.setter
|
263
|
+
def own_proxy_handler(self, value: bool) -> None:
|
264
|
+
"""
|
265
|
+
Sets the state of the own proxy handler.
|
266
|
+
|
267
|
+
:param value:
|
268
|
+
The value to set.
|
269
|
+
|
270
|
+
:raise TypeError:
|
271
|
+
When :code:`value` is not a :py:class:`bool`.
|
272
|
+
"""
|
273
|
+
|
274
|
+
if not isinstance(value, bool):
|
275
|
+
raise TypeError(f"<value> should be {bool}, {type(value)} given.")
|
276
|
+
|
277
|
+
self._own_proxy_handler = value
|
278
|
+
|
279
|
+
if value:
|
280
|
+
# We force the recreation of the session.
|
281
|
+
self._session = None
|
282
|
+
|
283
|
+
def set_own_proxy_handler(self, value: bool) -> "DownloadHelper":
|
284
|
+
"""
|
285
|
+
Sets the state of the own proxy handler.
|
286
|
+
|
287
|
+
:param value:
|
288
|
+
The value to set.
|
289
|
+
"""
|
290
|
+
|
291
|
+
self.own_proxy_handler = value
|
292
|
+
|
293
|
+
return self
|
294
|
+
|
295
|
+
@property
|
296
|
+
def proxies(self) -> Optional[dict]:
|
297
|
+
"""
|
298
|
+
Provides the current state of the :code:`_proxies` attribute.
|
299
|
+
"""
|
300
|
+
|
301
|
+
return self._proxies
|
302
|
+
|
303
|
+
@proxies.setter
|
304
|
+
def proxies(self, value: Optional[dict]) -> None:
|
305
|
+
"""
|
306
|
+
Sets the proxy to use.
|
307
|
+
|
308
|
+
:param value:
|
309
|
+
The proxy to use.
|
310
|
+
|
311
|
+
When :code:`own_proxy_handler` is set to :code:`True`, the proxies
|
312
|
+
are expected to come from the global configuration.
|
313
|
+
Otherwise, the proxies are expected to be a dictionary as defined
|
314
|
+
by the requests library.
|
315
|
+
|
316
|
+
:raise TypeError:
|
317
|
+
When :code:`value` is not a :py:class:`dict`.
|
318
|
+
"""
|
319
|
+
|
320
|
+
if not isinstance(value, dict):
|
321
|
+
raise TypeError(f"<value> should be {dict}, {type(value)} given.")
|
322
|
+
|
323
|
+
self._proxies = value
|
324
|
+
|
325
|
+
if value:
|
326
|
+
# We force the recreation of the session.
|
327
|
+
self._session = None
|
328
|
+
|
329
|
+
def set_proxies(self, value: Optional[dict]) -> "DownloadHelper":
|
330
|
+
"""
|
331
|
+
Sets the proxy to use.
|
332
|
+
|
333
|
+
:param value:
|
334
|
+
The proxy to use.
|
335
|
+
|
336
|
+
When :code:`own_proxy_handler` is set to :code:`True`, the proxies
|
337
|
+
are expected to come from the global configuration.
|
338
|
+
Otherwise, the proxies are expected to be a dictionary as defined
|
339
|
+
by the requests library.
|
340
|
+
"""
|
341
|
+
|
342
|
+
self.proxies = value
|
343
|
+
|
344
|
+
return self
|
345
|
+
|
346
|
+
def download_text(
|
347
|
+
self,
|
348
|
+
*,
|
349
|
+
destination: Optional[str] = None,
|
350
|
+
) -> str:
|
212
351
|
"""
|
213
352
|
Download the body of the set url.
|
214
353
|
|
@@ -224,15 +363,7 @@ class DownloadHelper:
|
|
224
363
|
:raise UnableToDownload: When could not unable to download the URL.
|
225
364
|
"""
|
226
365
|
|
227
|
-
|
228
|
-
|
229
|
-
retries = Retry(total=self.retries, backoff_factor=3)
|
230
|
-
adapter = HTTPAdapter(max_retries=retries)
|
231
|
-
|
232
|
-
session.mount("http://", adapter)
|
233
|
-
session.mount("https://", adapter)
|
234
|
-
|
235
|
-
req = session.get(self.url, verify=self.certificate_validation)
|
366
|
+
req = self.session.get(self.url, verify=self.certificate_validation)
|
236
367
|
|
237
368
|
if req.status_code == 200:
|
238
369
|
response = req.text
|
@@ -240,12 +371,8 @@ class DownloadHelper:
|
|
240
371
|
if destination and isinstance(destination, str):
|
241
372
|
FileHelper(destination).write(req.text, overwrite=True)
|
242
373
|
|
243
|
-
adapter.close()
|
244
|
-
req.close()
|
245
374
|
return response
|
246
375
|
|
247
|
-
adapter.close()
|
248
|
-
session.close()
|
249
376
|
raise PyFunceble.helpers.exceptions.UnableToDownload(
|
250
377
|
f"{req.url} (retries: {self.retries} | status code: {req.status_code})"
|
251
378
|
)
|
PyFunceble/helpers/hash.py
CHANGED
@@ -50,11 +50,9 @@ License:
|
|
50
50
|
limitations under the License.
|
51
51
|
"""
|
52
52
|
|
53
|
+
import hashlib
|
53
54
|
from typing import Optional, Union
|
54
55
|
|
55
|
-
from cryptography.hazmat.backends import default_backend
|
56
|
-
from cryptography.hazmat.primitives import hashes
|
57
|
-
|
58
56
|
from PyFunceble.helpers.file import FileHelper
|
59
57
|
|
60
58
|
|
@@ -68,7 +66,7 @@ class HashHelper:
|
|
68
66
|
:raise ValueError: When the given algo is not known.
|
69
67
|
"""
|
70
68
|
|
71
|
-
_algo: str = "
|
69
|
+
_algo: str = "sha512_224"
|
72
70
|
|
73
71
|
def __init__(self, algo: Optional[str] = None):
|
74
72
|
if algo is not None:
|
@@ -97,11 +95,12 @@ class HashHelper:
|
|
97
95
|
if not isinstance(value, str):
|
98
96
|
raise TypeError(f"<value> should be {str}, {type(value)} given.")
|
99
97
|
|
100
|
-
value = value.
|
98
|
+
value = value.lower()
|
101
99
|
|
102
|
-
if not
|
100
|
+
if value not in hashlib.algorithms_available:
|
103
101
|
raise ValueError(
|
104
|
-
f"<value> ({value!r}) in an unknown algorithm
|
102
|
+
f"<value> ({value!r}) in an unknown algorithm "
|
103
|
+
f"({hashlib.algorithms_available})."
|
105
104
|
)
|
106
105
|
|
107
106
|
self._algo = value
|
@@ -118,13 +117,6 @@ class HashHelper:
|
|
118
117
|
|
119
118
|
return self
|
120
119
|
|
121
|
-
def __get_hash(self) -> hashes.Hash:
|
122
|
-
"""
|
123
|
-
Provides the Hash to use.
|
124
|
-
"""
|
125
|
-
|
126
|
-
return hashes.Hash(getattr(hashes, self.algo)(), backend=default_backend())
|
127
|
-
|
128
120
|
def hash_file(self, file_path: str) -> str:
|
129
121
|
"""
|
130
122
|
Hashes the content of the given file.
|
@@ -135,7 +127,7 @@ class HashHelper:
|
|
135
127
|
|
136
128
|
block_size = 4096
|
137
129
|
|
138
|
-
digest = self.
|
130
|
+
digest = hashlib.new(self.algo)
|
139
131
|
|
140
132
|
with FileHelper(file_path).open("rb") as file_stream:
|
141
133
|
block = file_stream.read(block_size)
|
@@ -144,7 +136,7 @@ class HashHelper:
|
|
144
136
|
digest.update(block)
|
145
137
|
block = file_stream.read(block_size)
|
146
138
|
|
147
|
-
return digest.
|
139
|
+
return digest.hexdigest()
|
148
140
|
|
149
141
|
def hash_data(self, data: Union[str, bytes]) -> str:
|
150
142
|
"""
|
@@ -163,7 +155,7 @@ class HashHelper:
|
|
163
155
|
if isinstance(data, str):
|
164
156
|
data = data.encode()
|
165
157
|
|
166
|
-
digest = self.
|
158
|
+
digest = hashlib.new(self.algo)
|
167
159
|
digest.update(data)
|
168
160
|
|
169
|
-
return digest.
|
161
|
+
return digest.hexdigest()
|
@@ -50,6 +50,7 @@ License:
|
|
50
50
|
limitations under the License.
|
51
51
|
"""
|
52
52
|
|
53
|
+
import ipaddress
|
53
54
|
from typing import List, Optional, Tuple
|
54
55
|
|
55
56
|
import dns.exception
|
@@ -79,15 +80,19 @@ class Nameservers:
|
|
79
80
|
|
80
81
|
protocol: Optional[str] = None
|
81
82
|
|
82
|
-
domain_syntax_checker: DomainSyntaxChecker =
|
83
|
-
url_syntax_checker: URLSyntaxChecker =
|
84
|
-
url2netloc: Url2Netloc =
|
83
|
+
domain_syntax_checker: Optional[DomainSyntaxChecker] = None
|
84
|
+
url_syntax_checker: Optional[URLSyntaxChecker] = None
|
85
|
+
url2netloc: Optional[Url2Netloc] = None
|
85
86
|
|
86
87
|
def __init__(
|
87
88
|
self, nameserver: Optional[List[str]] = None, protocol: str = "TCP"
|
88
89
|
) -> None:
|
89
90
|
self.protocol = protocol
|
90
91
|
|
92
|
+
self.domain_syntax_checker = DomainSyntaxChecker()
|
93
|
+
self.url_syntax_checker = URLSyntaxChecker()
|
94
|
+
self.url2netloc = Url2Netloc()
|
95
|
+
|
91
96
|
if nameserver is not None:
|
92
97
|
self.set_nameservers(nameserver)
|
93
98
|
|
@@ -141,7 +146,10 @@ class Nameservers:
|
|
141
146
|
|
142
147
|
result = []
|
143
148
|
|
144
|
-
|
149
|
+
try:
|
150
|
+
_ = ipaddress.ip_address(nameserver)
|
151
|
+
result.append(nameserver)
|
152
|
+
except ValueError:
|
145
153
|
try:
|
146
154
|
result.extend(
|
147
155
|
[
|
@@ -161,8 +169,6 @@ class Nameservers:
|
|
161
169
|
)
|
162
170
|
except dns.exception.DNSException:
|
163
171
|
pass
|
164
|
-
else:
|
165
|
-
result.append(nameserver)
|
166
172
|
|
167
173
|
PyFunceble.facility.Logger.debug(
|
168
174
|
"IP from nameserver (%r):\n%r", nameserver, result
|
@@ -96,7 +96,7 @@ class DNSQueryTool:
|
|
96
96
|
x.name: x.value for x in dns.rdatatype.RdataType
|
97
97
|
}
|
98
98
|
|
99
|
-
nameservers: Nameservers =
|
99
|
+
nameservers: Optional[Nameservers] = None
|
100
100
|
_query_record_type: int = dns.rdatatype.RdataType.ANY
|
101
101
|
|
102
102
|
_subject: Optional[str] = None
|
@@ -120,6 +120,8 @@ class DNSQueryTool:
|
|
120
120
|
trust_server: Optional[bool] = None,
|
121
121
|
delay: Optional[bool] = None,
|
122
122
|
) -> None:
|
123
|
+
self.nameservers = Nameservers()
|
124
|
+
|
123
125
|
if nameservers is not None:
|
124
126
|
self.nameservers.set_nameservers(nameservers)
|
125
127
|
else: # pragma: no cover ## I'm not playing with system resolver.
|
@@ -55,9 +55,9 @@ import socket
|
|
55
55
|
from typing import Optional, Union
|
56
56
|
|
57
57
|
import PyFunceble.facility
|
58
|
-
import PyFunceble.factory
|
59
58
|
import PyFunceble.storage
|
60
59
|
from PyFunceble.converter.url2netloc import Url2Netloc
|
60
|
+
from PyFunceble.query.requests.requester import Requester
|
61
61
|
|
62
62
|
|
63
63
|
class HTTPStatusCode:
|
@@ -75,6 +75,7 @@ class HTTPStatusCode:
|
|
75
75
|
_verify_certificate: bool = True
|
76
76
|
_allow_redirects: bool = False
|
77
77
|
_url2netloc: Optional[Url2Netloc] = None
|
78
|
+
requester: Optional[Requester] = None
|
78
79
|
|
79
80
|
def __init__(
|
80
81
|
self,
|
@@ -103,6 +104,7 @@ class HTTPStatusCode:
|
|
103
104
|
self.allow_redirects = self.STD_ALLOW_REDIRECTS
|
104
105
|
|
105
106
|
self._url2netloc = Url2Netloc()
|
107
|
+
self.requester = Requester(config=PyFunceble.storage.CONFIGURATION)
|
106
108
|
|
107
109
|
def ensure_subject_is_given(func): # pylint: disable=no-self-argument
|
108
110
|
"""
|
@@ -334,7 +336,7 @@ class HTTPStatusCode:
|
|
334
336
|
""" # pylint: disable=line-too-long
|
335
337
|
|
336
338
|
try:
|
337
|
-
req =
|
339
|
+
req = self.requester.get(
|
338
340
|
self.subject,
|
339
341
|
timeout=self.timeout,
|
340
342
|
verify=self.verify_certificate,
|
@@ -363,12 +365,12 @@ class HTTPStatusCode:
|
|
363
365
|
|
364
366
|
return req.status_code
|
365
367
|
except (
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
368
|
+
self.requester.exceptions.RequestException,
|
369
|
+
self.requester.exceptions.InvalidSchema,
|
370
|
+
self.requester.exceptions.InvalidURL,
|
371
|
+
self.requester.exceptions.MissingSchema,
|
370
372
|
socket.timeout,
|
371
|
-
|
373
|
+
self.requester.urllib3_exceptions.InvalidHeader,
|
372
374
|
):
|
373
375
|
pass
|
374
376
|
|