turn firmware_ and hardware_description into properties
This commit is contained in:
parent
58df04b4af
commit
8efb1057d1
6 changed files with 35 additions and 24 deletions
|
@ -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,
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue