feat: release regional radar and mailbox integrations
deploy / deploy (push) Canceled after 0s

This commit is contained in:
Jens
2026-07-22 05:12:07 +02:00
parent 598d3ec18a
commit 551d0f46c2
131 changed files with 6209 additions and 336 deletions
+133 -6
View File
@@ -4,39 +4,88 @@ from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Count, Q
from django.http import HttpRequest
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils import timezone
from django.views.decorators.cache import never_cache
from django.views.decorators.http import require_POST
from django.views.generic import ListView
from apps.core.rate_limit import clear_rate_limit, is_rate_limited, register_rate_limit_failure
from apps.profiles.models import SearchProfile
from .forms import ManualImportForm
from .models import Source, SourcePolicyReview
from .forms import MailboxConnectionForm, ManualImportForm
from .models import MailboxConnection, Source, SourcePolicyReview
from .platforms import PLATFORM_ALERTS
from .services.mailbox_connections import MailboxCredentialError, save_mailbox_connection
from .services.manual_import import ManualImportError, ManualImportSummary, import_manual_source
from .services.policy import create_policy_review
from .tasks import fetch_source
from .tasks import fetch_source, poll_mailbox
def _source_list_queryset():
return Source.objects.prefetch_related("policy_reviews").all().order_by("name")
return (
Source.objects.prefetch_related("policy_reviews")
.exclude(domain="jobs.example.org", status=Source.Status.DISABLED)
.filter(
Q(metadata__hidden_from_source_list__isnull=True)
| Q(metadata__hidden_from_source_list=False)
)
.filter(Q(metadata__watchlist__isnull=True) | Q(metadata__watchlist=False))
.annotate(job_count=Count("job_aliases", distinct=True))
.order_by("name")
)
def _manual_import_context(request: HttpRequest, *, form: ManualImportForm, manual_result=None):
def _watchlist_queryset():
return (
Source.objects.filter(metadata__watchlist=True)
.filter(
Q(metadata__hidden_from_source_list__isnull=True)
| Q(metadata__hidden_from_source_list=False)
)
.order_by("name")
)
def _manual_import_context(
request: HttpRequest,
*,
form: ManualImportForm,
manual_result=None,
mailbox_form: MailboxConnectionForm | None = None,
editing_mailbox: MailboxConnection | None = None,
):
base_queryset = _source_list_queryset()
watchlist_queryset = _watchlist_queryset()
mailbox_connections = list(
request.user.mailbox_connections.filter(platform__in=PLATFORM_ALERTS)
)
active_search_profile = SearchProfile.objects.filter(user=request.user, is_active=True).first()
return {
"sources": base_queryset,
"active_source_count": Source.objects.filter(status=Source.Status.ACTIVE).count(),
"source_total_count": base_queryset.count(),
"review_pending_count": Source.objects.filter(policy=Source.Policy.REVIEW).count(),
"watchlist_sources": watchlist_queryset,
"watchlist_count": watchlist_queryset.count(),
"manual_import_form": form,
"manual_import_bookmarklet_endpoint": request.build_absolute_uri(
reverse("sources:manual_import")
),
"manual_import_paste_max_bytes": settings.MANUAL_IMPORT_PASTE_MAX_BYTES,
"manual_import_result": manual_result,
"platform_alert_ingress_ready": any(
connection.enabled for connection in mailbox_connections
),
"mailbox_connections": mailbox_connections,
"platform_alerts": PLATFORM_ALERTS.values(),
"mailbox_form": mailbox_form or MailboxConnectionForm(),
"editing_mailbox": editing_mailbox,
"mailbox_credential_key_ready": bool(settings.MAILBOX_CREDENTIAL_KEYS),
"active_search_profile": active_search_profile,
}
@@ -108,7 +157,7 @@ def _action_to_review(
def bulk_candidate_action(request):
action = request.POST.get("action")
source_ids = [int(raw_id) for raw_id in request.POST.getlist("source_ids") if raw_id.isdigit()]
sources = Source.objects.filter(id__in=source_ids).exclude(policy=Source.Policy.DENY)
sources = _source_list_queryset().filter(id__in=source_ids).exclude(policy=Source.Policy.DENY)
if not sources.exists():
messages.info(request, "Geen bruikbare bronregels geselecteerd.")
return redirect("sources:list")
@@ -148,6 +197,84 @@ def retry_source(request, pk: int):
return redirect("sources:list")
@login_required
@require_POST
def save_mailbox(request, pk: int | None = None):
instance = None
if pk is not None:
instance = get_object_or_404(MailboxConnection, pk=pk, user=request.user)
form = MailboxConnectionForm(request.POST, instance=instance)
if form.is_valid():
try:
connection = save_mailbox_connection(
user=request.user,
cleaned_data=dict(form.cleaned_data),
instance=instance,
)
except MailboxCredentialError as exc:
form.add_error("password", str(exc))
else:
poll_mailbox.delay(connection.pk, force=True)
messages.success(
request,
f"{connection.get_platform_display()}-mailbox opgeslagen; "
"verbindingstest ingepland.",
)
return redirect("sources:list")
messages.error(request, "Controleer de mailboxinstellingen.")
return render(
request,
"sources/list.html",
_manual_import_context(
request,
form=ManualImportForm(),
mailbox_form=form,
editing_mailbox=instance,
),
)
@login_required
def edit_mailbox(request, pk: int):
connection = get_object_or_404(MailboxConnection, pk=pk, user=request.user)
if request.method == "POST":
return save_mailbox(request, pk=pk)
return render(
request,
"sources/list.html",
_manual_import_context(
request,
form=ManualImportForm(),
mailbox_form=MailboxConnectionForm(instance=connection),
editing_mailbox=connection,
),
)
@login_required
@require_POST
def sync_platform_alerts(request, pk: int):
connection = get_object_or_404(MailboxConnection, pk=pk, user=request.user)
if not connection.enabled:
messages.error(request, "Activeer deze mailbox voordat je synchroniseert.")
else:
poll_mailbox.delay(connection.pk, force=True)
messages.success(request, f"{connection.get_platform_display()}-mailimport ingepland.")
return redirect("sources:list")
@login_required
@require_POST
def toggle_mailbox(request, pk: int):
connection = get_object_or_404(MailboxConnection, pk=pk, user=request.user)
connection.enabled = not connection.enabled
connection.next_poll_at = timezone.now()
connection.save(update_fields=["enabled", "next_poll_at", "updated_at"])
state = "geactiveerd" if connection.enabled else "gepauzeerd"
messages.success(request, f"{connection.get_platform_display()}-mailbox {state}.")
return redirect("sources:list")
@login_required
@never_cache
def manual_import_view(request):