turn firmware_ and hardware_description into properties

This commit is contained in:
Laura Klünder 2023-11-10 16:19:57 +01:00
parent 58df04b4af
commit 8efb1057d1
6 changed files with 35 additions and 24 deletions

View file

@ -1,4 +1,5 @@
from collections import UserDict, namedtuple from collections import UserDict, namedtuple
from contextlib import suppress
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime, timedelta from datetime import datetime, timedelta
from functools import cached_property from functools import cached_property
@ -102,7 +103,7 @@ class MeshNodeQuerySet(models.QuerySet):
# fetch matching firmware builds # fetch matching firmware builds
firmwares = { firmwares = {
fw_desc.get_lookup(): fw_desc for fw_desc in fw_desc.get_lookup(): fw_desc for fw_desc in
(build.get_firmware_description() for build in FirmwareBuild.objects.filter( (build.firmware_description for build in FirmwareBuild.objects.filter(
sha256_hash__in=set( sha256_hash__in=set(
node.last_messages[MeshMessageType.CONFIG_FIRMWARE].parsed.app_desc.app_elf_sha256 node.last_messages[MeshMessageType.CONFIG_FIRMWARE].parsed.app_desc.app_elf_sha256
for node in self._result_cache for node in self._result_cache
@ -112,20 +113,21 @@ class MeshNodeQuerySet(models.QuerySet):
# assign firmware descriptions # assign firmware descriptions
for node in nodes.values(): for node in nodes.values():
firmware_desc = node.get_firmware_description() firmware_desc = node.firmware_description
node.firmware_desc = firmwares.get(firmware_desc.get_lookup(), firmware_desc) node._firmware_description = firmwares.get(firmware_desc.get_lookup(), firmware_desc)
# get date of first appearance # get date of first appearance
nodes_to_complete = tuple( nodes_to_complete = tuple(
node for node in nodes.values() node for node in nodes.values()
if node.firmware_desc.build is None if node._firmware_description.build is None
) )
try: try:
created_lookup = { created_lookup = {
msg.parsed.app_desc.app_elf_sha256: msg.datetime msg.parsed.app_desc.app_elf_sha256: msg.datetime
for msg in NodeMessage.objects.filter( for msg in NodeMessage.objects.filter(
message_type=MeshMessageType.CONFIG_FIRMWARE.name, message_type=MeshMessageType.CONFIG_FIRMWARE.name,
data__app_elf_sha256__in=(node.firmware_desc.sha256_hash for node in nodes_to_complete) data__app_elf_sha256__in=(node._firmware_description.sha256_hash
for node in nodes_to_complete)
).order_by('data__app_elf_sha256', 'datetime').distinct('data__app_elf_sha256') ).order_by('data__app_elf_sha256', 'datetime').distinct('data__app_elf_sha256')
} }
print(created_lookup) print(created_lookup)
@ -135,10 +137,10 @@ class MeshNodeQuerySet(models.QuerySet):
message_type=MeshMessageType.CONFIG_FIRMWARE.name, message_type=MeshMessageType.CONFIG_FIRMWARE.name,
data__app_elf_sha256=app_elf_sha256 data__app_elf_sha256=app_elf_sha256
).order_by('datetime').first() ).order_by('datetime').first()
for app_elf_sha256 in {node.firmware_desc.sha256_hash for node in nodes_to_complete} for app_elf_sha256 in {node.f_firmware_description.sha256_hash for node in nodes_to_complete}
} }
for node in nodes_to_complete: for node in nodes_to_complete:
node.firmware_desc.created = created_lookup[node.firmware_desc.sha256_hash] node._firmware_description.created = created_lookup[node._firmware_description.sha256_hash]
if self._prefetch_ota and not self._prefetch_ota_done: if self._prefetch_ota and not self._prefetch_ota_done:
if nodes is None: if nodes is None:
@ -222,7 +224,11 @@ class MeshNode(models.Model):
except AttributeError: except AttributeError:
return self.ota_updates.order_by('-update__created').first() return self.ota_updates.order_by('-update__created').first()
def get_firmware_description(self) -> FirmwareDescription: # noinspection PyUnresolvedReferences
@cached_property
def firmware_description(self) -> FirmwareDescription:
with suppress(AttributeError):
return self._firmware_description
# noinspection PyTypeChecker # noinspection PyTypeChecker
firmware_msg: ConfigFirmwareMessage = self.last_messages[MeshMessageType.CONFIG_FIRMWARE].parsed firmware_msg: ConfigFirmwareMessage = self.last_messages[MeshMessageType.CONFIG_FIRMWARE].parsed
# noinspection PyTypeChecker # noinspection PyTypeChecker
@ -235,7 +241,8 @@ class MeshNode(models.Model):
sha256_hash=firmware_msg.app_desc.app_elf_sha256, sha256_hash=firmware_msg.app_desc.app_elf_sha256,
) )
def get_hardware_description(self) -> HardwareDescription: @cached_property
def hardware_description(self) -> HardwareDescription:
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
return HardwareDescription( return HardwareDescription(
chip=self.last_messages[MeshMessageType.CONFIG_HARDWARE].parsed.chip, chip=self.last_messages[MeshMessageType.CONFIG_HARDWARE].parsed.chip,
@ -369,7 +376,8 @@ class FirmwareBuild(models.Model):
'boards': self.boards, 'boards': self.boards,
} }
def get_firmware_description(self) -> FirmwareDescription: @cached_property
def firmware_description(self) -> FirmwareDescription:
return FirmwareDescription( return FirmwareDescription(
chip=self.chip_type, chip=self.chip_type,
project_name=self.version.project_name, project_name=self.version.project_name,
@ -380,7 +388,8 @@ class FirmwareBuild(models.Model):
build=self, build=self,
) )
def get_hardware_descriptions(self) -> list[HardwareDescription]: @cached_property
def hardware_descriptions(self) -> list[HardwareDescription]:
return [ return [
HardwareDescription( HardwareDescription(
chip=self.chip_type, chip=self.chip_type,

View file

@ -51,12 +51,12 @@
{% mesh_node node %} {% mesh_node node %}
</td> </td>
<td> <td>
{% include "mesh/fragment_firmware_cell.html" with firmware_desc=node.firmware_desc %} {% include "mesh/fragment_firmware_cell.html" with firmware_desc=node.firmware_description %}
</td> </td>
<td> <td>
{% if node.current_ota %} {% if node.current_ota %}
<a>#{{ node.current_ota.update.pk }} <small>({{ node.current_ota.update.created }})</small></a><br> <a>#{{ node.current_ota.update.pk }} <small>({{ node.current_ota.update.created }})</small></a><br>
{% include "mesh/fragment_firmware_cell.html" with firmware_desc=node.current_ota.update.build.get_firmware_description %} {% include "mesh/fragment_firmware_cell.html" with firmware_desc=node.current_ota.update.build.firmware_description %}
{% else %} {% else %}
- -
{% endif %} {% endif %}

View file

@ -75,14 +75,14 @@
</p> </p>
<h4>Firmware</h4> <h4>Firmware</h4>
<p> <p>
{% if node.firmware_desc.build %} {% if node.firmware_description.build %}
<strong>Firmware:</strong> <a href="{% url "mesh.firmwares.detail" pk=node.firmware_desc.build.firmware.pk %}">{{ node.firmware_desc.project_name }} {{ node.firmware_desc.version }}</a><br> <strong>Firmware:</strong> <a href="{% url "mesh.firmwares.detail" pk=node.firmware_description.build.firmware.pk %}">{{ node.firmware_description.project_name }} {{ node.firmware_description.version }}</a><br>
<strong>Build:</strong> <a href="{% url "mesh.firmwares.build.detail" pk=node.firmware_desc.build.pk %}">{{ node.firmware_desc.build.variant }}</a><br> <strong>Build:</strong> <a href="{% url "mesh.firmwares.build.detail" pk=node.firmware_description.build.pk %}">{{ node.firmware_description.build.variant }}</a><br>
<strong>Created:</strong> {{ node.firmware_desc.created }}<br> <strong>Created:</strong> {{ node.firmware_description.created }}<br>
{% else %} {% else %}
<strong>Firmware:</strong> {{ node.firmware_desc.project_name }} {{ node.firmware_desc.version }}<br> <strong>Firmware:</strong> {{ node.firmware_description.project_name }} {{ node.firmware_description.version }}<br>
<strong>First seen:</strong> {{ node.firmware_desc.created }}<br> <strong>First seen:</strong> {{ node.firmware_description.created }}<br>
<strong>SHA256:</strong> <small>{{ node.firmware_desc.sha256_hash }}</small><br> <strong>SHA256:</strong> <small>{{ node.firmware_description.sha256_hash }}</small><br>
{% endif %} {% endif %}
</p> </p>
</div> </div>

View file

@ -21,7 +21,7 @@
<small>({{ node.last_messages.CONFIG_HARDWARE.parsed.chip.pretty_name }} rev{{ node.last_messages.CONFIG_HARDWARE.parsed.revision_major }}.{{ node.last_messages.CONFIG_HARDWARE.parsed.revision_minor }})</small> <small>({{ node.last_messages.CONFIG_HARDWARE.parsed.chip.pretty_name }} rev{{ node.last_messages.CONFIG_HARDWARE.parsed.revision_major }}.{{ node.last_messages.CONFIG_HARDWARE.parsed.revision_minor }})</small>
</td> </td>
<td> <td>
{% include "mesh/fragment_firmware_cell.html" with firmware_desc=node.firmware_desc %} {% include "mesh/fragment_firmware_cell.html" with firmware_desc=node.firmware_description %}
</td> </td>
<td> <td>
{% blocktrans trimmed with timesince=node.last_messages.any.datetime|timesince %} {% blocktrans trimmed with timesince=node.last_messages.any.datetime|timesince %}

View file

@ -23,7 +23,9 @@ class FirmwaresCurrentListView(MeshControlMixin, TemplateView):
firmwares = {} firmwares = {}
for node in nodes: for node in nodes:
firmwares.setdefault(node.firmware_desc.get_lookup(), (node.firmware_desc, []))[1].append(node) firmwares.setdefault(
node.firmware_description.get_lookup(), (node.firmware_description, [])
)[1].append(node)
firmwares = sorted(firmwares.values(), key=lambda k: k[0].created, reverse=True) firmwares = sorted(firmwares.values(), key=lambda k: k[0].created, reverse=True)

View file

@ -94,12 +94,12 @@ class OTACreateForm(Form):
builds_by_hardware = {} builds_by_hardware = {}
for build in builds: for build in builds:
for hardware_desc in build.get_hardware_descriptions(): for hardware_desc in build.hardware_descriptions:
builds_by_hardware.setdefault(hardware_desc, []).append(build) builds_by_hardware.setdefault(hardware_desc, []).append(build)
nodes_by_hardware = {} nodes_by_hardware = {}
for node in nodes: for node in nodes:
nodes_by_hardware.setdefault(node.get_hardware_description(), []).append(node) nodes_by_hardware.setdefault(node.hardware_description, []).append(node)
self._groups: list[OTAFormGroup] = [] self._groups: list[OTAFormGroup] = []
for hardware, hw_nodes in sorted(nodes_by_hardware.items(), key=lambda k: len(k[1]), reverse=True): for hardware, hw_nodes in sorted(nodes_by_hardware.items(), key=lambda k: len(k[1]), reverse=True):