Skip to content

Instantly share code, notes, and snippets.

@santiago-salas-v
Forked from leoloobeek/get_gists.py
Last active February 5, 2025 22:38
Show Gist options
  • Save santiago-salas-v/30aee4a1cc0340d843e1d93e46133408 to your computer and use it in GitHub Desktop.
Save santiago-salas-v/30aee4a1cc0340d843e1d93e46133408 to your computer and use it in GitHub Desktop.
Download all gists for a specific user
# first: mkdir user && cd user && cp /path/to/get_gists.py .
# python3 get_gists.py user
# ref. selimslab/get_gists.py: [email protected]:958e2255a105f9a3f4b421896bce715d.git
# ref. change_file_date_to_name_date.py: https://gist.github.com/santiago-salas-v/7f001a8d80534ebf9ec5104d409420bf
import sys
from os import walk,utime,listdir
from os.path import abspath,sep
from subprocess import call,getoutput
import json
from datetime import datetime
from zoneinfo import ZoneInfo # pip install tzdata
from re import compile
if len(sys.argv)<2:
user=json.loads(getoutput('gh api {0}'.format('user')))['login']
else:
user = sys.argv[1]
page=0
next_page=True
gitignore_fun=compile('\.gitignore') # to check if gitignore already has .gitignore
decription_fun=compile('description\.txt') # to check if gitignore already has description.txt
while next_page:
page+=1
endpoint='users/{0}/gists?page={1}'.format(user,str(page))
r=getoutput('gh api {0}'.format(endpoint)) # assumes gh api authentication done, needed for > 120 repos
reply_json=json.loads(r)
next_page=len(reply_json)>0
for i in reply_json:
filenames=[i['files'][key]['filename'] for key in i['files'].keys()]
filenames.sort()
dirname=filenames[0].replace('.','_') # splitext(filenames[0])[0]
created_at=datetime.strptime(i['created_at'],'%Y-%m-%dT%H:%M:%SZ').replace(tzinfo=ZoneInfo('UTC')).astimezone(datetime.now().astimezone().tzinfo)
updated_at=datetime.strptime(i['updated_at'],'%Y-%m-%dT%H:%M:%SZ').replace(tzinfo=ZoneInfo('UTC')).astimezone(datetime.now().astimezone().tzinfo)
call(['git', 'clone', i['git_pull_url'],dirname])
gist_id=i['id']
gitconfig_file='./{0}/.git/config'.format(dirname)
with open(gitconfig_file,'r') as f:
contents=f.read()
contents=contents.replace(i['git_pull_url'],f'[email protected]:{gist_id}.git')
with open(gitconfig_file,'w') as f:
contents=f.write(contents)
for root, dirs, files in walk(dirname):
utime(abspath(root),(created_at.timestamp(),created_at.timestamp()))
for file in files:
utime(abspath(root)+sep+file,(updated_at.timestamp(),updated_at.timestamp()))
description_file='./{0}/description.txt'.format(dirname)
with open(description_file,'w') as f:
f.write('{0}\n'.format(i['description']))
gitignore_found=False
description_found=False
if '.gitignore' in listdir(dirname):
# add to existing .gitignore
with open(dirname+sep+'.gitignore','r') as f:
contents=f.read()
gitignore_str='\n' # init
if not gitignore_fun.search(contents):
gitignore_str='\n{0}\n'.format('.gitignore')
if not decription_fun.search(contents):
gitignore_str+='{0}\n'.format('description.txt')
if gitignore_str=='\n':
gitignore_str='' # both found
else:
# create .gitignore with two entries
gitignore_str='{0}\n{1}\n'.format('.gitignore','description.txt')
with open(dirname+sep+'.gitignore', 'a') as f:
f.write(gitignore_str)
#!/bin/bash
# make symbolic link ln -s "$HOME"/git/gist/get_gists_py/ls_gists_descriptions ~/bin/ls_gists
for filename in "$HOME"/git/gist/*/description.txt; do tmp1=${filename#"$HOME"/git/gist/}; tmp2=${tmp1%/description.txt}; echo "$tmp2"; tmp3=${filename%/description.txt}; echo "file://${tmp3// /\%20}"; cat "$filename"; for i in {1..20}; do echo -n '='; done; echo -e '\n'; done | less
for filename in /home/ssv/git/gist/*; do if [[ ! ( "$filename" == "*get_gists_py*" || "$filename" == *.* || "$filename" == *remove_non_get_gists ) ]]; then echo "removing $filename"; rm -rf "$filename"; fi; done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment