dump-github 0.1.7__py3-none-any.whl → 0.2.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.
dump_github/__init__.py CHANGED
@@ -1,2 +1,4 @@
1
- # from .lib import *
2
- from .main import main
1
+ from ._version import __version__
2
+ from .main import main
3
+
4
+ __all__ = ["__version__", "main"]
@@ -0,0 +1 @@
1
+ __version__ = "0.2.0"
dump_github/lib.py CHANGED
@@ -1,31 +1,158 @@
1
+ from urllib.parse import quote
2
+
1
3
  import requests
2
4
 
5
+ GITHUB_API = "https://api.github.com"
6
+ PER_PAGE = 100
7
+
8
+
9
+ def _github_auth_headers(token):
10
+ """GitHub REST API expects Authorization: Bearer <token> (PAT classic / fine-grained)."""
11
+ if not token:
12
+ return {}
13
+ token = token.strip()
14
+ if not token:
15
+ return {}
16
+ if token.lower().startswith(("bearer ", "token ", "basic ")):
17
+ return {"Authorization": token}
18
+ return {"Authorization": "Bearer {}".format(token)}
19
+
20
+
21
+ def _api_headers(token=""):
22
+ headers = {
23
+ "Accept": "application/vnd.github+json",
24
+ "X-GitHub-Api-Version": "2022-11-28",
25
+ }
26
+ headers.update(_github_auth_headers(token))
27
+ return headers
28
+
29
+
30
+ def _api_get(path, token=""):
31
+ """GET one GitHub REST API path and return the decoded JSON, or None on failure."""
32
+ try:
33
+ response = requests.get(
34
+ GITHUB_API + path, headers=_api_headers(token), timeout=30
35
+ )
36
+ except requests.RequestException:
37
+ return None
38
+ if response.status_code != 200:
39
+ return None
40
+ try:
41
+ return response.json()
42
+ except ValueError:
43
+ return None
44
+
45
+
46
+ def get_authenticated_login(token=""):
47
+ """Return the login of the token owner, or None if there is no usable token."""
48
+ if not _github_auth_headers(token):
49
+ return None
50
+ account = _api_get("/user", token)
51
+ if not isinstance(account, dict):
52
+ return None
53
+ return account.get("login") or None
54
+
55
+
56
+ def get_account_type(username, token=""):
57
+ """Return ``"Organization"``/``"User"`` for ``username``, or None if unknown."""
58
+ quoted = quote(username, safe="")
59
+ account = _api_get("/users/{}".format(quoted), token)
60
+ if isinstance(account, dict) and account.get("type"):
61
+ return account["type"]
62
+ # ``/users/{org}`` is not guaranteed to resolve for organisations, so fall
63
+ # back to the org endpoint, which unambiguously identifies one.
64
+ org = _api_get("/orgs/{}".format(quoted), token)
65
+ if isinstance(org, dict) and org.get("login"):
66
+ return "Organization"
67
+ return None
68
+
69
+
70
+ def _repos_path(username, page, authenticated_login, account_type):
71
+ """Build a listing API path that only contains repositories owned by ``username``.
3
72
 
4
- def get_page_of_repos(username, page, token=""):
5
- url = "https://api.github.com/users/{}/repos?per_page=200&page={}".format(
6
- username, page
73
+ ``GET /user/repos`` (used by an earlier version whenever a token was
74
+ supplied) lists every repository the token owner can see, which includes
75
+ repositories of the organisations the token owner is a member of, and it
76
+ ignores ``username`` entirely. Listing must therefore be scoped to the
77
+ requested account:
78
+
79
+ * organisation -> ``/orgs/{org}/repos?type=all``; only repositories owned
80
+ by that organisation, including private ones the token may access
81
+ * own user account -> ``/user/repos?affiliation=owner``; keeps private
82
+ repos, drops organisation/collaborator repos
83
+ * any other user account -> ``/users/{username}/repos?type=owner``
84
+ """
85
+ quoted = quote(username, safe="")
86
+ if (account_type or "").lower() == "organization":
87
+ return "/orgs/{}/repos?type=all&per_page={}&page={}".format(
88
+ quoted, PER_PAGE, page
89
+ )
90
+ own_account = bool(authenticated_login) and (
91
+ authenticated_login.lower() == username.lower()
92
+ )
93
+ if own_account:
94
+ return "/user/repos?affiliation=owner&per_page={}&page={}".format(
95
+ PER_PAGE, page
96
+ )
97
+ return "/users/{}/repos?type=owner&per_page={}&page={}".format(
98
+ quoted, PER_PAGE, page
7
99
  )
