PyFunceble-dev 4.3.0a12__py3-none-any.whl → 4.3.0a14__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.
@@ -64,6 +64,7 @@ import PyFunceble.storage
64
64
  from PyFunceble.checker.availability.extras.base import ExtraRuleHandlerBase
65
65
  from PyFunceble.checker.availability.extras.dns import DNSRulesHandler
66
66
  from PyFunceble.checker.availability.extras.etoxic import EToxicHandler
67
+ from PyFunceble.checker.availability.extras.external import ExternalRulesHandler
67
68
  from PyFunceble.checker.availability.extras.rules import ExtraRulesHandler
68
69
  from PyFunceble.checker.availability.extras.subject_switch import (
69
70
  SubjectSwitchRulesHandler,
@@ -174,6 +175,7 @@ class AvailabilityCheckerBase(CheckerBase):
174
175
  DNSRulesHandler(),
175
176
  EToxicHandler(),
176
177
  ExtraRulesHandler(),
178
+ ExternalRulesHandler(rulesets=PyFunceble.storage.SPECIAL_RULES),
177
179
  ]
178
180
  self.db_session = db_session
179
181
 
@@ -328,7 +328,7 @@ class ExtraRuleHandlerBase:
328
328
  def handle_regex_match_mode(_req: requests.Response):
329
329
  matches2search_result = {}
330
330
 
331
- for header, loc_matches in matches:
331
+ for header, loc_matches in matches.items():
332
332
  matches2search_result[header] = False
333
333
 
334
334
  if header not in _req.headers:
