from datetime import datetime, timezone from issue_core.core.models import Issue, IssueState, Label, Priority from .issue_backends import gitea_configured, local_backend, remote_backend def aufgabe_zu_issue(aufgabe) -> Issue: """Konvertiert eine Aufgabe in ein issue-facade Issue-Objekt.""" prioritaet_map = {1: Priority.HIGH, 2: Priority.MEDIUM, 3: Priority.LOW} labels = [ Label(name='task'), Label(name=f'priority:{prioritaet_map.get(aufgabe.prioritaet, Priority.MEDIUM).value}'), ] if aufgabe.typ: labels.append(Label(name=aufgabe.typ)) now = datetime.now(timezone.utc) return Issue( id='', number=0, title=aufgabe.titel, description=aufgabe.beschreibung or '', state=IssueState.OPEN, created_at=now, updated_at=now, labels=labels, ) def lokales_issue_erstellen(aufgabe) -> dict: """ Legt ein Issue im lokalen SQLite-Backend an. Gibt {'issue_facade_id', 'issue_key', 'sync_status'} zurück. """ issue = aufgabe_zu_issue(aufgabe) with local_backend() as b: created = b.create_issue(issue) return { 'issue_facade_id': str(created.id), 'issue_key': f'#{created.number}', 'sync_status': created.state.value, } def an_gitea_delegieren(aufgabe, external_issue) -> dict: """ Schiebt ein lokales Issue nach Gitea. Gibt {'issue_facade_backend', 'issue_facade_id', 'issue_url', 'issue_key', 'sync_status'} zurück. Wirft ValueError wenn Gitea nicht konfiguriert ist. """ with remote_backend() as b: if b is None: raise ValueError('Gitea nicht konfiguriert (ISSUE_FACADE_GITEA fehlt in settings)') issue = aufgabe_zu_issue(aufgabe) created = b.create_issue(issue) url = '' if created.sync_metadata: url = created.sync_metadata.get('url', '') return { 'issue_facade_backend': 'gitea', 'issue_facade_id': str(created.number), 'issue_url': url, 'issue_key': f'#{created.number}', 'sync_status': created.state.value, } def status_synchronisieren(external_issue) -> str: """ Liest den aktuellen Status aus dem konfigurierten Backend. Gibt den neuen sync_status-String zurück. """ from django.utils import timezone as dj_tz backend_ctx = ( remote_backend() if external_issue.issue_facade_backend == 'gitea' else local_backend() ) with backend_ctx as b: if b is None: raise ValueError('Backend nicht verfügbar') issue = b.get_issue(external_issue.issue_facade_id) neuer_status = issue.state.value if issue else 'error' external_issue.sync_status = neuer_status external_issue.letzter_sync = dj_tz.now() external_issue.save(update_fields=['sync_status', 'letzter_sync']) return neuer_status def issue_schliessen(external_issue) -> None: """Setzt das Issue im Backend auf CLOSED.""" backend_ctx = ( remote_backend() if external_issue.issue_facade_backend == 'gitea' else local_backend() ) with backend_ctx as b: if b is None: return issue = b.get_issue(external_issue.issue_facade_id) if issue: issue.state = IssueState.CLOSED b.update_issue(issue) external_issue.sync_status = 'closed' external_issue.save(update_fields=['sync_status']) def get_adapter(system: str): """Rückwärtskompatible Stub — gibt None zurück (kein manuelles Adapter-Dict mehr).""" return None