196 lines
6.0 KiB
Python
196 lines
6.0 KiB
Python
import json
|
|
import urllib
|
|
|
|
from django.conf import settings
|
|
from django.http import HttpResponse, JsonResponse
|
|
from django.shortcuts import render
|
|
from django.urls import reverse
|
|
from django.views import View
|
|
from django_tables2 import SingleTableMixin
|
|
from rest_framework.parsers import FormParser
|
|
from rest_framework.views import APIView
|
|
|
|
from core.lib.opensearch import query_results
|
|
from core.lib.threshold import (
|
|
annotate_num_chans,
|
|
annotate_num_users,
|
|
get_chans,
|
|
get_users,
|
|
)
|
|
from core.views.ui.tables import DrilldownTable
|
|
|
|
|
|
class DrilldownTableView(View, SingleTableMixin):
|
|
table_class = DrilldownTable
|
|
template_name = "ui/drilldown/table_results.html"
|
|
paginate_by = 5
|
|
|
|
def post(self, request):
|
|
context = query_results(request)
|
|
table = DrilldownTable(context["results"])
|
|
context["table"] = table
|
|
del context["results"]
|
|
if "message" in context:
|
|
return render(request, self.template_name, context)
|
|
|
|
if self.request.htmx:
|
|
template_name = "ui/drilldown/table_results.html"
|
|
else:
|
|
template_name = "ui/drilldown/table_results_partial.html"
|
|
|
|
if context:
|
|
return render(request, template_name, context)
|
|
else:
|
|
return HttpResponse("No results")
|
|
|
|
|
|
def parse_dates(dates):
|
|
spl = dates.split(" - ")
|
|
if all(spl):
|
|
spl = [f"{x.replace(' ', 'T')}" for x in spl]
|
|
if not len(spl) == 2:
|
|
message = "Invalid dates"
|
|
message_class = "danger"
|
|
return {"message": message, "class": message_class}
|
|
from_ts, to_ts = spl
|
|
from_date, from_time = from_ts.split("T")
|
|
to_date, to_time = to_ts.split("T")
|
|
|
|
return {
|
|
"from_date": from_date,
|
|
"to_date": to_date,
|
|
"from_time": from_time,
|
|
"to_time": to_time,
|
|
}
|
|
|
|
|
|
def create_tags(query):
|
|
"""
|
|
Grab the tags out of the query and make a list
|
|
we can add to the Bulma tags element when the page loads.
|
|
"""
|
|
spl = query.split("AND")
|
|
spl = [x.strip() for x in spl if ":" in x]
|
|
spl = [x.replace('"', "") for x in spl]
|
|
tags = [f"{tag}: {elem}" for tag, elem in [x.split(":") for x in spl]]
|
|
return tags
|
|
|
|
|
|
def drilldown_search(request):
|
|
template_name = "ui/drilldown/results.html"
|
|
if request.GET:
|
|
query_params = request.GET.dict()
|
|
elif request.POST:
|
|
query_params = request.POST.dict()
|
|
|
|
# Parse the dates
|
|
if "dates" in query_params:
|
|
dates = parse_dates(query_params["dates"])
|
|
del query_params["dates"]
|
|
if dates:
|
|
if "message" in dates:
|
|
return render(request, template_name, dates)
|
|
query_params["from_date"] = dates["from_date"]
|
|
query_params["to_date"] = dates["to_date"]
|
|
query_params["from_time"] = dates["from_time"]
|
|
query_params["to_time"] = dates["to_time"]
|
|
|
|
if request.GET:
|
|
context = query_results(request, query_params)
|
|
elif request.POST:
|
|
context = query_results(request, query_params)
|
|
|
|
# Turn the query into tags for populating the taglist
|
|
tags = create_tags(query_params["query"])
|
|
context["tags"] = tags
|
|
|
|
context["params"] = query_params
|
|
if "message" in context:
|
|
return render(request, template_name, context)
|
|
|
|
context["data"] = json.dumps(
|
|
[
|
|
{
|
|
"text": item.get("msg", None) or item.get("id"),
|
|
"nick": item.get("nick", None),
|
|
"value": item.get("sentiment", None) or None,
|
|
"date": item.get("ts"),
|
|
}
|
|
for item in context["results"]
|
|
]
|
|
)
|
|
if context:
|
|
response = render(request, template_name, context)
|
|
if request.GET:
|
|
return context
|
|
elif request.POST:
|
|
del query_params["csrfmiddlewaretoken"]
|
|
url_params = urllib.parse.urlencode(query_params)
|
|
response["HX-Push"] = reverse("home") + "?" + url_params
|
|
return response
|
|
else:
|
|
return HttpResponse("No results")
|
|
|
|
|
|
class Drilldown(View):
|
|
template_name = "ui/drilldown/drilldown.html"
|
|
plan_name = "drilldown"
|
|
|
|
def get(self, request):
|
|
if request.user.is_anonymous:
|
|
sizes = settings.OPENSEARCH_MAIN_SIZES_ANON
|
|
else:
|
|
sizes = settings.OPENSEARCH_MAIN_SIZES
|
|
|
|
context = {}
|
|
if request.GET:
|
|
context = drilldown_search(request)
|
|
context["sizes"] = sizes
|
|
return render(request, self.template_name, context)
|
|
|
|
def post(self, request):
|
|
return drilldown_search(request)
|
|
|
|
|
|
class ThresholdInfoModal(APIView):
|
|
parser_classes = [FormParser]
|
|
plan_name = "drilldown"
|
|
template_name = "modals/drilldown.html"
|
|
|
|
def post(self, request):
|
|
# if not request.user.has_plan(self.plan_name):
|
|
# return JsonResponse({"success": False})
|
|
if "net" not in request.data:
|
|
return JsonResponse({"success": False})
|
|
if "nick" not in request.data:
|
|
return JsonResponse({"success": False})
|
|
if "channel" not in request.data:
|
|
return JsonResponse({"success": False})
|
|
net = request.data["net"]
|
|
nick = request.data["nick"]
|
|
channel = request.data["channel"]
|
|
channels = get_chans(net, [nick])
|
|
users = get_users(net, [channel])
|
|
num_users = annotate_num_users(net, channels)
|
|
num_chans = annotate_num_chans(net, users)
|
|
if channels:
|
|
inter_users = get_users(net, channels)
|
|
else:
|
|
inter_users = []
|
|
if users:
|
|
inter_chans = get_chans(net, users)
|
|
else:
|
|
inter_chans = []
|
|
context = {
|
|
"net": net,
|
|
"nick": nick,
|
|
"channel": channel,
|
|
"chans": channels,
|
|
"users": users,
|
|
"inter_chans": inter_chans,
|
|
"inter_users": inter_users,
|
|
"num_users": num_users,
|
|
"num_chans": num_chans,
|
|
}
|
|
return render(request, self.template_name, context)
|