PyFunceble-dev 4.3.0a13__py3-none-any.whl → 4.3.0a15__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
@@ -442,7 +442,7 @@ class ConfigLoader:
442
442
  if not self.is_already_loaded():
443
443
  if not self.file_helper.set_path(self.path_to_config).exists():
444
444
  self.file_helper.set_path(self.path_to_default_config).copy(
445
- self.path_to_config
445
+ self.path_to_config, create_parent=True
446
446
  )
447
447
 
448
448
  return self
@@ -515,7 +515,7 @@ class ConfigLoader:
515
515
  config = self.dict_helper.from_yaml_file(self.path_to_config)
516
516
  except (MarkedYAMLError, FileNotFoundError):
517
517
  self.file_helper.set_path(self.path_to_default_config).copy(
518
- self.path_to_config
518
+ self.path_to_config, create_parent=True
519
519
  )
520
520
  config = self.dict_helper.from_yaml_file(self.path_to_config)
521
521
 
@@ -651,6 +651,9 @@ class ConfigLoader:
651
651
  if "proxy" in config and config["proxy"]:
652
652
  PyFunceble.storage.PROXY = Box(config["proxy"])
653
653
 
654
+ if "special_rules" in config and config["special_rules"]:
655
+ PyFunceble.storage.SPECIAL_RULES = config["special_rules"]
656
+
654
657
  # Early load user agents to allow usage of defined user agents.
655
658
  UserAgentDataset().get_latest()
656
659
 
@@ -676,6 +679,7 @@ class ConfigLoader:
676
679
  PyFunceble.storage.PLATFORM = Box({})
677
680
  PyFunceble.storage.LINKS = Box({})
678
681
  PyFunceble.storage.PROXY = Box({})
682
+ PyFunceble.storage.SPECIAL_RULES = Box({})
679
683
  except (AttributeError, TypeError): # pragma: no cover ## Safety.
680
684
  pass
681
685
 
@@ -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
+ []
@@ -201,13 +201,17 @@ class FileHelper:
201
201
 
202
202
  return open(self.path, *args, **kwargs) # pylint: disable=unspecified-encoding
203
203
 
204
- def copy(self, destination: str) -> "FileHelper":
204
+ def copy(self, destination: str, *, create_parent: bool = False) -> "FileHelper":
205
205
  """
206
206
  Copy the globaly given file path to the given destination.
207
207
 
208
208
  :param str destination: The destination of the copy.
209
+ :param bool create_parent: Tell us if we have to create the parent directory.
209
210
  """
210
211
 
212
+ if create_parent:
213
+ DirectoryHelper(os.path.dirname(destination)).create()
214
+
211
215
  if self.exists():
212
216
  shutil.copy(self.path, destination)
213
217
 
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.0a13.dev (Blue Duckling: Tulip)"
63
+ PROJECT_VERSION: str = "4.3.0a15.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.0a13
3
+ Version: 4.3.0a15
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: requests[socks]<3
25
+ Requires-Dist: alembic
26
26
  Requires-Dist: domain2idna~=1.12.0
27
27
  Requires-Dist: setuptools>=65.5.1
28
- Requires-Dist: python-dotenv
29
- Requires-Dist: shtab
30
- Requires-Dist: PyYAML
31
- Requires-Dist: packaging
32
28
  Requires-Dist: inflection
29
+ Requires-Dist: shtab
33
30
  Requires-Dist: python-box[all]~=6.0.0
34
- Requires-Dist: PyMySQL
31
+ Requires-Dist: PyYAML
32
+ Requires-Dist: colorama
35
33
  Requires-Dist: dnspython[DOH]~=2.6.0
36
- Requires-Dist: alembic
37
34
  Requires-Dist: SQLAlchemy~=2.0
38
- Requires-Dist: colorama
35
+ Requires-Dist: requests[socks]<3
36
+ Requires-Dist: packaging
37
+ Requires-Dist: python-dotenv
38
+ Requires-Dist: PyMySQL
39
39
  Provides-Extra: docs
40
- Requires-Dist: mkdocs-literate-nav~=0.6; extra == "docs"
41
- Requires-Dist: mkdocs-gen-files~=0.5; extra == "docs"
40
+ Requires-Dist: mkdocs~=1.5; extra == "docs"
42
41
  Requires-Dist: mkdocstrings[python]~=0.26; extra == "docs"
