github-backup 0.51.3__py3-none-any.whl → 0.52.0__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.
- github_backup/__init__.py +1 -1
- github_backup/github_backup.py +58 -29
- {github_backup-0.51.3.dist-info → github_backup-0.52.0.dist-info}/METADATA +1 -1
- github_backup-0.52.0.dist-info/RECORD +9 -0
- github_backup-0.51.3.dist-info/RECORD +0 -9
- {github_backup-0.51.3.data → github_backup-0.52.0.data}/scripts/github-backup +0 -0
- {github_backup-0.51.3.dist-info → github_backup-0.52.0.dist-info}/WHEEL +0 -0
- {github_backup-0.51.3.dist-info → github_backup-0.52.0.dist-info}/licenses/LICENSE.txt +0 -0
- {github_backup-0.51.3.dist-info → github_backup-0.52.0.dist-info}/top_level.txt +0 -0
- {github_backup-0.51.3.dist-info → github_backup-0.52.0.dist-info}/zip-safe +0 -0
github_backup/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "0.52.0"
|
github_backup/github_backup.py
CHANGED
|
@@ -37,6 +37,15 @@ FNULL = open(os.devnull, "w")
|
|
|
37
37
|
FILE_URI_PREFIX = "file://"
|
|
38
38
|
logger = logging.getLogger(__name__)
|
|
39
39
|
|
|
40
|
+
|
|
41
|
+
class RepositoryUnavailableError(Exception):
|
|
42
|
+
"""Raised when a repository is unavailable due to legal reasons (e.g., DMCA takedown)."""
|
|
43
|
+
|
|
44
|
+
def __init__(self, message, dmca_url=None):
|
|
45
|
+
super().__init__(message)
|
|
46
|
+
self.dmca_url = dmca_url
|
|
47
|
+
|
|
48
|
+
|
|
40
49
|
# Setup SSL context with fallback chain
|
|
41
50
|
https_ctx = ssl.create_default_context()
|
|
42
51
|
if https_ctx.get_ca_certs():
|
|
@@ -612,6 +621,19 @@ def retrieve_data_gen(args, template, query_args=None, single_request=False):
|
|
|
612
621
|
|
|
613
622
|
status_code = int(r.getcode())
|
|
614
623
|
|
|
624
|
+
# Handle DMCA takedown (HTTP 451) - raise exception to skip entire repository
|
|
625
|
+
if status_code == 451:
|
|
626
|
+
dmca_url = None
|
|
627
|
+
try:
|
|
628
|
+
response_data = json.loads(r.read().decode("utf-8"))
|
|
629
|
+
dmca_url = response_data.get("block", {}).get("html_url")
|
|
630
|
+
except Exception:
|
|
631
|
+
pass
|
|
632
|
+
raise RepositoryUnavailableError(
|
|
633
|
+
"Repository unavailable due to legal reasons (HTTP 451)",
|
|
634
|
+
dmca_url=dmca_url
|
|
635
|
+
)
|
|
636
|
+
|
|
615
637
|
# Check if we got correct data
|
|
616
638
|
try:
|
|
617
639
|
response = json.loads(r.read().decode("utf-8"))
|
|
@@ -1668,40 +1690,47 @@ def backup_repositories(args, output_directory, repositories):
|
|
|
1668
1690
|
|
|
1669
1691
|
continue # don't try to back anything else for a gist; it doesn't exist
|
|
1670
1692
|
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1693
|
+
try:
|
|
1694
|
+
download_wiki = args.include_wiki or args.include_everything
|
|
1695
|
+
if repository["has_wiki"] and download_wiki:
|
|
1696
|
+
fetch_repository(
|
|
1697
|
+
repository["name"],
|
|
1698
|
+
repo_url.replace(".git", ".wiki.git"),
|
|
1699
|
+
os.path.join(repo_cwd, "wiki"),
|
|
1700
|
+
skip_existing=args.skip_existing,
|
|
1701
|
+
bare_clone=args.bare_clone,
|
|
1702
|
+
lfs_clone=args.lfs_clone,
|
|
1703
|
+
no_prune=args.no_prune,
|
|
1704
|
+
)
|
|
1705
|
+
if args.include_issues or args.include_everything:
|
|
1706
|
+
backup_issues(args, repo_cwd, repository, repos_template)
|
|
1684
1707
|
|
|
1685
|
-
|
|
1686
|
-
|
|
1708
|
+
if args.include_pulls or args.include_everything:
|
|
1709
|
+
backup_pulls(args, repo_cwd, repository, repos_template)
|
|
1687
1710
|
|
|
1688
|
-
|
|
1689
|
-
|
|
1711
|
+
if args.include_milestones or args.include_everything:
|
|
1712
|
+
backup_milestones(args, repo_cwd, repository, repos_template)
|
|
1690
1713
|
|
|
1691
|
-
|
|
1692
|
-
|
|
1714
|
+
if args.include_labels or args.include_everything:
|
|
1715
|
+
backup_labels(args, repo_cwd, repository, repos_template)
|
|
1693
1716
|
|
|
1694
|
-
|
|
1695
|
-
|
|
1717
|
+
if args.include_hooks or args.include_everything:
|
|
1718
|
+
backup_hooks(args, repo_cwd, repository, repos_template)
|
|
1696
1719
|
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1720
|
+
if args.include_releases or args.include_everything:
|
|
1721
|
+
backup_releases(
|
|
1722
|
+
args,
|
|
1723
|
+
repo_cwd,
|
|
1724
|
+
repository,
|
|
1725
|
+
repos_template,
|
|
1726
|
+
include_assets=args.include_assets or args.include_everything,
|
|
1727
|
+
)
|
|
1728
|
+
except RepositoryUnavailableError as e:
|
|
1729
|
+
logger.warning(f"Repository {repository['full_name']} is unavailable (HTTP 451)")
|
|
1730
|
+
if e.dmca_url:
|
|
1731
|
+
logger.warning(f"DMCA notice: {e.dmca_url}")
|
|
1732
|
+
logger.info(f"Skipping remaining resources for {repository['full_name']}")
|
|
1733
|
+
continue
|
|
1705
1734
|
|
|
1706
1735
|
if args.incremental:
|
|
1707
1736
|
if last_update == "0000-00-00T00:00:00Z":
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
github_backup/__init__.py,sha256=uXy9jtvBCb6cwZyNng8d7tehPtkx2Xcdr7Lm3SEzEF8,23
|
|
2
|
+
github_backup/github_backup.py,sha256=eo8P69vIgeP_ntzY4DdGrzFnEKPIoqBrgBX3Dw_2lIo,77487
|
|
3
|
+
github_backup-0.52.0.data/scripts/github-backup,sha256=I79TNA67phytRmI9nm_LlD9h2zauXFOsOn9tYyAy9pU,1546
|
|
4
|
+
github_backup-0.52.0.dist-info/licenses/LICENSE.txt,sha256=ML-pLyn1qtAKo_DHMcQ8-p7k3f8cp-IR-mf5B49R2rk,1085
|
|
5
|
+
github_backup-0.52.0.dist-info/METADATA,sha256=92rNj52N87cGNzBGRJYCyaotJIEgZ5ZgZ-DUugpuvlI,21544
|
|
6
|
+
github_backup-0.52.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
+
github_backup-0.52.0.dist-info/top_level.txt,sha256=Za6fKRAlxZ0b3ZBH_osPqklLe14LetdNAkvAQANT2AA,14
|
|
8
|
+
github_backup-0.52.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
9
|
+
github_backup-0.52.0.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
github_backup/__init__.py,sha256=sAWIo0cwKX_KPS0IfEe_3-fBMoQG8DTarkiPtqUIFPA,23
|
|
2
|
-
github_backup/github_backup.py,sha256=mNTcVRvdVEt5M8LNCO6zXV0c7g2w_Mm8Rb4Cv6jo2yA,76237
|
|
3
|
-
github_backup-0.51.3.data/scripts/github-backup,sha256=I79TNA67phytRmI9nm_LlD9h2zauXFOsOn9tYyAy9pU,1546
|
|
4
|
-
github_backup-0.51.3.dist-info/licenses/LICENSE.txt,sha256=ML-pLyn1qtAKo_DHMcQ8-p7k3f8cp-IR-mf5B49R2rk,1085
|
|
5
|
-
github_backup-0.51.3.dist-info/METADATA,sha256=JstsidKzhrLnOHESpVtf2-s4a_6oUCb8y_PIMiCVfas,21544
|
|
6
|
-
github_backup-0.51.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
-
github_backup-0.51.3.dist-info/top_level.txt,sha256=Za6fKRAlxZ0b3ZBH_osPqklLe14LetdNAkvAQANT2AA,14
|
|
8
|
-
github_backup-0.51.3.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
9
|
-
github_backup-0.51.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|