Faktenkompass: UI-Rebrand, Admin-Assistent und Produktions-Setup.
Modernisiert die öffentliche Oberfläche mit Inter, Dark Mode und Live-Suche, ergänzt KI-gestützte Entwürfe im Admin mit Nachweis-Uploads und dokumentiert Daphne/Nginx für den Serverbetrieb. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
from django.contrib import admin, messages
|
||||
from django.contrib.admin.views.decorators import staff_member_required
|
||||
from django.core.exceptions import SuspiciousFileOperation
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import path, reverse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views import View
|
||||
|
||||
from claims.forms import AssistantInputForm, RefineDraftForm, ReviewDraftForm
|
||||
from claims.models import ClaimDraft
|
||||
from claims.services.ai_assistant import AIAssistantError
|
||||
from claims.services.article_fetcher import ArticleFetchError
|
||||
from claims.services.draft_processor import process_claim_draft
|
||||
from claims.services.draft_publisher import DraftPublishError, publish_draft
|
||||
|
||||
|
||||
def _get_user_draft(request, draft_id):
|
||||
if request.user.is_superuser:
|
||||
return get_object_or_404(ClaimDraft, pk=draft_id)
|
||||
return get_object_or_404(ClaimDraft, pk=draft_id, created_by=request.user)
|
||||
|
||||
|
||||
@method_decorator(staff_member_required, name='dispatch')
|
||||
class AssistantView(View):
|
||||
template_name = 'admin/claims/assistant.html'
|
||||
|
||||
def get(self, request):
|
||||
form = AssistantInputForm()
|
||||
drafts = ClaimDraft.objects.filter(created_by=request.user).order_by('-created_at')[:10]
|
||||
return render(request, self.template_name, {
|
||||
**admin.site.each_context(request),
|
||||
'form': form,
|
||||
'recent_drafts': drafts,
|
||||
'title': 'Fakten-Assistent',
|
||||
'opts': ClaimDraft._meta,
|
||||
})
|
||||
|
||||
def post(self, request):
|
||||
form = AssistantInputForm(request.POST, request.FILES)
|
||||
if not form.is_valid():
|
||||
return render(request, self.template_name, {
|
||||
**admin.site.each_context(request),
|
||||
'form': form,
|
||||
'recent_drafts': ClaimDraft.objects.filter(created_by=request.user)[:10],
|
||||
'title': 'Fakten-Assistent',
|
||||
'opts': ClaimDraft._meta,
|
||||
})
|
||||
|
||||
draft = ClaimDraft.objects.create(
|
||||
created_by=request.user,
|
||||
article_url=form.cleaned_data.get('article_url') or '',
|
||||
user_notes=form.cleaned_data.get('user_notes') or '',
|
||||
uploaded_file=form.cleaned_data.get('uploaded_file'),
|
||||
)
|
||||
|
||||
try:
|
||||
process_claim_draft(draft)
|
||||
except (ArticleFetchError, AIAssistantError):
|
||||
return redirect('admin:claims_claimdraft_review', draft.pk)
|
||||
|
||||
messages.success(request, 'Entwurf wurde erstellt. Bitte vor der Veröffentlichung prüfen.')
|
||||
return redirect('admin:claims_claimdraft_review', draft.pk)
|
||||
|
||||
|
||||
@method_decorator(staff_member_required, name='dispatch')
|
||||
class ReviewDraftView(View):
|
||||
template_name = 'admin/claims/review_draft.html'
|
||||
|
||||
def get(self, request, draft_id):
|
||||
draft = _get_user_draft(request, draft_id)
|
||||
return render(request, self.template_name, {
|
||||
**admin.site.each_context(request),
|
||||
'draft': draft,
|
||||
'form': ReviewDraftForm(instance=draft),
|
||||
'refine_form': RefineDraftForm(),
|
||||
'title': f'Entwurf prüfen: {draft.title or draft.pk}',
|
||||
'opts': ClaimDraft._meta,
|
||||
})
|
||||
|
||||
def post(self, request, draft_id):
|
||||
draft = _get_user_draft(request, draft_id)
|
||||
action = request.POST.get('action')
|
||||
|
||||
if action == 'refine':
|
||||
refine_form = RefineDraftForm(request.POST)
|
||||
if refine_form.is_valid():
|
||||
try:
|
||||
process_claim_draft(draft, refinement=refine_form.cleaned_data['refinement'])
|
||||
messages.success(request, 'Entwurf wurde überarbeitet.')
|
||||
except (ArticleFetchError, AIAssistantError) as exc:
|
||||
messages.error(request, str(exc))
|
||||
return redirect('admin:claims_claimdraft_review', draft.pk)
|
||||
|
||||
if action == 'reject':
|
||||
draft.status = ClaimDraft.DraftStatus.REJECTED
|
||||
draft.save(update_fields=['status', 'updated_at'])
|
||||
messages.info(request, 'Entwurf wurde verworfen.')
|
||||
return redirect('admin:claims_claimdraft_assistant')
|
||||
|
||||
form = ReviewDraftForm(request.POST, instance=draft)
|
||||
if not form.is_valid():
|
||||
return render(request, self.template_name, {
|
||||
**admin.site.each_context(request),
|
||||
'draft': draft,
|
||||
'form': form,
|
||||
'refine_form': RefineDraftForm(),
|
||||
'title': f'Entwurf prüfen: {draft.title or draft.pk}',
|
||||
'opts': ClaimDraft._meta,
|
||||
})
|
||||
|
||||
draft = form.save()
|
||||
|
||||
if action == 'save':
|
||||
draft.status = ClaimDraft.DraftStatus.REVIEW
|
||||
draft.save(update_fields=['status', 'updated_at'])
|
||||
messages.success(request, 'Änderungen gespeichert.')
|
||||
return redirect('admin:claims_claimdraft_review', draft.pk)
|
||||
|
||||
if action == 'publish':
|
||||
try:
|
||||
claim = publish_draft(draft)
|
||||
except DraftPublishError as exc:
|
||||
messages.error(request, str(exc))
|
||||
return redirect('admin:claims_claimdraft_review', draft.pk)
|
||||
except SuspiciousFileOperation as exc:
|
||||
messages.error(request, f'Datei konnte nicht gespeichert werden: {exc}')
|
||||
return redirect('admin:claims_claimdraft_review', draft.pk)
|
||||
|
||||
messages.success(
|
||||
request,
|
||||
f'Behauptung „{claim.title}" wurde veröffentlicht.',
|
||||
)
|
||||
return redirect(reverse('admin:claims_claim_change', args=[claim.pk]))
|
||||
|
||||
return redirect('admin:claims_claimdraft_review', draft.pk)
|
||||
Reference in New Issue
Block a user