42
+ Requires-Dist: mkdocs-macros-plugin~=1.2; extra == "docs"
43
43
  Requires-Dist: zipp>=3.19.1; extra == "docs"
44
- Requires-Dist: mkdocs-git-authors-plugin~=0.9; extra == "docs"
44
+ Requires-Dist: mkdocs-gen-files~=0.5; extra == "docs"
45
45
  Requires-Dist: pymdown-extensions~=10.9; extra == "docs"
46
- Requires-Dist: mkdocs-git-revision-date-localized-plugin~=1.2; extra == "docs"
47
- Requires-Dist: mkdocs-macros-plugin~=1.2; extra == "docs"
48
- Requires-Dist: mkdocs~=1.5; extra == "docs"
46
+ Requires-Dist: mkdocs-literate-nav~=0.6; extra == "docs"
49
47
  Requires-Dist: mkdocs-section-index~=0.3; extra == "docs"
48
+ Requires-Dist: mkdocs-git-authors-plugin~=0.9; extra == "docs"
50
49
  Requires-Dist: mkdocs-material~=9.5; extra == "docs"
50
+ Requires-Dist: mkdocs-git-revision-date-localized-plugin~=1.2; extra == "docs"
51
51
  Provides-Extra: dev
52
- Requires-Dist: isort; extra == "dev"
53
52
  Requires-Dist: black; extra == "dev"
54
- Requires-Dist: flake8; extra == "dev"
55
53
  Requires-Dist: pylint; extra == "dev"
54
+ Requires-Dist: isort; extra == "dev"
55
+ Requires-Dist: flake8; extra == "dev"
56
56
  Provides-Extra: test
57
- Requires-Dist: coverage; extra == "test"
58
57
  Requires-Dist: tox; extra == "test"
58
+ Requires-Dist: coverage; extra == "test"
59
59
  Provides-Extra: psql
60
- Requires-Dist: requests[socks]<3; extra == "psql"
60
+ Requires-Dist: alembic; extra == "psql"
61
61
  Requires-Dist: domain2idna~=1.12.0; extra == "psql"
62
62
  Requires-Dist: setuptools>=65.5.1; extra == "psql"
63
- Requires-Dist: python-dotenv; extra == "psql"
64
- Requires-Dist: shtab; extra == "psql"
65
- Requires-Dist: PyYAML; extra == "psql"
66
- Requires-Dist: packaging; extra == "psql"
67
- Requires-Dist: psycopg2; extra == "psql"
68
63
  Requires-Dist: inflection; extra == "psql"
64
+ Requires-Dist: shtab; extra == "psql"
69
65
  Requires-Dist: python-box[all]~=6.0.0; extra == "psql"
70
- Requires-Dist: PyMySQL; extra == "psql"
66
+ Requires-Dist: PyYAML; extra == "psql"
67
+ Requires-Dist: colorama; extra == "psql"
71
68
  Requires-Dist: dnspython[DOH]~=2.6.0; extra == "psql"
72
- Requires-Dist: alembic; extra == "psql"
73
69
  Requires-Dist: SQLAlchemy~=2.0; extra == "psql"
74
- Requires-Dist: colorama; extra == "psql"
70
+ Requires-Dist: psycopg2; extra == "psql"
71
+ Requires-Dist: requests[socks]<3; extra == "psql"
72
+ Requires-Dist: packaging; extra == "psql"
73
+ Requires-Dist: python-dotenv; extra == "psql"
74
+ Requires-Dist: PyMySQL; extra == "psql"
75
75
  Provides-Extra: psql-binary
76
- Requires-Dist: psycopg2-binary; extra == "psql-binary"
77
- Requires-Dist: requests[socks]<3; extra == "psql-binary"
76
+ Requires-Dist: alembic; extra == "psql-binary"
78
77
  Requires-Dist: domain2idna~=1.12.0; extra == "psql-binary"
79
78
  Requires-Dist: setuptools>=65.5.1; extra == "psql-binary"
80
- Requires-Dist: python-dotenv; extra == "psql-binary"
81
- Requires-Dist: shtab; extra == "psql-binary"
82
- Requires-Dist: PyYAML; extra == "psql-binary"
83
- Requires-Dist: packaging; extra == "psql-binary"
84
79
  Requires-Dist: inflection; extra == "psql-binary"
