Skip to content

Instantly share code, notes, and snippets.

@wrboyce
Last active November 29, 2019 10:34
Show Gist options
  • Save wrboyce/a8f1064d48ccea3677d2 to your computer and use it in GitHub Desktop.
Save wrboyce/a8f1064d48ccea3677d2 to your computer and use it in GitHub Desktop.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.willboyce.github-stars</string>
<key>ProgramArguments</key>
<array>
<string>sync_github_stars</string>
</array>
<key>StartInterval</key>
<integer>3600</integer>
</dict>
</plist>
#!/usr/bin/env python
""" Fed up with GitHub stars being essentially useless, I decided to give them
some purpose.
Run this script occasionally (via cron or similar) to keep a local and
up-to-date copy of your starred repos (and even delete repos which
have been unstarred!).
Three variables may or may not need configuring to run this script in your
environment, they are ``github_username``, ``starred_dir`` and ``cleanup``.
Their purpose should be somewhat obvious.
"""
import getpass
import os
import subprocess
import requests
github_username = getpass.getuser()
starred_dir = os.path.expanduser('~/Source/Starred')
cleanup = True
def main(user, dest, cleanup):
url = 'https://api.github.com/users/{}/starred'.format(user)
starred_repos = {}
page = 1
while True:
data = requests.get(url, params=dict(per_page=100, page=page)).json()
if not data:
break
for repo in data:
repo_dir = repo['full_name'].replace('/', '_')
starred_repos[repo_dir] = repo['clone_url']
page += 1
for (repo_name, repo_url) in starred_repos.iteritems():
workdir = os.path.join(dest, repo_name)
if os.path.isdir(workdir):
cmd = ['git', '-C', workdir, 'pull']
else:
cmd = ['git', 'clone', repo_url, workdir]
subprocess.call(cmd)
if cleanup:
for repo in os.listdir(dest):
repo_path = os.path.join(dest, repo)
if not os.path.isdir(repo_path) or repo.startswith('.'):
continue
if repo not in starred_repos:
subprocess.call(['rm', '-r', repo_path])
if __name__ == '__main__':
main(github_username, starred_dir, cleanup)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment