diff --git a/admin.py b/admin.py index 1c6e392..cbda5b9 100644 --- a/admin.py +++ b/admin.py @@ -1,26 +1,54 @@ -from django.contrib import admin +import ast + +from django import forms +from django.contrib import admin +from django.contrib.admin import widgets as admin_widgets + +from django_coreprotect.models import CoWorld, Preset +from django_coreprotect.utils import time_to_form, form_to_time + + +class PresetAdminForm(forms.ModelForm): + def __init__(self, *args, **kwargs): + super(PresetAdminForm, self).__init__(*args, **kwargs) + + worlds = tuple([(world.id, world.world) for world in CoWorld.objects.all()]) + self.fields['worlds'].widget = forms.SelectMultiple(choices=worlds) + self.fields['date_from'].widget = admin_widgets.AdminSplitDateTime() + self.fields['date_to'].widget = admin_widgets.AdminSplitDateTime() + + if self.instance: + if "worlds" in self.initial and self.initial["worlds"]: + self.initial["worlds"] = tuple(self.initial["worlds"]) + if "date_from" in self.initial and self.initial["date_from"]: + self.initial["date_from"] = time_to_form(self.initial["date_from"]) + if "date_to" in self.initial and self.initial["date_to"]: + self.initial["date_to"] = time_to_form(self.initial["date_to"]) + + def clean(self): + cleaned = super(PresetAdminForm, self).clean() + worlds = cleaned.get("worlds", "") + if worlds: + worlds = ast.literal_eval(worlds) + cleaned.update({"worlds": ",".join(worlds)}) + date_from = cleaned.get("date_from", "") + if date_from: + cleaned.update({"date_from": form_to_time(date_from)}) + date_to = cleaned.get("date_to", "") + if date_to: + cleaned.update({"date_to": form_to_time(date_to)}) + return cleaned + + class Meta: + model = Preset + fields = "__all__" + + +class PresetAdmin(admin.ModelAdmin): + form = PresetAdminForm -from django_coreprotect.models import CoArtMap, CoBlock, CoBlockdataMap, CoChat, CoCommand, CoContainer, CoDatabaseLock, \ - CoEntity, CoEntityMap, CoMaterialMap, CoSession, CoSign, CoSkull, CoUser, CoUsernameLog, CoVersion, CoWorld try: - pass - # admin.site.register(CoArtMap) - # admin.site.register(CoBlock) - # admin.site.register(CoBlockdataMap) - # admin.site.register(CoChat) - # admin.site.register(CoCommand) - # admin.site.register(CoContainer) - # admin.site.register(CoDatabaseLock) - # admin.site.register(CoEntity) - # admin.site.register(CoEntityMap) - # admin.site.register(CoMaterialMap) - # admin.site.register(CoSession) - # admin.site.register(CoSign) - # admin.site.register(CoSkull) - # admin.site.register(CoUser) - # admin.site.register(CoUsernameLog) - # admin.site.register(CoVersion) - # admin.site.register(CoWorld) + admin.site.register(Preset, PresetAdmin) except admin.sites.AlreadyRegistered: pass diff --git a/gui.py b/gui.py index 1ed19d6..b902502 100644 --- a/gui.py +++ b/gui.py @@ -1,7 +1,7 @@ -from django_coreprotect.models import CoWorld, GUIResult -from django_coreprotect.utils import safe_int, checkbox from datetime import datetime -from django.db import connection + +from django_coreprotect.models import CoWorld, GUIResult +from django_coreprotect.utils import safe_int, checkbox, time_to_form class GUIForm: @@ -87,8 +87,12 @@ def gui_data(request): form.blocks = request_data["blocks"] if "blocks" 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 "" + form.date_from = time_to_form(request_data["date_from"]) if "date_from" in request_data else "" + if form.date_from: + form.date_from = form.date_from.timestamp() + form.date_to = time_to_form(request_data["date_to"]) if "date_to" in request_data else "" + if form.date_to: + form.date_to = form.date_to.timestamp() return form @@ -101,12 +105,12 @@ def gui_results(form): coords = [] radius = form.radius if form.radius else "0" if form.x: - coords.append(" AND x BETWEEN {0} - {1} AND {0} + {1}".format(form.x, radius)) + coords.append(" x BETWEEN {0} - {1} AND {0} + {1}".format(form.x, radius)) if form.y: - coords.append(" AND y BETWEEN {0} - {1} AND {0} + {1}".format(form.y, radius)) + coords.append(" y BETWEEN {0} - {1} AND {0} + {1}".format(form.y, radius)) if form.z: - coords.append(" AND z BETWEEN {0} - {1} AND {0} + {1}".format(form.z, radius)) - coords_clause = " AND ".join(coords) + coords.append(" z BETWEEN {0} - {1} AND {0} + {1}".format(form.z, radius)) + coords_clause = " AND ({})".format(" AND ".join(coords)) players = [] players_clause = "" @@ -117,10 +121,14 @@ def gui_results(form): blocks = [] blocks_clause = "" + chat_clause = "" + command_clause = "" if form.blocks: for block in form.blocks.split(","): blocks.append(block.strip()) blocks_clause = " AND ({})".format(" OR ".join(["cmm.material LIKE 'minecraft:{}%%'".format(b) for b in blocks])) + chat_clause = " AND ({})".format(" OR ".join(["cc.message LIKE '%%{}%%'".format(b) for b in blocks])) + command_clause = " AND ({})".format(" OR ".join(["cc.message LIKE '%%{}%%'".format(b) for b in blocks])) worlds_clause = "" worlds = [world["id"] for world in form.worlds if world["checked"]] @@ -134,7 +142,7 @@ def gui_results(form): dt = datetime.now().timestamp() if form.date_to and not form.date_from: df = datetime.now().timestamp() - time_clause = " HAVING unix BETWEEN {} AND {} ".format(df, dt) + time_clause = " GROUP BY unix HAVING unix BETWEEN {} AND {} ".format(df, dt) # Block Break, Block Place, and Interact block_actions = [] @@ -169,8 +177,9 @@ def gui_results(form): JOIN co_user cu ON cc.user = cu.rowid WHERE 1 = 1 {players} + {chat} {time} - '''.format(players=players_clause, time=time_clause)) + '''.format(players=players_clause, chat=chat_clause, time=time_clause)) # Chest Use if form.chest_use: @@ -199,9 +208,10 @@ def gui_results(form): JOIN co_user cu ON cc.user = cu.rowid WHERE 1 = 1 {players} + {command} {coords} {time} - '''.format(players=players_clause, coords=coords_clause, time=time_clause)) + '''.format(players=players_clause, command=command_clause, coords=coords_clause, time=time_clause)) # Login/Logout if form.login_logout: diff --git a/migrations/0002_preset.py b/migrations/0002_preset.py new file mode 100644 index 0000000..fe15e02 --- /dev/null +++ b/migrations/0002_preset.py @@ -0,0 +1,40 @@ +# Generated by Django 2.2.3 on 2019-10-01 04:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('django_coreprotect', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Preset', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50)), + ('block_break', models.BooleanField(default=False)), + ('block_place', models.BooleanField(default=False)), + ('chat', models.BooleanField(default=False)), + ('chest_use', models.BooleanField(default=False)), + ('command', models.BooleanField(default=False)), + ('interact', models.BooleanField(default=False)), + ('login_logout', models.BooleanField(default=False)), + ('sign_place', models.BooleanField(default=False)), + ('worlds', models.CharField(blank=True, default='', max_length=20)), + ('ignore_environment', models.BooleanField(default=False)), + ('oldest_first', models.BooleanField(default=False)), + ('players', models.CharField(blank=True, max_length=50)), + ('x', models.CharField(blank=True, default='', max_length=10)), + ('y', models.CharField(blank=True, default='', max_length=10)), + ('z', models.CharField(blank=True, default='', max_length=10)), + ('radius', models.CharField(blank=True, default='', max_length=10)), + ('blocks', models.CharField(blank=True, default='', max_length=50)), + ('date_from', models.CharField(blank=True, default='', max_length=50)), + ('date_to', models.CharField(blank=True, default='', max_length=50)), + ('enabled', models.BooleanField(default=True)), + ], + ), + ] diff --git a/models.py b/models.py index 4a1885f..15bede9 100644 --- a/models.py +++ b/models.py @@ -1,6 +1,9 @@ -from django.db import models -from django.contrib.auth.models import User from datetime import datetime + +from django.contrib.auth.models import User +from django.db import models +from django.shortcuts import reverse + from django_coreprotect.utils import safe_int @@ -291,6 +294,78 @@ class CoWorld(models.Model): return self.world +class Preset(models.Model): + name = models.CharField(max_length=50) + block_break = models.BooleanField(default=False) + block_place = models.BooleanField(default=False) + chat = models.BooleanField(default=False) + chest_use = models.BooleanField(default=False) + command = models.BooleanField(default=False) + interact = models.BooleanField(default=False) + login_logout = models.BooleanField(default=False) + sign_place = models.BooleanField(default=False) + worlds = models.CharField(max_length=20, default="", blank=True) + ignore_environment = models.BooleanField(default=False) + oldest_first = models.BooleanField(default=False) + players = models.CharField(max_length=50, blank=True) + x = models.CharField(max_length=10, default="", blank=True) + y = models.CharField(max_length=10, default="", blank=True) + z = models.CharField(max_length=10, default="", blank=True) + radius = models.CharField(max_length=10, default="", blank=True) + blocks = models.CharField(max_length=50, default="", blank=True) + date_from = models.CharField(max_length=50, default="", blank=True) + date_to = models.CharField(max_length=50, default="", blank=True) + enabled = models.BooleanField(default=True) + + @property + def link(self): + url = reverse("coreprotect_gui") + "?" + params = [] + if self.block_break: + params.append("block_break=on") + if self.block_place: + params.append("block_place=on") + if self.chat: + params.append("chat=on") + if self.chest_use: + params.append("chest_use=on") + if self.command: + params.append("command=on") + if self.interact: + params.append("interact=on") + if self.login_logout: + params.append("login_logout=on") + if self.sign_place: + params.append("sign_place=on") + if self.worlds: + for world in self.worlds.split(","): + params.append("world=" + world) + if self.ignore_environment: + params.append("ignore_environment=on") + if self.oldest_first: + params.append("oldest_first=on") + if self.players: + params.append("players=" + self.players) + if self.x: + params.append("x=" + self.x) + if self.y: + params.append("y=" + self.y) + if self.z: + params.append("z=" + self.z) + if self.radius: + params.append("radius=" + self.radius) + if self.blocks: + params.append("blocks=" + self.blocks) + if self.date_from: + params.append("date_from=" + self.date_from) + if self.date_to: + params.append("date_to=" + self.date_to) + return url + "&".join(params) + + def __str__(self): + return self.name + + class GUIResult(models.Model): type = models.TextField() unix = models.TextField() diff --git a/templates/coreprotect/coreprotect.html b/templates/coreprotect/coreprotect.html index b8b8dd6..f40b546 100644 --- a/templates/coreprotect/coreprotect.html +++ b/templates/coreprotect/coreprotect.html @@ -75,26 +75,25 @@ -
+ {% if presets %} +
-

