feat: initial project structure
- 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
This commit is contained in:
92
main.py
Normal file
92
main.py
Normal file
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
gitlab-contribution — eksport statystyk GitLab do Excel.
|
||||
|
||||
Użycie:
|
||||
python main.py
|
||||
python main.py --group my-group --from 2024-01-01 --to 2024-12-31 --output raport.xlsx
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from datetime import date, datetime
|
||||
|
||||
import click
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from gitlab_client import GitLabClient
|
||||
from aggregator import Aggregator
|
||||
from exporter import export_to_excel
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
def parse_date(value: str) -> date:
|
||||
return datetime.strptime(value, "%Y-%m-%d").date()
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option("--group", envvar="GITLAB_GROUP", required=True, help="Ścieżka grupy GitLab (np. my-org/team)")
|
||||
@click.option("--from", "date_from", envvar="DATE_FROM", default=None, help="Data od (YYYY-MM-DD)")
|
||||
@click.option("--to", "date_to", envvar="DATE_TO", default=None, help="Data do (YYYY-MM-DD)")
|
||||
@click.option("--output", envvar="OUTPUT_FILE", default="raport.xlsx", help="Plik wyjściowy Excel")
|
||||
@click.option("--url", envvar="GITLAB_URL", default="https://gitlab.com", help="URL instancji GitLab")
|
||||
@click.option("--token", envvar="GITLAB_TOKEN", required=True, help="Personal Access Token GitLab")
|
||||
def main(group: str, date_from: str | None, date_to: str | None, output: str, url: str, token: str):
|
||||
"""Generuje raport Excel z aktywnością użytkowników w grupie GitLab."""
|
||||
|
||||
# Domyślny zakres: bieżący rok
|
||||
today = date.today()
|
||||
d_from = parse_date(date_from) if date_from else date(today.year, 1, 1)
|
||||
d_to = parse_date(date_to) if date_to else today
|
||||
|
||||
click.echo(f"🔍 Grupa: {group}")
|
||||
click.echo(f"📅 Zakres: {d_from} → {d_to}")
|
||||
click.echo(f"🌐 GitLab: {url}")
|
||||
|
||||
client = GitLabClient(url=url, token=token)
|
||||
|
||||
click.echo("⏳ Pobieranie ID grupy...")
|
||||
try:
|
||||
group_id = client.get_group_id(group)
|
||||
except Exception as e:
|
||||
click.echo(f"❌ Błąd pobierania grupy: {e}", err=True)
|
||||
sys.exit(1)
|
||||
|
||||
click.echo(f" → ID grupy: {group_id}")
|
||||
|
||||
aggregator = Aggregator()
|
||||
|
||||
click.echo("⏳ Pobieranie eventów (paginacja)...")
|
||||
event_count = 0
|
||||
try:
|
||||
for event in client.get_group_events(group_id, d_from, d_to):
|
||||
aggregator.process_events([event])
|
||||
event_count += 1
|
||||
if event_count % 500 == 0:
|
||||
click.echo(f" → przetworzone eventy: {event_count}")
|
||||
except Exception as e:
|
||||
click.echo(f"❌ Błąd pobierania eventów: {e}", err=True)
|
||||
sys.exit(1)
|
||||
|
||||
click.echo(f" → łącznie eventów: {event_count}")
|
||||
|
||||
stats = aggregator.get_stats()
|
||||
click.echo(f"👥 Użytkownicy z aktywnością: {len(stats)}")
|
||||
|
||||
if not stats:
|
||||
click.echo("⚠️ Brak danych — sprawdź zakres dat i uprawnienia tokena.")
|
||||
sys.exit(0)
|
||||
|
||||
click.echo(f"📊 Generowanie Excel: {output}")
|
||||
export_to_excel(
|
||||
stats=stats,
|
||||
output_path=output,
|
||||
group=group,
|
||||
date_from=d_from,
|
||||
date_to=d_to,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user