The little things give you away... A collection of various small helper stuff
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

47 lines
1.4 KiB

  1. #!/usr/bin/env python3
  2. import logging
  3. import re
  4. import requests
  5. import sys
  6. users = sys.argv[1:]
  7. assert users, 'Usage: github-list-repos USER [USER...]'
  8. def get(url):
  9. while True:
  10. logging.info(f'Fetching {url}')
  11. r = requests.get(url, headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0'})
  12. if r.status_code == 429:
  13. logging.warning(f'Got 429, sleeping and retrying')
  14. time.sleep(5)
  15. else:
  16. break
  17. return r
  18. for user in users:
  19. r = get(f'https://github.com/{user}')
  20. if '<div id="org-repositories"' in r.text:
  21. # Organisation, ?page=2 pagination
  22. page = 1
  23. while True:
  24. for m in re.finditer(r'<a itemprop="name codeRepository"\s(?:[^>]*\s)?data-hovercard-url="/([^/>"]+/[^/>"]+)/hovercard"', r.text):
  25. print(f'https://github.com/{m.group(1)}')
  26. if '<a class="next_page"' not in r.text:
  27. # End of pagination
  28. break
  29. page += 1
  30. r = get(f'https://github.com/{user}?page={page}')
  31. else:
  32. # User, ?tab=repositories + cursor pagination
  33. r = get(f'https://github.com/{user}?tab=repositories')
  34. while True:
  35. for m in re.finditer(r'<a href="/([^/>"]+/[^/>"]+)" itemprop="name codeRepository"(\s[^>]*)?>', r.text):
  36. print(f'https://github.com/{m.group(1)}')
  37. if not (m := re.search(r'<a\s(?:[^>]*\s)?href="https://github\.com/[^/?"]+\?after=([^&]+)&amp;tab=repositories"(?:\s[^>]*)?>', r.text)):
  38. # End of pagination
  39. break
  40. r = get(f'https://github.com/{user}?after={m.group(1)}&tab=repositories')