@@ -0,0 +1,341 @@
1
+ """
2
+ The tool to check the availability or syntax of domain, IP or URL.
3
+
4
+ ::
5
+
6
+
7
+ ██████╗ ██╗ ██╗███████╗██╗ ██╗███╗ ██╗ ██████╗███████╗██████╗ ██╗ ███████╗
8
+ ██╔══██╗╚██╗ ██╔╝██╔════╝██║ ██║████╗ ██║██╔════╝██╔════╝██╔══██╗██║ ██╔════╝
9
+ ██████╔╝ ╚████╔╝ █████╗ ██║ ██║██╔██╗ ██║██║ █████╗ ██████╔╝██║ █████╗
10
+ ██╔═══╝ ╚██╔╝ ██╔══╝ ██║ ██║██║╚██╗██║██║ ██╔══╝ ██╔══██╗██║ ██╔══╝
11
+ ██║ ██║ ██║ ╚██████╔╝██║ ╚████║╚██████╗███████╗██████╔╝███████╗███████╗
12
+ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═════╝╚══════╝╚═════╝ ╚══════╝╚══════╝
13
+
14
+ Provides the extra rules handler based on some DNS records.
15
+
16
+ Author:
17
+ Nissar Chababy, @funilrys, contactTATAfunilrysTODTODcom
18
+
19
+ Special thanks:
20
+ https://pyfunceble.github.io/#/special-thanks
21
+
22
+ Contributors:
23
+ https://pyfunceble.github.io/#/contributors
24
+
25
+ Project link:
26
+ https://github.com/funilrys/PyFunceble
27
+
28
+ Project documentation:
29
+ https://docs.pyfunceble.com
30
+
31
+ Project homepage:
32
+ https://pyfunceble.github.io/
33
+
34
+ License:
35
+ ::
36
+
37
+
38
+ Copyright 2017, 2018, 2019, 2020, 2022, 2023, 2024 Nissar Chababy
39
+
40
+ Licensed under the Apache License, Version 2.0 (the "License");
41
+ you may not use this file except in compliance with the License.
42
+ You may obtain a copy of the License at
43
+
44
+ https://www.apache.org/licenses/LICENSE-2.0
45
+
46
+ Unless required by applicable law or agreed to in writing, software
47
+ distributed under the License is distributed on an "AS IS" BASIS,
48
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
49
+ See the License for the specific language governing permissions and
50
+ limitations under the License.
51
+ """
52
+
53
+ # pylint: disable=line-too-long
54
+
55
+ from typing import Optional
56
+
57
+ from PyFunceble.checker.availability.extras.base import ExtraRuleHandlerBase
58
+ from PyFunceble.checker.availability.status import AvailabilityCheckerStatus
59
+
60
+
61
+ class ExternalRulesHandler(ExtraRuleHandlerBase):
62
+ """
63
+ Provides the external rules handler that is used to handle the external
64
+ provided rules.
65
+
66
+ Through this handler, end-user can provide their own rules to handle
67
+ the availability status of a subject.
68
+
69
+ :param status:
70
+ The previously gathered status.
71
+ :type status:
72
+ :class:`~PyFunceble.checker.availability.status.AvailabilityCheckerStatus`
73
+ """
74
+
75
+ rulesets: list = []
76
+ """
77
+ The rulesets to process.
78
+
79
+ If you want to switch from the status code, you should provide a dict
80
+ with the following structure:
81
+
82
+ {
83
+ "subject_pattern": ".*", // The pattern the subject should match.
84
+ "validation_type": "status_code", // Type of validation (status_code, headers, body, etc.)
85
+ "state_transition": "up", // "up" -> ACTIVE, "down" -> INACTIVE
86
+ "required_status_code": [404], // Status code to match.
87
+ }
88
+
89
+ If you want to switch from the headers, you should provide a dict
90
+
91
+ {
92
+ "subject_pattern": ".*", // The pattern the subject should match.
93
+ "validation_type": "headers", // Type of validation (status_code, headers, body, etc.)
94
+ "state_transition": "up", // "up" -> ACTIVE, "down" -> INACTIVE
95
+ "required_headers_patterns": { // Required, the headers to match.
96
+ "header_name": ["possible", "values"]
97
+ },
98
+ }
99
+
100
+ If you want to switch from the body, you should provide a dict
101
+
102
+ {
103
+ "subject_pattern": ".*", // The pattern the subject should match.
104
+ "validation_type": "body", // Type of validation (status_code, headers, body, etc.)
105
+ "state_transition": "up", // "up" -> ACTIVE, "down" -> INACTIVE
106
+ "required_body_patterns": ["regex1", "regex2"] // Required, the body patterns to match.
107
+ }
108
+
109
+ If you want to switch from a combination of headers and body, you should provide a dict
110
+
111
+ {
112
+ "subject_pattern": ".*", // The pattern the subject should match.
113
+ "validation_type": "headers+body", // Type of validation (status_code, headers, body, etc.)
114
+ "state_transition": "up", // "up" -> ACTIVE, "down" -> INACTIVE
115
+ "required_headers_patterns": { // Required, the headers to match.
116
+ "header_name": ["possible", "values"]
117
+ },
118
+ "required_body_patterns": ["regex1", "regex2"] // Required, the body patterns to match.
119
+ }
120
+
121
+ If you want to switch from a combination of all, you should provide a dict
122
+
123
+ {
124
+ "subject_pattern": ".*", // The pattern the subject should match.
125
+ "validation_type": "all", // Type of validation (status_code, headers, body, etc.)
126
+ "state_transition": "up", // "up" -> ACTIVE, "down" -> INACTIVE
127
+ "required_status_code": [404], // Optional, Status code to match.
128
+ "required_headers_patterns": { // Optional, the headers to match.
129
+ "header_name": ["possible", "values"]
130
+ },
131
+ "required_body_patterns": ["regex1", "regex2"] // Optional, the body patterns to match.
132
+ }
133
+
134
+ """
135
+
136
+ def __init__(
137
+ self,
138
+ status: Optional[AvailabilityCheckerStatus] = None,
139
+ *,
140
+ rulesets: list = None
141
+ ) -> None:
142
+ if rulesets is not None:
143
+ self.rulesets = rulesets
144
+
145
+ super().__init__(status)
146
+
147
+ def switch_from_status_code_rule(self, rule: dict) -> "ExternalRulesHandler":
148
+ """
149
+ Switch from the status code rule.
150
+
151
+ :param rule:
152
+ The rule to switch from.
153
+ :type rule: dict
154
+ """
155
+
156
+ required_keys = ["validation_type", "required_status_code"]
157
+
158
+ if any(x not in rule for x in required_keys):
159
+ return self
160
+
161
+ if rule["validation_type"] != "status_code":
162
+ return self
163
+
164
+ if all(
165
+ self.status.http_status_code != int(x) for x in rule["required_status_code"]
166
+ ):
167
+ return self
168
+
169
+ if rule["state_transition"] == "up":
170
+ return self.switch_to_up()
171
+
172
+ if rule["state_transition"] == "down":
173
+ return self.switch_to_down()
174
+
175
+ return self
176
+
177
+ def switch_from_headers_rule(self, rule: dict) -> "ExternalRulesHandler":
178
+ """
179
+ Switch from the headers rule.
180
+
181
+ :param rule:
182
+ The rule to switch from.
183
+ :type rule: dict
184
+ """
185
+
186
+ required_keys = ["validation_type", "required_headers_patterns"]
187
+
188
+ if any(x not in rule for x in required_keys):
189
+ return self
190
+
191
+ if rule["validation_type"] != "headers":
192
+ return self
193
+
194
+ if rule["state_transition"] == "up":
195
+ switch_method = self.switch_to_up
196
+
197
+ if rule["state_transition"] == "down":
198
+ switch_method = self.switch_to_down
199
+
200
+ if "required_headers_patterns" in rule and rule["required_headers_patterns"]:
201
+ # pylint: disable=possibly-used-before-assignment
202
+ self.do_on_header_match(
203
+ self.req_url,
204
+ rule["required_headers_patterns"],
205
+ method=switch_method,
206
+ strict=False,
207
+ allow_redirects=False,
208
+ )
209
+
210
+ return self
211
+
212
+ def switch_from_body_rule(self, rule: dict) -> "ExternalRulesHandler":
213
+ """
214
+ Switch from the body rule.
215
+
216
+ :param rule:
217
+ The rule to switch from.
218
+ :type rule: dict
219
+ """
220
+
221
+ required_keys = ["validation_type", "required_body_patterns"]
222
+
223
+ if any(x not in rule for x in required_keys):
224
+ return self
225
+
226
+ if rule["validation_type"] != "body":
227
+ return self
228
+
229
+ if rule["state_transition"] == "up":
230
+ switch_method = self.switch_to_up
231
+
232
+ if rule["state_transition"] == "down":
233
+ switch_method = self.switch_to_down
234
+
235
+ if "required_body_patterns" in rule and rule["required_body_patterns"]:
236
+ # pylint: disable=possibly-used-before-assignment
237
+ self.do_on_body_match(
238
+ self.req_url,
239
+ rule["required_body_patterns"],
240
+ method=switch_method,
241
+ strict=False,
242
+ allow_redirects=False,
243
+ )
244
+
245
+ return self
246
+
247
+ def switch_from_all_rule(self, rule: dict) -> "ExternalRulesHandler":
248
+ """
249
+ Switch from the all rule.
250
+
251
+ :param rule:
252
+ The rule to switch from.
253
+ :type rule: dict
254
+ """
255
+
256
+ required_keys = [
257
+ "validation_type",
258
+ ]
259
+
260
+ if any(x not in rule for x in required_keys):
261
+ return self
262
+
263
+ if rule["validation_type"] != "all":
264
+ return self
265
+
266
+ if rule["state_transition"] == "up":
267
+ switch_method = self.switch_to_up
268
+
269
+ if rule["state_transition"] == "down":
270
+ switch_method = self.switch_to_down
271
+
272
+ if (
273
+ "required_status_code" in rule
274
+ and rule["required_status_code"]
275
+ and any(
276
+ self.status.http_status_code == int(x)
277
+ for x in rule["required_status_code"]
278
+ )
279
+ ):
280
+ # pylint: disable=possibly-used-before-assignment
281
+ switch_method()
282
+
283
+ if "required_headers_patterns" in rule and rule["required_headers_patterns"]:
284
+ self.do_on_header_match(
285
+ self.req_url,
286
+ rule["required_headers_patterns"],
287
+ method=switch_method,
288
+ strict=False,
289
+ allow_redirects=False,
290
+ )
291
+
292
+ if "required_body_patterns" in rule and rule["required_body_patterns"]:
293
+ self.do_on_body_match(
294
+ self.req_url,
295
+ rule["required_body_patterns"],
296
+ method=switch_method,
297
+ strict=False,
298
+ allow_redirects=False,
299
+ )
300
+
301
+ return self
302
+
303
+ @ExtraRuleHandlerBase.ensure_status_is_given
304
+ @ExtraRuleHandlerBase.setup_status_before
305
+ @ExtraRuleHandlerBase.setup_status_after
306
+ def start(self) -> "ExternalRulesHandler":
307
+ """
308
+ Process the check and handling of the external rules for the given subject.
309
+ """
310
+
311
+ required_keys = ["subject_pattern", "validation_type", "state_transition"]
312
+
313
+ for rule in self.rulesets:
314
+ if any(x not in rule for x in required_keys):
315
+ continue
316
+
317
+ if not self.regex_helper.set_regex(rule["subject_pattern"]).match(
318
+ self.status.netloc, return_match=False
319
+ ):
320
+ continue
321
+
322
+ if rule["state_transition"] not in ["up", "down"]:
323
+ continue
324
+
325
+ if self.status.status_after_extra_rules:
326
+ # We already switched the status.
327
+ break
328
+
329
+ if rule["validation_type"] == "status_code":
330
+ self.switch_from_status_code_rule(rule)
331
+ elif rule["validation_type"] == "headers":
332
+ self.switch_from_headers_rule(rule)
333
+ elif rule["validation_type"] == "body":
334
+ self.switch_from_body_rule(rule)
335
+ elif rule["validation_type"] == "headers+body":
336
+ self.switch_from_headers_rule(rule)
337
+ self.switch_from_body_rule(rule)
338
+ elif rule["validation_type"] == "all":
339
+ self.switch_from_all_rule(rule)
340
+
341
+ return self
@@ -92,11 +92,12 @@ class ConfigLoader:
92
92
  _path_to_config: Optional[str] = None
