FreedomBox/plinth/diagnostic_check.py
James Valleroy ddc9b434a7
diagnostics: Add optional component_id to DiagnosticCheck
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2024-05-02 21:45:12 -07:00

73 lines
2.0 KiB
Python

# SPDX-License-Identifier: AGPL-3.0-or-later
"""Diagnostic check data type."""
import dataclasses
import json
from dataclasses import dataclass, field
from enum import StrEnum
from typing import TypeAlias
from django.utils.translation import gettext
from plinth.utils import SafeFormatter
DiagnosticCheckParameters: TypeAlias = dict[str, str | int | bool | None]
class Result(StrEnum):
"""The result of a diagnostic check."""
NOT_DONE = 'not_done'
PASSED = 'passed'
WARNING = 'warning'
FAILED = 'failed'
ERROR = 'error'
@dataclass
class DiagnosticCheck:
"""A diagnostic check and optional result and parameters."""
check_id: str
description: str
result: Result = Result.NOT_DONE
parameters: DiagnosticCheckParameters = field(default_factory=dict)
component_id: str | None = None
@property
def translated_description(self):
"""Return translated string for description."""
description = gettext(self.description)
if self.parameters:
return SafeFormatter().vformat(description, [], self.parameters)
return description
class CheckJSONEncoder(json.JSONEncoder):
"""Encode objects that include DiagnosticChecks."""
def default(self, o):
"""Add class tag to DiagnosticChecks."""
if isinstance(o, DiagnosticCheck):
o = dataclasses.asdict(o)
o.update({'__class__': 'DiagnosticCheck'})
return o
return super().default(o)
class CheckJSONDecoder(json.JSONDecoder):
"""Decode objects that include DiagnosticChecks."""
def __init__(self):
json.JSONDecoder.__init__(self, object_hook=CheckJSONDecoder.from_dict)
@staticmethod
def from_dict(data):
"""Convert tagged data to DiagnosticCheck."""
if data.get('__class__') == 'DiagnosticCheck':
return DiagnosticCheck(data['check_id'], data['description'],
data['result'], data['parameters'],
data.get('component_id'))
return data