From 712ed9517326b85da848c40acf143213911b0d49 Mon Sep 17 00:00:00 2001 From: Etzelia Date: Fri, 16 Aug 2019 11:46:09 -0500 Subject: [PATCH] Add activity pages Signed-off-by: Etzelia --- activity.py | 55 +++ forms.py => gui.py | 33 +- migrations/0001_initial.py | 322 ------------------ models.py | 37 +- static/coreprotect/css/main.css | 4 + static/coreprotect/img/intelli.png | Bin 0 -> 629 bytes static/coreprotect/img/ymca.png | Bin 0 -> 866 bytes templates/coreprotect/activity.html | 84 +++++ templates/coreprotect/base.html | 23 ++ templates/coreprotect/coreprotect.html | 43 +-- templates/coreprotect/table/activity.html | 16 + .../{table.html => table/coreprotect.html} | 0 urls.py | 8 +- utils.py | 9 + views.py | 42 ++- 15 files changed, 295 insertions(+), 381 deletions(-) create mode 100644 activity.py rename forms.py => gui.py (93%) delete mode 100644 migrations/0001_initial.py create mode 100644 static/coreprotect/img/intelli.png create mode 100644 static/coreprotect/img/ymca.png create mode 100644 templates/coreprotect/activity.html create mode 100644 templates/coreprotect/base.html create mode 100644 templates/coreprotect/table/activity.html rename templates/coreprotect/{table.html => table/coreprotect.html} (100%) create mode 100644 utils.py diff --git a/activity.py b/activity.py new file mode 100644 index 0000000..f9b27f1 --- /dev/null +++ b/activity.py @@ -0,0 +1,55 @@ +from django_coreprotect.models import SessionResult, ActivityResult +from django_coreprotect.utils import safe_int + + +class ActivityForm: + + def __init__(self): + self.players = "" + self.date_from = "" + self.date_to = "" + + +def activity_data(request): + request_data = request.GET + form = ActivityForm() + + # Players + form.players = request_data["players"] if "players" in request_data else "" + + # Date and Time + form.date_from = request_data["date_from"] if "date_from" in request_data else "" + form.date_to = request_data["date_to"] if "date_to" in request_data else "" + + return form + + +def activity_results(form): + query = "" + players = [] + if form.players: + for player in form.players.split(","): + players.append(player.strip()) + players_clause = " WHERE ({}) ".format(" OR ".join(["player LIKE '%{}%'".format(p) for p in players])) + query = '''SELECT + 0 AS id, cs.time AS unix, cu.user AS player, cs.action + FROM co_session cs + JOIN co_user cu ON cs.user = cu.id + {players} + '''.format(players=players_clause) + + if query: + print(query) + sessions = SessionResult.objects.raw(query) + activity = {} + for session in sessions: + time = -safe_int(session.unix) if session.action == 1 else safe_int(session.unix) + if session.player in activity: + activity[session.player] += time + else: + activity[session.player] = time + results = [] + for player, time in activity.items(): + results.append(ActivityResult(player, time)) + return results + return [] diff --git a/forms.py b/gui.py similarity index 93% rename from forms.py rename to gui.py index 5cbd740..c5b8bde 100644 --- a/forms.py +++ b/gui.py @@ -1,7 +1,9 @@ -from django_coreprotect.models import * +from django_coreprotect.models import CoWorld, GUIResult +from django_coreprotect.utils import safe_int, checkbox +from datetime import datetime -class Form: +class GUIForm: def __init__(self): self.block_break = False @@ -14,6 +16,7 @@ class Form: self.sign_place = False self.worlds = [] self.ignore_environment = False + self.oldest_first = False self.page = "" self.page_size = "" self.start = "" @@ -27,20 +30,9 @@ class Form: self.date_to = "" -def checkbox(value): - return True if value == "on" else False - - -def safe_int(value): - try: - return int(value) - except: - return 0 - - -def form_data(request): +def gui_data(request): request_data = request.GET - form = Form() + form = GUIForm() worlds = CoWorld.objects.all() # Actions @@ -72,6 +64,7 @@ def form_data(request): # Options form.ignore_environment = checkbox(request_data["ignore_environment"]) if "ignore_environment" in request_data else False + form.oldest_first = checkbox(request_data["oldest_first"]) if "oldest_first" in request_data else False # Limit Results form.page = request_data["page"] if "page" in request_data else "0" @@ -99,9 +92,10 @@ def form_data(request): return form -def result_data(form): +def gui_results(form): queries = [] ignore_environment = " AND player NOT LIKE '#%' " if form.ignore_environment else "" + oldest_first = " ASC " if form.oldest_first else " DESC " coords = [] radius = form.radius if form.radius else "0" @@ -226,8 +220,7 @@ def result_data(form): query = " UNION ".join(queries) if query: - query += " ORDER BY unix DESC LIMIT {}, {}".format(form.start, form.page_size) - print(query) + query += " ORDER BY unix {} LIMIT {}, {}".format(oldest_first, form.start, form.page_size) if query: - return CoResult.objects.raw(query) - return [] \ No newline at end of file + return GUIResult.objects.raw(query) + return [] diff --git a/migrations/0001_initial.py b/migrations/0001_initial.py deleted file mode 100644 index a90384b..0000000 --- a/migrations/0001_initial.py +++ /dev/null @@ -1,322 +0,0 @@ -# Generated by Django 2.2.3 on 2019-08-16 03:39 - -import django.contrib.auth.models -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('auth', '0011_update_proxy_permissions'), - ] - - operations = [ - migrations.CreateModel( - name='CoArtMap', - fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('art', models.TextField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'Art Map', - 'verbose_name_plural': 'Art Maps', - 'db_table': 'co_art_map', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoBlock', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time', models.IntegerField(blank=True, null=True)), - ('user', models.IntegerField(blank=True, null=True)), - ('wid', models.IntegerField(blank=True, null=True)), - ('x', models.IntegerField(blank=True, null=True)), - ('y', models.IntegerField(blank=True, null=True)), - ('z', models.IntegerField(blank=True, null=True)), - ('type', models.IntegerField(blank=True, null=True)), - ('data', models.IntegerField(blank=True, null=True)), - ('meta', models.BinaryField(blank=True, null=True)), - ('blockdata', models.BinaryField(blank=True, null=True)), - ('action', models.IntegerField(blank=True, null=True)), - ('rolled_back', models.IntegerField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'Block', - 'verbose_name_plural': 'Blocks', - 'db_table': 'co_block', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoBlockdataMap', - fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('data', models.TextField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'BlockData Map', - 'verbose_name_plural': 'BlockData Maps', - 'db_table': 'co_blockdata_map', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoChat', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time', models.IntegerField(blank=True, null=True)), - ('user', models.IntegerField(blank=True, null=True)), - ('message', models.TextField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'Chat Message', - 'verbose_name_plural': 'Chat Messages', - 'db_table': 'co_chat', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoCommand', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time', models.IntegerField(blank=True, null=True)), - ('user', models.IntegerField(blank=True, null=True)), - ('message', models.TextField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'Command', - 'verbose_name_plural': 'Commands', - 'db_table': 'co_command', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoContainer', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time', models.IntegerField(blank=True, null=True)), - ('user', models.IntegerField(blank=True, null=True)), - ('wid', models.IntegerField(blank=True, null=True)), - ('x', models.IntegerField(blank=True, null=True)), - ('y', models.IntegerField(blank=True, null=True)), - ('z', models.IntegerField(blank=True, null=True)), - ('type', models.IntegerField(blank=True, null=True)), - ('data', models.IntegerField(blank=True, null=True)), - ('amount', models.IntegerField(blank=True, null=True)), - ('metadata', models.BinaryField(blank=True, null=True)), - ('action', models.IntegerField(blank=True, null=True)), - ('rolled_back', models.IntegerField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'Container Transaction', - 'verbose_name_plural': 'Container Transactions', - 'db_table': 'co_container', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoDatabaseLock', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('status', models.IntegerField(blank=True, null=True)), - ('time', models.IntegerField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'Database Lock', - 'verbose_name_plural': 'Database Locks', - 'db_table': 'co_database_lock', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoEntity', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time', models.IntegerField(blank=True, null=True)), - ('data', models.BinaryField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'Entity', - 'verbose_name_plural': 'Entities', - 'db_table': 'co_entity', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoEntityMap', - fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('entity', models.TextField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'Entity Mapping', - 'verbose_name_plural': 'Entity Mappings', - 'db_table': 'co_entity_map', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoMaterialMap', - fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('material', models.TextField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'Material Mapping', - 'verbose_name_plural': 'Material Mappings', - 'db_table': 'co_material_map', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoResult', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('type', models.TextField()), - ('unix', models.TextField()), - ('player', models.TextField()), - ('action', models.TextField()), - ('data', models.TextField()), - ('x', models.TextField()), - ('y', models.TextField()), - ('z', models.TextField()), - ('world', models.TextField()), - ], - options={ - 'verbose_name': 'Result', - 'verbose_name_plural': 'Results', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoSession', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time', models.IntegerField(blank=True, null=True)), - ('user', models.IntegerField(blank=True, null=True)), - ('wid', models.IntegerField(blank=True, null=True)), - ('x', models.IntegerField(blank=True, null=True)), - ('y', models.IntegerField(blank=True, null=True)), - ('z', models.IntegerField(blank=True, null=True)), - ('action', models.IntegerField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'Session', - 'verbose_name_plural': 'Sessions', - 'db_table': 'co_session', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoSign', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time', models.IntegerField(blank=True, null=True)), - ('user', models.IntegerField(blank=True, null=True)), - ('wid', models.IntegerField(blank=True, null=True)), - ('x', models.IntegerField(blank=True, null=True)), - ('y', models.IntegerField(blank=True, null=True)), - ('z', models.IntegerField(blank=True, null=True)), - ('color', models.IntegerField(blank=True, null=True)), - ('line_1', models.TextField(blank=True, null=True)), - ('line_2', models.TextField(blank=True, null=True)), - ('line_3', models.TextField(blank=True, null=True)), - ('line_4', models.TextField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'Sign', - 'verbose_name_plural': 'Signs', - 'db_table': 'co_sign', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoSkull', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time', models.IntegerField(blank=True, null=True)), - ('owner', models.TextField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'Skull', - 'verbose_name_plural': 'Skulls', - 'db_table': 'co_skull', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoUser', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time', models.IntegerField(blank=True, null=True)), - ('user', models.TextField(blank=True, null=True)), - ('uuid', models.TextField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'User', - 'verbose_name_plural': 'Users', - 'db_table': 'co_user', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoUsernameLog', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time', models.IntegerField(blank=True, null=True)), - ('uuid', models.TextField(blank=True, null=True)), - ('user', models.TextField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'Username', - 'verbose_name_plural': 'Usernames', - 'db_table': 'co_username_log', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoVersion', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time', models.IntegerField(blank=True, null=True)), - ('version', models.TextField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'Version', - 'verbose_name_plural': 'Versions', - 'db_table': 'co_version', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoWorld', - fields=[ - ('id', models.IntegerField(primary_key=True, serialize=False)), - ('world', models.TextField(blank=True, null=True)), - ], - options={ - 'verbose_name': 'World', - 'verbose_name_plural': 'Worlds', - 'db_table': 'co_world', - 'managed': False, - }, - ), - migrations.CreateModel( - name='CoreProtectUser', - fields=[ - ], - options={ - 'permissions': (('gui', 'Can use CoreProtect GUI'), ('gui_extra', 'Can search Chat/Commands'), ('activity', 'Can use CoreProtect Activity Monitor')), - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=('auth.user',), - managers=[ - ('objects', django.contrib.auth.models.UserManager()), - ], - ), - ] diff --git a/models.py b/models.py index 699dd3a..e50ec3b 100644 --- a/models.py +++ b/models.py @@ -1,6 +1,7 @@ from django.db import models from django.contrib.auth.models import User from datetime import datetime +from django_coreprotect.utils import safe_int class CoreProtectUser(User): @@ -290,7 +291,7 @@ class CoWorld(models.Model): return self.world -class CoResult(models.Model): +class GUIResult(models.Model): type = models.TextField() unix = models.TextField() player = models.TextField() @@ -338,5 +339,35 @@ class CoResult(models.Model): class Meta: managed = False - verbose_name = "Result" - verbose_name_plural = "Results" + verbose_name = "GUI Result" + verbose_name_plural = "GUI Results" + + +class SessionResult(models.Model): + unix = models.TextField() + player = models.TextField() + action = models.TextField() + + class Meta: + managed = False + verbose_name = "Session Result" + verbose_name_plural = "Session Results" + + +class ActivityResult: + + def __init__(self, player, time): + self.player = player + self.time = time + + @property + def time_display(self): + time = safe_int(self.time) + seconds = time % 60 + time //= 60 + minutes = time % 60 + time //= 60 + hours = time % 24 + time //= 24 + days = time + return "{}d, {}h, {}m, {}s".format(days, hours, minutes, seconds) diff --git a/static/coreprotect/css/main.css b/static/coreprotect/css/main.css index 4f12016..5283dee 100644 --- a/static/coreprotect/css/main.css +++ b/static/coreprotect/css/main.css @@ -1,3 +1,7 @@ .click-row { cursor: pointer; +} + +form { + margin-left: 7rem; } \ No newline at end of file diff --git a/static/coreprotect/img/intelli.png b/static/coreprotect/img/intelli.png new file mode 100644 index 0000000000000000000000000000000000000000..043e470a49863264cb77fa61cf3a46df27ceb507 GIT binary patch literal 629 zcmeAS@N?(olHy`uVBq!ia0vp^TR@nD2}o{QKQWbofyu_x#WAE}&YRmCd!+(J94<8S8>KH#RaSRW)4ontjjr-*mQx#atCt@iBWdZuA|0Z1k*d zKfhnZw5J6YJ^YD!_MDzFDuok{I0~^7!^o7De|Y#~_|tOL&Sn+9NfsWD6o_MN`S<5z zZNZVJMKibXoIm=MNL^4Xa-V;$EI2ZK{e3mv!zTa#|C5t{R7A9sq29XXxBT)w>pj&r za?QfmO6P7lJ>g@!Pvz;aRkHDiNp()O{)dO2`()+68}S!f{^%h-6u|zu{kH6OHT%3N zr-=-6s0X6{|NXi3JKq`er~a&ZL`4=-gf7_*OhNzuADklfMC9n+Nk9&Rr>mdKI;Vst E09nKErvLx| literal 0 HcmV?d00001 diff --git a/static/coreprotect/img/ymca.png b/static/coreprotect/img/ymca.png new file mode 100644 index 0000000000000000000000000000000000000000..766142a7cabe7b8eb3cf5095cdfab1300fe859ad GIT binary patch literal 866 zcmeAS@N?(olHy`uVBq!ia0vp^TR@nD2}o{QKQWbofmzej#WAE}&YL?Mvr=27+8%D5 zZ0mVWCPjutwCT(ju_V=|4j1c-_nfv|JSQ#iW{coQzBeq~g3+Ra%QkKoyqIOcqI*nX zadMM&X9eSXlX|VndE7sKFz1JDy%uL*__;APt=LZH$MveMrZE<_x6hovk#nw%J39KZ zeM;ms?bmM~9y)sTPuEkSe?tFOA8{07_moj7oIniY+VoHFe%yJMRCWCS_p)c{F}EXm z#m`N9+5PzRraM0$msA})`o*-$pYNSJu?9jcUGlZ&(O&bo+5K1%D;d2^N8pDxB0u{;N<4tg2bl@U>MtOwVzw@;?~ulvdh)g54TRzopr0K2by AF8}}l literal 0 HcmV?d00001 diff --git a/templates/coreprotect/activity.html b/templates/coreprotect/activity.html new file mode 100644 index 0000000..6443d9a --- /dev/null +++ b/templates/coreprotect/activity.html @@ -0,0 +1,84 @@ +{% extends "coreprotect/base.html" %} +{% load static %} +{% block head %} + +{% endblock %} +{% block body %} +
+
+