93
93
  _remote_config_location: Optional[str] = None
94
94
  path_to_default_config: Optional[str] = None
95
- path_to_overwrite_config: Optional[str] = None
95
+ _path_to_overwrite_config: Optional[str] = None
96
96
 
97
97
  _custom_config: dict = {}
98
98
  _merge_upstream: bool = False
99
99
  _config_dir: Optional[str] = None
100
+ __config_loaded: bool = False
100
101
 
101
102
  file_helper: FileHelper = FileHelper()
102
103
  dict_helper: DictHelper = DictHelper()
@@ -115,18 +116,8 @@ class ConfigLoader:
115
116
  else:
116
117
  self.config_dir = PyFunceble.storage.CONFIG_DIRECTORY
117
118
 
118
- self.path_to_config = os.path.join(
119
- self.config_dir,
120
- PyFunceble.storage.CONFIGURATION_FILENAME,
121
- )
122
-
123
119
  self.path_to_remote_config = None
124
120
 
125
- self.path_to_overwrite_config = os.path.join(
126
- self.config_dir,
127
- ".PyFunceble.overwrite.yaml",
128
- )
129
-
130
121
  if merge_upstream is not None:
131
122
  self.merge_upstream = merge_upstream
132
123
  elif EnvironmentVariableHelper("PYFUNCEBLE_AUTO_CONFIGURATION").exists():
@@ -206,14 +197,82 @@ class ConfigLoader:
206
197
 
207
198
  return config
208
199
 
209
- @staticmethod
210
- def is_already_loaded() -> bool:
200
+ def is_already_loaded(self) -> bool:
211
201
  """
212
202
  Checks if the configuration was already loaded.
213
203
  """
214
204
 
215
205
  return bool(PyFunceble.storage.CONFIGURATION)
216
206
 
207
+ def __is_completely_loaded(self) -> bool:
208
+ """
209
+ Checks if the configuration was completely loaded.
210
+ """
211
+
212
+ return self.is_already_loaded() and bool(self.__config_loaded)
213
+
214
+ @property
215
+ def path_to_config(self) -> Optional[str]:
216
+ """
217
+ Provides the current state of the :code:`_path_to_config` attribute.
218
+ """
219
+
220
+ if self._path_to_config is None:
221
+ self._path_to_config = os.path.join(
222
+ self.config_dir,
223
+ PyFunceble.storage.CONFIGURATION_FILENAME,
224
+ )
225
+
226
+ return self._path_to_config
227
+
228
+ @path_to_config.setter
229
+ def path_to_config(self, value: str) -> None:
230
+ """
231
+ Sets the path to the configuration file.
232
+
233
+ :param value:
234
+ The value to set.
235
+
236
+ :raise TypeError:
237
+ When value is not a :py:class:`str`.
238
+ """
239
+
240
+ if not isinstance(value, str):
241
+ raise TypeError(f"<value> should be {str}, {type(value)} given.")
242
+
243
+ self._path_to_config = value
244
+
245
+ @property
246
+ def path_to_overwrite_config(self) -> Optional[str]:
247
+ """
248
+ Provides the current state of the :code:`_path_to_overwrite_config` attribute.
249
+ """
250
+
251
+ if self._path_to_overwrite_config is None:
252
+ self._path_to_overwrite_config = os.path.join(
253
+ self.config_dir,
254
+ ".PyFunceble.overwrite.yaml",
255
+ )
256
+
257
+ return self._path_to_overwrite_config
258
+
259
+ @path_to_overwrite_config.setter
260
+ def path_to_overwrite_config(self, value: str) -> None:
261
+ """
262
+ Sets the path to the overwrite configuration file.
263
+
264
+ :param value:
265
+ The value to set.
266
+
267
+ :raise TypeError:
268
+ When value is not a :py:class:`str`.
269
+ """
270
+
271
+ if not isinstance(value, str):
272
+ raise TypeError(f"<value> should be {str}, {type(value)} given.")
273
+
274
+ self._path_to_overwrite_config = value
275
+
217
276
  @property
218
277
  def config_dir(self) -> Optional[str]:
219
278
  """
@@ -239,6 +298,9 @@ class ConfigLoader:
239
298
  raise TypeError(f"<value> should be {str}, {type(value)} given.")
240
299
 
241
300
  self._config_dir = value
301
+ # Reset the path to the configuration file.
302
+ self._path_to_config = None
303
+ self._path_to_overwrite_config = None
242
304
 
243
305
  def set_config_dir(self, value: str) -> "ConfigLoader":
244
306
  """
@@ -385,9 +447,8 @@ class ConfigLoader:
385
447
 
386
448
  return self
387
449
 
388
- @classmethod
389
450
  def download_dynamic_infrastructure_files(
390
- cls,
451
+ self,
391
452
  ) -> "ConfigLoader":
