youpdated 0.1.0__tar.gz → 0.1.1__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.
- {youpdated-0.1.0 → youpdated-0.1.1}/CHANGELOG.md +21 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/PKG-INFO +1 -1
- {youpdated-0.1.0 → youpdated-0.1.1}/pyproject.toml +1 -1
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/__init__.py +1 -1
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/http.py +5 -2
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/sources/browser.py +17 -10
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated.egg-info/PKG-INFO +1 -1
- {youpdated-0.1.0 → youpdated-0.1.1}/ADDING_SOURCES.md +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/CONTRIBUTING.md +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/LICENSE +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/MANIFEST.in +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/README.md +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/SECURITY.md +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/setup.cfg +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/__main__.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/cleanup.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/cli.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/config.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/models.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/py.typed +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/registry.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/render/__init__.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/render/json_out.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/render/rss_out.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/render/terminal.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/runner.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/sources/__init__.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/sources/base.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/sources/feed.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/sources/generic.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/sources/github.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/sources/itch.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/sources/npm.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/sources/steam.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/sources/youtube.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated/state.py +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated.egg-info/SOURCES.txt +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated.egg-info/dependency_links.txt +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated.egg-info/entry_points.txt +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated.egg-info/requires.txt +0 -0
- {youpdated-0.1.0 → youpdated-0.1.1}/youpdated.egg-info/top_level.txt +0 -0
|
@@ -4,6 +4,26 @@ All notable changes to this project are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
|
|
5
5
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.1.1] — 2026-08-18
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **`browser` / Brave: a server error killed the target instead of falling back.** The Brave source
|
|
12
|
+
reads the GitHub REST API and keeps the `.atom` feed as a fallback, but only a 403 or 429 reached
|
|
13
|
+
it. A 5xx: a timeout, or a DNS failure, was retried, then raised, and the whole target was
|
|
14
|
+
reported as failed. Observed against `api.github.com` returning 504. Any failure the HTTP client
|
|
15
|
+
gives up on now falls back to the atom feed; a genuine outage of *both* still reports an error.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Retry backoff is configurable on the HTTP client (`retry_backoff`), so the test suite no longer spends real seconds exercising retry paths. The suite went from ~4.9s to ~0.4s.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- A `release` workflow that publishes to PyPI via trusted publishing when a GitHub Release is
|
|
24
|
+
published, gated on the full 13-job test matrix and on the tag matching the version in
|
|
25
|
+
`pyproject.toml`.
|
|
26
|
+
|
|
7
27
|
## [0.1.0] — 2026-08-18
|
|
8
28
|
|
|
9
29
|
First release.
|
|
@@ -33,4 +53,5 @@ First release.
|
|
|
33
53
|
- Firefox publishes current versions, so it reports one item per channel.
|
|
34
54
|
- Edge exposes release notes only for the stable and beta channels. (But like, it's Edge, why do you want to know when it updates?)
|
|
35
55
|
|
|
56
|
+
[0.1.1]: https://github.com/Void1-1/youpdated/releases/tag/v0.1.1
|
|
36
57
|
[0.1.0]: https://github.com/Void1-1/youpdated/releases/tag/v0.1.0
|
|
@@ -73,6 +73,9 @@ class Client:
|
|
|
73
73
|
self.verbose = verbose
|
|
74
74
|
# Conditional GETs save requests, but a 304 doesn't return items
|
|
75
75
|
self.use_conditional = use_conditional
|
|
76
|
+
#: Seconds multiplied by the attempt number between retries. Tests set
|
|
77
|
+
#: this to 0 so a retry path costs no wall-clock time.
|
|
78
|
+
self.retry_backoff = 1.5
|
|
76
79
|
self._log = logger
|
|
77
80
|
self.requested_urls: list[str] = []
|
|
78
81
|
|
|
@@ -176,7 +179,7 @@ class Client:
|
|
|
176
179
|
last_error = exc
|
|
177
180
|
self.note(f"GET {url} -> {type(exc).__name__}: {exc}")
|
|
178
181
|
if attempt < retries:
|
|
179
|
-
time.sleep(
|
|
182
|
+
time.sleep(self.retry_backoff * (attempt + 1))
|
|
180
183
|
continue
|
|
181
184
|
raise FetchError(f"{url}: {type(exc).__name__}: {exc}") from exc
|
|
182
185
|
|
|
@@ -208,7 +211,7 @@ class Client:
|
|
|
208
211
|
)
|
|
209
212
|
|
|
210
213
|
if response.status_code in RETRY_STATUSES and attempt < retries:
|
|
211
|
-
time.sleep(
|
|
214
|
+
time.sleep(self.retry_backoff * (attempt + 1))
|
|
212
215
|
continue
|
|
213
216
|
|
|
214
217
|
raise FetchError(f"{url}: HTTP {response.status_code}")
|
|
@@ -20,7 +20,7 @@ import sys
|
|
|
20
20
|
from datetime import datetime, timezone
|
|
21
21
|
from typing import Any, ClassVar, Iterable
|
|
22
22
|
|
|
23
|
-
from ..http import Client
|
|
23
|
+
from ..http import Client, FetchError
|
|
24
24
|
from ..models import Target, Update
|
|
25
25
|
from ..registry import register
|
|
26
26
|
from .base import ConfigEntryError, entry_fields, require
|
|
@@ -203,18 +203,25 @@ class BrowserSource:
|
|
|
203
203
|
channel = target.params["channel"]
|
|
204
204
|
prefix = BRAVE_CHANNELS[channel].lower()
|
|
205
205
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
206
|
+
try:
|
|
207
|
+
fetched = client.get(
|
|
208
|
+
"https://api.github.com/repos/brave/brave-browser/releases?per_page=100",
|
|
209
|
+
conditional=True,
|
|
210
|
+
headers={"Accept": "application/vnd.github+json"},
|
|
211
|
+
soft_statuses=(403, 429),
|
|
212
|
+
)
|
|
213
|
+
except FetchError as exc:
|
|
214
|
+
client.note(f"brave: GitHub API failed ({exc}), falling back to the atom feed")
|
|
215
|
+
return self._brave_from_atom(target, client, channel, prefix)
|
|
216
|
+
|
|
214
217
|
if fetched is None:
|
|
215
218
|
return [] # 304: nothing changed
|
|
219
|
+
if fetched.status == 200:
|
|
220
|
+
return self._brave_from_api(target, fetched.json(), channel, prefix)
|
|
216
221
|
|
|
217
|
-
client.note(
|
|
222
|
+
client.note(
|
|
223
|
+
f"brave: GitHub API returned {fetched.status}, falling back to the atom feed"
|
|
224
|
+
)
|
|
218
225
|
return self._brave_from_atom(target, client, channel, prefix)
|
|
219
226
|
|
|
220
227
|
def _brave_from_api(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|