80
+ Requires-Dist: shtab; extra == "psql-binary"
85
81
  Requires-Dist: python-box[all]~=6.0.0; extra == "psql-binary"
86
- Requires-Dist: PyMySQL; extra == "psql-binary"
82
+ Requires-Dist: PyYAML; extra == "psql-binary"
83
+ Requires-Dist: colorama; extra == "psql-binary"
87
84
  Requires-Dist: dnspython[DOH]~=2.6.0; extra == "psql-binary"
88
- Requires-Dist: alembic; extra == "psql-binary"
89
85
  Requires-Dist: SQLAlchemy~=2.0; extra == "psql-binary"
90
- Requires-Dist: colorama; extra == "psql-binary"
86
+ Requires-Dist: requests[socks]<3; extra == "psql-binary"
87
+ Requires-Dist: packaging; extra == "psql-binary"
88
+ Requires-Dist: python-dotenv; extra == "psql-binary"
89
+ Requires-Dist: PyMySQL; extra == "psql-binary"
90
+ Requires-Dist: psycopg2-binary; extra == "psql-binary"
91
91
  Provides-Extra: postgresql
92
- Requires-Dist: requests[socks]<3; extra == "postgresql"
92
+ Requires-Dist: alembic; extra == "postgresql"
93
93
  Requires-Dist: domain2idna~=1.12.0; extra == "postgresql"
94
94
  Requires-Dist: setuptools>=65.5.1; extra == "postgresql"
95
- Requires-Dist: python-dotenv; extra == "postgresql"
96
- Requires-Dist: shtab; extra == "postgresql"
97
- Requires-Dist: PyYAML; extra == "postgresql"
98
- Requires-Dist: packaging; extra == "postgresql"
99
- Requires-Dist: psycopg2; extra == "postgresql"
100
95
  Requires-Dist: inflection; extra == "postgresql"
96
+ Requires-Dist: shtab; extra == "postgresql"
101
97
  Requires-Dist: python-box[all]~=6.0.0; extra == "postgresql"
102
- Requires-Dist: PyMySQL; extra == "postgresql"
98
+ Requires-Dist: PyYAML; extra == "postgresql"
99
+ Requires-Dist: colorama; extra == "postgresql"
103
100
  Requires-Dist: dnspython[DOH]~=2.6.0; extra == "postgresql"
104
- Requires-Dist: alembic; extra == "postgresql"
105
101
  Requires-Dist: SQLAlchemy~=2.0; extra == "postgresql"
106
- Requires-Dist: colorama; extra == "postgresql"
102
+ Requires-Dist: psycopg2; extra == "postgresql"
103
+ Requires-Dist: requests[socks]<3; extra == "postgresql"
104
+ Requires-Dist: packaging; extra == "postgresql"
105
+ Requires-Dist: python-dotenv; extra == "postgresql"
106
+ Requires-Dist: PyMySQL; extra == "postgresql"
107
107
  Provides-Extra: postgresql-binary
108
- Requires-Dist: psycopg2-binary; extra == "postgresql-binary"
109
- Requires-Dist: requests[socks]<3; extra == "postgresql-binary"
108
+ Requires-Dist: alembic; extra == "postgresql-binary"
110
109
  Requires-Dist: domain2idna~=1.12.0; extra == "postgresql-binary"
111
110
  Requires-Dist: setuptools>=65.5.1; extra == "postgresql-binary"
112
- Requires-Dist: python-dotenv; extra == "postgresql-binary"
113
- Requires-Dist: shtab; extra == "postgresql-binary"
114
- Requires-Dist: PyYAML; extra == "postgresql-binary"
115
- Requires-Dist: packaging; extra == "postgresql-binary"
116
111
  Requires-Dist: inflection; extra == "postgresql-binary"
112
+ Requires-Dist: shtab; extra == "postgresql-binary"
117
113
  Requires-Dist: python-box[all]~=6.0.0; extra == "postgresql-binary"
118
- Requires-Dist: PyMySQL; extra == "postgresql-binary"
114
+ Requires-Dist: PyYAML; extra == "postgresql-binary"
115
+ Requires-Dist: colorama; extra == "postgresql-binary"
119
116
  Requires-Dist: dnspython[DOH]~=2.6.0; extra == "postgresql-binary"