392
453
  """
393
454
  Downloads all the dynamicly (generated) infrastructure files.
@@ -400,7 +461,7 @@ class ConfigLoader:
400
461
 
401
462
  ## pragma: no cover ## Underlying download methods already tested.
402
463
 
403
- if not cls.is_already_loaded():
464
+ if not self.is_already_loaded():
404
465
  IANADownloader().start()
405
466
  PublicSuffixDownloader().start()
406
467
  UserAgentsDownloader().start()
@@ -494,7 +555,7 @@ class ConfigLoader:
494
555
  config,
495
556
  )
496
557
 
497
- if not self.is_already_loaded():
558
+ if not self.__is_completely_loaded():
498
559
  self.install_missing_infrastructure_files()
499
560
  self.download_dynamic_infrastructure_files()
500
561
  download_remote_config(
@@ -590,9 +651,14 @@ class ConfigLoader:
590
651
  if "proxy" in config and config["proxy"]:
591
652
  PyFunceble.storage.PROXY = Box(config["proxy"])
592
653
 
654
+ if "special_rules" in config and config["special_rules"]:
655
+ PyFunceble.storage.SPECIAL_RULES = config["special_rules"]
656
+
593
657
  # Early load user agents to allow usage of defined user agents.
594
658
  UserAgentDataset().get_latest()
595
659
 
660
+ self.__config_loaded = True
661
+
596
662
  return self
597
663
 
598
664
  def destroy(self, keep_custom: bool = False) -> "ConfigLoader":
@@ -613,6 +679,7 @@ class ConfigLoader:
613
679
  PyFunceble.storage.PLATFORM = Box({})
614
680
  PyFunceble.storage.LINKS = Box({})
615
681
  PyFunceble.storage.PROXY = Box({})
682
+ PyFunceble.storage.SPECIAL_RULES = Box({})
616
683
  except (AttributeError, TypeError): # pragma: no cover ## Safety.
617
684
  pass
618
685
 
@@ -620,4 +687,6 @@ class ConfigLoader:
620
687
  # This is not a mistake.
621
688
  self._custom_config = {}
622
689
 
690
+ self.__config_loaded = False
691
+
623
692
  return self
@@ -852,3 +852,86 @@ platform:
852
852
  # CLI Argument: none
853
853
  checker_exclude:
854
854
  - none
855
+
856
+ special_rules:
857
+ # Let end-user define or integrate their own special rules.
858
+ #
859
+ # The idea: We want to give the end-user the possibility to define their own
860
+ # rules. This is useful when they want to switch the status of a subject based
861
+ # on a specific pattern, header, body, or status code.
862
+ #
863
+ # The structure:
864
+ # subject_pattern:
865
+ # -> The pattern to match against the subject.
866
+ # validation_type:
867
+ # -> The type of validation to perform. It can be one of the following:
868
+ # - all: A combination of everything (first match wins).
869
+ # - status_code: Only the status code.
870
+ # - headers: Only the headers.
871
+ # - body: Only the body.
872
+ # - headers+body: Match against the headers and the body.
873
+ # state_transition:
874
+ # -> The state to switch to when the validation is successful.
875
+ # When set to `down`, the status will be switched to INACTIVE. When set
876
+ # to `up`, the status will be switched to ACTIVE.
877
+ # required_status_code:
878
+ # -> A list of status code to match against.
879
+ # required_headers_patterns:
880
+ # -> A dictionary of headers to match against. The key is the header name
881
+ # and the value is a list of patterns to match against.
882
+ # required_body_patterns:
883
+ # -> A list of patterns to match against the body.
884
+ #
885
+ # Examples:
886
+ # When testing httpbin.org, we want to switch the status to down when the
887
+ # status code is 403 and the server header contains "gunicorn".
888
+ #
889
+ # - subject_pattern: "^httpbin\\.org$"
890
+ # validation_type: all
891
+ # state_transition: down
892
+ # required_status_code:
893
+ # - 403
894
+ # required_headers_patterns:
895
+ # server:
896
+ # - gunicorn
897
+ #
898
+ # When testing example.org, we want to switch the status to down when the
899
+ # status code is 404.
900
+ #
901
+ # - subject_pattern: "^example\\.org$"
902
+ # validation_type: status_code
903
+ # state_transition: down
904
+ # required_status_code:
905
+ # - 404
906
+ #
907
+ # When testing example.com, we want to switch The body and headers.the status to down when the
908
+ # header `server` contains `nginx`.
909
+ #
910
+ # - subject_pattern: "^example\\.com$"
911
+ # validation_type: headers
912
+ # state_transition: down
913
+ # required_headers_patterns:
914
+ # server:
915
+ # - nginx
916
+ #
917
+ # When testing example.net, we want to switch the status to down when the
918
+ # body contains "Hello, World!".
919
+ #
920
+ # - subject_pattern: "^example\\.net$"
921
+ # validation_type: body
922
+ # state_transition: down
923
+ # required_body_patterns:
924
+ # - Hello, World!
925
+ #
926
+ # When testing example.dev, we want to switch the status to down when the
927
+ # headers server contains `nginx` or the body contains "Hello, World!".
928
+ #
929
+ # - subject_pattern: "^example\\.dev$"
930
+ # validation_type: headers+body
931
+ # state_transition: down
932
+ # required_headers_patterns:
933
+ # server:
934
+ # - nginx
935
+ # required_body_patterns:
936
+ # - Hello, World!
937
+ []
PyFunceble/storage.py CHANGED
@@ -52,7 +52,7 @@ License:
52
52
  """
53
53
 
54
54
  import os
55
- from typing import Optional
55
+ from typing import List, Optional
56
56
 
57
57
  from box import Box
58
58
  from dotenv import load_dotenv
@@ -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.0a12.dev (Blue Duckling: Tulip)"
63
+ PROJECT_VERSION: str = "4.3.0a14.dev (Blue Duckling: Tulip)"
64
64
 
65
65
  DISTRIBUTED_CONFIGURATION_FILENAME: str = ".PyFunceble_production.yaml"
66
66
 
@@ -107,6 +107,7 @@ STATUS: Optional[Box] = Box(
107
107
  )
108
108
  HTTP_CODES: Optional[Box] = Box({})
109
109
  PLATFORM: Optional[Box] = Box({})
110
+ SPECIAL_RULES: Optional[List[dict]] = []
110
111
  LINKS: Optional[Box] = Box({})
111
112
  PROXY: Optional[Box] = Box({})
112
113
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyFunceble-dev
3
- Version: 4.3.0a12
3
+ Version: 4.3.0a14
4
4
  Summary: The tool to check the availability or syntax of domain, IP or URL.
5
5
  Home-page: https://github.com/funilrys/PyFunceble
6
6
  Author: funilrys
@@ -22,169 +22,169 @@ Classifier: License :: OSI Approved
22
22
  Requires-Python: >=3.9, <4
23
23
  Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
- Requires-Dist: dnspython[DOH]~=2.6.0
26
- Requires-Dist: packaging
27
- Requires-Dist: python-box[all]~=6.0.0
28
- Requires-Dist: PyYAML
29
- Requires-Dist: python-dotenv
30
- Requires-Dist: PyMySQL
31
- Requires-Dist: SQLAlchemy~=2.0
32
- Requires-Dist: alembic
33
- Requires-Dist: domain2idna~=1.12.0
34
25
  Requires-Dist: colorama
35
- Requires-Dist: inflection
26
+ Requires-Dist: PyMySQL
27
+ Requires-Dist: python-box[all]~=6.0.0
36
28
  Requires-Dist: requests[socks]<3
29
+ Requires-Dist: packaging
30
+ Requires-Dist: inflection
37
31
  Requires-Dist: shtab
32
+ Requires-Dist: domain2idna~=1.12.0
38
33
  Requires-Dist: setuptools>=65.5.1
34
+ Requires-Dist: dnspython[DOH]~=2.6.0
35
+ Requires-Dist: SQLAlchemy~=2.0
36
+ Requires-Dist: python-dotenv
37
+ Requires-Dist: PyYAML
38
+ Requires-Dist: alembic
39
39
  Provides-Extra: docs
40
+ Requires-Dist: mkdocs-material~=9.5; extra == "docs"
40
41
  Requires-Dist: mkdocs-git-revision-date-localized-plugin~=1.2; extra == "docs"
41
- Requires-Dist: mkdocs-literate-nav~=0.6; extra == "docs"
42
- Requires-Dist: mkdocs-gen-files~=0.5; extra == "docs"
42
+ Requires-Dist: mkdocs-git-authors-plugin~=0.9; extra == "docs"
43
43
  Requires-Dist: pymdown-extensions~=10.9; extra == "docs"
44
- Requires-Dist: zipp>=3.19.1; extra == "docs"
44
+ Requires-Dist: mkdocs-gen-files~=0.5; extra == "docs"
45
+ Requires-Dist: mkdocs~=1.5; extra == "docs"
46
+ Requires-Dist: mkdocstrings[python]~=0.26; extra == "docs"
47
+ Requires-Dist: mkdocs-literate-nav~=0.6; extra == "docs"
45
48
  Requires-Dist: mkdocs-section-index~=0.3; extra == "docs"
49
+ Requires-Dist: zipp>=3.19.1; extra == "docs"
46
50
  Requires-Dist: mkdocs-macros-plugin~=1.2; extra == "docs"
47
- Requires-Dist: mkdocs-git-authors-plugin~=0.9; extra == "docs"
48
- Requires-Dist: mkdocstrings[python]~=0.26; extra == "docs"
49
- Requires-Dist: mkdocs~=1.5; extra == "docs"
50
- Requires-Dist: mkdocs-material~=9.5; extra == "docs"
51
51
  Provides-Extra: dev
52
+ Requires-Dist: isort; extra == "dev"
52
53
  Requires-Dist: flake8; extra == "dev"
53
- Requires-Dist: black; extra == "dev"
54
54
  Requires-Dist: pylint; extra == "dev"
55
- Requires-Dist: isort; extra == "dev"
55
+ Requires-Dist: black; extra == "dev"
56
56
  Provides-Extra: test
57
57
  Requires-Dist: coverage; extra == "test"
58
58
  Requires-Dist: tox; extra == "test"
59
59
  Provides-Extra: psql
60
- Requires-Dist: dnspython[DOH]~=2.6.0; extra == "psql"
61
- Requires-Dist: packaging; extra == "psql"
62
- Requires-Dist: python-box[all]~=6.0.0; extra == "psql"
63
- Requires-Dist: PyYAML; extra == "psql"
64
- Requires-Dist: python-dotenv; extra == "psql"
65
- Requires-Dist: psycopg2; extra == "psql"
66
- Requires-Dist: PyMySQL; extra == "psql"
67
- Requires-Dist: SQLAlchemy~=2.0; extra == "psql"
68
- Requires-Dist: alembic; extra == "psql"
69
- Requires-Dist: domain2idna~=1.12.0; extra == "psql"
70
60
  Requires-Dist: colorama; extra == "psql"
71
- Requires-Dist: inflection; extra == "psql"
61
+ Requires-Dist: PyMySQL; extra == "psql"
62
+ Requires-Dist: python-box[all]~=6.0.0; extra == "psql"
72
63
  Requires-Dist: requests[socks]<3; extra == "psql"
64
+ Requires-Dist: packaging; extra == "psql"
65
+ Requires-Dist: inflection; extra == "psql"
73
66
  Requires-Dist: shtab; extra == "psql"
67
+ Requires-Dist: domain2idna~=1.12.0; extra == "psql"
74
68
  Requires-Dist: setuptools>=65.5.1; extra == "psql"
69
+ Requires-Dist: dnspython[DOH]~=2.6.0; extra == "psql"
70
+ Requires-Dist: SQLAlchemy~=2.0; extra == "psql"
71
+ Requires-Dist: psycopg2; extra == "psql"
72
+ Requires-Dist: python-dotenv; extra == "psql"
73
+ Requires-Dist: PyYAML; extra == "psql"
74
+ Requires-Dist: alembic; extra == "psql"
75
75
  Provides-Extra: psql-binary
76
- Requires-Dist: dnspython[DOH]~=2.6.0; extra == "psql-binary"
77
- Requires-Dist: packaging; extra == "psql-binary"
78
- Requires-Dist: python-box[all]~=6.0.0; extra == "psql-binary"
79
- Requires-Dist: PyYAML; extra == "psql-binary"
80
- Requires-Dist: python-dotenv; extra == "psql-binary"
81
- Requires-Dist: PyMySQL; extra == "psql-binary"
82
- Requires-Dist: SQLAlchemy~=2.0; extra == "psql-binary"
83
- Requires-Dist: alembic; extra == "psql-binary"
84
- Requires-Dist: psycopg2-binary; extra == "psql-binary"
85
- Requires-Dist: domain2idna~=1.12.0; extra == "psql-binary"
86
76
  Requires-Dist: colorama; extra == "psql-binary"
87
- Requires-Dist: inflection; extra == "psql-binary"
77
+ Requires-Dist: PyMySQL; extra == "psql-binary"
78
+ Requires-Dist: python-box[all]~=6.0.0; extra == "psql-binary"
88
79
  Requires-Dist: requests[socks]<3; extra == "psql-binary"
80
+ Requires-Dist: packaging; extra == "psql-binary"
81
+ Requires-Dist: inflection; extra == "psql-binary"
89
82
  Requires-Dist: shtab; extra == "psql-binary"
83
+ Requires-Dist: psycopg2-binary; extra == "psql-binary"
84
+ Requires-Dist: domain2idna~=1.12.0; extra == "psql-binary"
90
85
  Requires-Dist: setuptools>=65.5.1; extra == "psql-binary"
86
+ Requires-Dist: dnspython[DOH]~=2.6.0; extra == "psql-binary"
87
+ Requires-Dist: SQLAlchemy~=2.0; extra == "psql-binary"
88
+ Requires-Dist: python-dotenv; extra == "psql-binary"
89
+ Requires-Dist: PyYAML; extra == "psql-binary"
90
+ Requires-Dist: alembic; extra == "psql-binary"
91
91
  Provides-Extra: postgresql
92
- Requires-Dist: dnspython[DOH]~=2.6.0; extra == "postgresql"
93
- Requires-Dist: packaging; extra == "postgresql"
94
- Requires-Dist: python-box[all]~=6.0.0; extra == "postgresql"
95
- Requires-Dist: PyYAML; extra == "postgresql"
96
- Requires-Dist: python-dotenv; extra == "postgresql"
97
- Requires-Dist: psycopg2; extra == "postgresql"
98
- Requires-Dist: PyMySQL; extra == "postgresql"
99
- Requires-Dist: SQLAlchemy~=2.0; extra == "postgresql"
100
- Requires-Dist: alembic; extra == "postgresql"
101
- Requires-Dist: domain2idna~=1.12.0; extra == "postgresql"
102
92
  Requires-Dist: colorama; extra == "postgresql"
103
- Requires-Dist: inflection; extra == "postgresql"
93
+ Requires-Dist: PyMySQL; extra == "postgresql"
94
+ Requires-Dist: python-box[all]~=6.0.0; extra == "postgresql"
104
95
  Requires-Dist: requests[socks]<3; extra == "postgresql"
96
+ Requires-Dist: packaging; extra == "postgresql"
97
+ Requires-Dist: inflection; extra == "postgresql"
105
98
  Requires-Dist: shtab; extra == "postgresql"
99
+ Requires-Dist: domain2idna~=1.12.0; extra == "postgresql"
106
100
  Requires-Dist: setuptools>=65.5.1; extra == "postgresql"
101
+ Requires-Dist: dnspython[DOH]~=2.6.0; extra == "postgresql"
102
+ Requires-Dist: SQLAlchemy~=2.0; extra == "postgresql"
103
+ Requires-Dist: psycopg2; extra == "postgresql"
104
+ Requires-Dist: python-dotenv; extra == "postgresql"
105
+ Requires-Dist: PyYAML; extra == "postgresql"
106
+ Requires-Dist: alembic; extra == "postgresql"
107
107
  Provides-Extra: postgresql-binary
