#!/usr/bin/env python # -*- coding: utf-8 -*- """Clone all gists of GitHub user with given username. Clones all gist repos into the current directory, using the gist id as the directory name. If the directory already exists as a git repo, try to perform a 'git pull' in it. """ import argparse import sys from os.path import exists, join from subprocess import CalledProcessError, check_call import requests def main(args=None): ap = argparse.ArgumentParser(description=__doc__) ap.add_argument( "-p", "--page", type=int, metavar="PAGE", help="Fetch only page PAGE from list of Gists" ) ap.add_argument( "--per-page", type=int, metavar="NUM", default=100, help="Fetch NUM gists per page" ) ap.add_argument( "-s", "--ssh-url", action="store_true", help="Clone gists using SSH URL instead of HTTPS" ) ap.add_argument( "-v", "--verbose", action="store_true", help="Run git commands with verbose messages" ) ap.add_argument("username", help="GitHub username") ap.add_argument("token", nargs="?", help="GitHub auth token") args = ap.parse_args(args) page = args.page while True: if page is None: page = 1 print(f"Fetching page {page} of list of Gists of user {args.username}...") url = "https://api.github.com/users/{}/gists".format(args.username) headers = {"Authorization": "token " + args.token} if args.token else {} resp = requests.get(url, headers=headers, params={"per_page": args.per_page, "page": page}) if resp.status_code == 200: for gist in resp.json(): gistid = gist["id"] try: if exists(join(gist["id"], ".git")): print(f"Updating gist {gistid} via 'git pull'...") check_call(["git", "pull", "-v" if args.verbose else "-q"], cwd=gistid) else: url = gist["git_pull_url"] if args.ssh_url: url = url.replace("https://gist.github.com/", "git@gist.github.com:") print(f"Cloning Gist from {url}...") check_call(["git", "clone", "-v" if args.verbose else "-q", url]) except CalledProcessError: print(f"*** ERROR cloning/updating gist {gistid}. Please check output.") except KeyboardInterrupt: break if 'rel="next"' in resp.headers.get("link", ""): page += 1 else: break else: return "Error reponse: {}".format(req.json().get("message")) if args.page: break if __name__ == "__main__": sys.exit(main() or 0)