PyFunceble-dev 4.3.0a23__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.
Files changed (99) hide show
  1. PyFunceble/checker/availability/base.py +5 -2
  2. PyFunceble/checker/availability/domain.py +18 -0
  3. PyFunceble/checker/availability/extras/base.py +4 -4
  4. PyFunceble/checker/availability/extras/dns.py +1 -1
  5. PyFunceble/checker/availability/extras/etoxic.py +3 -3
  6. PyFunceble/checker/availability/extras/parked.py +22 -20
  7. PyFunceble/checker/availability/extras/rules.py +5 -13
  8. PyFunceble/checker/availability/extras/subject_switch.py +4 -5
  9. PyFunceble/checker/availability/ip.py +18 -0
  10. PyFunceble/checker/availability/params.py +1 -1
  11. PyFunceble/checker/availability/status.py +9 -4
  12. PyFunceble/checker/availability/url.py +6 -0
  13. PyFunceble/checker/base.py +4 -0
  14. PyFunceble/checker/reputation/base.py +5 -2
  15. PyFunceble/checker/reputation/domain.py +11 -0
  16. PyFunceble/checker/reputation/ip.py +11 -0
  17. PyFunceble/checker/reputation/status.py +1 -1
  18. PyFunceble/checker/reputation/url.py +12 -1
  19. PyFunceble/checker/syntax/base.py +4 -1
  20. PyFunceble/checker/syntax/domain.py +4 -0
  21. PyFunceble/checker/syntax/ip.py +4 -0
  22. PyFunceble/checker/syntax/ipv4.py +10 -13
  23. PyFunceble/checker/syntax/ipv6.py +9 -11
  24. PyFunceble/checker/syntax/params.py +1 -1
  25. PyFunceble/checker/syntax/second_lvl_domain.py +3 -4
  26. PyFunceble/checker/syntax/subdomain.py +3 -4
  27. PyFunceble/checker/syntax/url.py +9 -6
  28. PyFunceble/checker/utils/whois.py +7 -11
  29. PyFunceble/cli/continuous_integration/base.py +14 -14
  30. PyFunceble/cli/credential_loader.py +4 -6
  31. PyFunceble/cli/entry_points/clean.py +0 -1
  32. PyFunceble/cli/entry_points/production.py +1 -1
  33. PyFunceble/cli/entry_points/pyfunceble/cli.py +1 -1
  34. PyFunceble/cli/execution_time.py +2 -2
  35. PyFunceble/cli/filesystem/cleanup.py +1 -3
  36. PyFunceble/cli/filesystem/dir_base.py +5 -1
  37. PyFunceble/cli/filesystem/dir_structure/backup.py +1 -2
  38. PyFunceble/cli/filesystem/dir_structure/base.py +0 -1
  39. PyFunceble/cli/filesystem/dir_structure/restore.py +5 -7
  40. PyFunceble/cli/filesystem/status_file.py +2 -3
  41. PyFunceble/cli/migrators/alembic.py +2 -4
  42. PyFunceble/cli/migrators/csv_file/inactive_source_delete.py +0 -1
  43. PyFunceble/cli/migrators/csv_file/whois_registrar_add.py +0 -1
  44. PyFunceble/cli/migrators/db_base.py +2 -2
  45. PyFunceble/cli/migrators/file_cleanup/base.py +3 -3
  46. PyFunceble/cli/migrators/file_cleanup/hashes_file.py +2 -3
  47. PyFunceble/cli/migrators/file_cleanup/mining_file.py +2 -3
  48. PyFunceble/cli/migrators/file_cleanup/production_config_file.py +2 -3
  49. PyFunceble/cli/migrators/mariadb/base.py +2 -4
  50. PyFunceble/cli/migrators/mariadb/file_and_status.py +1 -1
  51. PyFunceble/cli/migrators/mariadb/whois_record_idna_subject.py +0 -2
  52. PyFunceble/cli/processes/workers/base.py +0 -1
  53. PyFunceble/cli/processes/workers/chancy_producer.py +1 -2
  54. PyFunceble/cli/processes/workers/dir_files_sorter.py +6 -14
  55. PyFunceble/cli/processes/workers/file_sorter.py +2 -9
  56. PyFunceble/cli/processes/workers/migrator.py +0 -1
  57. PyFunceble/cli/processes/workers/producer.py +2 -4
  58. PyFunceble/cli/processes/workers/tester.py +2 -3
  59. PyFunceble/cli/scripts/iana.py +14 -10
  60. PyFunceble/cli/scripts/production.py +2 -2
  61. PyFunceble/cli/scripts/public_suffix.py +2 -2
  62. PyFunceble/cli/system/integrator.py +1 -1
  63. PyFunceble/cli/system/launcher.py +9 -10
  64. PyFunceble/cli/utils/stdout.py +1 -1
  65. PyFunceble/cli/utils/testing.py +6 -16
  66. PyFunceble/config/compare.py +10 -9
  67. PyFunceble/config/loader.py +7 -4
  68. PyFunceble/converter/input_line2subject.py +2 -2
  69. PyFunceble/converter/internal_url.py +1 -1
  70. PyFunceble/converter/rpz_input_line2subject.py +2 -4
  71. PyFunceble/converter/subject2complements.py +4 -1
  72. PyFunceble/converter/url2netloc.py +3 -3
  73. PyFunceble/converter/wildcard2subject.py +3 -3
  74. PyFunceble/helpers/command.py +1 -1
  75. PyFunceble/helpers/dict.py +4 -4
  76. PyFunceble/helpers/file.py +2 -2
  77. PyFunceble/helpers/list.py +10 -7
  78. PyFunceble/helpers/merge.py +2 -2
  79. PyFunceble/helpers/regex.py +9 -11
  80. PyFunceble/query/dns/nameserver.py +9 -19
  81. PyFunceble/query/dns/query_tool.py +64 -205
  82. PyFunceble/query/dns/resolver.py +64 -51
  83. PyFunceble/query/netinfo/address.py +4 -6
  84. PyFunceble/query/netinfo/base.py +1 -1
  85. PyFunceble/query/netinfo/hostbyaddr.py +5 -8
  86. PyFunceble/query/requests/adapter/base.py +3 -3
  87. PyFunceble/query/requests/adapter/http.py +0 -1
  88. PyFunceble/query/requests/requester.py +6 -6
  89. PyFunceble/query/whois/converter/expiration_date.py +19 -8
  90. PyFunceble/query/whois/converter/month2unified.py +4 -6
  91. PyFunceble/query/whois/converter/registrar.py +18 -5
  92. PyFunceble/query/whois/query_tool.py +15 -18
  93. PyFunceble/storage.py +1 -1
  94. {pyfunceble_dev-4.3.0a23.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/METADATA +107 -106
  95. {pyfunceble_dev-4.3.0a23.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/RECORD +99 -99
  96. {pyfunceble_dev-4.3.0a23.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/WHEEL +0 -0
  97. {pyfunceble_dev-4.3.0a23.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/entry_points.txt +0 -0
  98. {pyfunceble_dev-4.3.0a23.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/licenses/LICENSE +0 -0
  99. {pyfunceble_dev-4.3.0a23.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/top_level.txt +0 -0
@@ -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 provides the nameserver to use.
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
- timeout: float = 3.0
72
+ _timeout: float = 3.0
74
73
 
75
- nameservers: Nameservers = Nameservers()
76
- internal_resolver: Optional[dns.resolver.Resolver] = None
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.set_nameservers(nameservers)
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.set_timeout(timeout)
88
+ self.timeout = timeout
88
89
  else:
89
90
  self.guess_and_set_timeout()
90
91
 
91
- def configure_resolver(func): # pylint: disable=no-self-argument
92
+ @property
93
+ def resolver(self) -> dns.resolver.Resolver:
92
94
  """
93
- Configures the resolvers after calling the decorated method.
95
+ Provides the resolver to work with.
94
96
  """
95
97
 
96
- @functools.wraps(func)
97
- def wrapper(self, *args, **kwargs):
98
- result = func(self, *args, **kwargs) # pylint: disable=not-callable
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
- self.internal_resolver.lifetime = self.timeout + 2.0
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
- return result
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
- return wrapper
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.set_nameservers(value)
133
+ self.nameservers = value
117
134
 
118
- def set_timeout(self, value: Union[float, int]) -> "Resolver":
135
+ return self
136
+
137
+ @property
138
+ def timeout(self) -> float:
119
139
  """
120
- Sets the timeout of a query.
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.timeout = float(value)
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 get_nameservers(self) -> Optional[List[str]]:
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 get_nameserver_ports(self) -> Optional[dict]:
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.set_timeout(float(PyFunceble.storage.CONFIGURATION.lookup.timeout))
186
+ self.timeout = PyFunceble.storage.CONFIGURATION.lookup.timeout
158
187
  else:
159
- self.set_timeout(self.STD_TIMEOUT)
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, Optional
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) -> Optional[List[str]]:
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 of IP related to the given host.
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
- pass
80
-
81
- return []
79
+ return []
@@ -133,4 +133,4 @@ class NetInfoBase:
133
133
  Provides the wanted network information.
134
134
  """
135
135
 
136
- raise NotImplementedError()
136
+ raise NotImplementedError("Subclasses must implement.")
@@ -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) -> Optional[dict]:
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 dictionnary with the following format or :py:class:`None` if nothing
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
- pass
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 adapater and acts as a base for all our own
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 prefered method.
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
- _ = pool_kwargs.pop("ssl_context", None)
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
@@ -124,7 +124,6 @@ class RequestHTTPAdapter(RequestAdapterBase):
124
124
 
125
125
  return self.fake_response()
126
126
 
127
- # raise Exception(hostname_ip, parsed_url, parsed_url.hostname, kwargs)
128
127
  response = super().send(request, **kwargs)
129
128
 
130
129
  if hostname_ip:
@@ -377,7 +377,7 @@ class Requester:
377
377
  """
378
378
 
379
379
  if not isinstance(value, bool):
380
- raise TypeError(f"<value> shoule be {bool}, {type(value)} given.")
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
- Whent the given :code:`value` is less than `1`.
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> shoule be {int} or {float}, {type(value)} given.")
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> shoule be {dict}, {type(value)} given.")
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 timetout.
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 am OPTIONS request and get its response.
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, Tuple
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 hava a list of regex, but no way to know
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 = RegexHelper(r"(?i)" + regex).match(
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 = RegexHelper(date_regex).match(
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 RegexHelper(self.REGEX_DIGITS).match(
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
- Overrites the default behavior.
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
- for to_return, possibilities in self.MAP.items():
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 extrator.
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 RegistarExtractor(ConverterBase):
59
+ class RegistrarExtractor(ConverterBase):
60
60
  """
61
- Provides an interface for the extration of the registrar.
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(RegistarExtractor, self.__class__).data_to_convert.fset(self, value)
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 = RegexHelper(r"(?i)" + regex).match(
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 quering the WHOIS Record of a given subject.
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 RegistarExtractor
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[RegistarExtractor] = None
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 = RegistarExtractor()
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[extension.rfind(".") + 1 :]
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
- req.close()
423
-
424
- try:
425
- self.lookup_record.record = self._record = response.decode()
426
- except UnicodeDecodeError:
427
- # Note: Because we don't want to deal with other issue, we
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._record = ""
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.0a23.dev (Blue Duckling: Tulip)"
63
+ PROJECT_VERSION: str = "4.3.0a24.dev (Blue Duckling: Tulip)"
64
64
 
65
65
  DISTRIBUTED_CONFIGURATION_FILENAME: str = ".PyFunceble_production.yaml"
66
66