Compare commits

..

17 Commits

Author SHA1 Message Date
Jose Diaz-Gonzalez
6db5bd731b Release version 0.24.0 2019-06-27 11:24:43 -04:00
Jose Diaz-Gonzalez
7305871c20 Merge pull request #117 from QuicketSolutions/master
Add option for Releases
2019-06-27 11:15:02 -04:00
Ethan Timm
baf7b1a9b4 Merge pull request #5 from QuicketSolutions/QKT-45
QKT-45: include assets - update readme
2019-06-25 15:41:11 -05:00
Ethan Timm
121fa68294 QKT-45: include assets - update readme
update readme with flag information for including assets alongside their respective releases
2019-06-25 15:41:02 -05:00
Ethan Timm
44dfc79edc Merge pull request #4 from whwright/wip-releases
Download github assets
2019-06-25 15:35:39 -05:00
Harrison Wright
89f59cc7a2 Make assets it's own flag 2019-06-24 15:49:19 -05:00
Jose Diaz-Gonzalez
ad8c5b8768 Merge pull request #118 from whwright/115-fix-pull-details
Fix pull details
2019-06-24 14:51:10 -04:00
Harrison Wright
921aab3729 Fix pull details 2019-06-22 13:19:45 -05:00
Harrison Wright
ea4c3d0f6f Fix super call for python2 2019-06-22 13:05:54 -05:00
Harrison Wright
9b6400932d Fix redirect to s3 2019-06-22 13:00:42 -05:00
Harrison Wright
de0c3f46c6 WIP: download assets 2019-06-21 20:03:14 -05:00
Ethan Timm
73b069f872 Merge pull request #3 from QuicketSolutions/QKT-42
QKT-42: releases - add readme info
2019-06-21 16:54:28 -05:00
ethan
3d3f512074 QKT-42: releases - add readme info 2019-06-21 16:53:40 -05:00
Ethan Timm
1c3078992d Merge pull request #2 from QuicketSolutions/QKT-42
QKT-42 update: shorter command flag
2019-06-21 16:49:40 -05:00
ethan
4b40ae94d7 QKT-42 update: shorter command flag 2019-06-21 16:48:25 -05:00
Ethan Timm
a18fda9faf Merge pull request #1 from QuicketSolutions/QKT-42
QKT-42: support saving release information
2019-06-21 16:43:48 -05:00
ethan
41130fc8b0 QKT-42: support saving release information 2019-06-21 11:20:32 -05:00
4 changed files with 102 additions and 5 deletions

View File

@@ -1,9 +1,24 @@
Changelog
=========
0.23.0 (2019-06-04)
0.24.0 (2019-06-27)
-------------------
------------------------
- QKT-45: include assets - update readme. [Ethan Timm]
update readme with flag information for including assets alongside their respective releases
- Make assets it's own flag. [Harrison Wright]
- Fix super call for python2. [Harrison Wright]
- Fix redirect to s3. [Harrison Wright]
- WIP: download assets. [Harrison Wright]
- QKT-42: releases - add readme info. [ethan]
- QKT-42 update: shorter command flag. [ethan]
- QKT-42: support saving release information. [ethan]
- Fix pull details. [Harrison Wright]
0.23.0 (2019-06-04)
-------------------
- Avoid to crash in case of HTTP 502 error. [Gael de Chalendar]
Survive also on socket.error connections like on HTTPError or URLError.

View File

