Implement graphs properly
This commit is contained in:
parent
d40557bbba
commit
4b4b8bfe72
14
app/urls.py
14
app/urls.py
|
@ -22,7 +22,7 @@ from django.views.generic import TemplateView
|
||||||
from core.ui.views.drilldown import Drilldown
|
from core.ui.views.drilldown import Drilldown
|
||||||
from core.views import Billing, Cancel, Home, Order, Portal, Signup
|
from core.views import Billing, Cancel, Home, Order, Portal, Signup
|
||||||
from core.views.callbacks import Callback
|
from core.views.callbacks import Callback
|
||||||
from core.views.charts import SentimentChartJSONView, VolumeChartJSONView
|
from core.views.dynamic.search import APISearch, Search
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", Home.as_view(), name="home"),
|
path("", Home.as_view(), name="home"),
|
||||||
|
@ -43,14 +43,6 @@ urlpatterns = [
|
||||||
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(
|
path("parts/search/", Search.as_view(), name="search"),
|
||||||
"ui/drilldown/chart/volume/json/",
|
path("api/search/", APISearch.as_view(), name="api_search"),
|
||||||
VolumeChartJSONView.as_view(),
|
|
||||||
name="chart_volume_json",
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
"ui/drilldown/chart/sentiment/json/",
|
|
||||||
SentimentChartJSONView.as_view(),
|
|
||||||
name="chart_sentiment_json",
|
|
||||||
),
|
|
||||||
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
function loadJson(selector) {
|
||||||
|
return JSON.parse(document.querySelector(selector).getAttribute('data-json'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var jsonData = loadJson('#jsonData');
|
||||||
|
var data = jsonData.map((item) => item.value);
|
||||||
|
var labels = jsonData.map((item) => item.date);
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: labels,
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: 'Sentiment',
|
||||||
|
backgroundColor: 'black',
|
||||||
|
borderColor: 'lightblue',
|
||||||
|
data: data,
|
||||||
|
fill: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var element = document.getElementById('volume');
|
||||||
|
element.removeAttribute("height");
|
||||||
|
element.removeAttribute("width");
|
||||||
|
|
||||||
|
var ctx = document.getElementById('volume').getContext('2d');
|
||||||
|
new Chart(ctx, config);
|
|
@ -10,6 +10,7 @@
|
||||||
<link rel="shortcut icon" href="{% static 'favicon.ico' %}">
|
<link rel="shortcut icon" href="{% static 'favicon.ico' %}">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
||||||
<link rel="stylesheet" href="https://site-assets.fontawesome.com/releases/v6.1.1/css/all.css" />
|
<link rel="stylesheet" href="https://site-assets.fontawesome.com/releases/v6.1.1/css/all.css" />
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.8.0" integrity="sha384-cZuAZ+ZbwkNRnrKi05G/fjBX+azI9DNOkNYysZ0I/X5ZFgsmMiBXgDZof30F5ofc" crossorigin="anonymous"></script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="box">
|
||||||
|
<form method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Search</label>
|
||||||
|
<div class="field-body">
|
||||||
|
<div class="field">
|
||||||
|
<div class="control is-expanded has-icons-left">
|
||||||
|
<input name="query" class="input" type="text" placeholder="Query">
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fas fa-magnifying-glass"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<label class="label">Timescale</label>
|
||||||
|
<div class="field-body">
|
||||||
|
<div class="field">
|
||||||
|
<div class="control is-expanded has-icons-left">
|
||||||
|
<div class="select is-fullwidth">
|
||||||
|
<select name="timescale">
|
||||||
|
{% for timescale in timescales %}
|
||||||
|
<option value="{{ timescale }}">{{ timescale }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fas fa-magnifying-glass"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<label class="label">Fields</label>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="control is-expanded has-icons-left">
|
||||||
|
<div class="select is-fullwidth is-multiple">
|
||||||
|
<select multiple name="fields">
|
||||||
|
{% for field in fields %}
|
||||||
|
<option value="{{ field }}">{{ field }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fas fa-magnifying-glass"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<label class="label">Results</label>
|
||||||
|
<div class="field">
|
||||||
|
<div class="control is-expanded has-icons-left">
|
||||||
|
<div class="select is-fullwidth">
|
||||||
|
<select name="size">
|
||||||
|
{% for size in sizes %}
|
||||||
|
<option value="{{ size }}">{{ size }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<span class="icon is-small is-left">
|
||||||
|
<i class="fas fa-magnifying-glass"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-primary is-fullwidth">
|
||||||
|
Search
|
||||||
|
</button>
|
||||||
|
<button hx-post="{% url 'search' %}"
|
||||||
|
hx-trigger="click"
|
||||||
|
hx-target="#parent-div"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
Click Me!
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% if results is not None %}
|
||||||
|
<div class="box">
|
||||||
|
<div class="table-container">
|
||||||
|
<table class="table is-striped is-hoverable is-fullwidth">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>TS</th>
|
||||||
|
<th>msg</th>
|
||||||
|
<th>host</th>
|
||||||
|
<th>nick</th>
|
||||||
|
<th>channel</th>
|
||||||
|
<th>net</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
{% for item in results %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ item.ts }}</td>
|
||||||
|
<td>{{ item.msg }}</td>
|
||||||
|
<td>{{ item.host }}</td>
|
||||||
|
<td>{{ item.nick }}</td>
|
||||||
|
<td>{{ item.channel }}</td>
|
||||||
|
<td>{{ item.net }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<p>{{ card }} hits</p>
|
||||||
|
</div>
|
||||||
|
{% if redacted != 0 %}
|
||||||
|
<div class="column">
|
||||||
|
<p>{{ redacted }} redacted</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if exemption is not None %}
|
||||||
|
<div class="column">
|
||||||
|
<p>god mode</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="column">
|
||||||
|
<p>{{ took }}ms</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column is-half">
|
||||||
|
<div class="box">
|
||||||
|
<label class="label">Volume</label>
|
||||||
|
<canvas id="volumeChart"></canvas>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$.post('{% url "chart_volume_json" %}', function(data) {
|
||||||
|
var ctx = $("#volumeChart").get(0).getContext("2d");
|
||||||
|
new Chart(ctx, {
|
||||||
|
type: 'line', data: data
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="box">
|
||||||
|
<label class="label">Sentiment</label>
|
||||||
|
<canvas id="sentimentChart"></canvas>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$.post('{% url "chart_sentiment_json" %}', function(data) {
|
||||||
|
var ctx = $("#sentimentChart").get(0).getContext("2d");
|
||||||
|
new Chart(ctx, {
|
||||||
|
type: 'line', data: data
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,11 @@
|
||||||
|
{% load static %}
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,8 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js"></script>
|
||||||
<script type="text/javascript" src="https://code.jquery.com/jquery-1.10.0.min.js"></script>
|
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
@ -79,102 +78,16 @@
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
|
<button class="button is-primary is-fullwidth" hx-post="{% url 'search' %}" hx-trigger="click" hx-target="#results" hx-swap="outerHTML">
|
||||||
<button class="button is-primary is-fullwidth">
|
|
||||||
Search
|
Search
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% if results is not None %}
|
|
||||||
<div class="box">
|
|
||||||
<div class="table-container">
|
|
||||||
<table class="table is-striped is-hoverable is-fullwidth">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>TS</th>
|
|
||||||
<th>msg</th>
|
|
||||||
<th>host</th>
|
|
||||||
<th>nick</th>
|
|
||||||
<th>channel</th>
|
|
||||||
<th>net</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
<div id="results">
|
||||||
{% for item in results %}
|
</div>
|
||||||
<tr>
|
|
||||||
<td>{{ item.ts }}</td>
|
|
||||||
<td>{{ item.msg }}</td>
|
|
||||||
<td>{{ item.host }}</td>
|
|
||||||
<td>{{ item.nick }}</td>
|
|
||||||
<td>{{ item.channel }}</td>
|
|
||||||
<td>{{ item.net }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box">
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column">
|
|
||||||
<p>{{ card }} hits</p>
|
|
||||||
</div>
|
|
||||||
{% if redacted != 0 %}
|
|
||||||
<div class="column">
|
|
||||||
<p>{{ redacted }} redacted</p>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if exemption is not None %}
|
|
||||||
<div class="column">
|
|
||||||
<p>god mode</p>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div class="column">
|
|
||||||
<p>{{ took }}ms</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column is-half">
|
|
||||||
<div class="box">
|
|
||||||
<label class="label">Volume</label>
|
|
||||||
<canvas id="volumeChart"></canvas>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
$.post('{% url "chart_volume_json" %}', { name: "John", time: "2pm" }, function(data) {
|
|
||||||
var ctx = $("#volumeChart").get(0).getContext("2d");
|
|
||||||
new Chart(ctx, {
|
|
||||||
type: 'line', data: data
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
<div class="box">
|
|
||||||
<label class="label">Sentiment</label>
|
|
||||||
<canvas id="sentimentChart"></canvas>
|
|
||||||
<script type="text/javascript">
|
|
||||||
$.post('{% url "chart_sentiment_json" %}', { name: "John", time: "2pm" }, function(data) {
|
|
||||||
var ctx = $("#sentimentChart").get(0).getContext("2d");
|
|
||||||
new Chart(ctx, {
|
|
||||||
type: 'line', data: data
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
<div id="results">
|
||||||
|
{% if results is not None %}
|
||||||
|
<div style="display: none" id="jsonData" data-json="{{ data }}"></div>
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<div class="box">
|
||||||
|
<label class="label">Sentiment</label>
|
||||||
|
<canvas id="volume"></canvas>
|
||||||
|
<script src="{% static 'chart.js' %}"></script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box">
|
||||||
|
<div class="table-container">
|
||||||
|
<table class="table is-striped is-hoverable is-fullwidth">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>TS</th>
|
||||||
|
<th>msg</th>
|
||||||
|
<th>host</th>
|
||||||
|
<th>nick</th>
|
||||||
|
<th>channel</th>
|
||||||
|
<th>net</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
{% for item in results %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ item.ts }}</td>
|
||||||
|
<td>{{ item.msg }}</td>
|
||||||
|
<td>{{ item.host }}</td>
|
||||||
|
<td>{{ item.nick }}</td>
|
||||||
|
<td>{{ item.channel }}</td>
|
||||||
|
<td>{{ item.net }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<p>{{ card }} hits</p>
|
||||||
|
</div>
|
||||||
|
{% if redacted != 0 %}
|
||||||
|
<div class="column">
|
||||||
|
<p>{{ redacted }} redacted</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if exemption is not None %}
|
||||||
|
<div class="column">
|
||||||
|
<p>god mode</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="column">
|
||||||
|
<p>{{ took }}ms</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
|
@ -1,14 +1,11 @@
|
||||||
import pprint
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.views import View
|
from django.views import View
|
||||||
|
|
||||||
from core.lib.opensearch import initialise_opensearch, run_main_query
|
from core.lib.opensearch import initialise_opensearch
|
||||||
|
|
||||||
client = initialise_opensearch()
|
client = initialise_opensearch()
|
||||||
pp = pprint.PrettyPrinter(indent=4)
|
|
||||||
|
|
||||||
|
|
||||||
class Drilldown(LoginRequiredMixin, View):
|
class Drilldown(LoginRequiredMixin, View):
|
||||||
|
@ -24,36 +21,3 @@ class Drilldown(LoginRequiredMixin, View):
|
||||||
"timescales": settings.OPENSEARCH_MAIN_TIMESCALES,
|
"timescales": settings.OPENSEARCH_MAIN_TIMESCALES,
|
||||||
}
|
}
|
||||||
return render(request, self.template_name, context)
|
return render(request, self.template_name, context)
|
||||||
|
|
||||||
def post(self, request):
|
|
||||||
if not request.user.has_plan(self.plan_name):
|
|
||||||
return render(request, "denied.html")
|
|
||||||
fields = None
|
|
||||||
if "fields" in request.POST:
|
|
||||||
fields = request.POST.getlist("fields")
|
|
||||||
if "size" in request.POST:
|
|
||||||
size = request.POST["size"]
|
|
||||||
if "query" in request.POST:
|
|
||||||
query = request.POST["query"]
|
|
||||||
results = run_main_query(client, request.user, query, fields, size)
|
|
||||||
if not results:
|
|
||||||
return render(request, "denied.html")
|
|
||||||
# pp.pprint(results)
|
|
||||||
results_parsed = []
|
|
||||||
if "hits" in results.keys():
|
|
||||||
if "hits" in results["hits"]:
|
|
||||||
for item in results["hits"]["hits"]:
|
|
||||||
results_parsed.append(item["_source"])
|
|
||||||
context = {
|
|
||||||
"query": query,
|
|
||||||
"results": results_parsed,
|
|
||||||
"card": results["hits"]["total"]["value"],
|
|
||||||
"took": results["took"],
|
|
||||||
"redacted": results["redacted"],
|
|
||||||
"exemption": results["exemption"],
|
|
||||||
"fields": settings.OPENSEARCH_MAIN_SEARCH_FIELDS,
|
|
||||||
"sizes": settings.OPENSEARCH_MAIN_SIZES,
|
|
||||||
"timescales": settings.OPENSEARCH_MAIN_TIMESCALES,
|
|
||||||
}
|
|
||||||
return render(request, self.template_name, context)
|
|
||||||
return render(request, self.template_name)
|
|
||||||
|
|
|
@ -41,14 +41,17 @@ class Order(LoginRequiredMixin, View):
|
||||||
def get(self, request, plan_name):
|
def get(self, request, plan_name):
|
||||||
plan = Plan.objects.get(name=plan_name)
|
plan = Plan.objects.get(name=plan_name)
|
||||||
try:
|
try:
|
||||||
session = stripe.checkout.Session.create(
|
cast = {
|
||||||
payment_method_types=settings.ALLOWED_PAYMENT_METHODS,
|
"payment_method_types": settings.ALLOWED_PAYMENT_METHODS,
|
||||||
mode="subscription",
|
"mode": "subscription",
|
||||||
customer=request.user.stripe_id,
|
"customer": request.user.stripe_id,
|
||||||
line_items=assemble_plan_map(product_id_filter=plan.product_id),
|
"line_items": assemble_plan_map(product_id_filter=plan.product_id),
|
||||||
success_url=request.build_absolute_uri(reverse("success")),
|
"success_url": request.build_absolute_uri(reverse("success")),
|
||||||
cancel_url=request.build_absolute_uri(reverse("cancel")),
|
"cancel_url": request.build_absolute_uri(reverse("cancel")),
|
||||||
)
|
}
|
||||||
|
if request.user.is_superuser:
|
||||||
|
cast["discounts"] = [{"coupon": settings.STRIPE_ADMIN_COUPON}]
|
||||||
|
session = stripe.checkout.Session.create(**cast)
|
||||||
Session.objects.create(user=request.user, session=session.id)
|
Session.objects.create(user=request.user, session=session.id)
|
||||||
return redirect(session.url)
|
return redirect(session.url)
|
||||||
# return JsonResponse({'id': session.id})
|
# return JsonResponse({'id': session.id})
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
from chartjs.views.lines import BaseLineChartView
|
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
|
||||||
from django.utils.decorators import method_decorator
|
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
|
||||||
|
|
||||||
|
|
||||||
class CSRFExemptMixin(object):
|
|
||||||
@method_decorator(csrf_exempt)
|
|
||||||
def dispatch(self, *args, **kwargs):
|
|
||||||
return super(CSRFExemptMixin, self).dispatch(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class VolumeChartJSONView(CSRFExemptMixin, LoginRequiredMixin, BaseLineChartView):
|
|
||||||
def post(self, request, *args, **kwargs):
|
|
||||||
print("POST")
|
|
||||||
context = self.get_context_data(**kwargs)
|
|
||||||
return self.render_to_response(context)
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
data = super(VolumeChartJSONView, self).get_context_data(**kwargs)
|
|
||||||
# data["colors"] = islice(next_color(), 0, 50)
|
|
||||||
print("KWARGS", kwargs)
|
|
||||||
return data
|
|
||||||
|
|
||||||
def get_labels(self):
|
|
||||||
"""Return 7 labels for the x-axis."""
|
|
||||||
return ["January", "February", "March", "April", "May", "June", "July"]
|
|
||||||
|
|
||||||
def get_providers(self):
|
|
||||||
"""Return names of datasets."""
|
|
||||||
return ["Central", "Eastside", "Westside"]
|
|
||||||
|
|
||||||
def get_data(self):
|
|
||||||
"""Return 3 datasets to plot."""
|
|
||||||
|
|
||||||
return [
|
|
||||||
[75, 44, 92, 11, 44, 95, 35],
|
|
||||||
[41, 92, 18, 3, 73, 87, 92],
|
|
||||||
[87, 21, 94, 3, 90, 13, 65],
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class SentimentChartJSONView(CSRFExemptMixin, LoginRequiredMixin, BaseLineChartView):
|
|
||||||
def post(self, request, *args, **kwargs):
|
|
||||||
print("POST")
|
|
||||||
print(request.POST)
|
|
||||||
context = self.get_context_data(**kwargs)
|
|
||||||
return self.render_to_response(context)
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
data = super(SentimentChartJSONView, self).get_context_data(**kwargs)
|
|
||||||
# data["colors"] = islice(next_color(), 0, 50)
|
|
||||||
print("KWARGS", kwargs)
|
|
||||||
return data
|
|
||||||
|
|
||||||
def get_labels(self):
|
|
||||||
"""Return 7 labels for the x-axis."""
|
|
||||||
return ["January", "February", "March", "April", "May", "June", "July"]
|
|
||||||
|
|
||||||
def get_providers(self):
|
|
||||||
"""Return names of datasets."""
|
|
||||||
return ["Central", "Eastside", "Westside"]
|
|
||||||
|
|
||||||
def get_data(self):
|
|
||||||
"""Return 3 datasets to plot."""
|
|
||||||
|
|
||||||
return [
|
|
||||||
[75, 44, 92, 11, 44, 95, 35],
|
|
||||||
[41, 92, 18, 3, 73, 87, 92],
|
|
||||||
[87, 21, 94, 3, 90, 13, 65],
|
|
||||||
]
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
import logging
|
||||||
|
from django.conf import settings
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.http import HttpResponse, JsonResponse
|
||||||
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
import json
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
from django.views import View
|
||||||
|
from rest_framework.parsers import JSONParser
|
||||||
|
from core.lib.opensearch import initialise_opensearch, run_main_query
|
||||||
|
client = initialise_opensearch()
|
||||||
|
|
||||||
|
|
||||||
|
def query_results(request, post_params, api=False):
|
||||||
|
fields = None
|
||||||
|
if "fields" in request.POST:
|
||||||
|
fields = request.POST.getlist("fields")
|
||||||
|
if "size" in request.POST:
|
||||||
|
size = request.POST["size"]
|
||||||
|
if "query" in request.POST:
|
||||||
|
query = request.POST["query"]
|
||||||
|
results = run_main_query(client, request.user, query, fields, size)
|
||||||
|
if not results:
|
||||||
|
return False
|
||||||
|
# pp.pprint(results)
|
||||||
|
results_parsed = []
|
||||||
|
if "hits" in results.keys():
|
||||||
|
if "hits" in results["hits"]:
|
||||||
|
for item in results["hits"]["hits"]:
|
||||||
|
results_parsed.append(item["_source"])
|
||||||
|
context = {
|
||||||
|
"query": query,
|
||||||
|
"results": results_parsed,
|
||||||
|
"card": results["hits"]["total"]["value"],
|
||||||
|
"took": results["took"],
|
||||||
|
"redacted": results["redacted"],
|
||||||
|
"exemption": results["exemption"],
|
||||||
|
"fields": settings.OPENSEARCH_MAIN_SEARCH_FIELDS,
|
||||||
|
"sizes": settings.OPENSEARCH_MAIN_SIZES,
|
||||||
|
"timescales": settings.OPENSEARCH_MAIN_TIMESCALES,
|
||||||
|
}
|
||||||
|
return context
|
||||||
|
|
||||||
|
class Search(LoginRequiredMixin, View):
|
||||||
|
#parser_classes = [JSONParser]
|
||||||
|
template_name = "ui/results.html"
|
||||||
|
plan_name = "drilldown"
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
if not request.user.has_plan(self.plan_name):
|
||||||
|
return render(request, "denied.html")
|
||||||
|
|
||||||
|
context = query_results(request, request.POST)
|
||||||
|
print("context: ", context)
|
||||||
|
context['data'] = json.dumps(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
'id': item.get('id'),
|
||||||
|
'value': item.get("sentiment", 0),
|
||||||
|
'date': item.get("ts"),
|
||||||
|
}
|
||||||
|
for item in context["results"]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
print("context['data']: ", context['data'])
|
||||||
|
if context:
|
||||||
|
print("OGING TO RENDER")
|
||||||
|
return render(request, self.template_name, context)
|
||||||
|
else:
|
||||||
|
return HttpResponse("No results")
|
||||||
|
|
||||||
|
class APISearch(LoginRequiredMixin, View):
|
||||||
|
#parser_classes = [JSONParser]
|
||||||
|
template_name = "ui/results.html"
|
||||||
|
plan_name = "drilldown"
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
print("POST")
|
||||||
|
if not request.user.has_plan(self.plan_name):
|
||||||
|
return JsonResponse({"success": False})
|
||||||
|
print("PERMS")
|
||||||
|
|
||||||
|
context = query_results(request, request.POST)
|
||||||
|
print("CONTEXT", context)
|
||||||
|
return JsonResponse(context)
|
|
@ -5,4 +5,3 @@ crispy-bulma
|
||||||
opensearch-py
|
opensearch-py
|
||||||
stripe
|
stripe
|
||||||
django-rest-framework
|
django-rest-framework
|
||||||
django-chartjs
|
|
||||||
|
|
Loading…
Reference in New Issue