108
- Requires-Dist: dnspython[DOH]~=2.6.0; extra == "postgresql-binary"
109
- Requires-Dist: packaging; extra == "postgresql-binary"
110
- Requires-Dist: python-box[all]~=6.0.0; extra == "postgresql-binary"
111
- Requires-Dist: PyYAML; extra == "postgresql-binary"
112
- Requires-Dist: python-dotenv; extra == "postgresql-binary"
113
- Requires-Dist: PyMySQL; extra == "postgresql-binary"
114
- Requires-Dist: SQLAlchemy~=2.0; extra == "postgresql-binary"
115
- Requires-Dist: alembic; extra == "postgresql-binary"
116
- Requires-Dist: psycopg2-binary; extra == "postgresql-binary"
117
- Requires-Dist: domain2idna~=1.12.0; extra == "postgresql-binary"
118
108
  Requires-Dist: colorama; extra == "postgresql-binary"
119
- Requires-Dist: inflection; extra == "postgresql-binary"
109
+ Requires-Dist: PyMySQL; extra == "postgresql-binary"
110
+ Requires-Dist: python-box[all]~=6.0.0; extra == "postgresql-binary"
120
111
  Requires-Dist: requests[socks]<3; extra == "postgresql-binary"
112
+ Requires-Dist: packaging; extra == "postgresql-binary"
113
+ Requires-Dist: inflection; extra == "postgresql-binary"
121
114
  Requires-Dist: shtab; extra == "postgresql-binary"
115
+ Requires-Dist: psycopg2-binary; extra == "postgresql-binary"
116
+ Requires-Dist: domain2idna~=1.12.0; extra == "postgresql-binary"
122
117
  Requires-Dist: setuptools>=65.5.1; extra == "postgresql-binary"
118
+ Requires-Dist: dnspython[DOH]~=2.6.0; extra == "postgresql-binary"
119
+ Requires-Dist: SQLAlchemy~=2.0; extra == "postgresql-binary"
120
+ Requires-Dist: python-dotenv; extra == "postgresql-binary"
121
+ Requires-Dist: PyYAML; extra == "postgresql-binary"
122
+ Requires-Dist: alembic; extra == "postgresql-binary"
123
123
  Provides-Extra: full
124
- Requires-Dist: PyMySQL; extra == "full"
124
+ Requires-Dist: python-box[all]~=6.0.0; extra == "full"
125
+ Requires-Dist: mkdocs-material~=9.5; extra == "full"
126
+ Requires-Dist: packaging; extra == "full"
127
+ Requires-Dist: inflection; extra == "full"
125
128
  Requires-Dist: black; extra == "full"
126
- Requires-Dist: colorama; extra == "full"
127
- Requires-Dist: tox; extra == "full"
128
- Requires-Dist: mkdocs-git-authors-plugin~=0.9; extra == "full"
129
+ Requires-Dist: domain2idna~=1.12.0; extra == "full"
129
130
  Requires-Dist: setuptools>=65.5.1; extra == "full"
130
- Requires-Dist: dnspython[DOH]~=2.6.0; extra == "full"
131
- Requires-Dist: mkdocs-material~=9.5; extra == "full"
132
- Requires-Dist: mkdocs-literate-nav~=0.6; extra == "full"
133
131
  Requires-Dist: SQLAlchemy~=2.0; extra == "full"
134
- Requires-Dist: pylint; extra == "full"
135
- Requires-Dist: mkdocs~=1.5; extra == "full"
136
- Requires-Dist: mkdocs-macros-plugin~=1.2; extra == "full"
137
- Requires-Dist: packaging; extra == "full"
132
+ Requires-Dist: mkdocstrings[python]~=0.26; extra == "full"
138
133
  Requires-Dist: PyYAML; extra == "full"
134
+ Requires-Dist: alembic; extra == "full"
135
+ Requires-Dist: mkdocs-macros-plugin~=1.2; extra == "full"
139
136
  Requires-Dist: coverage; extra == "full"
137
+ Requires-Dist: mkdocs-git-authors-plugin~=0.9; extra == "full"
138
+ Requires-Dist: shtab; extra == "full"
140
139
  Requires-Dist: mkdocs-gen-files~=0.5; extra == "full"
140
+ Requires-Dist: tox; extra == "full"
141
+ Requires-Dist: isort; extra == "full"
142
+ Requires-Dist: colorama; extra == "full"
143
+ Requires-Dist: PyMySQL; extra == "full"
141
144
  Requires-Dist: pymdown-extensions~=10.9; extra == "full"
142
- Requires-Dist: inflection; extra == "full"
143
- Requires-Dist: flake8; extra == "full"
145
+ Requires-Dist: mkdocs~=1.5; extra == "full"
146
+ Requires-Dist: pylint; extra == "full"
147
+ Requires-Dist: mkdocs-literate-nav~=0.6; extra == "full"
148
+ Requires-Dist: python-dotenv; extra == "full"
149
+ Requires-Dist: mkdocs-section-index~=0.3; extra == "full"
144
150
  Requires-Dist: requests[socks]<3; extra == "full"
145
- Requires-Dist: mkdocstrings[python]~=0.26; extra == "full"
146
- Requires-Dist: python-box[all]~=6.0.0; extra == "full"
147
151
  Requires-Dist: mkdocs-git-revision-date-localized-plugin~=1.2; extra == "full"
148
- Requires-Dist: python-dotenv; extra == "full"
149
- Requires-Dist: alembic; extra == "full"
150
- Requires-Dist: domain2idna~=1.12.0; extra == "full"
152
+ Requires-Dist: dnspython[DOH]~=2.6.0; extra == "full"
151
153
  Requires-Dist: zipp>=3.19.1; extra == "full"
152
- Requires-Dist: mkdocs-section-index~=0.3; extra == "full"
153
- Requires-Dist: shtab; extra == "full"
154
- Requires-Dist: isort; extra == "full"
154
+ Requires-Dist: flake8; extra == "full"
155
155
  Provides-Extra: all
156
- Requires-Dist: PyMySQL; extra == "all"
156
+ Requires-Dist: python-box[all]~=6.0.0; extra == "all"
157
+ Requires-Dist: mkdocs-material~=9.5; extra == "all"
158
+ Requires-Dist: packaging; extra == "all"
159
+ Requires-Dist: inflection; extra == "all"
157
160
  Requires-Dist: black; extra == "all"
158
- Requires-Dist: colorama; extra == "all"
159
- Requires-Dist: tox; extra == "all"
160
- Requires-Dist: mkdocs-git-authors-plugin~=0.9; extra == "all"
161
+ Requires-Dist: domain2idna~=1.12.0; extra == "all"
161
162
  Requires-Dist: setuptools>=65.5.1; extra == "all"
162
- Requires-Dist: dnspython[DOH]~=2.6.0; extra == "all"
163
- Requires-Dist: mkdocs-material~=9.5; extra == "all"
164
- Requires-Dist: mkdocs-literate-nav~=0.6; extra == "all"
165
163
  Requires-Dist: SQLAlchemy~=2.0; extra == "all"
166
- Requires-Dist: pylint; extra == "all"
167
- Requires-Dist: mkdocs~=1.5; extra == "all"
168
- Requires-Dist: mkdocs-macros-plugin~=1.2; extra == "all"
169
- Requires-Dist: packaging; extra == "all"
164
+ Requires-Dist: mkdocstrings[python]~=0.26; extra == "all"
170
165
  Requires-Dist: PyYAML; extra == "all"
166
+ Requires-Dist: alembic; extra == "all"
167
+ Requires-Dist: mkdocs-macros-plugin~=1.2; extra == "all"
171
168
  Requires-Dist: coverage; extra == "all"
172
- Requires-Dist: psycopg2-binary; extra == "all"
169
+ Requires-Dist: mkdocs-git-authors-plugin~=0.9; extra == "all"
170
+ Requires-Dist: shtab; extra == "all"
173
171
  Requires-Dist: mkdocs-gen-files~=0.5; extra == "all"
172
+ Requires-Dist: tox; extra == "all"
173
+ Requires-Dist: psycopg2-binary; extra == "all"
174
+ Requires-Dist: isort; extra == "all"
175
+ Requires-Dist: colorama; extra == "all"
176
+ Requires-Dist: PyMySQL; extra == "all"
174
177
  Requires-Dist: pymdown-extensions~=10.9; extra == "all"
175
- Requires-Dist: inflection; extra == "all"
176
- Requires-Dist: flake8; extra == "all"
178
+ Requires-Dist: mkdocs~=1.5; extra == "all"
179
+ Requires-Dist: pylint; extra == "all"
180
+ Requires-Dist: mkdocs-literate-nav~=0.6; extra == "all"
181
+ Requires-Dist: python-dotenv; extra == "all"
182
+ Requires-Dist: mkdocs-section-index~=0.3; extra == "all"
177
183
  Requires-Dist: requests[socks]<3; extra == "all"
178
- Requires-Dist: mkdocstrings[python]~=0.26; extra == "all"
179
- Requires-Dist: python-box[all]~=6.0.0; extra == "all"
180
184
  Requires-Dist: mkdocs-git-revision-date-localized-plugin~=1.2; extra == "all"
181
- Requires-Dist: python-dotenv; extra == "all"
182
- Requires-Dist: alembic; extra == "all"
183
- Requires-Dist: domain2idna~=1.12.0; extra == "all"
185
+ Requires-Dist: dnspython[DOH]~=2.6.0; extra == "all"
184
186
  Requires-Dist: zipp>=3.19.1; extra == "all"
185
- Requires-Dist: mkdocs-section-index~=0.3; extra == "all"
186
- Requires-Dist: shtab; extra == "all"
187
- Requires-Dist: isort; extra == "all"
187
+ Requires-Dist: flake8; extra == "all"
188
188
 
