diff --git a/dashboard/mixins.py b/dashboard/mixins.py
index bd93513..470bf0d 100644
--- a/dashboard/mixins.py
+++ b/dashboard/mixins.py
@@ -5,6 +5,7 @@ from django.core.exceptions import PermissionDenied
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.base import TemplateView
from device.models import Device
+from snapshot.models import Annotation
from lot.models import LotTag
@@ -45,7 +46,10 @@ class DashboardView(LoginRequiredMixin):
def get_session_devices(self):
# import pdb; pdb.set_trace()
dev_ids = self.request.session.pop("devices", [])
- self._devices = Device.objects.filter(id__in=dev_ids).filter(owner=self.request.user)
+
+ self._devices = []
+ for x in Annotation.objects.filter(value__in=dev_ids).filter(owner=self.request.user).distinct():
+ self._devices.append(Device(id=x.value))
return self._devices
@@ -53,7 +57,7 @@ class DetailsMixin(DashboardView, TemplateView):
def get(self, request, *args, **kwargs):
self.pk = kwargs['pk']
- self.object = get_object_or_404(self.model, pk=self.pk)
+ self.object = get_object_or_404(self.model, pk=self.pk, owner=self.request.user)
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
diff --git a/dashboard/templates/base.html b/dashboard/templates/base.html
index 296dd35..be20573 100644
--- a/dashboard/templates/base.html
+++ b/dashboard/templates/base.html
@@ -90,11 +90,6 @@
{% trans 'Unassigned devices' %}
-
-
- {% trans 'All devices' %}
-
-
diff --git a/dashboard/urls.py b/dashboard/urls.py
index 78aadfa..681b73e 100644
--- a/dashboard/urls.py
+++ b/dashboard/urls.py
@@ -5,6 +5,5 @@ app_name = 'dashboard'
urlpatterns = [
path("", views.UnassignedDevicesView.as_view(), name="unassigned_devices"),
- path("all/", views.AllDevicesView.as_view(), name="all_devices"),
path("/", views.LotDashboardView.as_view(), name="lot"),
]
diff --git a/dashboard/views.py b/dashboard/views.py
index 96db513..030ed81 100644
--- a/dashboard/views.py
+++ b/dashboard/views.py
@@ -17,9 +17,7 @@ class UnassignedDevicesView(InventaryMixin):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
- devices = Device.objects.filter(
- owner=self.request.user
- ).annotate(num_lots=Count('lot')).filter(num_lots=0)
+ devices = Device.get_unassigned(self.request.user)
context.update({
'devices': devices,
@@ -28,32 +26,21 @@ class UnassignedDevicesView(InventaryMixin):
return context
-class AllDevicesView(InventaryMixin):
- template_name = "unassigned_devices.html"
- section = "All"
- title = _("All Devices")
- breadcrumb = "Devices / All Devices"
-
- def get_context_data(self, **kwargs):
- context = super().get_context_data(**kwargs)
- devices = Device.objects.filter(owner=self.request.user)
- context.update({
- 'devices': devices,
- })
- return context
-
-
class LotDashboardView(InventaryMixin, DetailsMixin):
template_name = "unassigned_devices.html"
- section = "Unassigned"
+ section = "dashboard_lot"
title = _("Lot Devices")
- breadcrumb = "Devices / Lot Devices"
+ breadcrumb = "Lot / Devices"
model = Lot
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
- devices = self.object.devices.filter(owner=self.request.user)
+ devices = self.get_devices()
context.update({
'devices': devices,
})
return context
+
+ def get_devices(self):
+ chids = self.object.devicelot_set.all().values_list("device_id", flat=True).distinct()
+ return [Device(id=x) for x in chids]
diff --git a/device/forms.py b/device/forms.py
index 32d64dc..b74d29b 100644
--- a/device/forms.py
+++ b/device/forms.py
@@ -1,3 +1,17 @@
from django import forms
+from snapshot.models import Annotation
+class DeviceForm2(forms.ModelForm):
+ class Meta:
+ model = Annotation
+ fields = ['key', 'value']
+
+
+class DeviceForm(forms.Form):
+ name = forms.CharField()
+ value = forms.CharField()
+
+
+DeviceFormSet = forms.formset_factory(form=DeviceForm, extra=1)
+
diff --git a/device/migrations/0004_delete_device.py b/device/migrations/0004_delete_device.py
new file mode 100644
index 0000000..10cbd01
--- /dev/null
+++ b/device/migrations/0004_delete_device.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.0.6 on 2024-07-18 17:30
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("device", "0003_device_manufacturer"),
+ ("lot", "0002_remove_lot_devices_devicelot"),
+ ("snapshot", "0002_remove_annotation_device"),
+ ]
+
+ operations = [
+ migrations.DeleteModel(
+ name="Device",
+ ),
+ ]
diff --git a/device/models.py b/device/models.py
index 65a1e6b..f0ff3bc 100644
--- a/device/models.py
+++ b/device/models.py
@@ -3,9 +3,10 @@ from django.db import models
from utils.constants import STR_SM_SIZE, STR_SIZE, STR_EXTEND_SIZE, ALGOS
from snapshot.models import Annotation, Snapshot
from user.models import User
+from lot.models import DeviceLot
-class Device(models.Model):
+class Device:
class Types(models.TextChoices):
DESKTOP = "Desktop"
LAPTOP = "Laptop"
@@ -22,17 +23,18 @@ class Device(models.Model):
BATTERY = "Battery"
CAMERA = "Camera"
- owner = models.ForeignKey(User, on_delete=models.CASCADE)
- type = models.CharField(max_length=STR_SIZE, blank=True, null=True)
- manufacturer = models.CharField(max_length=STR_EXTEND_SIZE, blank=True, null=True)
- model = models.CharField(max_length=STR_EXTEND_SIZE, blank=True, null=True)
-
def __init__(self, *args, **kwargs):
+ # the id is the chid of the device
+ self.id = kwargs["id"]
+ self.pk = self.id
+ self.algorithm = None
+ self.owner = None
self.annotations = []
self.hids = []
self.uuids = []
self.snapshots = []
- super().__init__(*args, **kwargs)
+ self.last_snapshot = None
+ self.get_last_snapshot()
def initial(self):
self.get_annotations()
@@ -41,21 +43,29 @@ class Device(models.Model):
self.get_snapshots()
def get_annotations(self):
+ if self.annotations:
+ return self.annotations
+
self.annotations = Annotation.objects.filter(
- device=self,
- owner=self.owner
+ type=Annotation.Type.SYSTEM,
+ value=self.id
).order_by("-created")
+
+ if self.annotations.count():
+ self.algorithm = self.annotations[0].key
+ self.owner = self.annotations[0].owner
+
+ return self.annotations
def get_uuids(self):
- for a in self.annotations:
+ for a in self.get_annotations():
if not a.uuid in self.uuids:
self.uuids.append(a.uuid)
def get_hids(self):
- if not self.annotations:
- self.get_annotations()
+ annotations = self.get_annotations()
- self.hids = self.annotations.filter(
+ self.hids = annotations.filter(
type=Annotation.Type.SYSTEM,
key__in=ALGOS.keys(),
).values_list("value", flat=True)
@@ -67,14 +77,47 @@ class Device(models.Model):
self.snapshots = [Snapshot(u) for u in self.uuids]
def get_last_snapshot(self):
- if not self.snapshots:
- self.get_snapshots()
+ annotations = self.get_annotations()
+ if annotations:
+ annotation = annotations.first()
+ self.last_snapshot = Snapshot(annotation.uuid)
- if self.snapshots:
- return self.snapshots[0]
+ def last_uuid(self):
+ return self.uuids[0]
@classmethod
def get_unassigned(cls, user):
- return cls.objects.filter(
- owner=user
- ).annotate(num_lots=models.Count('lot')).filter(num_lots=0)
+ chids = DeviceLot.objects.filter(lot__owner=user).values_list("device_id", flat=True).distinct()
+ annotations = Annotation.objects.filter(
+ owner=user,
+ type=Annotation.Type.SYSTEM,
+ ).exclude(value__in=chids).values_list("value", flat=True).distinct()
+ return [cls(id=x) for x in annotations]
+
+ # return cls.objects.filter(
+ # owner=user
+ # ).annotate(num_lots=models.Count('lot')).filter(num_lots=0)
+
+ @property
+ def manufacturer(self):
+ if not self.last_snapshot:
+ self.get_last_snapshot()
+ return self.last_snapshot.doc['device']['manufacturer']
+
+ @property
+ def type(self):
+ if not self.last_snapshot:
+ self.get_last_snapshot()
+ return self.last_snapshot.doc['device']['type']
+
+ @property
+ def model(self):
+ if not self.last_snapshot:
+ self.get_last_snapshot()
+ return self.last_snapshot.doc['device']['model']
+
+ @property
+ def type(self):
+ if not self.last_snapshot:
+ self.get_last_snapshot()
+ return self.last_snapshot.doc['device']['type']
diff --git a/device/templates/details.html b/device/templates/details.html
index dd05dfd..1140dcb 100644
--- a/device/templates/details.html
+++ b/device/templates/details.html
@@ -26,9 +26,6 @@
-
-
-
@@ -47,7 +44,6 @@
(Edit Device)
- {% if object.hid %}Snapshot{% else %}Placeholder{% endif %}
@@ -56,29 +52,24 @@
{{ object.id }}
-
-
Type
-
{{ snapshot.doc.device.type }}
+
{{ object.type }}
Manufacturer
-
{{ snapshot.doc.device.manufacturer|default:"" }}
+
{{ object.manufacturer|default:"" }}
Model
-
{{ snapshot.doc.device.model|default:"" }}
+
{{ object.model|default:"" }}
Serial Number
-
{{ snapshot.doc.device.serialNumber|default:"" }}
+
{{ object.last_snapshot.doc.device.serialNumber|default:"" }}
Identifiers
@@ -132,7 +123,7 @@
{% for tag in lot_tags %}
{{ tag }}
- {% for lot in object.lot_set.filter %}
+ {% for lot in tag.lot_set.filter %}
{% if lot.type == tag %}
@@ -171,32 +162,10 @@
-
-
Traceability log Details
-
-
-
- Snapshot ✓
- 14:07 23-06-2024
-
-
-
- EraseCrypto ✓
- 14:07 23-06-2024
-
-
-
- EraseCrypto ✓
- 14:07 23-06-2024
-
-
-
-
-
Components last snapshot
- {% for c in snapshot.components %}
+ {% for c in object.last_snapshot.doc.components %}
{{ c.type }}
diff --git a/device/templates/new_device.html b/device/templates/new_device.html
index 8f2df37..8907ef0 100644
--- a/device/templates/new_device.html
+++ b/device/templates/new_device.html
@@ -22,11 +22,34 @@
{% endif %}
-{% bootstrap_form form %}
+{# bootstrap_form form #}
+
+
+
+
{% endblock %}
diff --git a/device/urls.py b/device/urls.py
index 7fc0e96..3d0b368 100644
--- a/device/urls.py
+++ b/device/urls.py
@@ -5,7 +5,7 @@ app_name = 'device'
urlpatterns = [
path("add/", views.NewDeviceView.as_view(), name="add"),
- path("edit/
/", views.EditDeviceView.as_view(), name="edit"),
- path("/", views.DetailsView.as_view(), name="details"),
- path("/annotation/add", views.AddAnnotationView.as_view(), name="add_annotation"),
+ path("edit//", views.EditDeviceView.as_view(), name="edit"),
+ path("/", views.DetailsView.as_view(), name="details"),
+ path("/annotation/add", views.AddAnnotationView.as_view(), name="add_annotation"),
]
diff --git a/device/views.py b/device/views.py
index 00255dd..012c878 100644
--- a/device/views.py
+++ b/device/views.py
@@ -6,21 +6,23 @@ from django.utils.translation import gettext_lazy as _
from django.views.generic.edit import (
CreateView,
UpdateView,
+ FormView,
)
from django.views.generic.base import TemplateView
-from dashboard.mixins import DashboardView, DetailsMixin
+from dashboard.mixins import DashboardView
from snapshot.models import Annotation
from snapshot.xapian import search
from lot.models import LotTag
from device.models import Device
+from device.forms import DeviceFormSet
-class NewDeviceView(DashboardView, CreateView):
+class NewDeviceView(DashboardView, FormView):
template_name = "new_device.html"
title = _("New Device")
breadcrumb = "Device / New Device"
success_url = reverse_lazy('dashboard:unassigned_devices')
- model = Device
+ form_class = DeviceFormSet
def form_valid(self, form):
form.instance.owner = self.request.user
@@ -28,12 +30,41 @@ class NewDeviceView(DashboardView, CreateView):
return response
+# class AddToLotView(DashboardView, FormView):
+# template_name = "list_lots.html"
+# title = _("Add to lots")
+# breadcrumb = "lot / add to lots"
+# success_url = reverse_lazy('dashboard:unassigned_devices')
+# form_class = LotsForm
+
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# lots = Lot.objects.filter(owner=self.request.user)
+# lot_tags = LotTag.objects.filter(owner=self.request.user)
+# context.update({
+# 'lots': lots,
+# 'lot_tags':lot_tags,
+# })
+# return context
+
+# def get_form(self):
+# form = super().get_form()
+# form.fields["lots"].queryset = Lot.objects.filter(owner=self.request.user)
+# return form
+
+# def form_valid(self, form):
+# form.devices = self.get_session_devices()
+# form.save()
+# response = super().form_valid(form)
+# return response
+
+
class EditDeviceView(DashboardView, UpdateView):
template_name = "new_device.html"
title = _("Update Device")
breadcrumb = "Device / Update Device"
success_url = reverse_lazy('dashboard:unassigned_devices')
- model = Device
+ model = Annotation
def get_form_kwargs(self):
pk = self.kwargs.get('pk')
@@ -43,17 +74,23 @@ class EditDeviceView(DashboardView, UpdateView):
return kwargs
-class DetailsView(DetailsMixin):
+class DetailsView(DashboardView, TemplateView):
template_name = "details.html"
title = _("Device")
breadcrumb = "Device / Details"
- model = Device
+ model = Annotation
+
+ def get(self, request, *args, **kwargs):
+ self.pk = kwargs['pk']
+ self.object = Device(id=self.pk)
+ return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
self.object.initial()
lot_tags = LotTag.objects.filter(owner=self.request.user)
context.update({
+ 'object': self.object,
'snapshot': self.object.get_last_snapshot(),
'lot_tags': lot_tags,
})
diff --git a/lot/forms.py b/lot/forms.py
index 0065960..7b809fd 100644
--- a/lot/forms.py
+++ b/lot/forms.py
@@ -15,13 +15,14 @@ class LotsForm(forms.Form):
def save(self, commit=True):
if not commit:
return
+
for dev in self.devices:
for lot in self._lots:
- lot.devices.add(dev.id)
+ lot.add(dev.id)
return
def remove(self):
for dev in self.devices:
for lot in self._lots:
- lot.devices.remove(dev.id)
+ lot.remove(dev.id)
return
diff --git a/lot/migrations/0002_remove_lot_devices_devicelot.py b/lot/migrations/0002_remove_lot_devices_devicelot.py
new file mode 100644
index 0000000..8496dea
--- /dev/null
+++ b/lot/migrations/0002_remove_lot_devices_devicelot.py
@@ -0,0 +1,39 @@
+# Generated by Django 5.0.6 on 2024-07-18 17:30
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("lot", "0001_initial"),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name="lot",
+ name="devices",
+ ),
+ migrations.CreateModel(
+ name="DeviceLot",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ ("device_id", models.CharField(max_length=256)),
+ (
+ "lot",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE, to="lot.lot"
+ ),
+ ),
+ ],
+ ),
+ ]
diff --git a/lot/models.py b/lot/models.py
index fb34778..9237a27 100644
--- a/lot/models.py
+++ b/lot/models.py
@@ -7,7 +7,7 @@ from utils.constants import (
)
from user.models import User
-from device.models import Device
+# from device.models import Device
from snapshot.models import Annotation
@@ -19,6 +19,11 @@ class LotTag(models.Model):
return self.name
+class DeviceLot(models.Model):
+ lot = models.ForeignKey("Lot", on_delete=models.CASCADE)
+ device_id = models.CharField(max_length=STR_EXTEND_SIZE, blank=False, null=False)
+
+
class Lot(models.Model):
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
@@ -28,4 +33,13 @@ class Lot(models.Model):
closed = models.BooleanField(default=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
type = models.ForeignKey(LotTag, on_delete=models.CASCADE)
- devices = models.ManyToManyField(Device)
+
+ def add(self, v):
+ if DeviceLot.objects.filter(lot=self, device_id=v).exists():
+ return
+ DeviceLot.objects.create(lot=self, device_id=v)
+
+ def remove(self, v):
+ for d in DeviceLot.objects.filter(lot=self, device_id=v):
+ d.delete()
+
diff --git a/lot/views.py b/lot/views.py
index 44d7266..9549076 100644
--- a/lot/views.py
+++ b/lot/views.py
@@ -6,7 +6,7 @@ from django.views.generic.edit import (
CreateView,
DeleteView,
UpdateView,
- FormView
+ FormView,
)
from dashboard.mixins import DashboardView
from lot.models import Lot, LotTag
diff --git a/snapshot/migrations/0002_remove_annotation_device.py b/snapshot/migrations/0002_remove_annotation_device.py
new file mode 100644
index 0000000..326eca2
--- /dev/null
+++ b/snapshot/migrations/0002_remove_annotation_device.py
@@ -0,0 +1,17 @@
+# Generated by Django 5.0.6 on 2024-07-18 17:30
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("snapshot", "0001_initial"),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name="annotation",
+ name="device",
+ ),
+ ]
diff --git a/snapshot/models.py b/snapshot/models.py
index bb6e40e..7c1a942 100644
--- a/snapshot/models.py
+++ b/snapshot/models.py
@@ -63,7 +63,6 @@ class Annotation(models.Model):
type = models.SmallIntegerField(choices=Type)
key = models.CharField(max_length=STR_EXTEND_SIZE)
value = models.CharField(max_length=STR_EXTEND_SIZE)
- device = models.ForeignKey('device.Device', on_delete=models.CASCADE)
class Meta:
constraints = [
diff --git a/snapshot/parse.py b/snapshot/parse.py
index ea7e0a5..8137a86 100644
--- a/snapshot/parse.py
+++ b/snapshot/parse.py
@@ -7,7 +7,6 @@ import hashlib
from datetime import datetime
from snapshot.xapian import search, index
from snapshot.models import Snapshot, Annotation
-from device.models import Device
from utils.constants import ALGOS
@@ -47,21 +46,10 @@ class Build:
value = algorithms['hidalgo1']
).first()
- if annotation:
- device = annotation.device
- else:
- device = Device.objects.create(
- type=self.json["device"]["type"],
- manufacturer=self.json["device"]["manufacturer"],
- model=self.json["device"]["model"],
- owner=self.user
- )
-
for k, v in algorithms.items():
Annotation.objects.create(
uuid=self.uuid,
owner=self.user,
- device=device,
type=Annotation.Type.SYSTEM,
key=k,
value=v
diff --git a/snapshot/views.py b/snapshot/views.py
index b49615c..6a7f98b 100644
--- a/snapshot/views.py
+++ b/snapshot/views.py
@@ -1,10 +1,10 @@
from django.utils.translation import gettext_lazy as _
from django.views.generic.base import TemplateView
-from django.views.generic.edit import FormView
from django.urls import reverse_lazy
from django.views.generic.edit import (
CreateView,
UpdateView,
+ FormView,
)
from dashboard.mixins import DashboardView