- GitLabClient: REST Events API z paginacją, pobieranie członków grupy - Aggregator: zliczanie commitów, MR, komentarzy per użytkownik - Exporter: generowanie pliku Excel (openpyxl) ze stylami - main.py: CLI (click) + .env support - README, .env.example, requirements.txt, .gitignore
70 lines
2.1 KiB
Python
70 lines
2.1 KiB
Python
"""
|
|
Agregator — przetwarza eventy GitLab na statystyki per użytkownik.
|
|
"""
|
|
|
|
from collections import defaultdict
|
|
from dataclasses import dataclass, field
|
|
|
|
|
|
@dataclass
|
|
class UserStats:
|
|
name: str = ""
|
|
username: str = ""
|
|
user_id: int = 0
|
|
commits: int = 0
|
|
merge_requests: int = 0
|
|
comments: int = 0
|
|
other: int = 0
|
|
|
|
@property
|
|
def total_contributions(self) -> int:
|
|
return self.commits + self.merge_requests + self.comments + self.other
|
|
|
|
|
|
class Aggregator:
|
|
def __init__(self):
|
|
self._stats: dict[int, UserStats] = defaultdict(UserStats)
|
|
|
|
def process_events(self, events: list[dict]) -> None:
|
|
"""
|
|
Przetwarza listę eventów GitLab i agreguje statystyki.
|
|
|
|
Typy akcji:
|
|
- pushed → commit
|
|
- merged → merge request
|
|
- commented → komentarz
|
|
- created/closed/reopened → inne
|
|
"""
|
|
for event in events:
|
|
author = event.get("author") or {}
|
|
uid = author.get("id") or event.get("author_id")
|
|
if not uid:
|
|
continue
|
|
|
|
stats = self._stats[uid]
|
|
stats.user_id = uid
|
|
stats.name = author.get("name", stats.name)
|
|
stats.username = author.get("username", stats.username)
|
|
|
|
action = event.get("action_name", "")
|
|
|
|
if action == "pushed to" or action == "pushed new":
|
|
# Liczymy commity z push events
|
|
push_data = event.get("push_data") or {}
|
|
commit_count = push_data.get("commit_count", 1)
|
|
stats.commits += max(commit_count, 1)
|
|
elif action in ("accepted", "merged"):
|
|
stats.merge_requests += 1
|
|
elif action == "commented on":
|
|
stats.comments += 1
|
|
else:
|
|
stats.other += 1
|
|
|
|
def get_stats(self) -> list[UserStats]:
|
|
"""Zwraca listę statystyk posortowaną malejąco po contributions."""
|
|
return sorted(
|
|
self._stats.values(),
|
|
key=lambda s: s.total_contributions,
|
|
reverse=True,
|
|
)
|