Skip to content

Instantly share code, notes, and snippets.

@k-takata
Created February 27, 2020 02:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save k-takata/6c90f977abfe0dc6ee0970ea3379c1f1 to your computer and use it in GitHub Desktop.
Save k-takata/6c90f977abfe0dc6ee0970ea3379c1f1 to your computer and use it in GitHub Desktop.
Download the latest silver searcher Win32 from the GitHub releases
#!/usr/bin/python3
# Download the latest silver searcher Win32 from the GitHub releases
import argparse
import calendar
import io
import json
import os
import sys
import time
import urllib.request, urllib.error
# Repository Name
repo_name = 'k-takata/the_silver_searcher-win32'
gh_releases_url = 'https://api.github.com/repos/' + repo_name + '/releases'
# Asset name checker
def does_skip_asset(asset):
return asset['name'].find('debug') >= 0
# Arguments properties
arg_desc = 'Download the latest silver searcher Win32 from the GitHub releases'
arg_archs = ['all', 'x86', 'x64']
arg_default_arch = 'all'
arg_allow_prerelease = True
# Parse arguments
def parse_args():
global parser
parser = argparse.ArgumentParser(description=arg_desc)
parser.add_argument('-c', '--check', action='store_true',
help='only check the information of the latest release')
parser.add_argument('--noprogress', action='store_true',
help="Don't show the progress")
parser.add_argument('-f', '--force', action='store_true',
help='overwrite the download file')
parser.add_argument('-n', '--filename', type=str, action='store',
help='filename to save')
parser.add_argument('-p', '--prerelease', action='store_true',
default=arg_allow_prerelease,
help='Allow downloading prerelease')
parser.add_argument('-a', '--arch', type=str, action='store',
choices=arg_archs, default=arg_default_arch,
help='architecture to download')
parser.add_argument('--auth', type=str, action='store',
default=os.getenv('AUTH_TOKEN'),
metavar="TOKEN", help='GitHub API token (Environment variable AUTH_TOKEN can be also used.)')
return parser.parse_args()
# Get information of GitHub release
# see: https://developer.github.com/v3/repos/releases/
def get_rel_info(url, auth):
if auth:
# Unauthenticated requests are limited up to 60 requests per hour.
# Authenticated requests are allowed up to 5,000 requests per hour.
# See: https://developer.github.com/v3/#rate-limiting
request = urllib.request.Request(url)
request.add_header("Authorization", "token " + auth)
else:
request = url
try:
response = urllib.request.urlopen(request)
except urllib.error.HTTPError as err:
print('GitHub release not found. (%s)' % err.reason, file=sys.stderr)
exit(1)
return json.load(io.StringIO(str(response.read(), 'utf-8')))
# Show progress
def reporthook(count, blocksize, totalsize):
size = count * blocksize
if totalsize <= 0:
print("\r{:,}".format(size))
else:
size = min(size, totalsize)
print("\r{:,} / {:,} ({:.1%})".format(size, totalsize, size / totalsize), end='')
# Download the files
def download(args, rel_info):
for asset in rel_info['assets']:
if args.filename:
name = args.filename
else:
name = asset['name']
if does_skip_asset(asset):
continue
if args.arch != 'all' and asset['name'].find(args.arch) < 0:
continue
if os.path.isfile(name) and not args.force:
print('File exists:', name)
continue
print('Downloading from:', asset['browser_download_url'])
print('Downloading to:', name)
if args.noprogress:
hook = None
else:
hook = reporthook
urllib.request.urlretrieve(asset['browser_download_url'], name, hook)
# Set timestamp
asset_time = time.strptime(asset['updated_at'], '%Y-%m-%dT%H:%M:%SZ')
os.utime(name, times=(time.time(), calendar.timegm(asset_time)))
if not args.noprogress:
print()
def main():
args = parse_args()
if args.filename and args.arch == 'all':
parser.error('-a must be specified when you specify -n.')
if args.prerelease:
rels_info = get_rel_info(gh_releases_url, args.auth)
for rel in rels_info:
if rel['draft']:
continue
gh_release_url = rel['url']
break
else:
print('GitHub release not found.', file=sys.stderr)
exit(1)
else:
gh_release_url = gh_releases_url + '/latest'
rel_info = get_rel_info(gh_release_url, args.auth)
print('Last release:', rel_info['name'])
print('Created at:', rel_info['created_at'])
if args.check:
exit(0)
download(args, rel_info)
exit(0)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment