diff --git a/.github/workflows/stats-tracker.yml b/.github/workflows/stats-tracker.yml index d26f0b7..d4c40b3 100644 --- a/.github/workflows/stats-tracker.yml +++ b/.github/workflows/stats-tracker.yml @@ -13,6 +13,7 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + metadata: read steps: - name: Checkout repository diff --git a/REALTIME_STATS.json b/REALTIME_STATS.json index 5d3ef15..d835670 100644 --- a/REALTIME_STATS.json +++ b/REALTIME_STATS.json @@ -1,13 +1,13 @@ { - "timestamp": "2026-01-04T23:06:02.761107Z", + "timestamp": "2026-01-05T14:37:41.805435Z", "local": { - "commit_count": 4, + "commit_count": 5, "unique_contributors": 2, - "last_commit_date": "2026-01-04 23:04:23 +0000", - "last_commit_message": "Remove stats files from .gitignore to enable auto-tracking workflow", - "current_branch": "copilot/fix-auto-tracking-issues", + "last_commit_date": "2026-01-05 14:36:30 +0000", + "last_commit_message": "Add caching for GitHub stats when API calls fail", + "current_branch": "copilot/fix-real-time-stats-api", "tracked_files": 63, - "timestamp": "2026-01-04T23:06:02.771988Z" + "timestamp": "2026-01-05T14:37:41.816614Z" }, "github": {} } \ No newline at end of file diff --git a/REALTIME_STATS.md b/REALTIME_STATS.md index 35bc497..bff996a 100644 --- a/REALTIME_STATS.md +++ b/REALTIME_STATS.md @@ -1,6 +1,6 @@ # Repository Statistics - Real-Time -**Last Updated:** 2026-01-04T23:06:02.761107Z +**Last Updated:** 2026-01-05T14:37:41.805435Z ## šŸ“Š Current Statistics @@ -8,12 +8,12 @@ | Metric | Value | |--------|-------| -| 🌿 Current Branch | `copilot/fix-auto-tracking-issues` | -| šŸ“ Total Commits | 4 | +| 🌿 Current Branch | `copilot/fix-real-time-stats-api` | +| šŸ“ Total Commits | 5 | | šŸ‘„ Contributors | 2 | | šŸ“„ Tracked Files | 63 | -| šŸ• Last Commit | 2026-01-04 23:04:23 | -| šŸ’¬ Last Message | Remove stats files from .gitignore to enable auto-tracking workflow | +| šŸ• Last Commit | 2026-01-05 14:36:30 | +| šŸ’¬ Last Message | Add caching for GitHub stats when API calls fail | --- @@ -22,7 +22,7 @@ Add these to your README.md: ```markdown - + ``` --- diff --git a/STATS_HISTORY.json b/STATS_HISTORY.json index 7e01710..96034cd 100644 --- a/STATS_HISTORY.json +++ b/STATS_HISTORY.json @@ -89,5 +89,83 @@ "timestamp": "2026-01-04T23:06:02.771988Z" }, "github": {} + }, + { + "timestamp": "2026-01-05T14:28:02.069860Z", + "local": { + "commit_count": 2, + "unique_contributors": 2, + "last_commit_date": "2026-01-05 14:26:06 +0000", + "last_commit_message": "Initial plan", + "current_branch": "copilot/fix-real-time-stats-api", + "tracked_files": 63, + "timestamp": "2026-01-05T14:28:02.080588Z" + }, + "github": {} + }, + { + "timestamp": "2026-01-05T14:28:11.901823Z", + "local": { + "commit_count": 2, + "unique_contributors": 2, + "last_commit_date": "2026-01-05 14:26:06 +0000", + "last_commit_message": "Initial plan", + "current_branch": "copilot/fix-real-time-stats-api", + "tracked_files": 63, + "timestamp": "2026-01-05T14:28:11.912102Z" + }, + "github": {} + }, + { + "timestamp": "2026-01-05T14:31:28.134321Z", + "local": { + "commit_count": 3, + "unique_contributors": 2, + "last_commit_date": "2026-01-05 14:30:26 +0000", + "last_commit_message": "Initial plan", + "current_branch": "copilot/fix-real-time-stats-api", + "tracked_files": 63, + "timestamp": "2026-01-05T14:31:28.144853Z" + }, + "github": {} + }, + { + "timestamp": "2026-01-05T14:32:59.155485Z", + "local": { + "commit_count": 3, + "unique_contributors": 2, + "last_commit_date": "2026-01-05 14:30:26 +0000", + "last_commit_message": "Initial plan", + "current_branch": "copilot/fix-real-time-stats-api", + "tracked_files": 63, + "timestamp": "2026-01-05T14:32:59.166468Z" + }, + "github": {} + }, + { + "timestamp": "2026-01-05T14:36:19.877520Z", + "local": { + "commit_count": 4, + "unique_contributors": 2, + "last_commit_date": "2026-01-05 14:33:19 +0000", + "last_commit_message": "Improve GitHub API error handling and update auth format", + "current_branch": "copilot/fix-real-time-stats-api", + "tracked_files": 63, + "timestamp": "2026-01-05T14:36:19.888287Z" + }, + "github": {} + }, + { + "timestamp": "2026-01-05T14:37:41.805435Z", + "local": { + "commit_count": 5, + "unique_contributors": 2, + "last_commit_date": "2026-01-05 14:36:30 +0000", + "last_commit_message": "Add caching for GitHub stats when API calls fail", + "current_branch": "copilot/fix-real-time-stats-api", + "tracked_files": 63, + "timestamp": "2026-01-05T14:37:41.816614Z" + }, + "github": {} } ] \ No newline at end of file diff --git a/realtime_stats_tracker.py b/realtime_stats_tracker.py index eaa6acf..8111eba 100755 --- a/realtime_stats_tracker.py +++ b/realtime_stats_tracker.py @@ -34,18 +34,41 @@ def github_api_request(self, endpoint): token = self.get_github_token() if token: - headers['Authorization'] = f'token {token}' + headers['Authorization'] = f'Bearer {token}' try: req = urllib.request.Request(url, headers=headers) with urllib.request.urlopen(req, timeout=10) as response: return json.loads(response.read().decode()) except urllib.error.HTTPError as e: + # Try to get detailed error message from response body + error_msg = None + try: + error_body = e.read().decode() + error_data = json.loads(error_body) + error_msg = error_data.get('message', '') + except Exception: + pass + if e.code == 403: - print(f"āš ļø GitHub API rate limit reached. Set GITHUB_TOKEN env var for higher limits.") + if error_msg: + print(f"āš ļø GitHub API error (403): {error_msg}") + if 'rate limit' in error_msg.lower(): + print(f"šŸ’” Set GITHUB_TOKEN env var for higher rate limits.") + elif 'credentials' in error_msg.lower() or 'token' in error_msg.lower(): + print(f"šŸ’” Check that GITHUB_TOKEN has the correct permissions.") + else: + print(f"āš ļø GitHub API access denied (403). Set GITHUB_TOKEN env var with proper permissions.") + return None + elif e.code == 404: + print(f"āš ļø GitHub API endpoint not found (404): {endpoint}") + return None + else: + if error_msg: + print(f"āš ļø GitHub API error {e.code}: {error_msg}") + else: + print(f"āš ļø GitHub API error {e.code}: {e.reason}") return None - print(f"āš ļø GitHub API error {e.code}: {e.reason}") - return None except Exception as e: print(f"āš ļø Error fetching from GitHub API: {e}") return None @@ -151,12 +174,28 @@ def collect_stats(self): """Collect all statistics""" print("šŸ” Collecting repository statistics...\n") + # Try to load previous stats for fallback + previous_github_stats = {} + if self.stats_file.exists(): + try: + with open(self.stats_file, 'r') as f: + previous_data = json.load(f) + previous_github_stats = previous_data.get('github', {}) + except Exception: + pass + stats = { "timestamp": datetime.now(UTC).strftime('%Y-%m-%dT%H:%M:%S.%fZ'), "local": self.get_local_git_stats(), "github": self.get_github_stats() } + # If GitHub stats are empty but we have previous stats, preserve them + if not stats["github"] and previous_github_stats: + print("ā„¹ļø Using cached GitHub stats from previous successful fetch") + stats["github"] = previous_github_stats + stats["github_cached"] = True + return stats def save_stats(self, stats): @@ -226,6 +265,8 @@ def display_stats(self, stats): # GitHub stats if stats.get("github"): print("\n🌐 GITHUB STATISTICS:") + if stats.get("github_cached"): + print(" ā„¹ļø (Using cached data from previous successful fetch)") print("-" * 80) gh = stats["github"] print(f" ⭐ Stars: {gh.get('stars', 'N/A')}") @@ -251,7 +292,12 @@ def generate_stats_markdown(self, stats): md = f"""# Repository Statistics - Real-Time **Last Updated:** {stats['timestamp']} - +""" + + if stats.get("github_cached"): + md += "\n> ā„¹ļø **Note:** GitHub metrics below are cached from previous successful fetch (current API call failed)\n" + + md += """ ## šŸ“Š Current Statistics """