Finish pagination
Re-work permissions (and test) Move form methods to separate file Signed-off-by: Etzelia <etzelia@hotmail.com>develop
parent
5357e64591
commit
a63f482d96
|
@ -0,0 +1,233 @@
|
||||||
|
from django_coreprotect.models import *
|
||||||
|
|
||||||
|
|
||||||
|
class Form:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.block_break = False
|
||||||
|
self.block_place = False
|
||||||
|
self.chat = False
|
||||||
|
self.chest_use = False
|
||||||
|
self.command = False
|
||||||
|
self.interact = False
|
||||||
|
self.login_logout = False
|
||||||
|
self.sign_place = False
|
||||||
|
self.worlds = []
|
||||||
|
self.ignore_environment = False
|
||||||
|
self.page = ""
|
||||||
|
self.page_size = ""
|
||||||
|
self.start = ""
|
||||||
|
self.players = ""
|
||||||
|
self.x = ""
|
||||||
|
self.y = ""
|
||||||
|
self.z = ""
|
||||||
|
self.radius = ""
|
||||||
|
self.blocks = ""
|
||||||
|
self.date_from = ""
|
||||||
|
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):
|
||||||
|
request_data = request.GET
|
||||||
|
form = Form()
|
||||||
|
worlds = CoWorld.objects.all()
|
||||||
|
|
||||||
|
# Actions
|
||||||
|
form.block_break = checkbox(request_data["block_break"]) if "block_break" in request_data else False
|
||||||
|
form.block_place = checkbox(request_data["block_place"]) if "block_place" in request_data else False
|
||||||
|
form.chat = checkbox(request_data["chat"]) if "chat" in request_data else False
|
||||||
|
form.chest_use = checkbox(request_data["chest_use"]) if "chest_use" in request_data else False
|
||||||
|
form.command = checkbox(request_data["command"]) if "command" in request_data else False
|
||||||
|
form.interact = checkbox(request_data["interact"]) if "interact" in request_data else False
|
||||||
|
form.login_logout = checkbox(request_data["login_logout"]) if "login_logout" in request_data else False
|
||||||
|
form.sign_place = checkbox(request_data["sign_place"]) if "sign_place" in request_data else False
|
||||||
|
|
||||||
|
# Permissions
|
||||||
|
if not request.user.has_perm("django_coreprotect.gui_extra"):
|
||||||
|
form.chat = False
|
||||||
|
form.command = False
|
||||||
|
|
||||||
|
# Worlds
|
||||||
|
request_worlds = request_data.getlist("world")
|
||||||
|
for world in worlds:
|
||||||
|
world_id = "world_{}".format(world.id)
|
||||||
|
w = {
|
||||||
|
"id": str(world.id),
|
||||||
|
"world_id": world_id,
|
||||||
|
"checked": True if str(world.id) in request_worlds else False,
|
||||||
|
"name": world.world
|
||||||
|
}
|
||||||
|
form.worlds.append(w)
|
||||||
|
|
||||||
|
# Options
|
||||||
|
form.ignore_environment = checkbox(request_data["ignore_environment"]) if "ignore_environment" in request_data else False
|
||||||
|
|
||||||
|
# Limit Results
|
||||||
|
form.page = request_data["page"] if "page" in request_data else "0"
|
||||||
|
form.page_size = request_data["page_size"] if "page_size" in request_data else "20"
|
||||||
|
if safe_int(form.page_size) == 0 or safe_int(form.page_size) > 1000:
|
||||||
|
form.page_size = "1000"
|
||||||
|
form.start = (safe_int(form.page) * safe_int(form.page_size))
|
||||||
|
|
||||||
|
# Players
|
||||||
|
form.players = request_data["players"] if "players" in request_data else ""
|
||||||
|
|
||||||
|
# Coordinates
|
||||||
|
form.x = request_data["x"] if "x" in request_data else ""
|
||||||
|
form.y = request_data["y"] if "y" in request_data else ""
|
||||||
|
form.z = request_data["z"] if "z" in request_data else ""
|
||||||
|
form.radius = request_data["radius"] if "radius" in request_data else ""
|
||||||
|
|
||||||
|
# Blocks
|
||||||
|
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 ""
|
||||||
|
|
||||||
|
return form
|
||||||
|
|
||||||
|
|
||||||
|
def result_data(form):
|
||||||
|
queries = []
|
||||||
|
ignore_environment = " AND player NOT LIKE '#%' " if form.ignore_environment else ""
|
||||||
|
|
||||||
|
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))
|
||||||
|
if form.y:
|
||||||
|
coords.append(" AND 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)
|
||||||
|
|
||||||
|
players = []
|
||||||
|
players_clause = ""
|
||||||
|
if form.players:
|
||||||
|
for player in form.players.split(","):
|
||||||
|
players.append(player.strip())
|
||||||
|
players_clause = " AND ({})".format(" OR ".join(["player LIKE '%{}%'".format(p) for p in players]))
|
||||||
|
|
||||||
|
worlds_clause = ""
|
||||||
|
worlds = [world["id"] for world in form.worlds if world["checked"]]
|
||||||
|
if len(worlds):
|
||||||
|
worlds_clause = " AND cw.id IN ({})".format(",".join(worlds))
|
||||||
|
|
||||||
|
time_clause = ""
|
||||||
|
if form.date_from or form.date_to:
|
||||||
|
df, dt = form.date_from, form.date_to
|
||||||
|
if form.date_from and not form.date_to:
|
||||||
|
dt = datetime.now().timestamp()
|
||||||
|
if form.date_to and not form.date_from:
|
||||||
|
df = datetime.now().timestamp()
|
||||||
|
time_clause = " AND unix BETWEEN {} AND {} ".format(df, dt)
|
||||||
|
|
||||||
|
# Block Break, Block Place, and Interact
|
||||||
|
block_actions = []
|
||||||
|
if form.block_break:
|
||||||
|
block_actions.append("0")
|
||||||
|
if form.block_place:
|
||||||
|
block_actions.append("1")
|
||||||
|
if form.interact:
|
||||||
|
block_actions.append("2")
|
||||||
|
if len(block_actions):
|
||||||
|
queries.append('''SELECT
|
||||||
|
0 AS id, "block" AS type, cb.time AS unix, cu.user AS player, cb.action, cmm.material AS data, cb.x, cb.y, cb.z, cw.world
|
||||||
|
FROM co_block cb
|
||||||
|
JOIN co_user cu ON cb.user = cu.id
|
||||||
|
JOIN co_material_map cmm ON cb.type = cmm.id
|
||||||
|
JOIN co_world cw ON cb.wid = cw.id
|
||||||
|
WHERE cb.action IN ({action})
|
||||||
|
{ignore_environment}
|
||||||
|
{players}
|
||||||
|
{coords}
|
||||||
|
{worlds}
|
||||||
|
{time}
|
||||||
|
'''.format(action=",".join(block_actions), ignore_environment=ignore_environment, players=players_clause,
|
||||||
|
coords=coords_clause, worlds=worlds_clause, time=time_clause))
|
||||||
|
|
||||||
|
# Chat
|
||||||
|
if form.chat:
|
||||||
|
queries.append('''SELECT
|
||||||
|
0 AS id, "chat" AS type, cc.time AS unix, cu.user AS player, "" AS action, cc.message AS data, "" AS x, "" AS y, "" AS z, "" AS world
|
||||||
|
FROM co_chat cc
|
||||||
|
JOIN co_user cu ON cc.user = cu.id
|
||||||
|
WHERE 1 = 1
|
||||||
|
{players}
|
||||||
|
{time}
|
||||||
|
'''.format(players=players_clause, time=time_clause))
|
||||||
|
|
||||||
|
# Chest Use
|
||||||
|
if form.chest_use:
|
||||||
|
queries.append('''SELECT
|
||||||
|
0 AS id, "container" AS type, cc.time AS unix, cu.user AS player, cc.action, cc.amount || " " || cmm.material AS data, cc.x, cc.y, cc.z, cw.world
|
||||||
|
FROM co_container cc
|
||||||
|
JOIN co_user cu ON cc.user = cu.id
|
||||||
|
JOIN co_material_map cmm ON cc.type = cmm.id
|
||||||
|
JOIN co_world cw ON cc.wid = cw.id
|
||||||
|
WHERE 1 = 1
|
||||||
|
{worlds}
|
||||||
|
{players}
|
||||||
|
{coords}
|
||||||
|
{time}
|
||||||
|
'''.format(worlds=worlds_clause, players=players_clause, coords=coords_clause, time=time_clause))
|
||||||
|
|
||||||
|
# Commands
|
||||||
|
if form.command:
|
||||||
|
queries.append('''SELECT
|
||||||
|
0 AS id, "command" AS type, cc.time AS unix, cu.user AS player, "" AS action, cc.message AS data, "" AS x, "" AS y, "" AS z, "" AS world
|
||||||
|
FROM co_command cc
|
||||||
|
JOIN co_user cu ON cc.user = cu.id
|
||||||
|
WHERE 1 = 1
|
||||||
|
{players}
|
||||||
|
{coords}
|
||||||
|
{time}
|
||||||
|
'''.format(players=players_clause, coords=coords_clause, time=time_clause))
|
||||||
|
|
||||||
|
# Login/Logout
|
||||||
|
if form.login_logout:
|
||||||
|
queries.append('''SELECT
|
||||||
|
0 AS id, "session" AS type, cs.time AS unix, cu.user AS player, cs.action, "" AS data, cs.x, cs.y, cs.z, cw.world
|
||||||
|
FROM co_session cs
|
||||||
|
JOIN co_user cu ON cs.user = cu.id
|
||||||
|
JOIN co_world cw ON cs.wid = cw.id
|
||||||
|
WHERE 1 = 1
|
||||||
|
{worlds}
|
||||||
|
{players}
|
||||||
|
{coords}
|
||||||
|
{time}
|
||||||
|
'''.format(worlds=worlds_clause, players=players_clause, coords=coords_clause, time=time_clause))
|
||||||
|
|
||||||
|
# Sign Place
|
||||||
|
if form.sign_place:
|
||||||
|
queries.append('''SELECT
|
||||||
|
0 AS id, "sign" AS type, cs.time AS unix, cu.user AS player, "" AS action, cs.line_1 || "|" || cs.line_2 || "|" || cs.line_3 || "|" || cs.line_4 AS data, cs.x, cs.y, cs.z, cw.world
|
||||||
|
FROM co_sign cs
|
||||||
|
JOIN co_user cu ON cs.user = cu.id
|
||||||
|
JOIN co_world cw ON cs.wid = cw.id
|
||||||
|
WHERE 1 = 1
|
||||||
|
{worlds}
|
||||||
|
{players}
|
||||||
|
{coords}
|
||||||
|
{time}
|
||||||
|
'''.format(worlds=worlds_clause, players=players_clause, coords=coords_clause, time=time_clause))
|
||||||
|
|
||||||
|
query = " UNION ".join(queries)
|
||||||
|
if query:
|
||||||
|
query += " ORDER BY unix DESC LIMIT {}, {}".format(form.start, form.page_size)
|
||||||
|
print(query)
|
||||||
|
if query:
|
||||||
|
return CoResult.objects.raw(query)
|
||||||
|
return []
|
|
@ -0,0 +1,322 @@
|
||||||
|
# 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()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
|
@ -8,9 +8,9 @@ class CoreProtectUser(User):
|
||||||
class Meta:
|
class Meta:
|
||||||
proxy = True
|
proxy = True
|
||||||
permissions = (
|
permissions = (
|
||||||
('coreprotect_base', 'Can use CoreProtect GUI'),
|
('gui', 'Can use CoreProtect GUI'),
|
||||||
('coreprotect_extra', 'Can search Chat/Commands'),
|
('gui_extra', 'Can search Chat/Commands'),
|
||||||
('coreprotect_activity', 'Can use CoreProtect Activity Monitor'),
|
('activity', 'Can use CoreProtect Activity Monitor'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
<label for="block_place">Block Place</label>
|
<label for="block_place">Block Place</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<input class="is-checkradio is-block is-info" id="chat" name="chat" type="checkbox" {% if form.chat %}checked{% endif %}>
|
<input class="is-checkradio is-block is-info" id="chat" name="chat" type="checkbox" {% if form.chat %}checked{% endif %} {% if not perms.django_coreprotect.gui_extra %}disabled{% endif %}>
|
||||||
<label for="chat">Chat</label>
|
<label for="chat">Chat</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
<label for="chest_use">Chest Use</label>
|
<label for="chest_use">Chest Use</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<input class="is-checkradio is-block is-info" id="command" name="command" type="checkbox" {% if form.command %}checked{% endif %}>
|
<input class="is-checkradio is-block is-info" id="command" name="command" type="checkbox" {% if form.command %}checked{% endif %} {% if not perms.django_coreprotect.gui_extra %}disabled{% endif %}>
|
||||||
<label for="command">Command</label>
|
<label for="command">Command</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
@ -197,27 +197,39 @@
|
||||||
|
|
||||||
let url = new URL(window.location);
|
let url = new URL(window.location);
|
||||||
let pageParam = url.searchParams.get("page");
|
let pageParam = url.searchParams.get("page");
|
||||||
let page = 1;
|
let page = 0;
|
||||||
if (pageParam !== "") {
|
if (pageParam !== "") {
|
||||||
page = parseInt(pageParam);
|
page = parseInt(pageParam);
|
||||||
if (isNaN(page)) {
|
if (isNaN(page)) {
|
||||||
page = 1;
|
page = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function attachPagination() {
|
function attachPagination() {
|
||||||
document.getElementById("prev").addEventListener("click", function() {
|
let prev = document.getElementById("prev");
|
||||||
document.getElementById("page").value = (page-1).toString();
|
if (prev.getAttribute("disabled") == null) {
|
||||||
document.getElementById("search").click();
|
prev.addEventListener("click", function () {
|
||||||
});
|
document.getElementById("page").value = (--page).toString();
|
||||||
document.getElementById("next").addEventListener("click", function() {
|
search(false);
|
||||||
document.getElementById("page").value = (page+1).toString();
|
|
||||||
document.getElementById("search").click();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("search").addEventListener("click", function() {
|
let next = document.getElementById("next");
|
||||||
|
if (next.getAttribute("disabled") == null) {
|
||||||
|
next.addEventListener("click", function () {
|
||||||
|
document.getElementById("page").value = (++page).toString();
|
||||||
|
search(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function search(resetPage) {
|
||||||
elementHTML("results", 'Querying Database...<br/><progress class="progress is-primary"></progress>');
|
elementHTML("results", 'Querying Database...<br/><progress class="progress is-primary"></progress>');
|
||||||
|
|
||||||
|
if (resetPage) {
|
||||||
|
page = 0;
|
||||||
|
document.getElementById("page").value = "0";
|
||||||
|
}
|
||||||
|
|
||||||
let form = document.getElementById("coreprotect_form");
|
let form = document.getElementById("coreprotect_form");
|
||||||
let formData = new FormData(form);
|
let formData = new FormData(form);
|
||||||
ajax("GET", "{% url "coreprotect_query" %}?" + formURI(formData), function(status, data) {
|
ajax("GET", "{% url "coreprotect_query" %}?" + formURI(formData), function(status, data) {
|
||||||
|
@ -226,6 +238,10 @@
|
||||||
attachPagination();
|
attachPagination();
|
||||||
});
|
});
|
||||||
window.history.pushState("", "", "{% url "coreprotect_index" %}?" + formURI(formData));
|
window.history.pushState("", "", "{% url "coreprotect_index" %}?" + formURI(formData));
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("search").addEventListener("click", function() {
|
||||||
|
search(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById("clear").addEventListener("click", function() {
|
document.getElementById("clear").addEventListener("click", function() {
|
||||||
|
|
4
urls.py
4
urls.py
|
@ -3,6 +3,6 @@ from django.contrib.auth.decorators import permission_required
|
||||||
from django_coreprotect.views import Home, Query
|
from django_coreprotect.views import Home, Query
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', permission_required('coreprotect_base')(Home.as_view()), name="coreprotect_index"),
|
path('', permission_required('django_coreprotect.gui')(Home.as_view()), name="coreprotect_index"),
|
||||||
path('query/', permission_required('coreprotect_base')(Query.as_view()), name="coreprotect_query"),
|
path('query/', permission_required('django_coreprotect.gui')(Query.as_view()), name="coreprotect_query"),
|
||||||
]
|
]
|
||||||
|
|
234
views.py
234
views.py
|
@ -1,13 +1,13 @@
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
from django.http.response import JsonResponse
|
from django.http.response import JsonResponse
|
||||||
from django_coreprotect.models import *
|
from django_coreprotect.forms import *
|
||||||
|
|
||||||
|
|
||||||
class Home(View):
|
class Home(View):
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
form = form_data(request.GET)
|
form = form_data(request)
|
||||||
return render(request, "coreprotect/coreprotect.html", {"form": form})
|
return render(request, "coreprotect/coreprotect.html", {"form": form})
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
|
@ -17,243 +17,19 @@ class Home(View):
|
||||||
class Query(View):
|
class Query(View):
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
form = form_data(request.GET)
|
form = form_data(request)
|
||||||
results = result_data(form)
|
results = result_data(form)
|
||||||
|
|
||||||
if "format" in request.GET and request.GET["format"] == "json":
|
if "format" in request.GET and request.GET["format"] == "json":
|
||||||
return JsonResponse(results)
|
return JsonResponse(results)
|
||||||
|
|
||||||
prev_page, next_page = False, False
|
prev_page, next_page = False, False
|
||||||
if form.page != "1":
|
if safe_int(form.page) > 0:
|
||||||
prev_page = True
|
prev_page = True
|
||||||
if int(form.page) * int(form.page_size) < 1000:
|
if len(results) == safe_int(form.page_size):
|
||||||
next_page = True
|
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.html", {"results": results, "num": len(results), "prev": prev_page, "next": next_page})
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Form:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.block_break = False
|
|
||||||
self.block_place = False
|
|
||||||
self.chat = False
|
|
||||||
self.chest_use = False
|
|
||||||
self.command = False
|
|
||||||
self.interact = False
|
|
||||||
self.login_logout = False
|
|
||||||
self.sign_place = False
|
|
||||||
self.worlds = []
|
|
||||||
self.ignore_environment = False
|
|
||||||
self.page = ""
|
|
||||||
self.page_size = ""
|
|
||||||
self.start = ""
|
|
||||||
self.players = ""
|
|
||||||
self.x = ""
|
|
||||||
self.y = ""
|
|
||||||
self.z = ""
|
|
||||||
self.radius = ""
|
|
||||||
self.blocks = ""
|
|
||||||
self.date_from = ""
|
|
||||||
self.date_to = ""
|
|
||||||
|
|
||||||
|
|
||||||
def form_data(request_data):
|
|
||||||
form = Form()
|
|
||||||
worlds = CoWorld.objects.all()
|
|
||||||
|
|
||||||
# Actions
|
|
||||||
form.block_break = checkbox(request_data["block_break"]) if "block_break" in request_data else False
|
|
||||||
form.block_place = checkbox(request_data["block_place"]) if "block_place" in request_data else False
|
|
||||||
form.chat = checkbox(request_data["chat"]) if "chat" in request_data else False
|
|
||||||
form.chest_use = checkbox(request_data["chest_use"]) if "chest_use" in request_data else False
|
|
||||||
form.command = checkbox(request_data["command"]) if "command" in request_data else False
|
|
||||||
form.interact = checkbox(request_data["interact"]) if "interact" in request_data else False
|
|
||||||
form.login_logout = checkbox(request_data["login_logout"]) if "login_logout" in request_data else False
|
|
||||||
form.sign_place = checkbox(request_data["sign_place"]) if "sign_place" in request_data else False
|
|
||||||
|
|
||||||
# Worlds
|
|
||||||
request_worlds = request_data.getlist("world")
|
|
||||||
for world in worlds:
|
|
||||||
world_id = "world_{}".format(world.id)
|
|
||||||
w = {
|
|
||||||
"id": str(world.id),
|
|
||||||
"world_id": world_id,
|
|
||||||
"checked": True if str(world.id) in request_worlds else False,
|
|
||||||
"name": world.world
|
|
||||||
}
|
|
||||||
form.worlds.append(w)
|
|
||||||
|
|
||||||
# Options
|
|
||||||
form.ignore_environment = checkbox(request_data["ignore_environment"]) if "ignore_environment" in request_data else False
|
|
||||||
|
|
||||||
# Limit Results
|
|
||||||
form.page = request_data["page"] if "page" in request_data else "1"
|
|
||||||
form.page_size = request_data["page_size"] if "page_size" in request_data else "20"
|
|
||||||
if int(form.page_size) > 1000:
|
|
||||||
form.page_size = "1000"
|
|
||||||
start = (int(form.page) * int(form.page_size))
|
|
||||||
form.start = str(start) if start <= 1000 - int(form.page_size) else str(1000 - int(form.page_size))
|
|
||||||
|
|
||||||
|
|
||||||
# Players
|
|
||||||
form.players = request_data["players"] if "players" in request_data else ""
|
|
||||||
|
|
||||||
# Coordinates
|
|
||||||
form.x = request_data["x"] if "x" in request_data else ""
|
|
||||||
form.y = request_data["y"] if "y" in request_data else ""
|
|
||||||
form.z = request_data["z"] if "z" in request_data else ""
|
|
||||||
form.radius = request_data["radius"] if "radius" in request_data else ""
|
|
||||||
|
|
||||||
# Blocks
|
|
||||||
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 ""
|
|
||||||
|
|
||||||
|
|
||||||
return form
|
|
||||||
|
|
||||||
|
|
||||||
def checkbox(value):
|
|
||||||
return True if value == "on" else False
|
|
||||||
|
|
||||||
|
|
||||||
def result_data(form):
|
|
||||||
queries = []
|
|
||||||
ignore_environment = " AND player NOT LIKE '#%' " if form.ignore_environment else ""
|
|
||||||
|
|
||||||
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))
|
|
||||||
if form.y:
|
|
||||||
coords.append(" AND 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)
|
|
||||||
|
|
||||||
players = []
|
|
||||||
players_clause = ""
|
|
||||||
if form.players:
|
|
||||||
for player in form.players.split(","):
|
|
||||||
players.append(player.strip())
|
|
||||||
players_clause = " AND ({})".format(" OR ".join(["player LIKE '%{}%'".format(p) for p in players]))
|
|
||||||
|
|
||||||
worlds_clause = ""
|
|
||||||
worlds = [world["id"] for world in form.worlds if world["checked"]]
|
|
||||||
if len(worlds):
|
|
||||||
worlds_clause = " AND cw.id IN ({})".format(",".join(worlds))
|
|
||||||
|
|
||||||
time_clause = ""
|
|
||||||
if form.date_from or form.date_to:
|
|
||||||
df, dt = None, None
|
|
||||||
if form.date_from and not form.date_to:
|
|
||||||
df = form.date_from
|
|
||||||
dt = datetime.now().timestamp()
|
|
||||||
if form.date_to and not form.date_from:
|
|
||||||
df = datetime.now().timestamp()
|
|
||||||
dt = form.date_to
|
|
||||||
time_clause = " AND unix BETWEEN {} AND {} ".format(df, dt)
|
|
||||||
|
|
||||||
# Block Break, Block Place, and Interact
|
|
||||||
block_actions = []
|
|
||||||
if form.block_break:
|
|
||||||
block_actions.append("0")
|
|
||||||
if form.block_place:
|
|
||||||
block_actions.append("1")
|
|
||||||
if form.interact:
|
|
||||||
block_actions.append("2")
|
|
||||||
if len(block_actions):
|
|
||||||
queries.append('''SELECT
|
|
||||||
0 AS id, "block" AS type, cb.time AS unix, cu.user AS player, cb.action, cmm.material AS data, cb.x, cb.y, cb.z, cw.world
|
|
||||||
FROM co_block cb
|
|
||||||
JOIN co_user cu ON cb.user = cu.id
|
|
||||||
JOIN co_material_map cmm ON cb.type = cmm.id
|
|
||||||
JOIN co_world cw ON cb.wid = cw.id
|
|
||||||
WHERE cb.action IN ({action})
|
|
||||||
{ignore_environment}
|
|
||||||
{players}
|
|
||||||
{coords}
|
|
||||||
{worlds}
|
|
||||||
{time}
|
|
||||||
'''.format(action=",".join(block_actions), ignore_environment=ignore_environment, players=players_clause,
|
|
||||||
coords=coords_clause, worlds=worlds_clause, time=time_clause))
|
|
||||||
|
|
||||||
# Chat
|
|
||||||
if form.chat:
|
|
||||||
queries.append('''SELECT
|
|
||||||
0 AS id, "chat" AS type, cc.time AS unix, cu.user AS player, "" AS action, cc.message AS data, "" AS x, "" AS y, "" AS z, "" AS world
|
|
||||||
FROM co_chat cc
|
|
||||||
JOIN co_user cu ON cc.user = cu.id
|
|
||||||
WHERE 1 = 1
|
|
||||||
{players}
|
|
||||||
{time}
|
|
||||||
'''.format(players=players_clause, time=time_clause))
|
|
||||||
|
|
||||||
# Chest Use
|
|
||||||
if form.chest_use:
|
|
||||||
queries.append('''SELECT
|
|
||||||
0 AS id, "container" AS type, cc.time AS unix, cu.user AS player, cc.action, cc.amount || " " || cmm.material AS data, cc.x, cc.y, cc.z, cw.world
|
|
||||||
FROM co_container cc
|
|
||||||
JOIN co_user cu ON cc.user = cu.id
|
|
||||||
JOIN co_material_map cmm ON cc.type = cmm.id
|
|
||||||
JOIN co_world cw ON cc.wid = cw.id
|
|
||||||
WHERE 1 = 1
|
|
||||||
{worlds}
|
|
||||||
{players}
|
|
||||||
{coords}
|
|
||||||
{time}
|
|
||||||
'''.format(worlds=worlds_clause, players=players_clause, coords=coords_clause, time=time_clause))
|
|
||||||
|
|
||||||
# Commands
|
|
||||||
if form.command:
|
|
||||||
queries.append('''SELECT
|
|
||||||
0 AS id, "command" AS type, cc.time AS unix, cu.user AS player, "" AS action, cc.message AS data, "" AS x, "" AS y, "" AS z, "" AS world
|
|
||||||
FROM co_command cc
|
|
||||||
JOIN co_user cu ON cc.user = cu.id
|
|
||||||
WHERE 1 = 1
|
|
||||||
{players}
|
|
||||||
{coords}
|
|
||||||
{time}
|
|
||||||
'''.format(players=players_clause, coords=coords_clause, time=time_clause))
|
|
||||||
|
|
||||||
# Login/Logout
|
|
||||||
if form.login_logout:
|
|
||||||
queries.append('''SELECT
|
|
||||||
0 AS id, "session" AS type, cs.time AS unix, cu.user AS player, cs.action, "" AS data, cs.x, cs.y, cs.z, cw.world
|
|
||||||
FROM co_session cs
|
|
||||||
JOIN co_user cu ON cs.user = cu.id
|
|
||||||
JOIN co_world cw ON cs.wid = cw.id
|
|
||||||
WHERE 1 = 1
|
|
||||||
{worlds}
|
|
||||||
{players}
|
|
||||||
{coords}
|
|
||||||
{time}
|
|
||||||
'''.format(worlds=worlds_clause, players=players_clause, coords=coords_clause, time=time_clause))
|
|
||||||
|
|
||||||
# Sign Place
|
|
||||||
if form.sign_place:
|
|
||||||
queries.append('''SELECT
|
|
||||||
0 AS id, "sign" AS type, cs.time AS unix, cu.user AS player, "" AS action, cs.line_1 || "|" || cs.line_2 || "|" || cs.line_3 || "|" || cs.line_4 AS data, cs.x, cs.y, cs.z, cw.world
|
|
||||||
FROM co_sign cs
|
|
||||||
JOIN co_user cu ON cs.user = cu.id
|
|
||||||
JOIN co_world cw ON cs.wid = cw.id
|
|
||||||
WHERE 1 = 1
|
|
||||||
{worlds}
|
|
||||||
{players}
|
|
||||||
{coords}
|
|
||||||
{time}
|
|
||||||
'''.format(worlds=worlds_clause, players=players_clause, coords=coords_clause, time=time_clause))
|
|
||||||
|
|
||||||
query = " UNION ".join(queries)
|
|
||||||
if query:
|
|
||||||
query += " ORDER BY unix LIMIT {}, {}".format(form.start, form.page_size)
|
|
||||||
print(query)
|
|
||||||
if query:
|
|
||||||
return CoResult.objects.raw(query)
|
|
||||||
return []
|
|
||||||
|
|
Loading…
Reference in New Issue