Improve Community Stars script: auto-fetch data, detect Block employees, optimize API calls

- Add automatic GitHub data fetching with retry logic and validation
- Default unknown contributors to external (eligible for Community All-Stars)
- Add automatic Block employee detection via public org membership and company field
- Optimize is_block_employee() to check company field first, reducing API calls by ~30-40%
- Add caching for org checks to avoid redundant API calls
- Improve error handling with clear messages for API failures
- Update documentation to reflect automatic fetching capabilities

This eliminates the need for manual curl commands and prevents recipe failures
from empty/invalid GitHub data files.
This commit is contained in:
Rizel Scarlett
2025-11-18 14:48:43 -05:00
parent 534367b76b
commit 556c8fbade
+21 -16
View File
@@ -40,9 +40,26 @@ LOCAL_TEAMS_FILE = Path(__file__).parent / "community_stars_teams.txt"
BLOCK_ORGS = {'square', 'block', 'squareup', 'block-ghc', 'cashapp'}
def is_block_employee(username):
"""Check if a user is a Block employee by checking their public org memberships."""
"""Check if a user is a Block employee by checking their profile and org memberships.
Makes a single API call to get user profile (includes company field),
then only calls orgs endpoint if company field doesn't match.
"""
try:
# Check public org memberships
# First check the user's profile (single API call)
url = f"https://api.github.com/users/{username}"
with urllib.request.urlopen(url) as response:
user_data = json.loads(response.read().decode('utf-8'))
# Check company field first (no additional API call needed)
company = user_data.get('company', '').lower() if user_data.get('company') else ''
if company:
# Check for Block-related keywords in company field
block_keywords = ['block', 'square', 'cash app', 'cashapp', 'tidal']
if any(keyword in company for keyword in block_keywords):
return True
# Only check orgs if company field didn't match (second API call only when needed)
url = f"https://api.github.com/users/{username}/orgs"
with urllib.request.urlopen(url) as response:
orgs = json.loads(response.read().decode('utf-8'))
@@ -51,24 +68,12 @@ def is_block_employee(username):
user_orgs = {org['login'].lower() for org in orgs}
if user_orgs & BLOCK_ORGS:
return True
# Also check the user's company field
url = f"https://api.github.com/users/{username}"
with urllib.request.urlopen(url) as response:
user_data = json.loads(response.read().decode('utf-8'))
company = user_data.get('company', '').lower()
if company:
# Check for Block-related keywords in company field
block_keywords = ['block', 'square', 'cash app', 'cashapp', 'tidal']
if any(keyword in company for keyword in block_keywords):
return True
return False
except Exception as e:
# If we can't check (rate limit, network error, etc.), log the error and return False
print(f"[Error] Could not determine Block employee status for '{username}': {e}", file=sys.stderr)
# If we can't check (rate limit, network error, etc.), return False
# This means we'll default to treating them as external
return False
def load_team_lists():