@@ -224,6 +224,14 @@ def parse_args():
224224 action = 'store_true' ,
225225 dest = 'include_wiki' ,
226226 help = 'include wiki clone in backup' )
227+ parser .add_argument ('--gists' ,
228+ action = 'store_true' ,
229+ dest = 'include_gists' ,
230+ help = 'include gists in backup' )
231+ parser .add_argument ('--starred-gists' ,
232+ action = 'store_true' ,
233+ dest = 'include_starred_gists' ,
234+ help = 'include starred gists in backup' )
227235 parser .add_argument ('--skip-existing' ,
228236 action = 'store_true' ,
229237 dest = 'skip_existing' ,
@@ -342,6 +350,9 @@ def get_github_repo_url(args, repository):
342350 if args .prefer_ssh :
343351 return repository ['ssh_url' ]
344352
353+ if repository .get ('is_gist' ):
354+ return repository ['git_pull_url' ]
355+
345356 auth = get_auth (args , False )
346357 if auth :
347358 repo_url = 'https://{0}@{1}/{2}/{3}.git' .format (
@@ -509,12 +520,30 @@ def retrieve_repositories(args):
509520 starred_template = 'https://{0}/user/starred' .format (
510521 get_github_api_host (args ))
511522 starred_repos = retrieve_data (args , starred_template , single_request = False )
512- # we need to be able to determine this repo was retrieved as a starred repo
513- # later, so add a flag to each item
523+ # flag each repo as starred for downstream processing
514524 for item in starred_repos :
515525 item .update ({'is_starred' : True })
516526 repos .extend (starred_repos )
517527
528+ if args .include_gists :
529+ gists_template = 'https://{0}/gists' .format (
530+ get_github_api_host (args ))
531+ gists = retrieve_data (args , gists_template , single_request = False )
532+ # flag each repo as a gist for downstream processing
533+ for item in gists :
534+ item .update ({'is_gist' : True })
535+ repos .extend (gists )
536+
537+ if args .include_starred_gists :
538+ starred_gists_template = 'https://{0}/gists/starred' .format (
539+ get_github_api_host (args ))
540+ starred_gists = retrieve_data (args , starred_gists_template , single_request = False )
541+ # flag each repo as a starred gist for downstream processing
542+ for item in starred_gists :
543+ item .update ({'is_gist' : True ,
544+ 'is_starred' : True })
545+ repos .extend (starred_gists )
546+
518547 return repos
519548
520549
@@ -523,7 +552,8 @@ def filter_repositories(args, unfiltered_repositories):
523552
524553 repositories = []
525554 for r in unfiltered_repositories :
526- if r ['owner' ]['login' ] == args .user or r .get ('is_starred' ):
555+ # gists can be anonymous, so need to safely check owner
556+ if r .get ('owner' , {}).get ('login' ) == args .user or r .get ('is_starred' ):
527557 repositories .append (r )
528558
529559 name_regex = None
@@ -535,11 +565,11 @@ def filter_repositories(args, unfiltered_repositories):
535565 languages = [x .lower () for x in args .languages ]
536566
537567 if not args .fork :
538- repositories = [r for r in repositories if not r [ 'fork' ] ]
568+ repositories = [r for r in repositories if not r . get ( 'fork' ) ]
539569 if not args .private :
540- repositories = [r for r in repositories if not r [ 'private' ] ]
570+ repositories = [r for r in repositories if not r . get ( 'private' ) or r . get ( 'public' ) ]
541571 if languages :
542- repositories = [r for r in repositories if r [ 'language' ] and r [ 'language' ] .lower () in languages ] # noqa
572+ repositories = [r for r in repositories if r . get ( 'language' ) and r . get ( 'language' ) .lower () in languages ] # noqa
543573 if name_regex :
544574 repositories = [r for r in repositories if name_regex .match (r ['name' ])]
545575
@@ -561,29 +591,37 @@ def backup_repositories(args, output_directory, repositories):
561591 args .since = None
562592
563593 for repository in repositories :
564- backup_cwd = os .path .join (output_directory , 'repositories' )
565- repo_cwd = os .path .join (backup_cwd , repository ['name' ])
566-
567- # put starred repos in -o/starred/${owner}/${repo} to prevent collision of
568- # any repositories with the same name
569- if repository .get ('is_starred' ):
570- backup_cwd = os .path .join (output_directory , 'starred' )
571- repo_cwd = os .path .join (backup_cwd , repository ['owner' ]['login' ],
572- repository ['name' ])
594+ if repository .get ('is_gist' ):
595+ repo_cwd = os .path .join (output_directory , 'gists' , repository ['id' ])
596+ elif repository .get ('is_starred' ):
597+ # put starred repos in -o/starred/${owner}/${repo} to prevent collision of
598+ # any repositories with the same name
599+ repo_cwd = os .path .join (output_directory , 'starred' , repository ['owner' ]['login' ], repository ['name' ])
600+ else :
601+ repo_cwd = os .path .join (output_directory , 'repositories' , repository ['name' ])
573602
574603 repo_dir = os .path .join (repo_cwd , 'repository' )
575604 repo_url = get_github_repo_url (args , repository )
576605
577- if args .include_repository or args .include_everything :
578- fetch_repository (repository ['name' ],
606+ include_gists = (args .include_gists or args .include_starred_gists )
607+ if (args .include_repository or args .include_everything ) \
608+ or (include_gists and repository .get ('is_gist' )):
609+ repo_name = repository .get ('name' ) if not repository .get ('is_gist' ) else repository .get ('id' )
610+ fetch_repository (repo_name ,
579611 repo_url ,
580612 repo_dir ,
581613 skip_existing = args .skip_existing ,
582614 bare_clone = args .bare_clone ,
583615 lfs_clone = args .lfs_clone )
584616
617+ # dump gist information to a file as well
618+ if repository .get ('is_gist' ):
619+ output_file = '{0}/gist.json' .format (repo_cwd )
620+ with codecs .open (output_file , 'w' , encoding = 'utf-8' ) as f :
621+ json_dump (repository , f )
622+
585623 download_wiki = (args .include_wiki or args .include_everything )
586- if repository [ 'has_wiki' ] and download_wiki :
624+ if repository . get ( 'has_wiki' ) and download_wiki :
587625 fetch_repository (repository ['name' ],
588626 repo_url .replace ('.git' , '.wiki.git' ),
589627 os .path .join (repo_cwd , 'wiki' ),
0 commit comments