120
- Requires-Dist: alembic; extra == "postgresql-binary"
121
117
  Requires-Dist: SQLAlchemy~=2.0; extra == "postgresql-binary"
122
- Requires-Dist: colorama; extra == "postgresql-binary"
118
+ Requires-Dist: requests[socks]<3; extra == "postgresql-binary"
119
+ Requires-Dist: packaging; extra == "postgresql-binary"
120
+ Requires-Dist: python-dotenv; extra == "postgresql-binary"
121
+ Requires-Dist: PyMySQL; extra == "postgresql-binary"
122
+ Requires-Dist: psycopg2-binary; extra == "postgresql-binary"
123
123
  Provides-Extra: full
124
+ Requires-Dist: alembic; extra == "full"
125
+ Requires-Dist: mkdocstrings[python]~=0.26; extra == "full"
126
+ Requires-Dist: colorama; extra == "full"
127
+ Requires-Dist: mkdocs-section-index~=0.3; extra == "full"
124
128
  Requires-Dist: requests[socks]<3; extra == "full"
125
- Requires-Dist: python-dotenv; extra == "full"
126
- Requires-Dist: pymdown-extensions~=10.9; extra == "full"
127
- Requires-Dist: PyYAML; extra == "full"
129
+ Requires-Dist: coverage; extra == "full"
128
130
  Requires-Dist: tox; extra == "full"
129
- Requires-Dist: mkdocs-git-revision-date-localized-plugin~=1.2; extra == "full"
130
- Requires-Dist: mkdocs~=1.5; extra == "full"
131
- Requires-Dist: python-box[all]~=6.0.0; extra == "full"
132
- Requires-Dist: dnspython[DOH]~=2.6.0; extra == "full"
131
+ Requires-Dist: mkdocs-macros-plugin~=1.2; extra == "full"
132
+ Requires-Dist: shtab; extra == "full"
133
133
  Requires-Dist: mkdocs-literate-nav~=0.6; extra == "full"
134
- Requires-Dist: zipp>=3.19.1; extra == "full"
135
- Requires-Dist: flake8; extra == "full"
136
- Requires-Dist: mkdocstrings[python]~=0.26; extra == "full"
137
- Requires-Dist: setuptools>=65.5.1; extra == "full"
134
+ Requires-Dist: PyYAML; extra == "full"
135
+ Requires-Dist: PyMySQL; extra == "full"
136
+ Requires-Dist: pylint; extra == "full"
137
+ Requires-Dist: domain2idna~=1.12.0; extra == "full"
138
+ Requires-Dist: inflection; extra == "full"
139
+ Requires-Dist: python-box[all]~=6.0.0; extra == "full"
138
140
  Requires-Dist: black; extra == "full"
139
- Requires-Dist: packaging; extra == "full"
140
- Requires-Dist: coverage; extra == "full"
141
- Requires-Dist: alembic; extra == "full"
141
+ Requires-Dist: dnspython[DOH]~=2.6.0; extra == "full"
142
142
  Requires-Dist: SQLAlchemy~=2.0; extra == "full"
143
- Requires-Dist: domain2idna~=1.12.0; extra == "full"
144
143
  Requires-Dist: mkdocs-git-authors-plugin~=0.9; extra == "full"
145
- Requires-Dist: mkdocs-macros-plugin~=1.2; extra == "full"
146
- Requires-Dist: PyMySQL; extra == "full"
147
- Requires-Dist: colorama; extra == "full"
144
+ Requires-Dist: mkdocs-material~=9.5; extra == "full"
145
+ Requires-Dist: flake8; extra == "full"
146
+ Requires-Dist: mkdocs~=1.5; extra == "full"
147
+ Requires-Dist: zipp>=3.19.1; extra == "full"
148
+ Requires-Dist: setuptools>=65.5.1; extra == "full"
148
149
  Requires-Dist: mkdocs-gen-files~=0.5; extra == "full"
149
- Requires-Dist: shtab; extra == "full"
150
- Requires-Dist: inflection; extra == "full"
150
+ Requires-Dist: pymdown-extensions~=10.9; extra == "full"
151
+ Requires-Dist: packaging; extra == "full"
152
+ Requires-Dist: python-dotenv; extra == "full"
151
153
  Requires-Dist: isort; extra == "full"