8
- headers = {"Authorization": token}
9
- if token != "":
10
- response = requests.get(url, headers=headers)
11
- else:
12
- response = requests.get(url)
13
- if response.status_code == 200:
14
- repos = response.json()
15
- return repos
16
- else:
100
+
101
+
102
+ def _is_owned_by(repo, username):
103
+ owner = repo.get("owner") or {}
104
+ login = owner.get("login") or ""
105
+ if login:
106
+ return login.lower() == username.lower()
107
+ full_name = repo.get("full_name") or ""
108
+ return full_name.split("/", 1)[0].lower() == username.lower()
109
+
110
+
111
+ def _fetch_repos_page(username, page, token="", authenticated_login=None,
112
+ account_type=None):
113
+ """Fetch one raw page of repositories owned by ``username``."""
114
+ path = _repos_path(username, page, authenticated_login, account_type)
115
+ repos = _api_get(path, token)
116
+ if not isinstance(repos, list):
17
117
  return []
118
+ return [repo for repo in repos if isinstance(repo, dict)]
18
119
 
19
120
 
20
- def serach_user_repos(username, token=""):
121
+ def get_page_of_repos(username, page, token="", authenticated_login=None,
122
+ account_type=None):
123
+ username = username.strip()
124
+ if account_type is None:
125
+ account_type = get_account_type(username, token)
126
+ if authenticated_login is None:
127
+ authenticated_login = get_authenticated_login(token)
128
+ repos = _fetch_repos_page(
129
+ username, page, token, authenticated_login, account_type
130
+ )
131
+ return [repo for repo in repos if _is_owned_by(repo, username)]
132
+
133
+
134
+ def search_user_repos(username, token=""):
135
+ username = username.strip()
136
+ authenticated_login = get_authenticated_login(token)
137
+ account_type = get_account_type(username, token)
21
138
  page = 0
22
139
  res_repos = []
23
140
 
24
141
  while True:
25
142
  page += 1
26
- repos = get_page_of_repos(username, page, token)
143
+ repos = _fetch_repos_page(
144
+ username, page, token, authenticated_login, account_type
145
+ )
27
146
  if len(repos) == 0:
28
147
  break
29
148
  res_repos += repos
149
+ if len(repos) < PER_PAGE:
150
+ break
151
+
152
+ # Never return repositories that belong to somebody else (e.g. a user repo
153
+ # returned for an organisation, or an organisation the token owner is in).
154
+ return [repo for repo in res_repos if _is_owned_by(repo, username)]
155
+
30
156
 
31
- return res_repos
157
+ # Backward-compatible alias for the historical typo
158
+ serach_user_repos = search_user_repos
dump_github/main.py CHANGED
@@ -1,6 +1,18 @@
1
1
  import argparse
2
2
  import os
3
- from .lib import *
3
+ import subprocess
4
+
5
+ from ._version import __version__
6
+ from .lib import search_user_repos
7
+
8
+ # One-shot credential helper: git asks for credentials, the helper answers with
9
+ # the token from the environment. The token is therefore never part of the
10
+ # clone URL and never gets written to the cloned repository's .git/config.
11
+ GIT_CREDENTIAL_HELPER = (
12
+ '!f() { test "$1" = get || return 0; '
13
+ 'echo username=x-access-token; '
14
+ 'echo "password=$DUMP_GITHUB_TOKEN"; }; f'
15
+ )
4
16
 
