Implement more elements on Insights page
This commit is contained in:
parent
9de9ddff6f
commit
17d465171b
17
app/urls.py
17
app/urls.py
|
@ -33,6 +33,8 @@ from core.views.dynamic.drilldown import DrilldownSearch, ThresholdInfoModal
|
||||||
from core.views.dynamic.insights import (
|
from core.views.dynamic.insights import (
|
||||||
InsightsChannels,
|
InsightsChannels,
|
||||||
InsightsInfoModal,
|
InsightsInfoModal,
|
||||||
|
InsightsMeta,
|
||||||
|
InsightsNicks,
|
||||||
InsightsSearch,
|
InsightsSearch,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -54,13 +56,18 @@ urlpatterns = [
|
||||||
path("admin/", admin.site.urls),
|
path("admin/", admin.site.urls),
|
||||||
path("accounts/", include("django.contrib.auth.urls")),
|
path("accounts/", include("django.contrib.auth.urls")),
|
||||||
path("accounts/signup/", Signup.as_view(), name="signup"),
|
path("accounts/signup/", Signup.as_view(), name="signup"),
|
||||||
|
##
|
||||||
path("ui/drilldown/", Drilldown.as_view(), name="drilldown"),
|
path("ui/drilldown/", Drilldown.as_view(), name="drilldown"),
|
||||||
|
path("ui/drilldown/modal/", ThresholdInfoModal.as_view(), name="modal_drilldown"),
|
||||||
|
path("ui/drilldown/search/", DrilldownSearch.as_view(), name="search_drilldown"),
|
||||||
|
##
|
||||||
path("ui/insights/", Insights.as_view(), name="insights"),
|
path("ui/insights/", Insights.as_view(), name="insights"),
|
||||||
path("parts/search/drilldown/", DrilldownSearch.as_view(), name="search_drilldown"),
|
path("ui/insights/search/", InsightsSearch.as_view(), name="search_insights"),
|
||||||
path("parts/search/insights/", InsightsSearch.as_view(), name="search_insights"),
|
path("ui/insights/channels/", InsightsChannels.as_view(), name="chans_insights"),
|
||||||
path("parts/channels/insights/", InsightsChannels.as_view(), name="chans_insights"),
|
path("ui/insights/nicks/", InsightsNicks.as_view(), name="nicks_insights"),
|
||||||
path("modal/drilldown/", ThresholdInfoModal.as_view(), name="modal_drilldown"),
|
path("ui/insights/meta/", InsightsMeta.as_view(), name="meta_insights"),
|
||||||
path("modal/insights/", InsightsInfoModal.as_view(), name="modal_insights"),
|
path("ui/insights/modal/", InsightsInfoModal.as_view(), name="modal_insights"),
|
||||||
|
##
|
||||||
path("api/chans/", ThresholdChans.as_view(), name="chans"),
|
path("api/chans/", ThresholdChans.as_view(), name="chans"),
|
||||||
path("api/users/", ThresholdUsers.as_view(), name="users"),
|
path("api/users/", ThresholdUsers.as_view(), name="users"),
|
||||||
path("api/online/", ThresholdOnline.as_view(), name="online"),
|
path("api/online/", ThresholdOnline.as_view(), name="online"),
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
from core.lib.opensearch import client, run_main_query
|
||||||
|
|
||||||
|
|
||||||
|
def get_nicks(request, net, nick):
|
||||||
|
"""
|
||||||
|
Get all related nicknames of the given nickname by tracking nickname changes.
|
||||||
|
"""
|
||||||
|
# Get the initial query
|
||||||
|
query = {}
|
||||||
|
results = set()
|
||||||
|
# nicks = query["nicks"]
|
||||||
|
# for nick in nicks:
|
||||||
|
# if nick not in results:
|
||||||
|
# nicks_result = get_nicks(request, net_nick)
|
||||||
|
# results.add(nick)
|
|
@ -93,7 +93,7 @@ def filter_blacklisted(user, response):
|
||||||
response["exemption"] = True
|
response["exemption"] = True
|
||||||
|
|
||||||
|
|
||||||
def run_main_query(client, user, query, size=None):
|
def run_main_query(client, user, query, custom_query=False, size=None):
|
||||||
"""
|
"""
|
||||||
Low level helper to run an ES query.
|
Low level helper to run an ES query.
|
||||||
Accept a user to pass it to the filter, so we can
|
Accept a user to pass it to the filter, so we can
|
||||||
|
@ -101,7 +101,10 @@ def run_main_query(client, user, query, size=None):
|
||||||
Accept fields and size, for the fields we want to match and the
|
Accept fields and size, for the fields we want to match and the
|
||||||
number of results to return.
|
number of results to return.
|
||||||
"""
|
"""
|
||||||
search_query = construct_query(query, size)
|
if custom_query:
|
||||||
|
search_query = query
|
||||||
|
else:
|
||||||
|
search_query = construct_query(query, size)
|
||||||
try:
|
try:
|
||||||
response = client.search(
|
response = client.search(
|
||||||
body=search_query, index=settings.OPENSEARCH_INDEX_MAIN
|
body=search_query, index=settings.OPENSEARCH_INDEX_MAIN
|
||||||
|
@ -131,7 +134,7 @@ def query_results(request, size=None):
|
||||||
client,
|
client,
|
||||||
request.user,
|
request.user,
|
||||||
query,
|
query,
|
||||||
size,
|
size=size,
|
||||||
)
|
)
|
||||||
if not results:
|
if not results:
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
|
<div id="channels">
|
||||||
|
<div class="panel is-primary" style="max-height: 30em; overflow: auto">
|
||||||
<div class="tile is-parent" id="chans1">
|
<p class="panel-heading">
|
||||||
<div class="tile is-child ">
|
Channels
|
||||||
<div class="panel is-primary" style="height: 30rem; overflow: auto">
|
</p>
|
||||||
<p class="panel-heading">
|
{% for chan in chans %}
|
||||||
Channels
|
|
||||||
</p>
|
|
||||||
{% for chan in chans %}
|
|
||||||
<a class="panel-block is-active">
|
<a class="panel-block is-active">
|
||||||
<span class="panel-icon">
|
<span class="panel-icon">
|
||||||
<i class="fa-solid fa-hashtag" aria-hidden="true"></i>
|
<i class="fa-solid fa-hashtag" aria-hidden="true"></i>
|
||||||
|
@ -20,9 +17,7 @@
|
||||||
class="button is-small">
|
class="button is-small">
|
||||||
{{ chan }}
|
{{ chan }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -0,0 +1,112 @@
|
||||||
|
{% load static %}
|
||||||
|
{% load index %}
|
||||||
|
<div id="info">
|
||||||
|
<div class="panel is-primary">
|
||||||
|
<p class="panel-heading">
|
||||||
|
Information
|
||||||
|
</p>
|
||||||
|
<div class="panel-block is-active">
|
||||||
|
{% if item is not None %}
|
||||||
|
<div class="table-container">
|
||||||
|
<table class="table is-fullwidth is-hoverable">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th>src</th>
|
||||||
|
<td>
|
||||||
|
{% if item.src == 'irc' %}
|
||||||
|
<span class="icon" data-tooltip="IRC">
|
||||||
|
<i class="fa-solid fa-hashtag" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
IRC
|
||||||
|
{% elif item.src == 'dis' %}
|
||||||
|
<span class="icon" data-tooltip="Discord">
|
||||||
|
<i class="fa-brands fa-discord" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
Discord
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>nick</th>
|
||||||
|
<td>
|
||||||
|
{% if item.online is True %}
|
||||||
|
<span class="icon has-text-success has-tooltip-success" data-tooltip="Online">
|
||||||
|
<i class="fa-solid fa-circle"></i>
|
||||||
|
</span>
|
||||||
|
{{ item.nick }}
|
||||||
|
{% elif item.online is False %}
|
||||||
|
<span class="icon has-text-danger has-tooltip-danger" data-tooltip="Offline">
|
||||||
|
<i class="fa-solid fa-circle"></i>
|
||||||
|
</span>
|
||||||
|
{{ item.nick }}
|
||||||
|
{% else %}
|
||||||
|
<span class="icon has-text-warning has-tooltip-warning" data-tooltip="Unknown">
|
||||||
|
<i class="fa-solid fa-circle"></i>
|
||||||
|
</span>
|
||||||
|
{{ item.nick }}
|
||||||
|
{% endif %}
|
||||||
|
{% if item.num_chans is not None %}
|
||||||
|
<span class="tag">
|
||||||
|
{{ item.num_chans }}
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>host</th>
|
||||||
|
<td>{{ item.host }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>actions</th>
|
||||||
|
<td>
|
||||||
|
{% if item.src == 'irc' %}
|
||||||
|
<button
|
||||||
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
|
hx-post="{% url 'modal_insights' %}"
|
||||||
|
hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}", "channel": "{{ item.channel }}"}'
|
||||||
|
hx-target="#modals-here"
|
||||||
|
hx-trigger="click"
|
||||||
|
class="button is-small">
|
||||||
|
Information
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>net</th>
|
||||||
|
<td>{{ item.net }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style="display: none;"
|
||||||
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
|
hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}"}'
|
||||||
|
hx-post="{% url 'chans_insights' %}"
|
||||||
|
hx-trigger="load"
|
||||||
|
hx-target="#channels"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style="display: none;"
|
||||||
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
|
hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}"}'
|
||||||
|
hx-post="{% url 'nicks_insights' %}"
|
||||||
|
hx-trigger="load"
|
||||||
|
hx-target="#nicks"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style="display: none;"
|
||||||
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
|
hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}"}'
|
||||||
|
hx-post="{% url 'meta_insights' %}"
|
||||||
|
hx-trigger="load"
|
||||||
|
hx-target="#meta"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -38,46 +38,66 @@
|
||||||
.icon { border-bottom: 0px !important;}
|
.icon { border-bottom: 0px !important;}
|
||||||
</style>
|
</style>
|
||||||
<div class="tile is-ancestor">
|
<div class="tile is-ancestor">
|
||||||
|
<div class="tile is-vertical is-9">
|
||||||
<div class="tile is-parent is-vertical">
|
<div class="tile">
|
||||||
<div class="tile is-child box">
|
<div class="tile is-parent is-vertical">
|
||||||
<form method="POST">
|
<article class="tile is-child box">
|
||||||
{% csrf_token %}
|
<form method="POST">
|
||||||
<div class="field">
|
{% csrf_token %}
|
||||||
<label class="label">Search</label>
|
|
||||||
<div class="field-body">
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<div class="control is-expanded has-icons-left">
|
<label class="label">Search</label>
|
||||||
<input name="query" class="input" type="text" placeholder="nickname">
|
<div class="field-body">
|
||||||
<span class="icon is-small is-left">
|
<div class="field">
|
||||||
<i class="fas fa-magnifying-glass"></i>
|
<div class="control is-expanded has-icons-left">
|
||||||
</span>
|
<input name="query" class="input" type="text" placeholder="nickname">
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fas fa-magnifying-glass"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="field">
|
||||||
</div>
|
<div class="control">
|
||||||
<div class="field">
|
<button
|
||||||
<div class="control">
|
class="button is-primary is-fullwidth"
|
||||||
<button
|
hx-post="{% url 'search_insights' %}"
|
||||||
class="button is-primary is-fullwidth"
|
hx-trigger="click"
|
||||||
hx-post="{% url 'search_insights' %}"
|
hx-target="#info"
|
||||||
hx-trigger="click"
|
hx-swap="outerHTML">
|
||||||
hx-target="#results"
|
Search
|
||||||
hx-swap="innerHTML">
|
</button>
|
||||||
Search
|
</div>
|
||||||
</button>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</article>
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="results">
|
</div>
|
||||||
|
<div class="tile is-parent">
|
||||||
|
<article class="tile is-child box">
|
||||||
|
<div id="nicks"></div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="tile">
|
||||||
|
<div class="tile is-parent is-vertical">
|
||||||
|
<article class="tile is-child box">
|
||||||
|
<div id="info"></div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="tile is-parent">
|
||||||
|
<article class="tile is-child box">
|
||||||
|
<div id="meta"></div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tile is-parent">
|
||||||
|
<article class="tile is-child box">
|
||||||
|
<div id="channels"></div>
|
||||||
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<article id="chans1">
|
|
||||||
</article>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="modals-here"></div>
|
<div id="modals-here"></div>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<div id="meta">
|
||||||
|
<div class="panel is-primary" style="max-height: 30em; overflow: auto">
|
||||||
|
<p class="panel-heading">
|
||||||
|
Meta
|
||||||
|
</p>
|
||||||
|
<a class="panel-block is-active">
|
||||||
|
<span class="panel-icon">
|
||||||
|
<i class="fa-solid fa-hashtag" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
|
hx-post="{% url 'modal_drilldown' %}"
|
||||||
|
hx-vals='{"net": "{{ net }}", "nick": "{{ nick }}", "channel": "{{ chan }}"}'
|
||||||
|
hx-target="#modals-here"
|
||||||
|
hx-trigger="click"
|
||||||
|
class="button is-small">
|
||||||
|
bbb
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,21 @@
|
||||||
|
<div id="nicks">
|
||||||
|
<div class="panel is-primary" style="max-height: 30em; overflow: auto">
|
||||||
|
<p class="panel-heading">
|
||||||
|
Nicks
|
||||||
|
</p>
|
||||||
|
<a class="panel-block is-active">
|
||||||
|
<span class="panel-icon">
|
||||||
|
<i class="fa-solid fa-hashtag" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
|
hx-post="{% url 'modal_drilldown' %}"
|
||||||
|
hx-vals='{"net": "{{ net }}", "nick": "{{ nick }}", "channel": "{{ chan }}"}'
|
||||||
|
hx-target="#modals-here"
|
||||||
|
hx-trigger="click"
|
||||||
|
class="button is-small">
|
||||||
|
aaa
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -1,94 +0,0 @@
|
||||||
{% load static %}
|
|
||||||
{% load index %}
|
|
||||||
|
|
||||||
<div class="panel is-primary">
|
|
||||||
<p class="panel-heading">
|
|
||||||
Information
|
|
||||||
</p>
|
|
||||||
<div class="panel-block is-active">
|
|
||||||
<div class="tile is-child">
|
|
||||||
{% if item is not None %}
|
|
||||||
<div class="table-container">
|
|
||||||
<table class="table is-fullwidth is-hoverable">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th>src</th>
|
|
||||||
<td>
|
|
||||||
{% if item.src == 'irc' %}
|
|
||||||
<span class="icon" data-tooltip="IRC">
|
|
||||||
<i class="fa-solid fa-hashtag" aria-hidden="true"></i>
|
|
||||||
</span>
|
|
||||||
IRC
|
|
||||||
{% elif item.src == 'dis' %}
|
|
||||||
<span class="icon" data-tooltip="Discord">
|
|
||||||
<i class="fa-brands fa-discord" aria-hidden="true"></i>
|
|
||||||
</span>
|
|
||||||
Discord
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>nick</th>
|
|
||||||
<td>
|
|
||||||
{% if item.online is True %}
|
|
||||||
<span class="icon has-text-success has-tooltip-success" data-tooltip="Online">
|
|
||||||
<i class="fa-solid fa-circle"></i>
|
|
||||||
</span>
|
|
||||||
{{ item.nick }}
|
|
||||||
{% elif item.online is False %}
|
|
||||||
<span class="icon has-text-danger has-tooltip-danger" data-tooltip="Offline">
|
|
||||||
<i class="fa-solid fa-circle"></i>
|
|
||||||
</span>
|
|
||||||
{{ item.nick }}
|
|
||||||
{% else %}
|
|
||||||
<span class="icon has-text-warning has-tooltip-warning" data-tooltip="Unknown">
|
|
||||||
<i class="fa-solid fa-circle"></i>
|
|
||||||
</span>
|
|
||||||
{{ item.nick }}
|
|
||||||
{% endif %}
|
|
||||||
{% if item.num_chans is not None %}
|
|
||||||
<span class="tag">
|
|
||||||
{{ item.num_chans }}
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>host</th>
|
|
||||||
<td>{{ item.host }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>actions</th>
|
|
||||||
<td>
|
|
||||||
{% if item.src == 'irc' %}
|
|
||||||
<button
|
|
||||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
|
||||||
hx-post="{% url 'modal_insights' %}"
|
|
||||||
hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}", "channel": "{{ item.channel }}"}'
|
|
||||||
hx-target="#modals-here"
|
|
||||||
hx-trigger="click"
|
|
||||||
class="button is-small">
|
|
||||||
Information
|
|
||||||
</button>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>net</th>
|
|
||||||
<td>{{ item.net }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
|
||||||
hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}"}'
|
|
||||||
hx-post="{% url 'chans_insights' %}"
|
|
||||||
hx-trigger="load"
|
|
||||||
hx-target="#chans1"
|
|
||||||
hx-swap="outerHTML">
|
|
||||||
</div>
|
|
|
@ -5,6 +5,7 @@ from django.views import View
|
||||||
from rest_framework.parsers import FormParser
|
from rest_framework.parsers import FormParser
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
|
||||||
|
from core.lib.nicktrace import get_nicks
|
||||||
from core.lib.opensearch import query_single_result
|
from core.lib.opensearch import query_single_result
|
||||||
from core.lib.threshold import (
|
from core.lib.threshold import (
|
||||||
annotate_num_chans,
|
annotate_num_chans,
|
||||||
|
@ -16,7 +17,7 @@ from core.lib.threshold import (
|
||||||
|
|
||||||
class InsightsSearch(LoginRequiredMixin, View):
|
class InsightsSearch(LoginRequiredMixin, View):
|
||||||
# parser_classes = [JSONParser]
|
# parser_classes = [JSONParser]
|
||||||
template_name = "ui/insights/results.html"
|
template_name = "ui/insights/info.html"
|
||||||
plan_name = "drilldown"
|
plan_name = "drilldown"
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
|
@ -57,6 +58,44 @@ class InsightsChannels(LoginRequiredMixin, APIView):
|
||||||
return HttpResponse("No results")
|
return HttpResponse("No results")
|
||||||
|
|
||||||
|
|
||||||
|
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"]
|
||||||
|
|
||||||
|
context = {"net": net, "nick": nick}
|
||||||
|
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 "nick" not in request.data:
|
||||||
|
return HttpResponse("No nick")
|
||||||
|
net = request.data["net"]
|
||||||
|
nick = request.data["nick"]
|
||||||
|
|
||||||
|
context = {"net": net, "nick": nick}
|
||||||
|
return render(request, self.template_name, context)
|
||||||
|
|
||||||
|
|
||||||
class InsightsInfoModal(LoginRequiredMixin, APIView):
|
class InsightsInfoModal(LoginRequiredMixin, APIView):
|
||||||
parser_classes = [FormParser]
|
parser_classes = [FormParser]
|
||||||
plan_name = "drilldown"
|
plan_name = "drilldown"
|
||||||
|
|
Loading…
Reference in New Issue