152
- Requires-Dist: mkdocs-section-index~=0.3; extra == "full"
153
- Requires-Dist: mkdocs-material~=9.5; extra == "full"
154
- Requires-Dist: pylint; extra == "full"
154
+ Requires-Dist: mkdocs-git-revision-date-localized-plugin~=1.2; extra == "full"
155
155
  Provides-Extra: all
156
+ Requires-Dist: alembic; extra == "all"
157
+ Requires-Dist: mkdocstrings[python]~=0.26; extra == "all"
158
+ Requires-Dist: colorama; extra == "all"
159
+ Requires-Dist: mkdocs-section-index~=0.3; extra == "all"
156
160
  Requires-Dist: requests[socks]<3; extra == "all"
157
- Requires-Dist: python-dotenv; extra == "all"
158
- Requires-Dist: pymdown-extensions~=10.9; extra == "all"
159
- Requires-Dist: PyYAML; extra == "all"
161
+ Requires-Dist: coverage; extra == "all"
160
162
  Requires-Dist: tox; extra == "all"
161
- Requires-Dist: mkdocs-git-revision-date-localized-plugin~=1.2; extra == "all"
162
- Requires-Dist: mkdocs~=1.5; extra == "all"
163
- Requires-Dist: python-box[all]~=6.0.0; extra == "all"
164
- Requires-Dist: dnspython[DOH]~=2.6.0; extra == "all"
165
- Requires-Dist: psycopg2-binary; extra == "all"
163
+ Requires-Dist: mkdocs-macros-plugin~=1.2; extra == "all"
164
+ Requires-Dist: shtab; extra == "all"
166
165
  Requires-Dist: mkdocs-literate-nav~=0.6; extra == "all"
167
- Requires-Dist: zipp>=3.19.1; extra == "all"
168
- Requires-Dist: flake8; extra == "all"
169
- Requires-Dist: mkdocstrings[python]~=0.26; extra == "all"
170
- Requires-Dist: setuptools>=65.5.1; extra == "all"
166
+ Requires-Dist: PyYAML; extra == "all"
167
+ Requires-Dist: PyMySQL; extra == "all"
168
+ Requires-Dist: pylint; extra == "all"
169
+ Requires-Dist: psycopg2-binary; extra == "all"
170
+ Requires-Dist: domain2idna~=1.12.0; extra == "all"
171
+ Requires-Dist: inflection; extra == "all"
172
+ Requires-Dist: python-box[all]~=6.0.0; extra == "all"
171
173
  Requires-Dist: black; extra == "all"
172
- Requires-Dist: packaging; extra == "all"
173
- Requires-Dist: coverage; extra == "all"
174
- Requires-Dist: alembic; extra == "all"
174
+ Requires-Dist: dnspython[DOH]~=2.6.0; extra == "all"
175
175
  Requires-Dist: SQLAlchemy~=2.0; extra == "all"
176
- Requires-Dist: domain2idna~=1.12.0; extra == "all"
177
176
  Requires-Dist: mkdocs-git-authors-plugin~=0.9; extra == "all"
178
- Requires-Dist: mkdocs-macros-plugin~=1.2; extra == "all"
179
- Requires-Dist: PyMySQL; extra == "all"
180
- Requires-Dist: colorama; extra == "all"
177
+ Requires-Dist: mkdocs-material~=9.5; extra == "all"
178
+ Requires-Dist: flake8; extra == "all"
179
+ Requires-Dist: mkdocs~=1.5; extra == "all"
180
+ Requires-Dist: zipp>=3.19.1; extra == "all"
181
+ Requires-Dist: setuptools>=65.5.1; extra == "all"
181
182
  Requires-Dist: mkdocs-gen-files~=0.5; extra == "all"
182
- Requires-Dist: shtab; extra == "all"
183
- Requires-Dist: inflection; extra == "all"
183
+ Requires-Dist: pymdown-extensions~=10.9; extra == "all"
184
+ Requires-Dist: packaging; extra == "all"
185
+ Requires-Dist: python-dotenv; extra == "all"
184
186
  Requires-Dist: isort; extra == "all"