5
17
  parser = argparse.ArgumentParser(
6
18
  prog="dump-github",
@@ -13,7 +25,15 @@ parser.add_argument(
13
25
  "-d", "--download_zip", action="store_true", help="only download zip file"
14
26
  )
15
27
  parser.add_argument("-p", "--print", action="store_true", help="only print urls")
16
- parser.add_argument("--token", action="store", default="", help="github token")
28
+ parser.add_argument(
29
+ "--version", action="version", version="%(prog)s {}".format(__version__)
30
+ )
31
+ parser.add_argument(
32
+ "--token",
33
+ action="store",
34
+ default="",
35
+ help="GitHub personal access token (or set GITHUB_TOKEN). Required for private repos and higher API rate limits.",
36
+ )
17
37
  parser.add_argument(
18
38
  "--limit_size",
19
39
  type=int,
@@ -21,41 +41,90 @@ parser.add_argument(
21
41
  help="limit size(MB) of download zip file, if 0 then no limit(default:100).",
22
42
  )
23
43
 
24
- args = parser.parse_args()
25
-
26
44
 
27
- def clone_repo(repo):
45
+ def clone_repo(repo, token=""):
28
46
  name = repo["name"]
29
47
  url = repo["clone_url"]
30
- size = repo["size"]
48
+ cmd = ["git", "clone", url]
49
+ env = None
50
+ if token:
51
+ # Use a credential helper instead of https://x-access-token:TOKEN@...
52
+ # so the token does not leak into `ps` output or .git/config.
53
+ cmd = [
54
+ "git",
55
+ "-c",
56
+ "credential.helper=",
57
+ "-c",
58
+ "credential.helper={}".format(GIT_CREDENTIAL_HELPER),
59
+ "clone",
60
+ url,
61
+ ]
62
+ env = os.environ.copy()
63
+ env["DUMP_GITHUB_TOKEN"] = token
64
+ env["GIT_TERMINAL_PROMPT"] = "0"
31
65
  print("Clone repo: {}".format(name))
32
- os.system("git clone {}".format(url))
33
-
34
-
35
- def download_zip(user_name, reop):
36
- url = f"https://github.com/{user_name}/{reop['name']}/archive/refs/heads/{reop['default_branch']}.zip"
37
- max_size = args.limit_size * 1000 * 1000
38
- file_name = f"./{user_name}_{reop['name']}.zip"
39
- cmd = "curl -L --connect-timeout 5 --retry 3 --retry-delay 3 --max-filesize {} {} -o {}".format(
40
- max_size, url, file_name
41
- )
42
- print(f"Download {reop['name']} : {url}")
43
- os.system(cmd)
44
- if os.path.exists(file_name) and max_size < os.stat(file_name).st_size:
66
+ subprocess.run(cmd, env=env, check=False)
67
+
68
+
69
+ def download_zip(user_name, reop, token="", limit_size=100):
70
+ ref = reop.get("default_branch") or "main"
71
+ # Always archive the repository the API actually listed. Using the
72
+ # positional username here would point at the wrong owner whenever the
73
+ # repo does not belong to that user.
74
+ full_name = reop.get("full_name") or "{}/{}".format(user_name, reop["name"])
75
+ max_size = limit_size * 1000 * 1000
76
+ file_name = "./{}.zip".format(full_name.replace("/", "_"))
77
+ curl_cmd = [
78
+ "curl",
79
+ "-sS",
80
+ "-L",
81
+ "--connect-timeout",
82
+ "5",
83
+ "--retry",
84
+ "3",
85
+ "--retry-delay",
86
+ "3",
87
+ ]
88
+ if max_size > 0:
89
+ curl_cmd.extend(["--max-filesize", str(max_size)])
90
+ if token:
91
+ url = "https://api.github.com/repos/{}/zipball/{}".format(full_name, ref)
92
+ curl_cmd.extend(
93
+ [
94
+ "-H",
95
+ "Authorization: Bearer {}".format(token),
96
+ "-H",
97
+ "Accept: application/vnd.github+json",
98
+ "-o",
99
+ file_name,
100
+ url,
101
+ ]
102
+ )
103
+ else:
104
+ url = "https://github.com/{}/archive/refs/heads/{}.zip".format(full_name, ref)
105
+ curl_cmd.extend(["-o", file_name, url])
106
+ print("Download {} : {}".format(reop["name"], url))
107
+ subprocess.run(curl_cmd, check=False)
108
+ if (
109
+ max_size > 0
110
+ and os.path.exists(file_name)
111
+ and os.stat(file_name).st_size > max_size
112
+ ):
45
113
  os.remove(file_name)
46
- print(f"Removed {file_name} because it exceeds the limit size.")
114
+ print("Removed {} because it exceeds the limit size.".format(file_name))
47
115
 
48
116
 
49
- def main():
50
- # print(args)
51
- repos = serach_user_repos(args.username, args.token)
117
+ def main(argv=None):
118
+ args = parser.parse_args(argv)
119
+ token = (args.token or "").strip() or (os.environ.get("GITHUB_TOKEN") or "").strip()
120
+ repos = search_user_repos(args.username, token)
52
121
  for repo in repos:
53
- if args.print == True:
122
+ if args.print:
54
123
  print(repo["clone_url"])
55
- elif args.download_zip == True:
56
- download_zip(args.username, repo)
124
+ elif args.download_zip:
125
+ download_zip(args.username, repo, token, args.limit_size)
57
126
  else:
58
- clone_repo(repo)
127
+ clone_repo(repo, token)
59
128
 
60
129
 
61
130
  if __name__ == "__main__":
@@ -0,0 +1,144 @@
1
+ Metadata-Version: 2.4
2
+ Name: dump-github
3
+ Version: 0.2.0
4
+ Summary: Back up users' GitHub repositories in case they need them later.
5
+ Author-email: core2002 <core2002@aliyun.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Core2002/dump_github
8
+ Project-URL: Repository, https://github.com/Core2002/dump_github
9
+ Project-URL: Issues, https://github.com/Core2002/dump_github/issues
10
+ Project-URL: Changelog, https://github.com/Core2002/dump_github/blob/main/CHANGELOG.md
11
+ Keywords: github,backup,repositories,cli
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Software Development :: Version Control :: Git
23
+ Classifier: Topic :: System :: Archiving :: Backup
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: requests>=2.28
28
+ Provides-Extra: dev
29
+ Requires-Dist: build>=1.2; extra == "dev"
30
+ Requires-Dist: twine>=5; extra == "dev"
31
+ Dynamic: license-file
32
+
33
+ ### Github Dumper
34
+
35
+ [![CI](https://github.com/Core2002/dump_github/actions/workflows/ci.yml/badge.svg)](https://github.com/Core2002/dump_github/actions/workflows/ci.yml)
36
+ [![PyPI](https://img.shields.io/pypi/v/dump-github.svg)](https://pypi.org/project/dump-github/)
37
+
38
+ Github Dumper is a Python program designed to search for users' GitHub repositories and download the repositories. This tool can be used to back up users' GitHub repositories in case they need them later.
39
+
40
+ **Install (Python 3.10+):**
41
+
42
+ ```
43
+ pip install -U dump-github
44
+ ```
45
+
46
+ **Usage:**
47
+
48
+ ```
49
+ usage: dump-github [-h] [-d] [-p] [--version] [--token TOKEN]
50
+ [--limit_size LIMIT_SIZE]
51
+ username
52
+
53
+ Backup users github repo.
54
+
55
+ positional arguments:
56
+ username
57
+
58
+ options:
59
+ -h, --help show this help message and exit
60
+ -d, --download_zip only download zip file
61
+ -p, --print only print urls
62
+ --version show program's version number and exit
63
+ --token TOKEN GitHub personal access token (or set GITHUB_TOKEN).
64
+ Required for private repos and higher API rate limits.
65
+ --limit_size LIMIT_SIZE
66
+ limit size(MB) of download zip file, if 0 then no
67
+ limit(default:100).
68
+
69
+ https://github.com/Core2002/dump_github
70
+ ```
71
+
72
+ ### Authentication (token)
73
+
74
+ GitHub’s API requires a proper `Authorization: Bearer <token>` header. This tool accepts a **personal access token** in two ways (first match wins):
75
+
76
+ 1. **`--token`** on the command line
77
+ 2. **`GITHUB_TOKEN`** environment variable (if `--token` is empty)
78
+
79
+ **Why use a token?**
80
+
81
+ - **Private repositories**: Without a token, only public repos are listed and can be cloned or archived. With a token that has the right scopes, you can include private repos you are allowed to access (for example when backing up your own account).
82
+ - **Rate limits**: Authenticated API requests get a much higher limit than anonymous requests.
83
+
84
+ **How the token is used**
85
+
86
+ - **Listing repos**: sent as `Bearer` on the REST API and scoped strictly to the requested account:
87
+ - **organisation** → `GET /orgs/{org}/repos?type=all` — only repositories owned by that organisation (private ones included when the token may access them);
88
+ - **your own user account** → `GET /user/repos?affiliation=owner` — private and public repos, without organisation/collaborator repos;
89
+ - **any other user** → `GET /users/{username}/repos?type=owner`.
90
+
91
+ Repositories whose owner is not the requested account are discarded as a final guard, so a user dump never includes organisation repositories and an organisation dump never includes user repositories.
92
+ - **Clone** (default mode): the token is handed to `git` through a one-shot credential helper (`credential.helper` reads `DUMP_GITHUB_TOKEN` from the child process environment), so the clone URL stays `https://github.com/...`. The token is never shown in `ps` output and never written to the cloned repository's `.git/config`; existing credential helpers are reset for that clone so a stale stored credential cannot shadow the token.
93
+ - **Zip download** (`-d`): uses the [repository archive (zipball)](https://docs.github.com/en/rest/repos/repos#download-a-repository-archive-zip) API with the same `Bearer` header (via `curl`), which works for private repos; without a token, public archive URLs are used instead.
94
+
95
+ Create a token under GitHub → **Settings** → **Developer settings** → **Personal access tokens**. For private repo backup, enable access to **repository contents** (classic PAT: `repo` scope; fine-grained: read access to the repositories you need).
96
+
97
+ **Examples**
98
+
99
+ ```bash
100
+ # Public repos only (no token)
101
+ dump-github Core2002 -p
102
+
103
+ # Token on the command line (private + higher API limits)
104
+ dump-github username --token ghp_xxxxxxxxxxxx
105
+
106
+ # Back up an organisation (only that organisation's repositories)
107
+ dump-github some-org --token ghp_xxxxxxxxxxxx
108
+
109
+ # Same, via environment variable (recommended to avoid shell history)
110
+ export GITHUB_TOKEN=ghp_xxxxxxxxxxxx
111
+ dump-github Core2002 -d
112
+ ```
113
+
114
+ **Security note:** Do not commit tokens or paste them into shared logs. Prefer `GITHUB_TOKEN` in a local shell profile or a secret manager, and rotate the token if it leaks. Cloned repositories keep a clean remote URL (`https://github.com/...`), so `.git/config` does not contain the token.
115
+
116
+ ### Development
117
+
118
+ ```bash
119
+ python -m venv .venv
120
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
121
+ python -m pip install -e ".[dev]"
122
+ python -m unittest discover -s tests -v
123
+ python -m build # dist/: sdist + wheel
124
+ python -m twine check dist/*
125
+ ```
126
+
127
+ CI runs the test suite on Python 3.10, 3.12 and 3.13, and checks the build metadata with `twine check` (`.github/workflows/ci.yml`).
128
+
129
+ ### Releasing
130
+
131
+ 1. Bump `__version__` in `dump_github/_version.py` and move the changelog entries in `CHANGELOG.md` to the new version.
132
+ 2. Commit, tag and push:
133
+ ```bash
134
+ git tag v0.2.0
135
+ git push origin main v0.2.0
136
+ ```
137
+ 3. The `Release` workflow runs the tests, builds the sdist and wheel, checks them with `twine check` and publishes both to PyPI through **Trusted Publishing**.
138
+
139
+ One-time setup on PyPI: add a trusted publisher for the `Core2002/dump_github` repository and the `release.yml` workflow. No PyPI API token is stored in the repository. Manual fallback:
140
+
141
+ ```bash
142
+ python -m build
143
+ python -m twine upload dist/*
144
+ ```
@@ -0,0 +1,10 @@
1
+ dump_github/__init__.py,sha256=7bV8yfP0ii_gvNXKfDzFhBj2V5nC82mcJrlZqs9fRZ0,92
2
+ dump_github/_version.py,sha256=Zn1KFblwuFHiDRdRAiRnDBRkbPttWh44jKa5zG2ov0E,22
3
+ dump_github/lib.py,sha256=l35zDGPRRKdMv6KzzcqJXnCmOMLrPY07wnsijcwbfCA,5485
4
+ dump_github/main.py,sha256=lYSma1C2m-7Pl5r4zwbEfeZyKqgVf2H2jFwD-98hnYg,4122
5
+ dump_github-0.2.0.dist-info/licenses/LICENSE,sha256=5tQa-lQLqvLhjTuELEk4bm70I5hcdjUeOn4qf3MK84E,1064
6
+ dump_github-0.2.0.dist-info/METADATA,sha256=vjimbmFSa9hnjYn8L58iX79KvNbL3tq104VVsIXg09I,6766
7
+ dump_github-0.2.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
8
+ dump_github-0.2.0.dist-info/entry_points.txt,sha256=2OAP2WnA1p54LWyCw3tHe44Pf4aR7Thsxf9uWKWfWl8,49
9
+ dump_github-0.2.0.dist-info/top_level.txt,sha256=6oWfdkP2U1AN9zL6AUIUTxe6hYIeo_Nf8M8SWBxElUw,12
10
+ dump_github-0.2.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (84.2.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
dump_github/mylib.py DELETED
@@ -1,31 +0,0 @@
1
- import requests
2
-
3
-
4
- def get_page_of_repos(username, page, token=""):
5
- url = "https://api.github.com/users/{}/repos?per_page=200&page={}".format(
6
- username, page
7
- )
8
- headers = {"Authorization": token}
9
- if token != "":
10
- response = requests.get(url, headers=headers)
11
- else:
12
- response = requests.get(url)
13
- if response.status_code == 200:
14
- repos = response.json()
15
- return repos
16
- else:
17
- raise []
18
-
19
-
20
- def serach_user_repos(username, token=""):
21
- page = 0
22
- res_repos = []
23
-
24
- while True:
25
- page += 1
26
- repos = get_page_of_repos(username, page, token)
27
- if len(repos) == 0:
28
- break
29
- res_repos += repos
30
-
31
- return res_repos
@@ -1,44 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: dump-github
3
- Version: 0.1.7
4
- Summary: This tool can be used to back up users' GitHub repositories in case they need them later.
5
- Home-page: https://github.com/core2002/dump_github
6
- Author: core2002
7
- Author-email: core2002@aliyun.com
8
- License: MIT
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Operating System :: OS Independent
12
- Description-Content-Type: text/markdown
13
- License-File: LICENSE
14
- Requires-Dist: argparse
15
- Requires-Dist: requests
16
-
17
- ### Github Dumper
18
-
19
- Github Dumper is a Python program designed to search for users' GitHub repositories and download the repositories. This tool can be used to back up users' GitHub repositories in case they need them later.
20
-
21
- **Install:**
22
- ```
23
- pip install -U dump-github
24
- ```
25
-
26
- **Usage:**
27
- ```
28
- usage: dump-github [-h] [-d] [-p] [--token TOKEN] [--limit_size LIMIT_SIZE] username
29
-
30
- Backup users github repo.
31
-
32
- positional arguments:
33
- username
34
-
35
- options:
36
- -h, --help show this help message and exit
37
- -d, --download_zip only download zip file
38
- -p, --print only print urls
39
- --token TOKEN github token
40
- --limit_size LIMIT_SIZE
41
- limit size(MB) of download zip file, if 0 then no limit(default:100).
42
-
43
- https://github.com/Core2002/dump_github
44
- ```
@@ -1,10 +0,0 @@
1
- dump_github/__init__.py,sha256=3XLRrchVn7g3TYWiQpv3u2lKdTO-jDqg4_0-lpmRuRs,43
2
- dump_github/lib.py,sha256=hE8ZXBB2BKHlPld0ufUgRaAr2hGouLeQ7jdZuqXX6Q8,716
3
- dump_github/main.py,sha256=uTPdcVwg0mkmOAGJXpVeBn3m3f7SyNOracyqAnR-KuA,1842
4
- dump_github/mylib.py,sha256=pHONzAjGbXkmAUvCGn8HkHWS7fyY2qu9R17to6jD1TU,715
5
- dump_github-0.1.7.dist-info/LICENSE,sha256=5tQa-lQLqvLhjTuELEk4bm70I5hcdjUeOn4qf3MK84E,1064
6
- dump_github-0.1.7.dist-info/METADATA,sha256=ZwZtZYP6H4p0NrK0La9C7lOeB4frgC2i3lwLPLH2D-Q,1316
7
- dump_github-0.1.7.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
8
- dump_github-0.1.7.dist-info/entry_points.txt,sha256=2OAP2WnA1p54LWyCw3tHe44Pf4aR7Thsxf9uWKWfWl8,49
9
- dump_github-0.1.7.dist-info/top_level.txt,sha256=6oWfdkP2U1AN9zL6AUIUTxe6hYIeo_Nf8M8SWBxElUw,12
10
- dump_github-0.1.7.dist-info/RECORD,,