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.
 
 
 

68 lines
2.1 KiB

  1. #!/usr/bin/env python3
  2. import logging
  3. import re
  4. import requests
  5. import sys
  6. import time
  7. GIT_URLS_OPTION = '--git-urls'
  8. GITGUD_COMPLETE_ITEMS_OPTION = '--gitgud-complete-items'
  9. MODES = (GIT_URLS_OPTION, GITGUD_COMPLETE_ITEMS_OPTION)
  10. mode = None
  11. users = sys.argv[1:]
  12. if users and users[0] in MODES:
  13. mode = users[0]
  14. users = users[1:]
  15. assert users and (mode is None or mode in MODES) and not users[0].startswith('--'), f'Usage: github-list-repos [{" | ".join(MODES)}] USER [USER...]'
  16. def get(url):
  17. while True:
  18. logging.info(f'Fetching {url}')
  19. r = requests.get(url, headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0'})
  20. if r.status_code == 429:
  21. logging.warning(f'Got 429, sleeping and retrying')
  22. time.sleep(5)
  23. else:
  24. break
  25. return r
  26. def p(repoName):
  27. if mode is None:
  28. print(f'https://github.com/{repoName}')
  29. elif mode == GIT_URLS_OPTION:
  30. print(f'https://github.com/{repoName}.git')
  31. print(f'https://github.com/{repoName}.wiki.git')
  32. elif mode == GITGUD_COMPLETE_ITEMS_OPTION:
  33. print(f'web:complete:{repoName}')
  34. for user in users:
  35. r = get(f'https://github.com/{user}')
  36. if '<div id="org-repositories"' in r.text:
  37. # Organisation, complete list under /orgs/ with ?page=2 pagination
  38. r = get(f'https://github.com/orgs/{user}/repositories')
  39. page = 1
  40. while True:
  41. for m in re.finditer(r'<a itemprop="name codeRepository"\s(?:[^>]*\s)?data-hovercard-url="/([^/>"]+/[^/>"]+)/hovercard"', r.text):
  42. p(m.group(1))
  43. if '<a class="next_page"' not in r.text:
  44. # End of pagination
  45. break
  46. page += 1
  47. r = get(f'https://github.com/orgs/{user}/repositories?page={page}')
  48. else:
  49. # User, ?tab=repositories + cursor pagination
  50. r = get(f'https://github.com/{user}?tab=repositories')
  51. while True:
  52. for m in re.finditer(r'<a href="/([^/>"]+/[^/>"]+)" itemprop="name codeRepository"(\s[^>]*)?>', r.text):
  53. p(m.group(1))
  54. if not (m := re.search(r'<a\s(?=(?:[^>]*\s)?class="next_page"(?:\s[^>]*)?>)(?:[^>]*\s)?href="/[^/?"]+\?page=([^&]+)&amp;tab=repositories"(?:\s[^>]*)?>', r.text)):
  55. # End of pagination
  56. break
  57. r = get(f'https://github.com/{user}?page={m.group(1)}&tab=repositories')