189
189
  ![image](https://raw.githubusercontent.com/PyFunceble/logo/dev/Green/HD/RM.png)
190
190
 
@@ -4,7 +4,7 @@ PyFunceble/facility.py,sha256=hyEzCCTOgtAS0x88uEtv9xNwIXnDCDvgq5RHcPNDE-A,2626
4
4
  PyFunceble/factory.py,sha256=ETvTe1Ss3VaIhSBOj-ro80XFAYiknsGG9B5oKpubr2s,2576
5
5
  PyFunceble/logger.py,sha256=pmValhdu0XB34FrK1rSgOAhr4spQ8a3QbqQ26jpJHa0,16815
6
6
  PyFunceble/sessions.py,sha256=juHBKHSuVd-tAEIMRj3RXyGyUhZQLEBmeMssd_5qo1U,2568
7
- PyFunceble/storage.py,sha256=l-irElCfBaHqwf9f8nPprRKrBhGx-FCacEtYY8WMFO0,5349
7
+ PyFunceble/storage.py,sha256=nqG7u6kLO80Y141dKR_H_yJS0a-gwbuD3ScqybfdMI8,5396
8
8
  PyFunceble/storage_facility.py,sha256=uvW91dOTxF7-2nXxIp2xGI5sDRABBoGMA7D9xfemfGk,4819
9
9
  PyFunceble/checker/__init__.py,sha256=jSCfY25VNBrxLECSgNwU6kTGSl0bM1_JLl_UKvtKP6w,2430
10
10
  PyFunceble/checker/base.py,sha256=WP9Rjl6rvsq69oCaG4a5WDhoWofMpyxfa4K-WY27Gxw,13615
@@ -12,7 +12,7 @@ PyFunceble/checker/complex_json_encoder.py,sha256=oYVqzOV7qICTsN3f2mHtIJU1WdT-41
12
12
  PyFunceble/checker/params_base.py,sha256=eUqfukjplc68QYGbaMsyAv925axxNr3S4Vd2ZvHZfBw,3281
13
13
  PyFunceble/checker/status_base.py,sha256=Rlz9oNMLjCwDeTwH1rYfothY8UDsmpdj4Ll3Qds6fno,3584
14
14
  PyFunceble/checker/availability/__init__.py,sha256=Ir6tRpMV9qLmED3LOsDQYyVx1YgGvzePLYejd9OAk3w,2475
15
- PyFunceble/checker/availability/base.py,sha256=938MMkIYe8zXjFL6x-MfbCb91KGV-PsSn9oTDctXOqU,39250
15
+ PyFunceble/checker/availability/base.py,sha256=hx_4eAGfykN62si91KkzB_6o7QzENS_t2ZaStMo7SKc,39408
16
16
  PyFunceble/checker/availability/domain.py,sha256=DMb2fxh9JYuNBLCzy_kahca6rFCekZl5s57VOGFHAhE,7430
17
17
  PyFunceble/checker/availability/domain_and_ip.py,sha256=gClAt_qmggNE4VpPH4XJ-1sHdVOzOOqWV_fuFC6bD3M,6577
18
18
  PyFunceble/checker/availability/ip.py,sha256=x41TEko2ajBWzPyfgCT6KXtVxcd8HHPuKVIeNHeWQIc,7025
@@ -20,9 +20,10 @@ PyFunceble/checker/availability/params.py,sha256=Z5kpiFWA-txTSE4Yp-SJM7gJd7jvicT
20
20
  PyFunceble/checker/availability/status.py,sha256=l30efESj8LWvyXr-QRnRicmIQN_b9P74qJ5veNpwknU,5228
21
21
  PyFunceble/checker/availability/url.py,sha256=1Xz_lTQjflNIFgNegpUOXjZfXP-clCmXCfdxEQ_hthg,11310
22
22
  PyFunceble/checker/availability/extras/__init__.py,sha256=x2tAu7KXzzrf1b0rB42tfBlZwQZC2F3jKMAtzXKpl9U,2477
23
- PyFunceble/checker/availability/extras/base.py,sha256=N7kyhvHiqT8n3l2eNzVFZTw--dmBe2juubSawqyCBsU,15426
23
+ PyFunceble/checker/availability/extras/base.py,sha256=aUzG-K8gvjDURC_ipv7J46FhvqfpVe473m1NUng84dg,15434
24
24
  PyFunceble/checker/availability/extras/dns.py,sha256=Dgaw1PaQJytPpH-WAtVokE_baFKX_bWTsOn4IyO2a4k,6830
25
25
  PyFunceble/checker/availability/extras/etoxic.py,sha256=p-DfvrBhVx71-MUliVW1i7lyrz_4TTnBb5rqmJ7b1pI,10056
26
+ PyFunceble/checker/availability/extras/external.py,sha256=RcYpYw4jGgT-0pxBNn8P0PM2i_pPOOT4N01LsGn9xZw,12122
26
27
  PyFunceble/checker/availability/extras/parked.py,sha256=1wFHVUgEpe0kZcDw8D2gmOzZ8TNVKvo29g-AseihZfI,5258
27
28
  PyFunceble/checker/availability/extras/rules.py,sha256=Sf9R58W3XmKNtov0HeGMUptNWqlHss2utO1j_DuOXJo,11731
28
29
  PyFunceble/checker/availability/extras/subject_switch.py,sha256=lKWGuK98nu7LKceHbjpBKMtxRoWlTdUvhfr8yjHAA-g,5863
@@ -147,7 +148,7 @@ PyFunceble/cli/utils/testing.py,sha256=yobBqTpA-MT8_sPRMohCuP4ujeCfjUMg7DhOVHfD9
147
148
  PyFunceble/cli/utils/version.py,sha256=G-yLUVolaQouGz1qnQigT33VgH6EEUu8-Qm_QkkXfUo,13892
148
149
  PyFunceble/config/__init__.py,sha256=5t7ypzV6rpSz5IC0QwQMEbmWb0H_w3J917L6DC9NaWw,2454
149
150
  PyFunceble/config/compare.py,sha256=GLmrcAdCXX2SmWQph8kMG0hdDeKgr-LxMSzFGhkxb5E,13631
150
- PyFunceble/config/loader.py,sha256=TS4GTyWlYQmVmoobdSsPM74rd1f_flZEXFHACE4S2c4,20741
151
+ PyFunceble/config/loader.py,sha256=syRD0jmR5Y9TU-aIGJJ_7zxKJSfYcAOG1jNv-YML3cY,22824
151
152
  PyFunceble/converter/__init__.py,sha256=xV1NBUxxzsArjJfhSj0c3HLXs0QPHrX196YsbVPvrbw,2436
152
153
  PyFunceble/converter/adblock_input_line2subject.py,sha256=88zGa0BJacMVIV4LkRXX0EqT9Fez8BTUw8pzas0AwPI,12925
153
154
  PyFunceble/converter/base.py,sha256=bhljvSmbqTiEHXkZ01WyD7XYXXxYG9VmW3RNRtcZlB0,4915
@@ -184,7 +185,7 @@ PyFunceble/data/alembic/postgresql/env.py,sha256=UfJff9bY99TTC0z9bQgsm17NqsGnLmz
184
185
  PyFunceble/data/alembic/postgresql/script.py.mako,sha256=8_xgA-gm_OhehnO7CiIijWgnm00ZlszEHtIHrAYFJl0,494
185
186
  PyFunceble/data/alembic/postgresql/versions/__init__.py,sha256=5E57ZZeUcnx4sgc3LJh6e6bjgeaQhS4W-f2UVuUYsrs,2452
186
187
  PyFunceble/data/alembic/postgresql/versions/a32ac5d66eee_initial_version.py,sha256=xJdnoCnHAG1vmt-nBeomuIEDRwUK1Upv1mtkUt1txQM,2487
187
- PyFunceble/data/infrastructure/.PyFunceble_production.yaml,sha256=Mpz5HKewJvZNhyOV0W4WLURgoOVtPC7bQJ2-yh3StE4,25411
188
+ PyFunceble/data/infrastructure/.PyFunceble_production.yaml,sha256=iGHEYd4R9zg37vocZKKpDyCnaOlBKBiUv01u8AykpWk,28488
188
189
  PyFunceble/data/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
189
190
  PyFunceble/data/infrastructure/dir_structure_production.json,sha256=XpWin49SkoWu3pvnsoNlbNh6j9MlTGVKkvTmX99jZkM,5722
190
191
  PyFunceble/database/__init__.py,sha256=r8zmExtTZguf07GzlaYW5hz11DCC1C6qeU3XvkSQXSU,2492
@@ -275,9 +276,9 @@ PyFunceble/utils/__init__.py,sha256=Vnhd0wNrWJulWwUUK-vlv5VWBiKfSnXtI2XH_FyYkBA,
275
276
  PyFunceble/utils/platform.py,sha256=JA6rc6Uyx6czNWR9917HGB-EZyMjMK17kUVagMtEEjs,3906
276
277
  PyFunceble/utils/profile.py,sha256=f9FsKuiN3ScftqqrZ3yGpcIFqGSf616dPT_QvBduqxw,4552
277
278
  PyFunceble/utils/version.py,sha256=LvSiIrQWztuQ1qT7ekiDvh5TateyVRGMFRui73O4wFQ,8371
278
- PyFunceble_dev-4.3.0a12.dist-info/LICENSE,sha256=JBG6UfPnf3940AtwZB6vwAK6YH82Eo6nzMVnjGqopF0,10796
279
- PyFunceble_dev-4.3.0a12.dist-info/METADATA,sha256=GpLyEPEnZkt_glJF6_X5EiUPX3DT0M1xLuhUdI6SyTs,46666
280
- PyFunceble_dev-4.3.0a12.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
281
- PyFunceble_dev-4.3.0a12.dist-info/entry_points.txt,sha256=Ic1suwopOi_XTgiQi2ErtpY5xT3R8EFMI6B_ONDuR9E,201
282
- PyFunceble_dev-4.3.0a12.dist-info/top_level.txt,sha256=J7GBKIiNYv93m1AxLy8_gr6ExXyZbMmCVXHMQBTUq2Y,11
283
- PyFunceble_dev-4.3.0a12.dist-info/RECORD,,
279
+ PyFunceble_dev-4.3.0a14.dist-info/LICENSE,sha256=JBG6UfPnf3940AtwZB6vwAK6YH82Eo6nzMVnjGqopF0,10796
280
+ PyFunceble_dev-4.3.0a14.dist-info/METADATA,sha256=4AVyFnooal83gmSj5mJKaXnQty_XV_RXWVJC5SZjUnk,46666
281
+ PyFunceble_dev-4.3.0a14.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
282
+ PyFunceble_dev-4.3.0a14.dist-info/entry_points.txt,sha256=Ic1suwopOi_XTgiQi2ErtpY5xT3R8EFMI6B_ONDuR9E,201
283
+ PyFunceble_dev-4.3.0a14.dist-info/top_level.txt,sha256=J7GBKIiNYv93m1AxLy8_gr6ExXyZbMmCVXHMQBTUq2Y,11
284
+ PyFunceble_dev-4.3.0a14.dist-info/RECORD,,