185
- Requires-Dist: mkdocs-section-index~=0.3; extra == "all"
186
- Requires-Dist: mkdocs-material~=9.5; extra == "all"
187
- Requires-Dist: pylint; extra == "all"
187
+ Requires-Dist: mkdocs-git-revision-date-localized-plugin~=1.2; 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=zlXjBisXljB0u--UPFKoTHhyjO2S4dYCfjOLpvMe9y4,5349
7
+ PyFunceble/storage.py,sha256=LF7wCAkhFwsJrqoo2Gjhddaq0XHDBAwOgLh1v0ceYeU,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=A4qhaVqoCFcBKiLAZ7O-5RXGywquxwJEGqXIX6FYEIE,22631
151
+ PyFunceble/config/loader.py,sha256=P3bkXdqOUxygME0C0Tb-qiaYM3wGeIbWmm6D-7J4Qes,22864
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
@@ -237,7 +238,7 @@ PyFunceble/helpers/directory.py,sha256=8Zj1bipT-znsJSXuOGMqgm0-OzuEz11RD3b9EmWSy
237
238
  PyFunceble/helpers/download.py,sha256=G9Jv1Kj3qKgYcJdNPEy9k3IWZBn_OoOZGRS_i0pV_5s,11261
238
239
  PyFunceble/helpers/environment_variable.py,sha256=7PlDw6OqWwIUnpf71V-IhGSUAe9jNQrS-Z4RNC-zVts,7313
239
240
  PyFunceble/helpers/exceptions.py,sha256=DTUWqjG7gUkIpv3ppQF_S_yC2w9ZKuOSAFQ5-_YXQ7M,2760
240
- PyFunceble/helpers/file.py,sha256=FU_KzUB7Jf-LyGPDK7N8m0OH3kHQFSpY1Wt7ZKGCwP8,6575
241
+ PyFunceble/helpers/file.py,sha256=ASJ0TusZKXVIfMJZXPguEdcAWEbIGVb36SJQ_cil75Q,6787
241
242
  PyFunceble/helpers/hash.py,sha256=X52JGAh8hxF_Ooy7FqxLOOATtv5LDflBbShtAgXpLIo,5034
242
243
  PyFunceble/helpers/list.py,sha256=teTpHvarS0yj1BKzggHhTTHKB5BSRfjkt4wY3Ya2pjk,5001
243
244
  PyFunceble/helpers/merge.py,sha256=IZGhP2UgFxFl-hpsReFsSRZ9ewL-SDmTkKNH4u7bI7E,6046
@@ -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.0a13.dist-info/LICENSE,sha256=JBG6UfPnf3940AtwZB6vwAK6YH82Eo6nzMVnjGqopF0,10796
279
- PyFunceble_dev-4.3.0a13.dist-info/METADATA,sha256=Bo8sFXk056mAtQG4mxPokO3Y6ZClCqz8W4Ingr0b-4o,46666
280
- PyFunceble_dev-4.3.0a13.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
281
- PyFunceble_dev-4.3.0a13.dist-info/entry_points.txt,sha256=Ic1suwopOi_XTgiQi2ErtpY5xT3R8EFMI6B_ONDuR9E,201
282
- PyFunceble_dev-4.3.0a13.dist-info/top_level.txt,sha256=J7GBKIiNYv93m1AxLy8_gr6ExXyZbMmCVXHMQBTUq2Y,11
283
- PyFunceble_dev-4.3.0a13.dist-info/RECORD,,
279
+ PyFunceble_dev-4.3.0a15.dist-info/LICENSE,sha256=JBG6UfPnf3940AtwZB6vwAK6YH82Eo6nzMVnjGqopF0,10796
280
+ PyFunceble_dev-4.3.0a15.dist-info/METADATA,sha256=9FX8LRVLduMa19Z2UyT6QrSr8hqxZ2ivhWNAdOifC40,46666
281
+ PyFunceble_dev-4.3.0a15.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
282
+ PyFunceble_dev-4.3.0a15.dist-info/entry_points.txt,sha256=Ic1suwopOi_XTgiQi2ErtpY5xT3R8EFMI6B_ONDuR9E,201
283
+ PyFunceble_dev-4.3.0a15.dist-info/top_level.txt,sha256=J7GBKIiNYv93m1AxLy8_gr6ExXyZbMmCVXHMQBTUq2Y,11
284
+ PyFunceble_dev-4.3.0a15.dist-info/RECORD,,