termux-sync 1.2.1__tar.gz → 1.2.2__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.
@@ -18,6 +18,14 @@ Version numbers follow [Semantic Versioning](https://semver.org/).
18
18
 
19
19
  ---
20
20
 
21
+ ## [1.2.2] - 2026-07-11
22
+
23
+ ### Fixed
24
+
25
+ - **`restore` — stuck retrying and failing with `HTTP Error 404: Not Found` when the GitHub backend points to a private repo** — `GitHubStorage.download()` and the `manifest.json` lookup in `list_backups()` downloaded release assets via `asset["browser_download_url"]` using the standard `Accept: application/vnd.github.v3+json` header. That URL only resolves without further authentication for public repos; for private repos GitHub returns 404 even with a valid token, since the download must go through the `/repos/{repo}/releases/assets/{id}` API endpoint with `Accept: application/octet-stream`. Added `GitHubStorage._asset_headers()` and `_asset_url()` and switched both call sites to use them, so restoring from a private-repo backend now downloads correctly instead of exhausting all 8 retries.
26
+
27
+ ---
28
+
21
29
  ## [1.2.1] - 2026-05-22
22
30
 
23
31
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: termux-sync
3
- Version: 1.2.1
3
+ Version: 1.2.2
4
4
  Summary: Backup and restore your entire Termux environment across devices
5
5
  Project-URL: Homepage, https://github.com/djunekz/termux-sync
6
6
  Project-URL: Repository, https://github.com/djunekz/termux-sync
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "termux-sync"
7
- version = "1.2.1"
7
+ version = "1.2.2"
8
8
  description = "Backup and restore your entire Termux environment across devices"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -469,6 +469,15 @@ class GitHubStorage:
469
469
  "Accept": "application/vnd.github.v3+json",
470
470
  }
471
471
 
472
+ def _asset_headers(self) -> dict:
473
+ return {
474
+ "Authorization": f"token {self.token}",
475
+ "Accept": "application/octet-stream",
476
+ }
477
+
478
+ def _asset_url(self, asset_id: int) -> str:
479
+ return f"{self.API}/repos/{self.repo}/releases/assets/{asset_id}"
480
+
472
481
  def _api(self, method: str, endpoint: str, **kwargs):
473
482
  import urllib.request, urllib.error
474
483
  url = f"{self.API}{endpoint}"
@@ -633,8 +642,8 @@ class GitHubStorage:
633
642
  try:
634
643
  import urllib.request
635
644
  req = urllib.request.Request(
636
- asset["browser_download_url"],
637
- headers=self._headers()
645
+ self._asset_url(asset["id"]),
646
+ headers=self._asset_headers()
638
647
  )
639
648
  with urllib.request.urlopen(req, timeout=30) as r:
640
649
  manifest = json.loads(r.read())
@@ -659,14 +668,14 @@ class GitHubStorage:
659
668
  dl_task = progress.add_task("[cyan]Downloading from GitHub...", total=len(assets))
660
669
 
661
670
  for asset in assets:
662
- url = asset["browser_download_url"]
671
+ url = self._asset_url(asset["id"])
663
672
  out = dest / asset["name"]
664
673
  size = asset.get("size", 0)
665
674
  f_task = progress.add_task(f"[cyan]{asset['name']}...", total=max(size, 1))
666
675
  last_err = None
667
676
  for attempt in range(8):
668
677
  try:
669
- req = urllib.request.Request(url, headers=self._headers())
678
+ req = urllib.request.Request(url, headers=self._asset_headers())
670
679
  with urllib.request.urlopen(req, timeout=120) as r:
671
680
  data = r.read()
672
681
  out.write_bytes(data)
File without changes
File without changes