- Page Size -

-
+

+ Presets +

+

- + + {% for preset in presets %} + + {% endfor %}

-
- +
+ {% endif %} @@ -155,6 +154,27 @@
+

+ Page Size +

+
+

+ + + +

+
+ + +
+

@@ -278,5 +298,13 @@ document.getElementById("export").addEventListener("click", function() { exportTableToCSV("coreprotect.csv", "results"); }); + + {% if presets %} + document.getElementById("preset").addEventListener("change", function() { + if (this.value !== "") { + location.href = this.value; + } + }); + {% endif %} {% endblock %} \ No newline at end of file diff --git a/utils.py b/utils.py index 3dab566..c8ddeae 100644 --- a/utils.py +++ b/utils.py @@ -1,3 +1,7 @@ +import ast +from datetime import datetime, timedelta + + def checkbox(value): return True if value == "on" else False @@ -6,4 +10,27 @@ def safe_int(value): try: return int(value) except: - return 0 \ No newline at end of file + return 0 + + +def time_to_form(date_time): + if date_time == "~T": + return datetime.today() + elif date_time == "~N": + return datetime.now() + elif date_time == "~Y": + return datetime.today() - timedelta(days=1) + elif date_time == "": + return "" + else: + return datetime.utcfromtimestamp(float(date_time)) + + +def form_to_time(date_time): + dt = ast.literal_eval(date_time) + if dt[0] in ["~T", "~N", "~Y"]: + return dt[0] + else: + dt[0] = dt[0] if dt[0] else datetime.now().strftime("%Y-%m-%d") + dt[1] = dt[1] if dt[1] else "00:00:00" + return datetime.strptime(" ".join(dt), "%Y-%m-%d %H:%M:%S").timestamp() diff --git a/views.py b/views.py index f92f30e..1596230 100644 --- a/views.py +++ b/views.py @@ -1,8 +1,10 @@ +from django.http.response import JsonResponse from django.shortcuts import render from django.views.generic import View -from django.http.response import JsonResponse -from django_coreprotect.gui import gui_data, gui_results + from django_coreprotect.activity import activity_data, activity_results +from django_coreprotect.gui import gui_data, gui_results +from django_coreprotect.models import Preset from django_coreprotect.utils import safe_int @@ -10,7 +12,7 @@ class GUI(View): def get(self, request): form = gui_data(request) - return render(request, "coreprotect/coreprotect.html", {"form": form}) + return render(request, "coreprotect/coreprotect.html", {"form": form, "presets": Preset.objects.filter(enabled=True)}) def post(self, request): pass