@@ -32,8 +32,9 @@ CLI Usage is as follows::
[--watched] [--followers] [--following] [--all]
[--issues] [--issue-comments] [--issue-events] [--pulls]
[--pull-comments] [--pull-commits] [--labels] [--hooks]
[--milestones] [--repositories] [--bare] [--lfs]
[--wikis] [--gists] [--starred-gists] [--skip-existing]
[--milestones] [--repositories] [--releases] [--assets]
[--bare] [--lfs] [--wikis] [--gists] [--starred-gists]
[--skip-existing]
[-L [LANGUAGES [LANGUAGES ...]]] [-N NAME_REGEX]
[-H GITHUB_HOST] [-O] [-R REPOSITORY] [-P] [-F]
[--prefer-ssh] [-v]
@@ -76,6 +77,8 @@ CLI Usage is as follows::
authenticated)
--milestones include milestones in backup
--repositories include repository clone in backup
--releases include repository releases' information without assets or binaries
--assets include assets alongside release information; only applies if including releases
--bare clone bare repositories
--lfs clone LFS repositories (requires Git LFS to be
installed, https://git-lfs.github.com)

View File

@@ -18,6 +18,7 @@ import subprocess
import sys
import time
import platform
PY2 = False
try:
# python 3
from urllib.parse import urlparse
@@ -26,14 +27,19 @@ try:
from urllib.error import HTTPError, URLError
from urllib.request import urlopen
from urllib.request import Request
from urllib.request import HTTPRedirectHandler
from urllib.request import build_opener
except ImportError:
# python 2
PY2 = True
from urlparse import urlparse
from urllib import quote as urlquote
from urllib import urlencode
from urllib2 import HTTPError, URLError
from urllib2 import urlopen
from urllib2 import Request
from urllib2 import HTTPRedirectHandler
from urllib2 import build_opener
from github_backup import __version__
@@ -303,6 +309,15 @@ def parse_args():
parser.add_argument('--keychain-account',
dest='osx_keychain_item_account',
help='OSX ONLY: account field of password item in OSX keychain that holds the personal access or OAuth token')
parser.add_argument('--releases',
action='store_true',
dest='include_releases',
help='include release information, not including assets or binaries'
)
parser.add_argument('--assets',
action='store_true',
dest='include_assets',
help='include assets alongside release information; only applies if including releases')
return parser.parse_args()
@@ -532,6 +547,39 @@ def _request_url_error(template, retry_timeout):
return False
class S3HTTPRedirectHandler(HTTPRedirectHandler):
"""
A subclassed redirect handler for downloading Github assets from S3.
urllib will add the Authorization header to the redirected request to S3, which will result in a 400,
so we should remove said header on redirect.
"""
def redirect_request(self, req, fp, code, msg, headers, newurl):
if PY2:
# HTTPRedirectHandler is an old style class
request = HTTPRedirectHandler.redirect_request(self, req, fp, code, msg, headers, newurl)
else:
request = super(S3HTTPRedirectHandler, self).redirect_request(req, fp, code, msg, headers, newurl)
del request.headers['Authorization']
return request
def download_file(url, path, auth):
request = Request(url)
request.add_header('Accept', 'application/octet-stream')
request.add_header('Authorization', 'Basic '.encode('ascii') + auth)
opener = build_opener(S3HTTPRedirectHandler)
response = opener.open(request)
chunk_size = 16 * 1024
with open(path, 'wb') as f:
while True:
chunk = response.read(chunk_size)
if not chunk:
break
f.write(chunk)
def get_authenticated_user(args):
template = 'https://{0}/user'.format(get_github_api_host(args))
data = retrieve_data(args, template, single_request=True)
@@ -699,6 +747,10 @@ def backup_repositories(args, output_directory, repositories):
if args.include_hooks or args.include_everything:
backup_hooks(args, repo_cwd, repository, repos_template)
if args.include_releases or args.include_everything:
backup_releases(args, repo_cwd, repository, repos_template,
include_assets=args.include_assets or args.include_everything)
if args.incremental:
open(last_update_path, 'w').write(last_update)
@@ -801,7 +853,7 @@ def backup_pulls(args, repo_cwd, repository, repos_template):
args,
_pulls_template + '/{}'.format(pull['number']),
single_request=True
)
)[0]
log_info('Saving {0} pull requests to disk'.format(
len(list(pulls.keys()))))
@@ -880,6 +932,33 @@ def backup_hooks(args, repo_cwd, repository, repos_template):
log_info("Unable to read hooks, skipping")
def backup_releases(args, repo_cwd, repository, repos_template, include_assets=False):
repository_fullname = repository['full_name']
# give release files somewhere to live & log intent
release_cwd = os.path.join(repo_cwd, 'releases')
log_info('Retrieving {0} releases'.format(repository_fullname))
mkdir_p(repo_cwd, release_cwd)
query_args = {}
release_template = '{0}/{1}/releases'.format(repos_template, repository_fullname)
releases = retrieve_data(args, release_template, query_args=query_args)
# for each release, store it
log_info('Saving {0} releases to disk'.format(len(releases)))
for release in releases:
release_name = release['tag_name']
output_filepath = os.path.join(release_cwd, '{0}.json'.format(release_name))
with codecs.open(output_filepath, 'w+', encoding='utf-8') as f:
json_dump(release, f)
if include_assets:
assets = retrieve_data(args, release['assets_url'])
for asset in assets:
download_file(asset['url'], os.path.join(release_cwd, asset['name']), get_auth(args))
def fetch_repository(name,
remote_url,
local_dir,

View File

@@ -1 +1 @@
__version__ = '0.23.0'
__version__ = '0.24.0'