Add downsample series functionality and related UI updates

- Implemented asynchronous downsample task for series with progress tracking.
- Added new URL endpoint for downsample status.
- Updated Series model to include source_series_instance_uid.
- Enhanced case display template with new buttons for series actions.
- Added password reset functionality in user profile with appropriate alerts.
- Created migration for new source_series_instance_uid field in Series model.
This commit is contained in:
Ross
2026-05-18 16:20:38 +01:00
parent c55797636a
commit 63ea4cdf23
12 changed files with 606 additions and 294 deletions
+35
View File
@@ -30,6 +30,7 @@ from django.utils.safestring import mark_safe
# from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib.auth.forms import PasswordResetForm
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
@@ -167,6 +168,7 @@ def profile(request):
"is_cid_user_manager": is_cid_user_manager,
"supervisor_account": supervisor_account,
"supervisor_action": request.GET.get("supervisor_action", ""),
"password_reset_action": request.GET.get("password_reset_action", ""),
},
)
@@ -216,6 +218,7 @@ def account_profile(request, slug):
"is_cid_user_manager": is_cid_user_manager,
"supervisor_account": supervisor_account,
"supervisor_action": request.GET.get("supervisor_action", ""),
"password_reset_action": request.GET.get("password_reset_action", ""),
},
)
@@ -257,6 +260,38 @@ def account_set_supervisor(request, slug):
return redirect(f"{next_url}?supervisor_action=created")
@require_POST
@user_is_cid_user_manager
def account_send_password_reset(request, slug):
"""Send a password reset email for an existing user from their profile page."""
user = get_object_or_404(User, username=slug)
next_url = request.POST.get("next") or reverse("account_profile", kwargs={"slug": user.username})
email = (user.email or user.username or "").strip()
if not email:
return redirect(f"{next_url}?password_reset_action=no_email")
if not user.is_active:
return redirect(f"{next_url}?password_reset_action=inactive")
form = PasswordResetForm({"email": email})
if not form.is_valid():
return redirect(f"{next_url}?password_reset_action=invalid")
try:
form.save(
request=request,
use_https=request.is_secure(),
from_email=getattr(settings, "DEFAULT_FROM_EMAIL", None),
)
except Exception:
logger.exception("Failed to send password reset email for user {}", user.pk)
return redirect(f"{next_url}?password_reset_action=error")
return redirect(f"{next_url}?password_reset_action=sent")
@user_passes_test(lambda u: u.is_superuser)
def logs_view(request):
"""Display production logs from log.txt with search filtering.