|
| 1 | +# This python script accesses the GitHub API to extract the |
| 2 | +# number of stars, watchers and forks for all public repos. |
| 3 | +# Any public repo can be excluded by adding its name to the |
| 4 | +# exclude_repos list in the script. Once the data has been |
| 5 | +# extracted it will append to the activity.csv file that is |
| 6 | +# located in the data directory of the main branch. This file |
| 7 | +# is scheduled to run once a day at midnight using cron. The |
| 8 | +# scheduling code is located in .github/workflows/activity.yml |
| 9 | + |
| 10 | +import os |
| 11 | +import requests |
| 12 | +import csv |
| 13 | +from datetime import datetime, timedelta |
| 14 | +from github import Github |
| 15 | + |
| 16 | + |
| 17 | +def fetch_activity_stats(organization, token): |
| 18 | + base_url = 'https://api.github.com/orgs' |
| 19 | + headers = {'Authorization': f'token {token}'} |
| 20 | + |
| 21 | + url = f'{base_url}/{organization}/repos' |
| 22 | + response = requests.get(url, headers=headers) |
| 23 | + if response.status_code == 200: |
| 24 | + output = response.json() |
| 25 | + |
| 26 | + data = [] |
| 27 | + exclude_repos = ["discussions", ".github"] |
| 28 | + |
| 29 | + today = datetime.now().date() |
| 30 | + yesterday = today - timedelta(days=1) |
| 31 | + |
| 32 | + for repo_data in output: |
| 33 | + repo_name = repo_data['name'] |
| 34 | + repo_stars = repo_data['stargazers_count'] |
| 35 | + repo_forks = repo_data['forks_count'] |
| 36 | + repo_private = repo_data["private"] |
| 37 | + |
| 38 | + if repo_name in exclude_repos or repo_private: |
| 39 | + continue |
| 40 | + |
| 41 | + org_url = repo_data['url'] |
| 42 | + org_response = requests.get(org_url, headers=headers) |
| 43 | + org_data = org_response.json() |
| 44 | + repo_watchers = org_data['subscribers_count'] |
| 45 | + |
| 46 | + result = f"{yesterday},{repo_name},{repo_stars},{repo_watchers},{repo_forks}" |
| 47 | + data.append(result) |
| 48 | + |
| 49 | + return data |
| 50 | + |
| 51 | + else: |
| 52 | + print(f"Error: Unable to get data for {organization}. Status code: {response.status_code}") |
| 53 | + |
| 54 | + |
| 55 | +def update_csv_file(repo, file_path, data): |
| 56 | + file_contents = repo.get_contents(file_path) |
| 57 | + existing_data = file_contents.decoded_content.decode().splitlines() |
| 58 | + updated_data = existing_data + data |
| 59 | + |
| 60 | + updated_file_contents = '\n'.join(updated_data).encode() |
| 61 | + |
| 62 | + repo.update_file(file_path, "Appending data to CSV", updated_file_contents, file_contents.sha) |
| 63 | + |
| 64 | +def main(): |
| 65 | + organization = "analyticsinmotion" |
| 66 | + token = os.environ.get('TOKEN') |
| 67 | + |
| 68 | + data = fetch_activity_stats(organization, token) |
| 69 | + print(data) |
| 70 | + |
| 71 | + g = Github(os.getenv('TOKEN')) |
| 72 | + repo = g.get_repo('analyticsinmotion/github-stats') |
| 73 | + file_path = 'data/activity.csv' |
| 74 | + |
| 75 | + try: |
| 76 | + update_csv_file(repo, file_path, data) |
| 77 | + print("Data appended to CSV file successfully.") |
| 78 | + except Exception as e: |
| 79 | + print(f"Failed to update CSV file: {str(e)}") |
| 80 | + |
| 81 | +if __name__ == "__main__": |
| 82 | + main() |
0 commit comments