CoreProtect Activity Monitor

+
+
+
+
+

+ Players +

+
+ +
+ +
+ +

+ Date and Time +

+
+

+ +

+
+
+

+ +

+
+ +
+ +
+

+ +

+

+ +

+

+ +

+
+
+
+ +
+
+{% endblock %} +{% block script %} + +{% endblock %} \ No newline at end of file diff --git a/templates/coreprotect/base.html b/templates/coreprotect/base.html new file mode 100644 index 0000000..1f15c1f --- /dev/null +++ b/templates/coreprotect/base.html @@ -0,0 +1,23 @@ +{% load static %} + + + + CoreProtect Web Interface + {% block head %}{% endblock %} + + + + + + + + + + +{% block body %}{% endblock %} + + + + +{% block script %}{% endblock %} + \ No newline at end of file diff --git a/templates/coreprotect/coreprotect.html b/templates/coreprotect/coreprotect.html index 49bc6ea..b8b8dd6 100644 --- a/templates/coreprotect/coreprotect.html +++ b/templates/coreprotect/coreprotect.html @@ -1,29 +1,16 @@ +{% extends "coreprotect/base.html" %} {% load static %} - - - - CoreProtect Web Interface - - - - - - - - - - - - - - +{% block head %} + +{% endblock %} +{% block body %}
-

