diff --git a/api/migrations/0001_initial.py b/api/migrations/0001_initial.py index 22c5a1f..2101a8a 100644 --- a/api/migrations/0001_initial.py +++ b/api/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.6 on 2024-09-19 15:09 +# Generated by Django 5.0.6 on 2024-10-10 10:35 import django.db.models.deletion from django.conf import settings diff --git a/dashboard/mixins.py b/dashboard/mixins.py index df6e206..aa63d36 100644 --- a/dashboard/mixins.py +++ b/dashboard/mixins.py @@ -45,7 +45,7 @@ class DashboardView(LoginRequiredMixin): def get_session_devices(self): dev_ids = self.request.session.pop("devices", []) - + self._devices = [] for x in Annotation.objects.filter(value__in=dev_ids).filter( owner=self.request.user.institution @@ -58,7 +58,11 @@ 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, owner=self.request.user.institution) + self.object = get_object_or_404( + self.model, + pk=self.pk, + owner=self.request.user.institution + ) return super().get(request, *args, **kwargs) def get_context_data(self, **kwargs): @@ -72,14 +76,17 @@ class DetailsMixin(DashboardView, TemplateView): class InventaryMixin(DashboardView, TemplateView): def post(self, request, *args, **kwargs): - dev_ids = dict(self.request.POST).get("devices", []) - self.request.session["devices"] = dev_ids - url = self.request.POST.get("url") + post = dict(self.request.POST) + url = post.get("url") + if url: + dev_ids = post.get("devices", []) + self.request.session["devices"] = dev_ids + try: - resource = resolve(url) + resource = resolve(url[0]) if resource and dev_ids: - return redirect(url) + return redirect(url[0]) except Exception: pass return super().get(request, *args, **kwargs) diff --git a/dashboard/templates/base.html b/dashboard/templates/base.html index d2c1612..6aeee6a 100644 --- a/dashboard/templates/base.html +++ b/dashboard/templates/base.html @@ -185,15 +185,17 @@ {% endblock messages %}

{{ title }}

-
- {% csrf_token %} -
- - - - -
-
+ +
+ {% csrf_token %} +
+ + + + +
+
+
diff --git a/dashboard/urls.py b/dashboard/urls.py index 681b73e..835e708 100644 --- a/dashboard/urls.py +++ b/dashboard/urls.py @@ -6,4 +6,5 @@ app_name = 'dashboard' urlpatterns = [ path("", views.UnassignedDevicesView.as_view(), name="unassigned_devices"), path("/", views.LotDashboardView.as_view(), name="lot"), + path("search", views.SearchView.as_view(), name="search"), ] diff --git a/dashboard/views.py b/dashboard/views.py index 7a9a397..b34e2a6 100644 --- a/dashboard/views.py +++ b/dashboard/views.py @@ -1,7 +1,13 @@ +import json + from django.utils.translation import gettext_lazy as _ +from django.views.generic.edit import FormView from django.shortcuts import Http404 +from django.db.models import Q from dashboard.mixins import InventaryMixin, DetailsMixin +from evidence.models import Annotation +from evidence.xapian import search from device.models import Device from lot.models import Lot @@ -32,6 +38,68 @@ class LotDashboardView(InventaryMixin, DetailsMixin): return context def get_devices(self, user, offset, limit): - chids = self.object.devicelot_set.all().values_list("device_id", flat=True).distinct() + chids = self.object.devicelot_set.all().values_list( + "device_id", flat=True + ).distinct() + chids_page = chids[offset:offset+limit] return [Device(id=x) for x in chids_page], chids.count() + + +class SearchView(InventaryMixin): + template_name = "unassigned_devices.html" + section = "Search" + title = _("Search Devices") + breadcrumb = "Devices / Search Devices" + + def get_devices(self, user, offset, limit): + post = dict(self.request.POST) + query = post.get("search") + + if not query: + return [], 0 + + matches = search( + self.request.user.institution, + query[0], + offset, + limit + ) + + if not matches.size(): + return self.search_hids(query, offset, limit) + + annotations = [] + for x in matches: + annotations.extend(self.get_annotations(x)) + + devices = [Device(id=x) for x in set(annotations)] + count = matches.size() + return devices, count + + def get_annotations(self, xp): + snap = xp.document.get_data() + uuid = json.loads(snap).get('uuid') + + return Annotation.objects.filter( + type=Annotation.Type.SYSTEM, + owner=self.request.user.institution, + uuid=uuid + ).values_list("value", flat=True).distinct() + + def search_hids(self, query, offset, limit): + qry = Q() + + for i in query[0].split(" "): + if i: + qry |= Q(value__startswith=i) + + chids = Annotation.objects.filter( + type=Annotation.Type.SYSTEM, + owner=self.request.user.institution + ).filter( + qry + ).values_list("value", flat=True).distinct() + chids_page = chids[offset:offset+limit] + + return [Device(id=x) for x in chids_page], chids.count() diff --git a/evidence/xapian.py b/evidence/xapian.py index 27c03c5..3c0361c 100644 --- a/evidence/xapian.py +++ b/evidence/xapian.py @@ -18,7 +18,6 @@ def search(institution, qs, offset=0, limit=10): qp.set_stemmer(xapian.Stem("english")) qp.set_stemming_strategy(xapian.QueryParser.STEM_SOME) qp.add_prefix("uuid", "uuid") - # qp.add_prefix("snapshot", "snapshot") query = qp.parse_query(qs) institution_term = "U{}".format(institution.id) final_query = xapian.Query( diff --git a/lot/migrations/0001_initial.py b/lot/migrations/0001_initial.py index 538ba90..04afd88 100644 --- a/lot/migrations/0001_initial.py +++ b/lot/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.6 on 2024-10-10 10:14 +# Generated by Django 5.0.6 on 2024-10-10 10:35 import django.db.models.deletion from django.conf import settings diff --git a/lot/views.py b/lot/views.py index 46252c8..e9bb081 100644 --- a/lot/views.py +++ b/lot/views.py @@ -29,6 +29,7 @@ class NewLotView(DashboardView, CreateView): def form_valid(self, form): form.instance.owner = self.request.user.institution + form.instance.user = self.request.user response = super().form_valid(form) return response @@ -68,7 +69,11 @@ class EditLotView(DashboardView, UpdateView): def get_form_kwargs(self): pk = self.kwargs.get('pk') - self.object = get_object_or_404(self.model, pk=pk) + self.object = get_object_or_404( + self.model, + owner=self.request.user.institution, + pk=pk, + ) # self.success_url = reverse_lazy('dashbiard:lot', args=[pk]) kwargs = super().get_form_kwargs() return kwargs @@ -145,6 +150,7 @@ class LotAddDocumentView(DashboardView, CreateView): def form_valid(self, form): form.instance.owner = self.request.user.institution + form.instance.user = self.request.user form.instance.lot = self.lot form.instance.type = LotAnnotation.Type.DOCUMENT response = super().form_valid(form) @@ -214,6 +220,7 @@ class LotAddAnnotationView(DashboardView, CreateView): def form_valid(self, form): form.instance.owner = self.request.user.institution + form.instance.user = self.request.user form.instance.lot = self.lot form.instance.type = LotAnnotation.Type.USER response = super().form_valid(form) diff --git a/utils/device.py b/utils/device.py index f177aae..a358266 100644 --- a/utils/device.py +++ b/utils/device.py @@ -87,4 +87,4 @@ def create_index(doc, user): _uuid = doc['uuid'] ev = json.dumps(doc) - index(user, _uuid, ev) + index(user.institution, _uuid, ev)