search in xapian

This commit is contained in:
Cayo Puigdefabregas 2024-10-09 12:18:09 +02:00
parent 355355dcfc
commit 1abd846922
5 changed files with 70 additions and 8 deletions

View File

@ -28,7 +28,7 @@ class DashboardView(LoginRequiredMixin):
title = "" title = ""
subtitle = "" subtitle = ""
section = "" section = ""
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context.update({ context.update({
@ -72,14 +72,17 @@ class DetailsMixin(DashboardView, TemplateView):
class InventaryMixin(DashboardView, TemplateView): class InventaryMixin(DashboardView, TemplateView):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
dev_ids = dict(self.request.POST).get("devices", []) post = dict(self.request.POST)
self.request.session["devices"] = dev_ids url = post.get("url")
url = self.request.POST.get("url")
if url: if url:
dev_ids = post.get("devices", [])
self.request.session["devices"] = dev_ids
try: try:
resource = resolve(url) resource = resolve(url[0])
if resource and dev_ids: if resource and dev_ids:
return redirect(url) return redirect(url[0])
except Exception: except Exception:
pass pass
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)

View File

@ -179,6 +179,17 @@
{% endblock messages %} {% endblock messages %}
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2"> <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2">
<h1 class="h2">{{ title }}</h1> <h1 class="h2">{{ title }}</h1>
<form method="post" action="{% url 'dashboard:search' %}">
{% csrf_token %}
<div class="input-group rounded">
<input type="search" name="search" class="form-control rounded" placeholder="Search your device..." aria-label="Search" aria-describedby="search-addon" />
<span class="input-group-text border-0" id="search-addon">
<i class="fas fa-search"></i>
</span>
</div>
</form>
</div> </div>
<div class="row border-bottom mb-3"> <div class="row border-bottom mb-3">
<div class="col"> <div class="col">

View File

@ -6,4 +6,5 @@ app_name = 'dashboard'
urlpatterns = [ urlpatterns = [
path("", views.UnassignedDevicesView.as_view(), name="unassigned_devices"), path("", views.UnassignedDevicesView.as_view(), name="unassigned_devices"),
path("<int:pk>/", views.LotDashboardView.as_view(), name="lot"), path("<int:pk>/", views.LotDashboardView.as_view(), name="lot"),
path("search", views.SearchView.as_view(), name="search"),
] ]

View File

@ -1,7 +1,12 @@
import json
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic.edit import FormView
from django.shortcuts import Http404 from django.shortcuts import Http404
from dashboard.mixins import InventaryMixin, DetailsMixin from dashboard.mixins import InventaryMixin, DetailsMixin
from evidence.models import Annotation
from evidence.xapian import search
from device.models import Device from device.models import Device
from lot.models import Lot from lot.models import Lot
@ -32,6 +37,49 @@ class LotDashboardView(InventaryMixin, DetailsMixin):
return context return context
def get_devices(self, user, offset, limit): 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] chids_page = chids[offset:offset+limit]
return [Device(id=x) for x in chids_page], chids.count() 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
)
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()

View File

@ -18,7 +18,6 @@ def search(institution, qs, offset=0, limit=10):
qp.set_stemmer(xapian.Stem("english")) qp.set_stemmer(xapian.Stem("english"))
qp.set_stemming_strategy(xapian.QueryParser.STEM_SOME) qp.set_stemming_strategy(xapian.QueryParser.STEM_SOME)
qp.add_prefix("uuid", "uuid") qp.add_prefix("uuid", "uuid")
# qp.add_prefix("snapshot", "snapshot")
query = qp.parse_query(qs) query = qp.parse_query(qs)
institution_term = "U{}".format(institution.id) institution_term = "U{}".format(institution.id)
final_query = xapian.Query( final_query = xapian.Query(