Skip to content

Instantly share code, notes, and snippets.

@bnlucas
Last active December 20, 2015 13:19
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 bnlucas/6137706 to your computer and use it in GitHub Desktop.
Save bnlucas/6137706 to your computer and use it in GitHub Desktop.
Download GitHub repository, not a GIT clone command! This was the answer to a problem I was having, creating a skeleton app structure and easily setting up a local file structure. For example, obtaining the src directory from https://github.com/kamalgill/flask-appengine-template. This is a work in progress, not the prettiest of things.
'''
c:\local\dev>python ghget.py -h
usage: ghget.py [-h] -u USER -r REPO [-b BRANCH] [-s SUB] [-p PATH] [-v]
GitHub repository downloader.
optional arguments:
-h, --help show this help message and exit
-u USER, --user USER github user (required)
-r REPO, --repo REPO github repository (required)
-b BRANCH, --branch BRANCH
repository branch, default master
-s SUB, --sub SUB repository subdirectory
-p PATH, --path PATH local path, default cwd
-v, --verbose
'''
'''
c:\local\dev>python ghget.py -u kamalgill -r flask-appengine-template -p ./PROJECT -s src
Creates local structure, c:\local\dev\PROJECT, and extracts everything from the ./src/
folder of the repository.
'''
import argparse
import os
import re
import requests
import sys
import StringIO
import zipfile
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description='GitHub repository downloader.'
)
parser.add_argument('-u', '--user', type=str, dest='user', required=True,
help='github user (required)')
parser.add_argument('-r', '--repo', type=str, dest='repo', required=True,
help='github repository (required)')
parser.add_argument('-b', '--branch', type=str, dest='branch', default='master',
help='repository branch, default master')
parser.add_argument('-s', '--sub', type=str, dest='sub',
help='repository subdirectory')
parser.add_argument('-p', '--path', type=str, dest='path', default='.',
help='local path, default cwd')
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true')
args = parser.parse_args(sys.argv[1:])
def main():
path = os.path.abspath(args.path)
if args.path != '.':
if not os.path.exists(path):
os.mkdir(path)
repo = 'https://github.com/{0}/{1}/archive/{2}.zip'.format(args.user,
args.repo,
args.branch)
result = requests.get(repo)
if not result.ok:
print 'Repository archive not found.'
print '- {0}'.format(repo)
exit()
zip_file = zipfile.ZipFile(StringIO.StringIO(result.content))
root = '{0}-{1}'.format(args.repo, args.branch)
if args.sub:
sub_dir = '/'.join([root, args.sub, ''])
if not sub_dir in zip_file.namelist():
print './{0}/ is an invalid directory.'.format(args.sub)
exit()
plen = len('/'.join([root, args.sub])) + 1
files = [i for i in zip_file.namelist() if i.startswith(sub_dir)]
else:
plen = len(root) + 1
files = zip_file.namelist()
for item in files:
d, f = os.path.split(item)
if f == '':
dpath = os.path.join(path, d[plen:])
if not os.path.exists(dpath):
if args.verbose:
print 'Creating:', dpath
os.mkdir(dpath)
else:
fpath = os.path.join(path, d[plen:], f)
with open(fpath, 'wb') as fp:
if args.verbose:
print 'Creating:', fpath
fp.write(zip_file.read(item))
zip_file.close()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment