Last active
December 20, 2015 13:19
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
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