]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Add sanity check to system status
authorshamoon <4887959+shamoon@users.noreply.github.com>
Fri, 14 Feb 2025 03:38:59 +0000 (19:38 -0800)
committershamoon <4887959+shamoon@users.noreply.github.com>
Mon, 17 Feb 2025 16:19:11 +0000 (08:19 -0800)
src-ui/src/app/components/common/system-status-dialog/system-status-dialog.component.html
src-ui/src/app/components/common/system-status-dialog/system-status-dialog.component.spec.ts
src-ui/src/app/data/system-status.ts
src/documents/sanity_checker.py
src/documents/views.py

index 2dc934df455aad7a3e16fcd6bb2beec15a5ccc54..091123fc9f7bd65b58b343605dfd08a370c7f819 100644 (file)
               <ng-template #classifierStatus>
                 <h6><ng-container i18n>Last Trained</ng-container>:</h6> <span class="font-monospace small">{{status.tasks.classifier_last_trained | customDate:'medium'}}</span>
               </ng-template>
+              <dt i18n>Sanity Checker</dt>
+              <dd class="d-flex align-items-center">
+                {{status.tasks.sanity_check_status}}
+                @if (status.tasks.sanity_check_status === 'OK') {
+                  @if (isStale(status.tasks.sanity_check_last_run)) {
+                    <i-bs name="exclamation-triangle-fill" class="text-warning ms-2 lh-1" [ngbPopover]="sanityCheckerStatus" triggers="mouseenter:mouseleave"></i-bs>
+                  } @else {
+                    <i-bs name="check-circle-fill" class="text-primary ms-2 lh-1" [ngbPopover]="sanityCheckerStatus" triggers="mouseenter:mouseleave"></i-bs>
+                  }
+                } @else {
+                  <i-bs name="exclamation-triangle-fill" class="text-danger ms-2 lh-1" ngbPopover="{{status.tasks.sanity_check_error}}" triggers="mouseenter:mouseleave"></i-bs>
+                }
+              </dd>
+              <ng-template #sanityCheckerStatus>
+                <h6><ng-container i18n>Last Run</ng-container>:</h6> <span class="font-monospace small">{{status.tasks.sanity_check_last_run | customDate:'medium'}}</span>
+              </ng-template>
             </dl>
           </div>
         </div>
index cd076b18553935cd9048af3894f9cbfea240a728..af76a53f5ed2a12ea95c1fd6ed665ed46bbde7db 100644 (file)
@@ -42,6 +42,9 @@ const status: SystemStatus = {
     classifier_status: SystemStatusItemStatus.OK,
     classifier_last_trained: new Date().toISOString(),
     classifier_error: null,
+    sanity_check_status: SystemStatusItemStatus.OK,
+    sanity_check_last_run: new Date().toISOString(),
+    sanity_check_error: null,
   },
 }
 
index a8f4ca621d83a7f140caa0abf59ff405fbecb7f0..146208bad38fd44abf1b884dae032eb1dd3d8969 100644 (file)
@@ -38,5 +38,8 @@ export interface SystemStatus {
     classifier_status: SystemStatusItemStatus
     classifier_last_trained: string // ISO date string
     classifier_error: string
+    sanity_check_status: SystemStatusItemStatus
+    sanity_check_last_run: string // ISO date string
+    sanity_check_error: string
   }
 }
index cfb30e584c328639306eaff9a9580606f4f62b23..5cd5bdce4d6eb625c68d981e862dcf5f0c4731cf 100644 (file)
@@ -62,13 +62,13 @@ class SanityCheckFailedException(Exception):
 
 
 def check_sanity(*, progress=False, scheduled=True) -> SanityCheckMessages:
-    task = PaperlessTask.objects.create(
+    paperless_task = PaperlessTask.objects.create(
         task_id=uuid.uuid4(),
         type=PaperlessTask.TaskType.SCHEDULED_TASK
         if scheduled
         else PaperlessTask.TaskType.MANUAL_TASK,
         task_name="check_sanity",
-        status=PaperlessTask.TASK_STATE_CHOICES.STARTED,
+        status=states.STARTED,
         date_created=timezone.now(),
         date_started=timezone.now(),
     )
@@ -156,8 +156,11 @@ def check_sanity(*, progress=False, scheduled=True) -> SanityCheckMessages:
     for extra_file in present_files:
         messages.warning(None, f"Orphaned file in media dir: {extra_file}")
 
-    task.status = states.SUCCESS if not messages.has_error else states.FAILED
+    paperless_task.status = states.SUCCESS if not messages.has_error else states.FAILURE
     # result is concatenated messages
-    task.result = str(messages)
-    task.date_done = timezone.now()
+    paperless_task.result = f"{len(messages)} issues found."
+    if messages.has_error:
+        paperless_task.result += " Check logs for details."
+    paperless_task.date_done = timezone.now()
+    paperless_task.save(update_fields=["status", "result", "date_done"])
     return messages
index 2da457bd0dd3a374220cb3c12393ce5de97b0528..398d87c6e7bb8bea4c86003dcf90daf53b24987d 100644 (file)
@@ -2568,6 +2568,14 @@ class CustomFieldViewSet(ModelViewSet):
                             "last_trained": serializers.DateTimeField(),
                         },
                     ),
+                    "sanity_check": inline_serializer(
+                        name="SanityCheck",
+                        fields={
+                            "status": serializers.CharField(),
+                            "error": serializers.CharField(),
+                            "last_run": serializers.DateTimeField(),
+                        },
+                    ),
                 },
             ),
         },
@@ -2672,6 +2680,27 @@ class SystemStatusView(PassUserMixin):
             last_trained_task.date_done if last_trained_task else None
         )
 
+        last_sanity_check = (
+            PaperlessTask.objects.filter(
+                task_name__icontains="check_sanity",
+            )
+            .order_by("-date_done")
+            .first()
+        )
+
+        sanity_check_status = (
+            "OK"
+            if last_sanity_check is not None
+            and last_sanity_check.status == states.SUCCESS
+            else "ERROR"
+        )
+        sanity_check_error = None
+        if last_sanity_check.status == states.FAILURE:
+            sanity_check_error = last_sanity_check.result
+        sanity_check_last_run = (
+            last_sanity_check.date_done if last_sanity_check else None
+        )
+
         return Response(
             {
                 "pngx_version": current_version,
@@ -2704,6 +2733,9 @@ class SystemStatusView(PassUserMixin):
                     "classifier_status": classifier_status,
                     "classifier_last_trained": classifier_last_trained,
                     "classifier_error": classifier_error,
+                    "sanity_check_status": sanity_check_status,
+                    "sanity_check_last_run": sanity_check_last_run,
+                    "sanity_check_error": sanity_check_error,
                 },
             },
         )