From 02851dbdaf4aef9a619cab45766f28b78c0f8d31 Mon Sep 17 00:00:00 2001
From: Ernesto Rico Schmidt <ernesto@helsinki.at>
Date: Mon, 9 Dec 2024 19:43:46 -0400
Subject: Add search view


diff --git a/program/views.py b/program/views.py
index c369b85..6ddeacb 100644
--- a/program/views.py
+++ b/program/views.py
@@ -1,8 +1,10 @@
 import json
 from datetime import date, datetime, time, timedelta
+from itertools import chain
 
+from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
 from django.db.models import Q
-from django.http import HttpResponse
+from django.http import HttpResponse, JsonResponse
 from django.shortcuts import get_object_or_404
 from django.views.generic.base import TemplateView
 from django.views.generic.detail import DetailView
@@ -356,3 +358,79 @@ def json_timeslots_specials(request):
 
     return HttpResponse(json.dumps(specials, ensure_ascii=False, encoding='utf8').encode('utf8'),
                         content_type="application/json; charset=utf-8")
+
+
+def search(request):
+    q = request.GET.get("q")
+    page = request.GET.get("page")
+    types = request.GET.get("types").split(",") if "types" in request.GET else None
+
+    if q is None:
+        return HttpResponse("query parameter 'q' is required", status=400)
+
+    if types is None or "host" in types:
+        hosts = list(
+            Host.objects.filter(name__icontains=q).values(
+                "id",
+                "name",
+            )
+        )
+    else:
+        hosts = []
+
+    if types is None or "note" in types:
+        notes = list(
+            Note.objects.filter(title__icontains=q)
+            .select_related("show", "timeslot")
+            .values(
+                "content",
+                "image",
+                "show__image",
+                "show__name",
+                "show__slug",
+                "start",
+                "timeslot",
+                "title",
+            )
+        )
+    else:
+        notes = []
+
+    if types is None or "show" in types:
+        shows = list(
+            Show.objects.filter(name__icontains=q).values(
+                "description",
+                "image",
+                "name",
+                "short_description",
+                "slug",
+            )
+        )
+    else:
+        shows = []
+
+    # FIXME: this is a very ugly way to "annotate" the results with their type
+    for host in hosts:
+        host["type"] = "host"
+    for note in notes:
+        note["type"] = "note"
+    for show in shows:
+        show["type"] = "show"
+
+    paginator = Paginator(list(chain(hosts, notes, shows)), per_page=10)
+
+    try:
+        page = paginator.page(page)
+    except PageNotAnInteger:
+        page = paginator.page(1)
+    except EmptyPage:
+        page = paginator.page(paginator.num_pages)
+
+    return JsonResponse(
+        {
+            "count": paginator.count,
+            "page": page.number,
+            "pages": paginator.num_pages,
+            "results": list(page.object_list),
+        }
+    )
-- 
cgit v0.10.2


From a0af34e28b6013b21ed2d6dfdd9b2db303cad506 Mon Sep 17 00:00:00 2001
From: Ernesto Rico Schmidt <ernesto@helsinki.at>
Date: Mon, 9 Dec 2024 19:47:03 -0400
Subject: Add url for search


diff --git a/program/urls.py b/program/urls.py
index 78b9af4..bfed531 100644
--- a/program/urls.py
+++ b/program/urls.py
@@ -28,6 +28,8 @@ urlpatterns = patterns('',
                        url(r'^v2/shows/(?P<slug>[\w-]+)/?$', views.ShowDetailViewV2.as_view()),
                        url(r'^v2/(?P<pk>\d+)/?$', views.TimeSlotDetailViewV2.as_view()),
                        url(r'^v2/show-filters/?$', views.ShowFilterListViewV2.as_view()),
+                       # search view for WordPress 2025
+                       url(r'^v3/search/?$', views.search)
                        )
 if settings.DEBUG:
     urlpatterns += \
-- 
cgit v0.10.2