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)