189 lines
6.4 KiB
Python
189 lines
6.4 KiB
Python
from ast import literal_eval
|
|
|
|
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
|
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.db.storage import db
|
|
from core.lib.meta import get_meta
|
|
from core.lib.nicktrace import get_nicks
|
|
from core.lib.threshold import (
|
|
annotate_num_chans,
|
|
annotate_num_users,
|
|
annotate_online,
|
|
get_chans,
|
|
get_users,
|
|
)
|
|
|
|
|
|
class Insights(LoginRequiredMixin, PermissionRequiredMixin, View):
|
|
template_name = "ui/insights/insights.html"
|
|
permission_required = "use_insights"
|
|
|
|
def get(self, request, index):
|
|
context = {"index": index}
|
|
return render(request, self.template_name, context)
|
|
|
|
|
|
class InsightsSearch(LoginRequiredMixin, PermissionRequiredMixin, View):
|
|
# parser_classes = [JSONParser]
|
|
template_name = "ui/insights/info.html"
|
|
permission_required = "use_insights"
|
|
|
|
def post(self, request, index):
|
|
query_params = request.POST.dict()
|
|
if "query" in query_params:
|
|
query_params["query"] = "nick: " + query_params["query"]
|
|
query_params["source"] = "all"
|
|
query_params["index"] = index
|
|
context = db.query_single_result(request, query_params)
|
|
if not context:
|
|
return HttpResponseForbidden()
|
|
context["index"] = index
|
|
return render(request, self.template_name, context)
|
|
|
|
|
|
class InsightsChannels(LoginRequiredMixin, PermissionRequiredMixin, APIView):
|
|
parser_classes = [FormParser]
|
|
template_name = "ui/insights/channels.html"
|
|
permission_required = "use_insights"
|
|
|
|
def post(self, request, index):
|
|
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,
|
|
"index": index,
|
|
}
|
|
return render(request, self.template_name, context)
|
|
|
|
|
|
class InsightsNicks(LoginRequiredMixin, PermissionRequiredMixin, APIView):
|
|
parser_classes = [FormParser]
|
|
template_name = "ui/insights/nicks.html"
|
|
permission_required = "use_insights"
|
|
|
|
def post(self, request, index):
|
|
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"]
|
|
if not nick:
|
|
return HttpResponseForbidden()
|
|
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,
|
|
"index": index,
|
|
}
|
|
return render(request, self.template_name, context)
|
|
|
|
|
|
class InsightsMeta(LoginRequiredMixin, PermissionRequiredMixin, APIView):
|
|
parser_classes = [FormParser]
|
|
template_name = "ui/insights/meta.html"
|
|
permission_required = "use_insights"
|
|
|
|
def post(self, request, index):
|
|
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)
|
|
|
|
# Check the user has permissions to use the meta index
|
|
if not request.user.has_perm("core.index_meta"):
|
|
return HttpResponseForbidden()
|
|
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, "index": index}
|
|
return render(request, self.template_name, context)
|
|
|
|
|
|
class InsightsInfoModal(LoginRequiredMixin, PermissionRequiredMixin, APIView):
|
|
parser_classes = [FormParser]
|
|
template_name = "modals/drilldown.html"
|
|
permission_required = "use_insights"
|
|
|
|
def post(self, request, index):
|
|
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,
|
|
"index": index,
|
|
}
|
|
return render(request, self.template_name, context)
|