neptune/core/views/dynamic/insights.py

165 lines
5.7 KiB
Python

from ast import literal_eval
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponse, HttpResponseForbidden, JsonResponse
from django.shortcuts import render
from django.views import View
from rest_framework.parsers import FormParser
from rest_framework.views import APIView
from core.lib.meta import get_meta
from core.lib.nicktrace import get_nicks
from core.lib.opensearch import query_single_result
from core.lib.threshold import (
annotate_num_chans,
annotate_num_users,
annotate_online,
get_chans,
get_users,
)
class InsightsSearch(LoginRequiredMixin, View):
# parser_classes = [JSONParser]
template_name = "ui/insights/info.html"
plan_name = "drilldown"
def post(self, request):
if not request.user.has_plan(self.plan_name):
return HttpResponseForbidden()
results, context = query_single_result(request)
if not context:
return HttpResponseForbidden()
return render(request, self.template_name, context)
class InsightsChannels(LoginRequiredMixin, APIView):
parser_classes = [FormParser]
template_name = "ui/insights/channels.html"
plan_name = "drilldown"
def post(self, request):
if not request.user.has_plan(self.plan_name):
return HttpResponseForbidden()
if "net" not in request.data:
return HttpResponse("No net")
if "nick" not in request.data:
return HttpResponse("No nick")
net = request.data["net"]
nick = request.data["nick"]
chans = get_chans(net, [nick])
num_users = annotate_num_users(net, chans)
if not chans:
return HttpResponseForbidden()
context = {"net": net, "nick": nick, "chans": chans, "num_users": num_users}
return render(request, self.template_name, context)
class InsightsNicks(LoginRequiredMixin, APIView):
parser_classes = [FormParser]
template_name = "ui/insights/nicks.html"
plan_name = "drilldown"
def post(self, request):
if not request.user.has_plan(self.plan_name):
return HttpResponseForbidden()
if "net" not in request.data:
return HttpResponse("No net")
if "nick" not in request.data:
return HttpResponse("No nick")
net = request.data["net"]
nick = request.data["nick"]
nicks = get_nicks(request, net, [nick])
# Filter Guest
nicks = [x for x in nicks if not x.startswith("Guest")]
online = annotate_online(net, nicks)
if not nicks:
return HttpResponseForbidden()
context = {"net": net, "nick": nick, "nicks": nicks, "online": online}
return render(request, self.template_name, context)
class InsightsMeta(LoginRequiredMixin, APIView):
parser_classes = [FormParser]
template_name = "ui/insights/meta.html"
plan_name = "drilldown"
def post(self, request):
if not request.user.has_plan(self.plan_name):
return HttpResponseForbidden()
if "net" not in request.data:
return HttpResponse("No net")
if "nicks" not in request.data:
return HttpResponse("No nicks")
net = request.data["net"]
nicks = request.data["nicks"]
nicks = literal_eval(nicks)
meta = get_meta(request, net, nicks)
unique_values = {}
# Create a map of unique values for each key for each nick
for x in meta:
nick = x["nick"]
if nick not in unique_values:
unique_values[nick] = {}
for k, v in x.items():
if k not in unique_values[nick]:
unique_values[nick][k] = set()
if k in ["ts", "time", "date", "id"]:
continue
unique_values[nick][k].add(v)
meta_dedup = {}
for x in meta:
nick = x["nick"]
for k, v in x.items():
if v in unique_values[nick][k]:
if k not in meta_dedup:
meta_dedup[k] = set()
meta_dedup[k].add(v)
unique_values[nick][k].remove(v)
context = {"net": net, "nicks": nicks, "meta": meta_dedup}
return render(request, self.template_name, context)
class InsightsInfoModal(LoginRequiredMixin, 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)