CoreProtect Web GUI

+

CoreProtect GUI


-
+

@@ -83,6 +70,10 @@

+
+ + +

@@ -182,9 +173,8 @@
- - - +{% endblock %} +{% block script %} - +{% endblock %} \ No newline at end of file diff --git a/templates/coreprotect/table/activity.html b/templates/coreprotect/table/activity.html new file mode 100644 index 0000000..361fdf7 --- /dev/null +++ b/templates/coreprotect/table/activity.html @@ -0,0 +1,16 @@ + + + + + + + + + {% for result in results %} + + + + + {% endfor %} + +
PlayerTime
{{ result.player }}{{ result.time_display }}
\ No newline at end of file diff --git a/templates/coreprotect/table.html b/templates/coreprotect/table/coreprotect.html similarity index 100% rename from templates/coreprotect/table.html rename to templates/coreprotect/table/coreprotect.html diff --git a/urls.py b/urls.py index 43ace8b..28eecae 100644 --- a/urls.py +++ b/urls.py @@ -1,8 +1,10 @@ from django.urls import path from django.contrib.auth.decorators import permission_required -from django_coreprotect.views import Home, Query +from django_coreprotect.views import GUI, GUIQuery, Activity, ActivityQuery urlpatterns = [ - path('', permission_required('django_coreprotect.gui')(Home.as_view()), name="coreprotect_index"), - path('query/', permission_required('django_coreprotect.gui')(Query.as_view()), name="coreprotect_query"), + path('', permission_required('django_coreprotect.gui')(GUI.as_view()), name="coreprotect_gui"), + path('query/', permission_required('django_coreprotect.gui')(GUIQuery.as_view()), name="coreprotect_gui_query"), + path('activity/', permission_required('django_coreprotect.activity')(Activity.as_view()), name="coreprotect_activity"), + path('activity/query/', permission_required('django_coreprotect.activity')(ActivityQuery.as_view()), name="coreprotect_activity_query"), ] diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..3dab566 --- /dev/null +++ b/utils.py @@ -0,0 +1,9 @@ +def checkbox(value): + return True if value == "on" else False + + +def safe_int(value): + try: + return int(value) + except: + return 0 \ No newline at end of file diff --git a/views.py b/views.py index 29e6bfa..f92f30e 100644 --- a/views.py +++ b/views.py @@ -1,24 +1,26 @@ from django.shortcuts import render from django.views.generic import View from django.http.response import JsonResponse -from django_coreprotect.forms import * +from django_coreprotect.gui import gui_data, gui_results +from django_coreprotect.activity import activity_data, activity_results +from django_coreprotect.utils import safe_int -class Home(View): +class GUI(View): def get(self, request): - form = form_data(request) + form = gui_data(request) return render(request, "coreprotect/coreprotect.html", {"form": form}) def post(self, request): pass -class Query(View): +class GUIQuery(View): def get(self, request): - form = form_data(request) - results = result_data(form) + form = gui_data(request) + results = gui_results(form) if "format" in request.GET and request.GET["format"] == "json": return JsonResponse(results) @@ -29,7 +31,33 @@ class Query(View): if len(results) == safe_int(form.page_size): next_page = True - return render(request, "coreprotect/table.html", {"results": results, "num": len(results), "prev": prev_page, "next": next_page}) + return render(request, "coreprotect/table/coreprotect.html", {"results": results, "num": len(results), "prev": prev_page, "next": next_page}) def post(self, request): pass + + +class Activity(View): + + def get(self, request): + form = activity_data(request) + return render(request, "coreprotect/activity.html", {"form": form}) + + def post(self, request): + pass + + +class ActivityQuery(View): + + def get(self, request): + form = activity_data(request) + results = activity_results(form) + + if "format" in request.GET and request.GET["format"] == "json": + return JsonResponse(results) + + return render(request, "coreprotect/table/activity.html", {"results": results}) + + def post(self, request): + pass +