webchanges 3.31.3__tar.gz → 3.31.4__tar.gz
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.
- {webchanges-3.31.3/webchanges.egg-info → webchanges-3.31.4}/PKG-INFO +9 -5
- {webchanges-3.31.3 → webchanges-3.31.4}/README.rst +5 -2
- {webchanges-3.31.3 → webchanges-3.31.4}/pyproject.toml +86 -141
- {webchanges-3.31.3 → webchanges-3.31.4}/requirements.txt +1 -1
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/__init__.py +3 -3
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/cli.py +16 -17
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/command.py +52 -72
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/config.py +1 -1
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/differs.py +210 -187
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/filters.py +64 -101
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/handler.py +15 -21
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/jobs.py +107 -132
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/mailer.py +7 -4
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/main.py +11 -9
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/reporters.py +99 -122
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/storage.py +70 -106
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/storage_minidb.py +1 -1
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/util.py +10 -18
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/worker.py +6 -10
- {webchanges-3.31.3 → webchanges-3.31.4/webchanges.egg-info}/PKG-INFO +9 -5
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges.egg-info/SOURCES.txt +1 -1
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges.egg-info/requires.txt +2 -0
- /webchanges-3.31.3/LICENSE → /webchanges-3.31.4/LICENSE.md +0 -0
- {webchanges-3.31.3 → webchanges-3.31.4}/MANIFEST.in +0 -0
- {webchanges-3.31.3 → webchanges-3.31.4}/setup.cfg +0 -0
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/__main__.py +0 -0
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/_vendored/__init__.py +0 -0
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/_vendored/headers.py +0 -0
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/_vendored/packaging_version.py +0 -0
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges/py.typed +0 -0
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges.egg-info/dependency_links.txt +0 -0
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges.egg-info/entry_points.txt +0 -0
- {webchanges-3.31.3 → webchanges-3.31.4}/webchanges.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: webchanges
|
|
3
|
-
Version: 3.31.
|
|
3
|
+
Version: 3.31.4
|
|
4
4
|
Summary: Web Changes Delivered. AI-Summarized. Totally Anonymous.
|
|
5
5
|
Author-email: Mike Borsetti <mike+webchanges@borsetti.com>
|
|
6
6
|
Maintainer-email: Mike Borsetti <mike+webchanges@borsetti.com>
|
|
@@ -92,6 +92,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
92
92
|
Classifier: Programming Language :: Python :: 3.11
|
|
93
93
|
Classifier: Programming Language :: Python :: 3.12
|
|
94
94
|
Classifier: Programming Language :: Python :: 3.13
|
|
95
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
95
96
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
96
97
|
Classifier: Topic :: Internet
|
|
97
98
|
Classifier: Topic :: Internet :: WWW/HTTP
|
|
@@ -101,7 +102,7 @@ Classifier: Topic :: Utilities
|
|
|
101
102
|
Classifier: Typing :: Typed
|
|
102
103
|
Requires-Python: >=3.10
|
|
103
104
|
Description-Content-Type: text/x-rst
|
|
104
|
-
License-File: LICENSE
|
|
105
|
+
License-File: LICENSE.md
|
|
105
106
|
Requires-Dist: colorama; sys_platform == "win32"
|
|
106
107
|
Requires-Dist: cssselect
|
|
107
108
|
Requires-Dist: h2
|
|
@@ -113,7 +114,7 @@ Requires-Dist: msgpack
|
|
|
113
114
|
Requires-Dist: platformdirs
|
|
114
115
|
Requires-Dist: pyyaml
|
|
115
116
|
Requires-Dist: tzdata; sys_platform == "win32"
|
|
116
|
-
Requires-Dist: zstandard
|
|
117
|
+
Requires-Dist: zstandard; python_version < "3.14"
|
|
117
118
|
Provides-Extra: use-browser
|
|
118
119
|
Requires-Dist: playwright; extra == "use-browser"
|
|
119
120
|
Requires-Dist: psutil; extra == "use-browser"
|
|
@@ -266,7 +267,7 @@ Schedule
|
|
|
266
267
|
|
|
267
268
|
Code
|
|
268
269
|
====
|
|
269
|
-
|coveralls| |snyk| |issues| |code_style|
|
|
270
|
+
|coveralls| |snyk| |issues| |code_style| |OpenSSF_Scorecard|
|
|
270
271
|
|
|
271
272
|
The code, issues tracker, and discussions are hosted on `GitHub <https://github.com/mborsetti/webchanges>`__.
|
|
272
273
|
|
|
@@ -285,7 +286,7 @@ License
|
|
|
285
286
|
=======
|
|
286
287
|
|license|
|
|
287
288
|
|
|
288
|
-
See the `complete licenses <https://raw.githubusercontent.com/mborsetti/webchanges/refs/heads/main/LICENSE>`__ (released
|
|
289
|
+
See the `complete licenses <https://raw.githubusercontent.com/mborsetti/webchanges/refs/heads/main/LICENSE.md>`__ (released
|
|
289
290
|
under the `MIT License <https://opensource.org/licenses/MIT>`__ but redistributing modified source code, dated 30
|
|
290
291
|
July 2020, from `urlwatch 2.21 <https://github.com/thp/urlwatch/tree/346b25914b0418342ffe2fb0529bed702fddc01f>`__
|
|
291
292
|
licensed under a `BSD 3-Clause License
|
|
@@ -346,3 +347,6 @@ configuration files), see `here <https://webchanges.readthedocs.io/en/stable/upg
|
|
|
346
347
|
.. |snyk| image:: https://snyk.io/advisor/python/holidays/badge.svg
|
|
347
348
|
:target: https://snyk.io/advisor/python/holidays
|
|
348
349
|
:alt: Snyk Package Health Score
|
|
350
|
+
.. |OpenSSF_Scorecard| image:: https://api.scorecard.dev/projects/github.com/mborsetti/webchanges/badge
|
|
351
|
+
:target: https://scorecard.dev/viewer/?uri=github.com/mborsetti/webchanges
|
|
352
|
+
:alt: OpenSSF Scoreard
|
|
@@ -100,7 +100,7 @@ Schedule
|
|
|
100
100
|
|
|
101
101
|
Code
|
|
102
102
|
====
|
|
103
|
-
|coveralls| |snyk| |issues| |code_style|
|
|
103
|
+
|coveralls| |snyk| |issues| |code_style| |OpenSSF_Scorecard|
|
|
104
104
|
|
|
105
105
|
The code, issues tracker, and discussions are hosted on `GitHub <https://github.com/mborsetti/webchanges>`__.
|
|
106
106
|
|
|
@@ -119,7 +119,7 @@ License
|
|
|
119
119
|
=======
|
|
120
120
|
|license|
|
|
121
121
|
|
|
122
|
-
See the `complete licenses <https://raw.githubusercontent.com/mborsetti/webchanges/refs/heads/main/LICENSE>`__ (released
|
|
122
|
+
See the `complete licenses <https://raw.githubusercontent.com/mborsetti/webchanges/refs/heads/main/LICENSE.md>`__ (released
|
|
123
123
|
under the `MIT License <https://opensource.org/licenses/MIT>`__ but redistributing modified source code, dated 30
|
|
124
124
|
July 2020, from `urlwatch 2.21 <https://github.com/thp/urlwatch/tree/346b25914b0418342ffe2fb0529bed702fddc01f>`__
|
|
125
125
|
licensed under a `BSD 3-Clause License
|
|
@@ -180,3 +180,6 @@ configuration files), see `here <https://webchanges.readthedocs.io/en/stable/upg
|
|
|
180
180
|
.. |snyk| image:: https://snyk.io/advisor/python/holidays/badge.svg
|
|
181
181
|
:target: https://snyk.io/advisor/python/holidays
|
|
182
182
|
:alt: Snyk Package Health Score
|
|
183
|
+
.. |OpenSSF_Scorecard| image:: https://api.scorecard.dev/projects/github.com/mborsetti/webchanges/badge
|
|
184
|
+
:target: https://scorecard.dev/viewer/?uri=github.com/mborsetti/webchanges
|
|
185
|
+
:alt: OpenSSF Scoreard
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
[build-system]
|
|
8
8
|
# Minimum requirements for the build system to execute.
|
|
9
|
-
requires = ['setuptools']
|
|
9
|
+
requires = ['setuptools'] # PEP 508 specifications.
|
|
10
10
|
# Setuptools specification
|
|
11
11
|
build-backend = "setuptools.build_meta"
|
|
12
12
|
|
|
@@ -17,12 +17,10 @@ name = 'webchanges'
|
|
|
17
17
|
description = 'Web Changes Delivered. AI-Summarized. Totally Anonymous.'
|
|
18
18
|
readme = { file = 'README.rst', content-type = 'text/x-rst' }
|
|
19
19
|
requires-python = '>=3.10'
|
|
20
|
-
license = {file = 'LICENSE'}
|
|
21
|
-
authors = [
|
|
22
|
-
{name = 'Mike Borsetti', email = 'mike+webchanges@borsetti.com'},
|
|
23
|
-
]
|
|
20
|
+
license = { file = 'LICENSE.md' }
|
|
21
|
+
authors = [{ name = 'Mike Borsetti', email = 'mike+webchanges@borsetti.com' }]
|
|
24
22
|
maintainers = [
|
|
25
|
-
{name = 'Mike Borsetti', email = 'mike+webchanges@borsetti.com'},
|
|
23
|
+
{ name = 'Mike Borsetti', email = 'mike+webchanges@borsetti.com' },
|
|
26
24
|
]
|
|
27
25
|
keywords = ['webmonitoring', 'monitoring']
|
|
28
26
|
classifiers = [
|
|
@@ -42,6 +40,7 @@ classifiers = [
|
|
|
42
40
|
'Programming Language :: Python :: 3.11',
|
|
43
41
|
'Programming Language :: Python :: 3.12',
|
|
44
42
|
'Programming Language :: Python :: 3.13',
|
|
43
|
+
'Programming Language :: Python :: 3.14',
|
|
45
44
|
'Programming Language :: Python :: Implementation :: CPython',
|
|
46
45
|
'Topic :: Internet',
|
|
47
46
|
'Topic :: Internet :: WWW/HTTP',
|
|
@@ -90,56 +89,27 @@ redis = ['redis']
|
|
|
90
89
|
requests = ['requests']
|
|
91
90
|
safe_password = ['keyring']
|
|
92
91
|
all = [
|
|
93
|
-
'webchanges[use_browser,beautify,bs4,html5lib,ical2text,jq,ocr,pdf2text,pypdf_crypto,deepdiff_xml,imagediff,matrix,pushbullet,pushover,xmpp,redis,requests,safe_password]'
|
|
92
|
+
'webchanges[use_browser,beautify,bs4,html5lib,ical2text,jq,ocr,pdf2text,pypdf_crypto,deepdiff_xml,imagediff,matrix,pushbullet,pushover,xmpp,redis,requests,safe_password]',
|
|
94
93
|
]
|
|
95
94
|
|
|
96
95
|
|
|
97
96
|
# -------------------------- setuptools --------------------------
|
|
97
|
+
[tool.setuptools]
|
|
98
98
|
# Called by build
|
|
99
99
|
# See https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html
|
|
100
|
-
|
|
101
|
-
#
|
|
100
|
+
|
|
101
|
+
# Explicit package listing is required for building in tox -e new-install
|
|
102
102
|
# https://setuptools.pypa.io/en/latest/userguide/package_discovery.html
|
|
103
103
|
packages = ['webchanges', 'webchanges._vendored']
|
|
104
104
|
|
|
105
105
|
[tool.setuptools.dynamic]
|
|
106
|
-
version = {attr = 'webchanges.__version__'}
|
|
107
|
-
dependencies = {file = 'requirements.txt'}
|
|
106
|
+
version = { attr = 'webchanges.__version__' }
|
|
107
|
+
dependencies = { file = 'requirements.txt' }
|
|
108
108
|
|
|
109
109
|
[tool.setuptools.package-data]
|
|
110
110
|
'webchanges' = ['py.typed']
|
|
111
111
|
|
|
112
112
|
|
|
113
|
-
# -------------------------- bandit --------------------------
|
|
114
|
-
[tool.bandit]
|
|
115
|
-
# Find common security issues in Python code.
|
|
116
|
-
# Runs as part of pre-commit.
|
|
117
|
-
# Config file documentation at https://bandit.readthedocs.io/en/latest/config.html
|
|
118
|
-
|
|
119
|
-
targets = ['webchanges', 'tests']
|
|
120
|
-
skips = [
|
|
121
|
-
'B101', # Use of assert detected.
|
|
122
|
-
'B404', # Consider possible security implications associated with subprocess module.
|
|
123
|
-
'B602', # subprocess call with shell=True identified, security issue.
|
|
124
|
-
'B603' # subprocess call - check for execution of untrusted input.
|
|
125
|
-
]
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
# -------------------------- black --------------------------
|
|
129
|
-
[tool.black]
|
|
130
|
-
# Uncompromising code formatting
|
|
131
|
-
# Runs as part of pre-commit
|
|
132
|
-
# Config file documentation
|
|
133
|
-
# https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-via-a-file
|
|
134
|
-
|
|
135
|
-
# What's in here overrides the command-line options shown by running $ black --help.
|
|
136
|
-
line-length = 120
|
|
137
|
-
target-version = ['py310']
|
|
138
|
-
skip-string-normalization = true
|
|
139
|
-
extend-exclude = '/(\.idea|\.pytest_cache|\__pycache__|\venv.*|\webchanges.egg-info)/'
|
|
140
|
-
color = true
|
|
141
|
-
|
|
142
|
-
|
|
143
113
|
# -------------------------- coverage --------------------------
|
|
144
114
|
[tool.coverage.run]
|
|
145
115
|
# Runs in Github Actions (see .github/workflows/ci-cd.yaml) and in tox (see tox.ini).
|
|
@@ -193,50 +163,13 @@ exclude_lines = [
|
|
|
193
163
|
'except ImportError:',
|
|
194
164
|
|
|
195
165
|
# Don't cover IDE code:
|
|
196
|
-
'if TYPE_CHECKING:'
|
|
166
|
+
'if TYPE_CHECKING:',
|
|
197
167
|
]
|
|
198
168
|
# Exclude entire files if they have a custom # pragma: exclude file remark
|
|
199
169
|
# exclude_also = '(?s)\A.*# pragma: exclude file.*\Z'
|
|
200
170
|
# ignore_errors = true
|
|
201
171
|
|
|
202
172
|
|
|
203
|
-
# -------------------------- isort --------------------------
|
|
204
|
-
[tool.isort]
|
|
205
|
-
# isort your imports, so you don't have to.
|
|
206
|
-
# Runs as part of pre-commit.
|
|
207
|
-
# Config file documentation https://pycqa.github.io/isort/docs/configuration/options.html
|
|
208
|
-
|
|
209
|
-
profile = 'black'
|
|
210
|
-
# multi_line_output = 3
|
|
211
|
-
# use_parentheses = True
|
|
212
|
-
# include_trailing_comma = True
|
|
213
|
-
# force_grid_wrap = 0
|
|
214
|
-
# ensure_newline_before_comments = True
|
|
215
|
-
line_length = 120
|
|
216
|
-
|
|
217
|
-
# Treat project as a git repository and ignore files listed in .gitignore.
|
|
218
|
-
skip_gitignore = true
|
|
219
|
-
|
|
220
|
-
# Force isort to recognize a module as being part of the current python project.
|
|
221
|
-
known_first_party = 'webchanges'
|
|
222
|
-
|
|
223
|
-
# Force isort to recognize a module as being a local folder.
|
|
224
|
-
# Generally, this is reserved for relative imports (from . import module).
|
|
225
|
-
known_local_folder = 'webchanges'
|
|
226
|
-
|
|
227
|
-
# Force all imports to be sorted alphabetically within a section.
|
|
228
|
-
force_alphabetical_sort_within_sections = true
|
|
229
|
-
|
|
230
|
-
# Automatically create section groups by the top-level package they come from.
|
|
231
|
-
group_by_package = true
|
|
232
|
-
|
|
233
|
-
# Remove redundant aliases from imports, such as import os as os.
|
|
234
|
-
remove_redundant_aliases = true
|
|
235
|
-
|
|
236
|
-
# Use color in terminal output.
|
|
237
|
-
color_output = true
|
|
238
|
-
|
|
239
|
-
|
|
240
173
|
# -------------------------- mypy --------------------------
|
|
241
174
|
[tool.mypy]
|
|
242
175
|
# Static Typing for Python
|
|
@@ -244,7 +177,7 @@ color_output = true
|
|
|
244
177
|
# Config file documentation at https://mypy.readthedocs.io/en/stable/config_file.html
|
|
245
178
|
|
|
246
179
|
# Disables import discovery of namespace packages (see PEP 420)
|
|
247
|
-
namespace_packages =
|
|
180
|
+
namespace_packages = true
|
|
248
181
|
|
|
249
182
|
# Specifies the Python version used to parse and check the target program.
|
|
250
183
|
# python_version = 3.12
|
|
@@ -253,7 +186,7 @@ namespace_packages = false
|
|
|
253
186
|
ignore_missing_imports = true
|
|
254
187
|
|
|
255
188
|
# Disallows calling functions without type annotations from functions with type annotations.
|
|
256
|
-
disallow_untyped_calls =
|
|
189
|
+
disallow_untyped_calls = false
|
|
257
190
|
|
|
258
191
|
# Disallows defining functions without type annotations or with incomplete type annotations.
|
|
259
192
|
disallow_untyped_defs = true
|
|
@@ -310,13 +243,9 @@ report_level = 'WARNING'
|
|
|
310
243
|
log_auto_indent = true
|
|
311
244
|
# Enable log display during test run (aka "live logging" https://docs.pytest.org/en/stable/logging.html#live-logs)
|
|
312
245
|
log_cli = true
|
|
313
|
-
minversion = '8.
|
|
246
|
+
minversion = '8.4.1'
|
|
314
247
|
testpaths = ['tests']
|
|
315
248
|
|
|
316
|
-
# the below is for pytest-asyncio (used to be required due to Playwright)
|
|
317
|
-
# asyncio_mode = 'auto'
|
|
318
|
-
# asyncio_default_fixture_loop_scope = 'function'
|
|
319
|
-
|
|
320
249
|
# Adds pytest-cov functionality (see https://pytest-cov.readthedocs.io/en/latest/config.html)
|
|
321
250
|
# Note: --cov moved to .github/workflows/ci-cd.yaml and tox.ini due to interference with PyCharm breakpoints (see
|
|
322
251
|
# https://github.com/pytest-dev/pytest-cov/issues/131) and to enable running tox --parallel
|
|
@@ -326,37 +255,10 @@ testpaths = ['tests']
|
|
|
326
255
|
|
|
327
256
|
# -------------------------- ruff --------------------------
|
|
328
257
|
[tool.ruff]
|
|
329
|
-
# Config file documentation at https://docs.astral.sh/ruff/configuration/
|
|
330
|
-
|
|
331
|
-
# Exclude a variety of commonly ignored directories.
|
|
332
|
-
exclude = [
|
|
333
|
-
".bzr",
|
|
334
|
-
".direnv",
|
|
335
|
-
".eggs",
|
|
336
|
-
".git",
|
|
337
|
-
".git-rewrite",
|
|
338
|
-
".hg",
|
|
339
|
-
".ipynb_checkpoints",
|
|
340
|
-
".mypy_cache",
|
|
341
|
-
".nox",
|
|
342
|
-
".pants.d",
|
|
343
|
-
".pyenv",
|
|
344
|
-
".pytest_cache",
|
|
345
|
-
".pytype",
|
|
346
|
-
".ruff_cache",
|
|
347
|
-
".svn",
|
|
348
|
-
".tox",
|
|
349
|
-
".venv",
|
|
350
|
-
".vscode",
|
|
351
|
-
"__pypackages__",
|
|
352
|
-
"_build",
|
|
353
|
-
"buck-out",
|
|
354
|
-
"build",
|
|
355
|
-
"dist",
|
|
356
|
-
"node_modules",
|
|
357
|
-
"site-packages",
|
|
358
|
-
"venv",
|
|
258
|
+
# Config file documentation at https://docs.astral.sh/ruff/configuration/ and https://docs.astral.sh/ruff/settings/
|
|
359
259
|
|
|
260
|
+
# File patterns to omit from formatting and linting, in addition to those specified by exclude.
|
|
261
|
+
extend-exclude = [
|
|
360
262
|
"webchanges/storage_minidb.py",
|
|
361
263
|
"webchanges/_vendored",
|
|
362
264
|
]
|
|
@@ -367,7 +269,6 @@ exclude = [
|
|
|
367
269
|
|
|
368
270
|
# Set the maximum line length.
|
|
369
271
|
line-length = 120
|
|
370
|
-
indent-width = 4
|
|
371
272
|
|
|
372
273
|
# Target Python version
|
|
373
274
|
# target-version = "py311" # Commented out to infer from [project] requires-python
|
|
@@ -376,27 +277,55 @@ indent-width = 4
|
|
|
376
277
|
# By default, Ruff enables Flake8's F rules, along with a subset of the E rules
|
|
377
278
|
# Enable rules not enabled by default, and ignore specific rules.
|
|
378
279
|
select = [
|
|
379
|
-
# flake8-
|
|
380
|
-
"
|
|
381
|
-
# flake8-
|
|
382
|
-
"
|
|
383
|
-
# flake8-
|
|
384
|
-
"
|
|
385
|
-
#
|
|
386
|
-
"
|
|
387
|
-
#
|
|
388
|
-
|
|
389
|
-
#
|
|
390
|
-
"
|
|
391
|
-
#
|
|
392
|
-
"
|
|
393
|
-
#
|
|
394
|
-
"
|
|
395
|
-
#
|
|
396
|
-
"
|
|
280
|
+
"ANN", # flake8-annotations
|
|
281
|
+
"S", # flake8-bandit
|
|
282
|
+
"BLE", # flake8-blind-except
|
|
283
|
+
"B", # flake8-bugbear
|
|
284
|
+
"A", # flake8-builtin
|
|
285
|
+
"C4", # flake8-comprehensions
|
|
286
|
+
"DTZ", # flake8-datetimez
|
|
287
|
+
# "EM", # flake8-errmsg # TODO
|
|
288
|
+
"FA", # flake8-future-annotations
|
|
289
|
+
"INT", # flake8-gettext
|
|
290
|
+
"ISC", # flake8-implicit-str-concat
|
|
291
|
+
"LOG", # flake8-logging
|
|
292
|
+
# "G", # flake8-logging-format # TODO
|
|
293
|
+
"PIE", # flake8-pie
|
|
294
|
+
"PYI", # flake8-pyi
|
|
295
|
+
"PT", # flake8-pytest-style
|
|
296
|
+
"Q", # flake8-quotes
|
|
297
|
+
"RSE", # flake8-raise
|
|
298
|
+
"RET", # flake8-return
|
|
299
|
+
"SIM", # flake8-simplify
|
|
300
|
+
"TID", # flake8-tidy-imports
|
|
301
|
+
"TD", # flake8-todos
|
|
302
|
+
"TC", # flake8-type-checking
|
|
303
|
+
# "ARG", # flake8-unused-arguments # TODO
|
|
304
|
+
"PTH", # flake8-use-pathlib
|
|
305
|
+
# "FLY", # flynt # TODO
|
|
306
|
+
"I", # isort
|
|
307
|
+
"C90", # mccabe
|
|
308
|
+
"N", # pep8-naming
|
|
309
|
+
"PERF", # Perflint
|
|
310
|
+
"E", # pycodestyle errors
|
|
311
|
+
"W", # pycodestyle warnings
|
|
312
|
+
# "DOC", # pydoclint # TODO
|
|
313
|
+
# "D", # pydocstyle # TODO
|
|
314
|
+
"F", # Pyflakes
|
|
315
|
+
# "PL", # Pylint # TODO
|
|
316
|
+
"FURB", # refurb
|
|
317
|
+
"RUF", # Ruff-specific rules
|
|
318
|
+
# "TRY", # tryceratops # TODO
|
|
397
319
|
]
|
|
320
|
+
|
|
398
321
|
ignore = [
|
|
322
|
+
"PT011", # pytest.raises({exception}) is too broad, set the match parameter or use a more specific exception
|
|
323
|
+
"PT030", # pytest.warns({warning}) is too broad, set the match parameter or use a more specific warning
|
|
399
324
|
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
|
|
325
|
+
"SIM105", # Use contextlib.suppress({exception}) instead of try-except-pass
|
|
326
|
+
"SIM115", # Use a context manager for opening files
|
|
327
|
+
"TD002", # Missing author in TODO
|
|
328
|
+
"TD003", # Missing issue link for this TODO
|
|
400
329
|
]
|
|
401
330
|
|
|
402
331
|
# Allow fix for all enabled rules (when `--fix`) is provided.
|
|
@@ -406,6 +335,28 @@ unfixable = []
|
|
|
406
335
|
# Allow unused variables when underscore-prefixed.
|
|
407
336
|
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
|
408
337
|
|
|
338
|
+
[tool.ruff.lint.flake8-annotations]
|
|
339
|
+
allow-star-arg-any = true # TODO
|
|
340
|
+
|
|
341
|
+
[tool.ruff.lint.flake8-quotes]
|
|
342
|
+
inline-quotes = "single"
|
|
343
|
+
|
|
344
|
+
[tool.ruff.lint.mccabe]
|
|
345
|
+
# Flag errors (`C901`) whenever the complexity level exceeds below.
|
|
346
|
+
max-complexity = 30
|
|
347
|
+
|
|
348
|
+
[tool.ruff.lint.per-file-ignores]
|
|
349
|
+
"tests/*" = [
|
|
350
|
+
"S101", # Use of `assert` detected
|
|
351
|
+
]
|
|
352
|
+
|
|
353
|
+
[tool.ruff.lint.pydoclint]
|
|
354
|
+
# Skip docstrings which fit on a single line.
|
|
355
|
+
ignore-one-line-docstrings = true
|
|
356
|
+
|
|
357
|
+
[tool.ruff.lint.pydocstyle]
|
|
358
|
+
convention = "google"
|
|
359
|
+
|
|
409
360
|
[tool.ruff.format]
|
|
410
361
|
# Enable the formatter, which is a drop-in replacement for Black.
|
|
411
362
|
# No extra configuration is needed for basic formatting.
|
|
@@ -438,9 +389,3 @@ docstring-code-format = true
|
|
|
438
389
|
# This only has an effect when the `docstring-code-format` setting is
|
|
439
390
|
# enabled.
|
|
440
391
|
docstring-code-line-length = "dynamic"
|
|
441
|
-
|
|
442
|
-
[tool.ruff.lint.per-file-ignores]
|
|
443
|
-
"tests/*" = [
|
|
444
|
-
# Use of `assert` detected
|
|
445
|
-
"S101"
|
|
446
|
-
]
|
|
@@ -3,7 +3,7 @@ it summarizes (including with Gen AI) what changed ('diff') and displays it and/
|
|
|
3
3
|
supported services. Can check the output of local commands as well.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
# The code below is subject to the license contained in the LICENSE file, which is part of the source code.
|
|
6
|
+
# The code below is subject to the license contained in the LICENSE.md file, which is part of the source code.
|
|
7
7
|
|
|
8
8
|
# The docstring above (__doc__) and the variables below are used in the program and for builds, including in building
|
|
9
9
|
# documentation with Sphinx.
|
|
@@ -22,7 +22,7 @@ __project_name__ = str(__package__)
|
|
|
22
22
|
# * MINOR version when you add functionality in a backwards compatible manner, and
|
|
23
23
|
# * MICRO or PATCH version when you make backwards compatible bug fixes. We no longer use '0'
|
|
24
24
|
# If unsure on increments, use pkg_resources.parse_version to parse
|
|
25
|
-
__version__ = '3.31.
|
|
25
|
+
__version__ = '3.31.4'
|
|
26
26
|
__description__ = (
|
|
27
27
|
'Check web (or command output) for changes since last run and notify.\n\nAnonymously alerts you of web changes.'
|
|
28
28
|
)
|
|
@@ -40,7 +40,7 @@ def init_data() -> dict[str, str | tuple]:
|
|
|
40
40
|
|
|
41
41
|
:returns: dict of globals()
|
|
42
42
|
"""
|
|
43
|
-
return
|
|
43
|
+
return dict(globals().items())
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
if __name__ == '__main__':
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# See config module for the command line arguments.
|
|
6
6
|
|
|
7
|
-
# The code below is subject to the license contained in the LICENSE file, which is part of the source code.
|
|
7
|
+
# The code below is subject to the license contained in the LICENSE.md file, which is part of the source code.
|
|
8
8
|
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
@@ -33,7 +33,8 @@ logger = logging.getLogger(__name__)
|
|
|
33
33
|
|
|
34
34
|
def python_version_warning() -> None:
|
|
35
35
|
"""Check if we're running on the minimum Python version supported and if so print and issue a pending deprecation
|
|
36
|
-
warning.
|
|
36
|
+
warning.
|
|
37
|
+
"""
|
|
37
38
|
if sys.version_info[0:2] == __min_python_version__:
|
|
38
39
|
current_minor_version = '.'.join(str(n) for n in sys.version_info[0:2])
|
|
39
40
|
next_minor_version = f'{__min_python_version__[0]}.{__min_python_version__[1] + 1}'
|
|
@@ -126,10 +127,9 @@ def teardown_logger(verbose: int | None = None) -> None:
|
|
|
126
127
|
|
|
127
128
|
:param verbose: the verbosity level (1 = INFO, 2 = ERROR).
|
|
128
129
|
"""
|
|
129
|
-
if verbose is not None:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
os.environ.pop('DEBUG', None)
|
|
130
|
+
if verbose is not None and verbose >= 2:
|
|
131
|
+
# https://playwright.dev/python/docs/debug#verbose-api-logs
|
|
132
|
+
os.environ.pop('DEBUG', None)
|
|
133
133
|
|
|
134
134
|
|
|
135
135
|
def _expand_glob_files(
|
|
@@ -167,7 +167,7 @@ def _expand_glob_files(
|
|
|
167
167
|
return file_list
|
|
168
168
|
|
|
169
169
|
# no directory specified (and not in current one): add default one
|
|
170
|
-
if not file.is_absolute() and
|
|
170
|
+
if not file.is_absolute() and Path(file).parent != Path.cwd():
|
|
171
171
|
file_list = list(default_path.glob(str(file)))
|
|
172
172
|
if any(f.is_file() for f in file_list):
|
|
173
173
|
return file_list
|
|
@@ -222,7 +222,7 @@ def locate_storage_file(
|
|
|
222
222
|
return file
|
|
223
223
|
|
|
224
224
|
# no directory specified (and not in current one): add default one
|
|
225
|
-
if file.parent == PurePath(
|
|
225
|
+
if file.parent == PurePath():
|
|
226
226
|
new_file = default_path.joinpath(file)
|
|
227
227
|
if new_file.is_file():
|
|
228
228
|
return new_file
|
|
@@ -307,7 +307,8 @@ def load_hooks(hooks_file: Path, is_default: bool = False) -> None:
|
|
|
307
307
|
|
|
308
308
|
def handle_unitialized_actions(urlwatch_config: CommandConfig) -> None:
|
|
309
309
|
"""Handles CLI actions that do not require all classes etc. to be initialized (and command.py loaded). For speed
|
|
310
|
-
purposes.
|
|
310
|
+
purposes.
|
|
311
|
+
"""
|
|
311
312
|
|
|
312
313
|
def _exit(arg: str | int | None) -> None:
|
|
313
314
|
logger.info(f'Exiting with exit code {arg}')
|
|
@@ -323,16 +324,14 @@ def handle_unitialized_actions(urlwatch_config: CommandConfig) -> None:
|
|
|
323
324
|
f"'pip install -U {__project_name__}'."
|
|
324
325
|
)
|
|
325
326
|
return 0
|
|
326
|
-
|
|
327
|
+
if new_release == '':
|
|
327
328
|
print(' You are running the latest release.')
|
|
328
329
|
return 0
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
return 1
|
|
330
|
+
print(' Error contacting PyPI to determine the latest release.')
|
|
331
|
+
return 1
|
|
332
332
|
|
|
333
333
|
def playwright_install_chrome() -> int: # pragma: no cover
|
|
334
|
-
"""
|
|
335
|
-
Replicates playwright.___main__.main() function, which is called by the playwright executable, in order to
|
|
334
|
+
"""Replicates playwright.___main__.main() function, which is called by the playwright executable, in order to
|
|
336
335
|
install the browser executable.
|
|
337
336
|
|
|
338
337
|
:return: Playwright's executable return code.
|
|
@@ -347,7 +346,7 @@ def handle_unitialized_actions(urlwatch_config: CommandConfig) -> None:
|
|
|
347
346
|
env['PW_CLI_TARGET_LANG'] = 'python'
|
|
348
347
|
cmd = [str(driver_executable), 'install', 'chrome']
|
|
349
348
|
logger.info(f'Running playwright CLI: {" ".join(cmd)}')
|
|
350
|
-
completed_process = subprocess.run(cmd, env=env, capture_output=True, text=True) # noqa: S603
|
|
349
|
+
completed_process = subprocess.run(cmd, check=False, env=env, capture_output=True, text=True) # noqa: S603
|
|
351
350
|
if completed_process.returncode:
|
|
352
351
|
print(completed_process.stderr)
|
|
353
352
|
return completed_process.returncode
|
|
@@ -478,7 +477,7 @@ def main() -> None: # pragma: no cover
|
|
|
478
477
|
max_snapshots = command_config.max_snapshots or config_storage.config.get('database', {}).get('max_snapshots') or 4
|
|
479
478
|
if database_engine == 'sqlite3':
|
|
480
479
|
ssdb_storage: SsdbStorage = SsdbSQLite3Storage(command_config.ssdb_file, max_snapshots) # storage.py
|
|
481
|
-
elif any(str(command_config.ssdb_file).startswith(prefix) for prefix in
|
|
480
|
+
elif any(str(command_config.ssdb_file).startswith(prefix) for prefix in ('redis://', 'rediss://')):
|
|
482
481
|
ssdb_storage = SsdbRedisStorage(command_config.ssdb_file) # storage.py
|
|
483
482
|
elif database_engine.startswith('redis'):
|
|
484
483
|
ssdb_storage = SsdbRedisStorage(database_engine)
|