concat (#1)
Fix concatenation for MySQL Signed-off-by: Etzelia <etzelia@hotmail.com> Add block clause (#1) Change UNION to UNION ALL Change action to compare with strings Improve LIKE query Signed-off-by: Etzelia <etzelia@hotmail.com> Try to prevent corrupt activity Signed-off-by: Etzelia <etzelia@hotmail.com> Update user in activity query Signed-off-by: Etzelia <etzelia@hotmail.com> Convert to HAVING Signed-off-by: Etzelia <etzelia@hotmail.com> Escape percent signs in raw SQL Signed-off-by: Etzelia <etzelia@hotmail.com> Convert id to rowid Signed-off-by: Etzelia <etzelia@hotmail.com> New migration Signed-off-by: Etzelia <etzelia@hotmail.com> Add activity pages Signed-off-by: Etzelia <etzelia@hotmail.com> Finish pagination Re-work permissions (and test) Move form methods to separate file Signed-off-by: Etzelia <etzelia@hotmail.com> Start pagination SQL is finished Signed-off-by: Etzelia <etzelia@hotmail.com> Half SQL completed Signed-off-by: Etzelia <etzelia@hotmail.com> Move to Bulma Start UI work Signed-off-by: Etzelia <etzelia@hotmail.com> More work Signed-off-by: Etzelia <etzelia@hotmail.com> Add migration Signed-off-by: Etzelia <etzelia@hotmail.com> More work Signed-off-by: Etzelia <etzelia@hotmail.com> Initial local commit Signed-off-by: Etzelia <etzelia@hotmail.com> Reviewed-on: https://git.birbmc.com/BirbMC/django_coreprotect/pulls/1 Co-Authored-By: Etzelia <etzelia@hotmail.com> Co-Committed-By: Etzelia <etzelia@hotmail.com>pull/3/head
parent
1de266df7e
commit
fbd29e2c70
|
@ -0,0 +1,5 @@
|
||||||
|
# PyCharm
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# Compiled
|
||||||
|
*.pyc
|
|
@ -0,0 +1,75 @@
|
||||||
|
from django_coreprotect.models import SessionResult, ActivityResult
|
||||||
|
from django_coreprotect.utils import safe_int
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
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_clause = ""
|
||||||
|
if form.players:
|
||||||
|
players = []
|
||||||
|
for player in form.players.split(","):
|
||||||
|
players.append(player.strip())
|
||||||
|
players_clause = " WHERE ({}) ".format(" OR ".join(["cu.user LIKE '%%{}%%'".format(p) for p in players]))
|
||||||
|
|
||||||
|
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 = " HAVING unix BETWEEN {} AND {} ".format(df, dt)
|
||||||
|
|
||||||
|
if players_clause or time_clause:
|
||||||
|
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.rowid
|
||||||
|
{players}
|
||||||
|
{time}
|
||||||
|
'''.format(players=players_clause, time=time_clause)
|
||||||
|
|
||||||
|
if query:
|
||||||
|
print(query)
|
||||||
|
sessions = SessionResult.objects.raw(query)
|
||||||
|
activity = {}
|
||||||
|
last_session = {}
|
||||||
|
for session in sessions:
|
||||||
|
time = -safe_int(session.unix) if session.action == 1 else safe_int(session.unix)
|
||||||
|
if session.player in activity:
|
||||||
|
if last_session[session.player] == session.action:
|
||||||
|
continue
|
||||||
|
activity[session.player] += time
|
||||||
|
last_session[session.player] = session.action
|
||||||
|
else:
|
||||||
|
activity[session.player] = time
|
||||||
|
last_session[session.player] = session.action
|
||||||
|
results = []
|
||||||
|
for player, time in activity.items():
|
||||||
|
results.append(ActivityResult(player, time))
|
||||||
|
return results
|
||||||
|
return []
|
|
@ -0,0 +1,26 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
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)
|
||||||
|
except admin.sites.AlreadyRegistered:
|
||||||
|
pass
|
|
@ -0,0 +1,5 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class DjangoCoreprotectConfig(AppConfig):
|
||||||
|
name = 'django_coreprotect'
|
|
@ -0,0 +1,239 @@
|
||||||
|
from django_coreprotect.models import CoWorld, GUIResult
|
||||||
|
from django_coreprotect.utils import safe_int, checkbox
|
||||||
|
from datetime import datetime
|
||||||
|
from django.db import connection
|
||||||
|
|
||||||
|
|
||||||
|
class GUIForm:
|
||||||
|
|
||||||
|
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.oldest_first = 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 gui_data(request):
|
||||||
|
request_data = request.GET
|
||||||
|
form = GUIForm()
|
||||||
|
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
|
||||||
|
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"
|
||||||
|
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 gui_results(form):
|
||||||
|
queries = []
|
||||||
|
ignore_environment = " AND cu.user 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"
|
||||||
|
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(["cu.user LIKE '{}%%'".format(p) for p in players]))
|
||||||
|
|
||||||
|
blocks = []
|
||||||
|
blocks_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]))
|
||||||
|
|
||||||
|
worlds_clause = ""
|
||||||
|
worlds = [world["id"] for world in form.worlds if world["checked"]]
|
||||||
|
if len(worlds):
|
||||||
|
worlds_clause = " AND cw.rowid 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 = " HAVING 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.rowid
|
||||||
|
JOIN co_material_map cmm ON cb.type = cmm.rowid
|
||||||
|
JOIN co_world cw ON cb.wid = cw.rowid
|
||||||
|
WHERE cb.action IN ({action})
|
||||||
|
{ignore_environment}
|
||||||
|
{players}
|
||||||
|
{coords}
|
||||||
|
{blocks}
|
||||||
|
{worlds}
|
||||||
|
{time}
|
||||||
|
'''.format(action=",".join(block_actions), ignore_environment=ignore_environment, players=players_clause,
|
||||||
|
coords=coords_clause, blocks=blocks_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.rowid
|
||||||
|
WHERE 1 = 1
|
||||||
|
{players}
|
||||||
|
{time}
|
||||||
|
'''.format(players=players_clause, time=time_clause))
|
||||||
|
|
||||||
|
# Chest Use
|
||||||
|
if form.chest_use:
|
||||||
|
concat = 'CONCAT(cc.amount, " ", cmm.material)'
|
||||||
|
if connection.vendor == "sqlite":
|
||||||
|
concat = 'cc.amount || " " || cmm.material'
|
||||||
|
queries.append('''SELECT
|
||||||
|
0 AS id, "container" AS type, cc.time AS unix, cu.user AS player, cc.action, {concat} AS data, cc.x, cc.y, cc.z, cw.world
|
||||||
|
FROM co_container cc
|
||||||
|
JOIN co_user cu ON cc.user = cu.rowid
|
||||||
|
JOIN co_material_map cmm ON cc.type = cmm.rowid
|
||||||
|
JOIN co_world cw ON cc.wid = cw.rowid
|
||||||
|
WHERE 1 = 1
|
||||||
|
{worlds}
|
||||||
|
{players}
|
||||||
|
{coords}
|
||||||
|
{blocks}
|
||||||
|
{time}
|
||||||
|
'''.format(concat=concat, worlds=worlds_clause, players=players_clause, coords=coords_clause, blocks=blocks_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.rowid
|
||||||
|
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.rowid
|
||||||
|
JOIN co_world cw ON cs.wid = cw.rowid
|
||||||
|
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.rowid
|
||||||
|
JOIN co_world cw ON cs.wid = cw.rowid
|
||||||
|
WHERE 1 = 1
|
||||||
|
{worlds}
|
||||||
|
{players}
|
||||||
|
{coords}
|
||||||
|
{time}
|
||||||
|
'''.format(worlds=worlds_clause, players=players_clause, coords=coords_clause, time=time_clause))
|
||||||
|
|
||||||
|
query = " UNION ALL ".join(queries)
|
||||||
|
if query:
|
||||||
|
query += " ORDER BY unix {} LIMIT {}, {}".format(oldest_first, form.start, form.page_size)
|
||||||
|
if query:
|
||||||
|
return GUIResult.objects.raw(query)
|
||||||
|
return []
|
|
@ -0,0 +1,336 @@
|
||||||
|
# Generated by Django 2.2.3 on 2019-08-16 16:28
|
||||||
|
|
||||||
|
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='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='GUIResult',
|
||||||
|
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': 'GUI Result',
|
||||||
|
'verbose_name_plural': 'GUI Results',
|
||||||
|
'managed': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SessionResult',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('unix', models.TextField()),
|
||||||
|
('player', models.TextField()),
|
||||||
|
('action', models.TextField()),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Session Result',
|
||||||
|
'verbose_name_plural': 'Session Results',
|
||||||
|
'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()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,373 @@
|
||||||
|
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):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
permissions = (
|
||||||
|
('gui', 'Can use CoreProtect GUI'),
|
||||||
|
('gui_extra', 'Can search Chat/Commands'),
|
||||||
|
('activity', 'Can use CoreProtect Activity Monitor'),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CoArtMap(models.Model):
|
||||||
|
id = models.IntegerField(primary_key=True)
|
||||||
|
art = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_art_map'
|
||||||
|
verbose_name = 'Art Map'
|
||||||
|
verbose_name_plural = 'Art Maps'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.art
|
||||||
|
|
||||||
|
|
||||||
|
class CoBlock(models.Model):
|
||||||
|
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)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_block'
|
||||||
|
verbose_name = 'Block'
|
||||||
|
verbose_name_plural = 'Blocks'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.type
|
||||||
|
|
||||||
|
|
||||||
|
class CoBlockdataMap(models.Model):
|
||||||
|
id = models.IntegerField(primary_key=True)
|
||||||
|
data = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_blockdata_map'
|
||||||
|
verbose_name = 'BlockData Map'
|
||||||
|
verbose_name_plural = 'BlockData Maps'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.data
|
||||||
|
|
||||||
|
|
||||||
|
class CoChat(models.Model):
|
||||||
|
time = models.IntegerField(blank=True, null=True)
|
||||||
|
user = models.IntegerField(blank=True, null=True)
|
||||||
|
message = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_chat'
|
||||||
|
verbose_name = 'Chat Message'
|
||||||
|
verbose_name_plural = 'Chat Messages'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.message
|
||||||
|
|
||||||
|
|
||||||
|
class CoCommand(models.Model):
|
||||||
|
time = models.IntegerField(blank=True, null=True)
|
||||||
|
user = models.IntegerField(blank=True, null=True)
|
||||||
|
message = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_command'
|
||||||
|
verbose_name = 'Command'
|
||||||
|
verbose_name_plural = 'Commands'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.message
|
||||||
|
|
||||||
|
|
||||||
|
class CoContainer(models.Model):
|
||||||
|
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)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_container'
|
||||||
|
verbose_name = 'Container Transaction'
|
||||||
|
verbose_name_plural = 'Container Transactions'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.user
|
||||||
|
|
||||||
|
|
||||||
|
class CoDatabaseLock(models.Model):
|
||||||
|
status = models.IntegerField(blank=True, null=True)
|
||||||
|
time = models.IntegerField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_database_lock'
|
||||||
|
verbose_name = 'Database Lock'
|
||||||
|
verbose_name_plural = 'Database Locks'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.status
|
||||||
|
|
||||||
|
|
||||||
|
class CoEntity(models.Model):
|
||||||
|
time = models.IntegerField(blank=True, null=True)
|
||||||
|
data = models.BinaryField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_entity'
|
||||||
|
verbose_name = 'Entity'
|
||||||
|
verbose_name_plural = 'Entities'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.time
|
||||||
|
|
||||||
|
|
||||||
|
class CoEntityMap(models.Model):
|
||||||
|
id = models.IntegerField(primary_key=True)
|
||||||
|
entity = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_entity_map'
|
||||||
|
verbose_name = 'Entity Mapping'
|
||||||
|
verbose_name_plural = 'Entity Mappings'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.entity
|
||||||
|
|
||||||
|
|
||||||
|
class CoMaterialMap(models.Model):
|
||||||
|
id = models.IntegerField(primary_key=True)
|
||||||
|
material = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_material_map'
|
||||||
|
verbose_name = 'Material Mapping'
|
||||||
|
verbose_name_plural = 'Material Mappings'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.material
|
||||||
|
|
||||||
|
|
||||||
|
class CoSession(models.Model):
|
||||||
|
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)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_session'
|
||||||
|
verbose_name = 'Session'
|
||||||
|
verbose_name_plural = 'Sessions'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.user
|
||||||
|
|
||||||
|
|
||||||
|
class CoSign(models.Model):
|
||||||
|
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)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_sign'
|
||||||
|
verbose_name = 'Sign'
|
||||||
|
verbose_name_plural = 'Signs'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "{} | {} | {} | {}".format(self.line_1, self.line_2, self.line_3, self.line_4)
|
||||||
|
|
||||||
|
|
||||||
|
class CoSkull(models.Model):
|
||||||
|
time = models.IntegerField(blank=True, null=True)
|
||||||
|
owner = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_skull'
|
||||||
|
verbose_name = 'Skull'
|
||||||
|
verbose_name_plural = 'Skulls'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.owner
|
||||||
|
|
||||||
|
|
||||||
|
class CoUser(models.Model):
|
||||||
|
time = models.IntegerField(blank=True, null=True)
|
||||||
|
user = models.TextField(blank=True, null=True)
|
||||||
|
uuid = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_user'
|
||||||
|
verbose_name = 'User'
|
||||||
|
verbose_name_plural = 'Users'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.user
|
||||||
|
|
||||||
|
|
||||||
|
class CoUsernameLog(models.Model):
|
||||||
|
time = models.IntegerField(blank=True, null=True)
|
||||||
|
uuid = models.TextField(blank=True, null=True)
|
||||||
|
user = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_username_log'
|
||||||
|
verbose_name = 'Username'
|
||||||
|
verbose_name_plural = 'Usernames'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.user
|
||||||
|
|
||||||
|
|
||||||
|
class CoVersion(models.Model):
|
||||||
|
time = models.IntegerField(blank=True, null=True)
|
||||||
|
version = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_version'
|
||||||
|
verbose_name = 'Version'
|
||||||
|
verbose_name_plural = 'Versions'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.version
|
||||||
|
|
||||||
|
|
||||||
|
class CoWorld(models.Model):
|
||||||
|
id = models.IntegerField(primary_key=True)
|
||||||
|
world = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
db_table = 'co_world'
|
||||||
|
verbose_name = 'World'
|
||||||
|
verbose_name_plural = 'Worlds'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.world
|
||||||
|
|
||||||
|
|
||||||
|
class GUIResult(models.Model):
|
||||||
|
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()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def display_time(self):
|
||||||
|
dt = datetime.fromtimestamp(float(self.unix))
|
||||||
|
return dt.strftime("%b %d, %Y at %I:%M:%S %p")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def display_action(self):
|
||||||
|
if self.type == "block":
|
||||||
|
return "Block Break" if str(self.action) == "0" else "Block Place" if str(self.action) == "1" else "Interact/Used"
|
||||||
|
if self.type == "chat":
|
||||||
|
return "Chat"
|
||||||
|
if self.type == "container":
|
||||||
|
return "Took from Container" if str(self.action) == "0" else "Placed in Container"
|
||||||
|
if self.type == "command":
|
||||||
|
return "Command"
|
||||||
|
if self.type == "session":
|
||||||
|
return "Logout" if str(self.action) == "0" else "Login"
|
||||||
|
if self.type == "sign":
|
||||||
|
return "Sign"
|
||||||
|
return self.action
|
||||||
|
|
||||||
|
@property
|
||||||
|
def display_data(self):
|
||||||
|
def material_name(namespace):
|
||||||
|
m = namespace.replace("minecraft:", "")
|
||||||
|
pp = m.split("_")
|
||||||
|
return " ".join([p.capitalize() for p in pp])
|
||||||
|
|
||||||
|
if self.type == "block":
|
||||||
|
return material_name(self.data)
|
||||||
|
if self.type == "container":
|
||||||
|
parts = self.data.split()
|
||||||
|
return "{} {}".format(parts[0], material_name(parts[1]))
|
||||||
|
return self.data
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
managed = False
|
||||||
|
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)
|
|
@ -0,0 +1,38 @@
|
||||||
|
class CoreProtectRouter:
|
||||||
|
"""
|
||||||
|
A router to control all database operations on models in the
|
||||||
|
auth application.
|
||||||
|
"""
|
||||||
|
def db_for_read(self, model, **hints):
|
||||||
|
"""
|
||||||
|
Attempts to read auth models go to auth_db.
|
||||||
|
"""
|
||||||
|
if model._meta.app_label == 'django_coreprotect':
|
||||||
|
return 'django_coreprotect'
|
||||||
|
return None
|
||||||
|
|
||||||
|
def db_for_write(self, model, **hints):
|
||||||
|
"""
|
||||||
|
Attempts to write django_coreprotect models go to django_coreprotect.
|
||||||
|
"""
|
||||||
|
if model._meta.app_label == 'django_coreprotect':
|
||||||
|
return 'django_coreprotect'
|
||||||
|
return None
|
||||||
|
|
||||||
|
def allow_relation(self, obj1, obj2, **hints):
|
||||||
|
"""
|
||||||
|
Allow relations if a model in the django_coreprotect app is involved.
|
||||||
|
"""
|
||||||
|
if obj1._meta.app_label == 'django_coreprotect' or \
|
||||||
|
obj2._meta.app_label == 'django_coreprotect':
|
||||||
|
return True
|
||||||
|
return None
|
||||||
|
|
||||||
|
def allow_migrate(self, db, app_label, model_name=None, **hints):
|
||||||
|
"""
|
||||||
|
Make sure the django_coreprotect app only appears in the 'django_coreprotect'
|
||||||
|
database.
|
||||||
|
"""
|
||||||
|
if app_label == 'django_coreprotect':
|
||||||
|
return db == 'django_coreprotect'
|
||||||
|
return None
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,784 @@
|
||||||
|
.flatpickr-calendar {
|
||||||
|
background: transparent;
|
||||||
|
opacity: 0;
|
||||||
|
display: none;
|
||||||
|
text-align: center;
|
||||||
|
visibility: hidden;
|
||||||
|
padding: 0;
|
||||||
|
-webkit-animation: none;
|
||||||
|
animation: none;
|
||||||
|
direction: ltr;
|
||||||
|
border: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 24px;
|
||||||
|
border-radius: 5px;
|
||||||
|
position: absolute;
|
||||||
|
width: 307.875px;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
-ms-touch-action: manipulation;
|
||||||
|
touch-action: manipulation;
|
||||||
|
background: #3f4458;
|
||||||
|
-webkit-box-shadow: 1px 0 0 #20222c, -1px 0 0 #20222c, 0 1px 0 #20222c, 0 -1px 0 #20222c, 0 3px 13px rgba(0,0,0,0.08);
|
||||||
|
box-shadow: 1px 0 0 #20222c, -1px 0 0 #20222c, 0 1px 0 #20222c, 0 -1px 0 #20222c, 0 3px 13px rgba(0,0,0,0.08);
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.open,
|
||||||
|
.flatpickr-calendar.inline {
|
||||||
|
opacity: 1;
|
||||||
|
max-height: 640px;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.open {
|
||||||
|
display: inline-block;
|
||||||
|
z-index: 99999;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.animate.open {
|
||||||
|
-webkit-animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1);
|
||||||
|
animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1);
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.inline {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.static {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 2px);
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.static.open {
|
||||||
|
z-index: 999;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+1) .flatpickr-day.inRange:nth-child(7n+7) {
|
||||||
|
-webkit-box-shadow: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+2) .flatpickr-day.inRange:nth-child(7n+1) {
|
||||||
|
-webkit-box-shadow: -2px 0 0 #e6e6e6, 5px 0 0 #e6e6e6;
|
||||||
|
box-shadow: -2px 0 0 #e6e6e6, 5px 0 0 #e6e6e6;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar .hasWeeks .dayContainer,
|
||||||
|
.flatpickr-calendar .hasTime .dayContainer {
|
||||||
|
border-bottom: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar .hasWeeks .dayContainer {
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.showTimeInput.hasTime .flatpickr-time {
|
||||||
|
height: 40px;
|
||||||
|
border-top: 1px solid #20222c;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.noCalendar.hasTime .flatpickr-time {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar:before,
|
||||||
|
.flatpickr-calendar:after {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
pointer-events: none;
|
||||||
|
border: solid transparent;
|
||||||
|
content: '';
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
left: 22px;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.rightMost:before,
|
||||||
|
.flatpickr-calendar.rightMost:after {
|
||||||
|
left: auto;
|
||||||
|
right: 22px;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar:before {
|
||||||
|
border-width: 5px;
|
||||||
|
margin: 0 -5px;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar:after {
|
||||||
|
border-width: 4px;
|
||||||
|
margin: 0 -4px;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.arrowTop:before,
|
||||||
|
.flatpickr-calendar.arrowTop:after {
|
||||||
|
bottom: 100%;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.arrowTop:before {
|
||||||
|
border-bottom-color: #20222c;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.arrowTop:after {
|
||||||
|
border-bottom-color: #3f4458;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.arrowBottom:before,
|
||||||
|
.flatpickr-calendar.arrowBottom:after {
|
||||||
|
top: 100%;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.arrowBottom:before {
|
||||||
|
border-top-color: #20222c;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar.arrowBottom:after {
|
||||||
|
border-top-color: #3f4458;
|
||||||
|
}
|
||||||
|
.flatpickr-calendar:focus {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
.flatpickr-wrapper {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.flatpickr-months {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.flatpickr-months .flatpickr-month {
|
||||||
|
background: #3f4458;
|
||||||
|
color: #fff;
|
||||||
|
fill: #fff;
|
||||||
|
height: 34px;
|
||||||
|
line-height: 1;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
overflow: hidden;
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-webkit-flex: 1;
|
||||||
|
-ms-flex: 1;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.flatpickr-months .flatpickr-prev-month,
|
||||||
|
.flatpickr-months .flatpickr-next-month {
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
height: 34px;
|
||||||
|
padding: 10px;
|
||||||
|
z-index: 3;
|
||||||
|
color: #fff;
|
||||||
|
fill: #fff;
|
||||||
|
}
|
||||||
|
.flatpickr-months .flatpickr-prev-month.flatpickr-disabled,
|
||||||
|
.flatpickr-months .flatpickr-next-month.flatpickr-disabled {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.flatpickr-months .flatpickr-prev-month i,
|
||||||
|
.flatpickr-months .flatpickr-next-month i {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.flatpickr-months .flatpickr-prev-month.flatpickr-prev-month,
|
||||||
|
.flatpickr-months .flatpickr-next-month.flatpickr-prev-month {
|
||||||
|
/*
|
||||||
|
/*rtl:begin:ignore*/
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
left: 0;
|
||||||
|
/*
|
||||||
|
/*rtl:end:ignore*/
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
/*rtl:begin:ignore*/
|
||||||
|
/*
|
||||||
|
/*rtl:end:ignore*/
|
||||||
|
.flatpickr-months .flatpickr-prev-month.flatpickr-next-month,
|
||||||
|
.flatpickr-months .flatpickr-next-month.flatpickr-next-month {
|
||||||
|
/*
|
||||||
|
/*rtl:begin:ignore*/
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
right: 0;
|
||||||
|
/*
|
||||||
|
/*rtl:end:ignore*/
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
/*rtl:begin:ignore*/
|
||||||
|
/*
|
||||||
|
/*rtl:end:ignore*/
|
||||||
|
.flatpickr-months .flatpickr-prev-month:hover,
|
||||||
|
.flatpickr-months .flatpickr-next-month:hover {
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
.flatpickr-months .flatpickr-prev-month:hover svg,
|
||||||
|
.flatpickr-months .flatpickr-next-month:hover svg {
|
||||||
|
fill: #f64747;
|
||||||
|
}
|
||||||
|
.flatpickr-months .flatpickr-prev-month svg,
|
||||||
|
.flatpickr-months .flatpickr-next-month svg {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
}
|
||||||
|
.flatpickr-months .flatpickr-prev-month svg path,
|
||||||
|
.flatpickr-months .flatpickr-next-month svg path {
|
||||||
|
-webkit-transition: fill 0.1s;
|
||||||
|
transition: fill 0.1s;
|
||||||
|
fill: inherit;
|
||||||
|
}
|
||||||
|
.numInputWrapper {
|
||||||
|
position: relative;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.numInputWrapper input,
|
||||||
|
.numInputWrapper span {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.numInputWrapper input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.numInputWrapper input::-ms-clear {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.numInputWrapper input::-webkit-outer-spin-button,
|
||||||
|
.numInputWrapper input::-webkit-inner-spin-button {
|
||||||
|
margin: 0;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
.numInputWrapper span {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
width: 14px;
|
||||||
|
padding: 0 4px 0 2px;
|
||||||
|
height: 50%;
|
||||||
|
line-height: 50%;
|
||||||
|
opacity: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid rgba(255,255,255,0.15);
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.numInputWrapper span:hover {
|
||||||
|
background: rgba(192,187,167,0.1);
|
||||||
|
}
|
||||||
|
.numInputWrapper span:active {
|
||||||
|
background: rgba(192,187,167,0.2);
|
||||||
|
}
|
||||||
|
.numInputWrapper span:after {
|
||||||
|
display: block;
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.numInputWrapper span.arrowUp {
|
||||||
|
top: 0;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
.numInputWrapper span.arrowUp:after {
|
||||||
|
border-left: 4px solid transparent;
|
||||||
|
border-right: 4px solid transparent;
|
||||||
|
border-bottom: 4px solid rgba(255,255,255,0.6);
|
||||||
|
top: 26%;
|
||||||
|
}
|
||||||
|
.numInputWrapper span.arrowDown {
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
.numInputWrapper span.arrowDown:after {
|
||||||
|
border-left: 4px solid transparent;
|
||||||
|
border-right: 4px solid transparent;
|
||||||
|
border-top: 4px solid rgba(255,255,255,0.6);
|
||||||
|
top: 40%;
|
||||||
|
}
|
||||||
|
.numInputWrapper span svg {
|
||||||
|
width: inherit;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.numInputWrapper span svg path {
|
||||||
|
fill: rgba(255,255,255,0.5);
|
||||||
|
}
|
||||||
|
.numInputWrapper:hover {
|
||||||
|
background: rgba(192,187,167,0.05);
|
||||||
|
}
|
||||||
|
.numInputWrapper:hover span {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month {
|
||||||
|
font-size: 135%;
|
||||||
|
line-height: inherit;
|
||||||
|
font-weight: 300;
|
||||||
|
color: inherit;
|
||||||
|
position: absolute;
|
||||||
|
width: 75%;
|
||||||
|
left: 12.5%;
|
||||||
|
padding: 7.48px 0 0 0;
|
||||||
|
line-height: 1;
|
||||||
|
height: 34px;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
-webkit-transform: translate3d(0px, 0px, 0px);
|
||||||
|
transform: translate3d(0px, 0px, 0px);
|
||||||
|
}
|
||||||
|
.flatpickr-current-month span.cur-month {
|
||||||
|
font-family: inherit;
|
||||||
|
font-weight: 700;
|
||||||
|
color: inherit;
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 0.5ch;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month span.cur-month:hover {
|
||||||
|
background: rgba(192,187,167,0.05);
|
||||||
|
}
|
||||||
|
.flatpickr-current-month .numInputWrapper {
|
||||||
|
width: 6ch;
|
||||||
|
width: 7ch\0;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month .numInputWrapper span.arrowUp:after {
|
||||||
|
border-bottom-color: #fff;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month .numInputWrapper span.arrowDown:after {
|
||||||
|
border-top-color: #fff;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month input.cur-year {
|
||||||
|
background: transparent;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: inherit;
|
||||||
|
cursor: text;
|
||||||
|
padding: 0 0 0 0.5ch;
|
||||||
|
margin: 0;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
font-weight: 300;
|
||||||
|
line-height: inherit;
|
||||||
|
height: auto;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
vertical-align: initial;
|
||||||
|
-webkit-appearance: textfield;
|
||||||
|
-moz-appearance: textfield;
|
||||||
|
appearance: textfield;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month input.cur-year:focus {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month input.cur-year[disabled],
|
||||||
|
.flatpickr-current-month input.cur-year[disabled]:hover {
|
||||||
|
font-size: 100%;
|
||||||
|
color: rgba(255,255,255,0.5);
|
||||||
|
background: transparent;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month .flatpickr-monthDropdown-months {
|
||||||
|
appearance: menulist;
|
||||||
|
background: #3f4458;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
font-weight: 300;
|
||||||
|
height: auto;
|
||||||
|
line-height: inherit;
|
||||||
|
margin: -1px 0 0 0;
|
||||||
|
outline: none;
|
||||||
|
padding: 0 0 0 0.5ch;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: initial;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-webkit-appearance: menulist;
|
||||||
|
-moz-appearance: menulist;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month .flatpickr-monthDropdown-months:focus,
|
||||||
|
.flatpickr-current-month .flatpickr-monthDropdown-months:active {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.flatpickr-current-month .flatpickr-monthDropdown-months:hover {
|
||||||
|
background: rgba(192,187,167,0.05);
|
||||||
|
}
|
||||||
|
.flatpickr-current-month .flatpickr-monthDropdown-months .flatpickr-monthDropdown-month {
|
||||||
|
background-color: #3f4458;
|
||||||
|
outline: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.flatpickr-weekdays {
|
||||||
|
background: transparent;
|
||||||
|
text-align: center;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-align: center;
|
||||||
|
-webkit-align-items: center;
|
||||||
|
-ms-flex-align: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 28px;
|
||||||
|
}
|
||||||
|
.flatpickr-weekdays .flatpickr-weekdaycontainer {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-webkit-flex: 1;
|
||||||
|
-ms-flex: 1;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
span.flatpickr-weekday {
|
||||||
|
cursor: default;
|
||||||
|
font-size: 90%;
|
||||||
|
background: #3f4458;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 1;
|
||||||
|
margin: 0;
|
||||||
|
text-align: center;
|
||||||
|
display: block;
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-webkit-flex: 1;
|
||||||
|
-ms-flex: 1;
|
||||||
|
flex: 1;
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
.dayContainer,
|
||||||
|
.flatpickr-weeks {
|
||||||
|
padding: 1px 0 0 0;
|
||||||
|
}
|
||||||
|
.flatpickr-days {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-align: start;
|
||||||
|
-webkit-align-items: flex-start;
|
||||||
|
-ms-flex-align: start;
|
||||||
|
align-items: flex-start;
|
||||||
|
width: 307.875px;
|
||||||
|
}
|
||||||
|
.flatpickr-days:focus {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
.dayContainer {
|
||||||
|
padding: 0;
|
||||||
|
outline: 0;
|
||||||
|
text-align: left;
|
||||||
|
width: 307.875px;
|
||||||
|
min-width: 307.875px;
|
||||||
|
max-width: 307.875px;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: inline-block;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: flex;
|
||||||
|
-webkit-flex-wrap: wrap;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
-ms-flex-wrap: wrap;
|
||||||
|
-ms-flex-pack: justify;
|
||||||
|
-webkit-justify-content: space-around;
|
||||||
|
justify-content: space-around;
|
||||||
|
-webkit-transform: translate3d(0px, 0px, 0px);
|
||||||
|
transform: translate3d(0px, 0px, 0px);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.dayContainer + .dayContainer {
|
||||||
|
-webkit-box-shadow: -1px 0 0 #20222c;
|
||||||
|
box-shadow: -1px 0 0 #20222c;
|
||||||
|
}
|
||||||
|
.flatpickr-day {
|
||||||
|
background: none;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 150px;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: rgba(255,255,255,0.95);
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 400;
|
||||||
|
width: 14.2857143%;
|
||||||
|
-webkit-flex-basis: 14.2857143%;
|
||||||
|
-ms-flex-preferred-size: 14.2857143%;
|
||||||
|
flex-basis: 14.2857143%;
|
||||||
|
max-width: 39px;
|
||||||
|
height: 39px;
|
||||||
|
line-height: 39px;
|
||||||
|
margin: 0;
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
-webkit-box-pack: center;
|
||||||
|
-webkit-justify-content: center;
|
||||||
|
-ms-flex-pack: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.flatpickr-day.inRange,
|
||||||
|
.flatpickr-day.prevMonthDay.inRange,
|
||||||
|
.flatpickr-day.nextMonthDay.inRange,
|
||||||
|
.flatpickr-day.today.inRange,
|
||||||
|
.flatpickr-day.prevMonthDay.today.inRange,
|
||||||
|
.flatpickr-day.nextMonthDay.today.inRange,
|
||||||
|
.flatpickr-day:hover,
|
||||||
|
.flatpickr-day.prevMonthDay:hover,
|
||||||
|
.flatpickr-day.nextMonthDay:hover,
|
||||||
|
.flatpickr-day:focus,
|
||||||
|
.flatpickr-day.prevMonthDay:focus,
|
||||||
|
.flatpickr-day.nextMonthDay:focus {
|
||||||
|
cursor: pointer;
|
||||||
|
outline: 0;
|
||||||
|
background: #646c8c;
|
||||||
|
border-color: #646c8c;
|
||||||
|
}
|
||||||
|
.flatpickr-day.today {
|
||||||
|
border-color: #eee;
|
||||||
|
}
|
||||||
|
.flatpickr-day.today:hover,
|
||||||
|
.flatpickr-day.today:focus {
|
||||||
|
border-color: #eee;
|
||||||
|
background: #eee;
|
||||||
|
color: #3f4458;
|
||||||
|
}
|
||||||
|
.flatpickr-day.selected,
|
||||||
|
.flatpickr-day.startRange,
|
||||||
|
.flatpickr-day.endRange,
|
||||||
|
.flatpickr-day.selected.inRange,
|
||||||
|
.flatpickr-day.startRange.inRange,
|
||||||
|
.flatpickr-day.endRange.inRange,
|
||||||
|
.flatpickr-day.selected:focus,
|
||||||
|
.flatpickr-day.startRange:focus,
|
||||||
|
.flatpickr-day.endRange:focus,
|
||||||
|
.flatpickr-day.selected:hover,
|
||||||
|
.flatpickr-day.startRange:hover,
|
||||||
|
.flatpickr-day.endRange:hover,
|
||||||
|
.flatpickr-day.selected.prevMonthDay,
|
||||||
|
.flatpickr-day.startRange.prevMonthDay,
|
||||||
|
.flatpickr-day.endRange.prevMonthDay,
|
||||||
|
.flatpickr-day.selected.nextMonthDay,
|
||||||
|
.flatpickr-day.startRange.nextMonthDay,
|
||||||
|
.flatpickr-day.endRange.nextMonthDay {
|
||||||
|
background: #80cbc4;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
color: #fff;
|
||||||
|
border-color: #80cbc4;
|
||||||
|
}
|
||||||
|
.flatpickr-day.selected.startRange,
|
||||||
|
.flatpickr-day.startRange.startRange,
|
||||||
|
.flatpickr-day.endRange.startRange {
|
||||||
|
border-radius: 50px 0 0 50px;
|
||||||
|
}
|
||||||
|
.flatpickr-day.selected.endRange,
|
||||||
|
.flatpickr-day.startRange.endRange,
|
||||||
|
.flatpickr-day.endRange.endRange {
|
||||||
|
border-radius: 0 50px 50px 0;
|
||||||
|
}
|
||||||
|
.flatpickr-day.selected.startRange + .endRange:not(:nth-child(7n+1)),
|
||||||
|
.flatpickr-day.startRange.startRange + .endRange:not(:nth-child(7n+1)),
|
||||||
|
.flatpickr-day.endRange.startRange + .endRange:not(:nth-child(7n+1)) {
|
||||||
|
-webkit-box-shadow: -10px 0 0 #80cbc4;
|
||||||
|
box-shadow: -10px 0 0 #80cbc4;
|
||||||
|
}
|
||||||
|
.flatpickr-day.selected.startRange.endRange,
|
||||||
|
.flatpickr-day.startRange.startRange.endRange,
|
||||||
|
.flatpickr-day.endRange.startRange.endRange {
|
||||||
|
border-radius: 50px;
|
||||||
|
}
|
||||||
|
.flatpickr-day.inRange {
|
||||||
|
border-radius: 0;
|
||||||
|
-webkit-box-shadow: -5px 0 0 #646c8c, 5px 0 0 #646c8c;
|
||||||
|
box-shadow: -5px 0 0 #646c8c, 5px 0 0 #646c8c;
|
||||||
|
}
|
||||||
|
.flatpickr-day.flatpickr-disabled,
|
||||||
|
.flatpickr-day.flatpickr-disabled:hover,
|
||||||
|
.flatpickr-day.prevMonthDay,
|
||||||
|
.flatpickr-day.nextMonthDay,
|
||||||
|
.flatpickr-day.notAllowed,
|
||||||
|
.flatpickr-day.notAllowed.prevMonthDay,
|
||||||
|
.flatpickr-day.notAllowed.nextMonthDay {
|
||||||
|
color: rgba(255,255,255,0.3);
|
||||||
|
background: transparent;
|
||||||
|
border-color: transparent;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.flatpickr-day.flatpickr-disabled,
|
||||||
|
.flatpickr-day.flatpickr-disabled:hover {
|
||||||
|
cursor: not-allowed;
|
||||||
|
color: rgba(255,255,255,0.1);
|
||||||
|
}
|
||||||
|
.flatpickr-day.week.selected {
|
||||||
|
border-radius: 0;
|
||||||
|
-webkit-box-shadow: -5px 0 0 #80cbc4, 5px 0 0 #80cbc4;
|
||||||
|
box-shadow: -5px 0 0 #80cbc4, 5px 0 0 #80cbc4;
|
||||||
|
}
|
||||||
|
.flatpickr-day.hidden {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.rangeMode .flatpickr-day {
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
.flatpickr-weekwrapper {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.flatpickr-weekwrapper .flatpickr-weeks {
|
||||||
|
padding: 0 12px;
|
||||||
|
-webkit-box-shadow: 1px 0 0 #20222c;
|
||||||
|
box-shadow: 1px 0 0 #20222c;
|
||||||
|
}
|
||||||
|
.flatpickr-weekwrapper .flatpickr-weekday {
|
||||||
|
float: none;
|
||||||
|
width: 100%;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
.flatpickr-weekwrapper span.flatpickr-day,
|
||||||
|
.flatpickr-weekwrapper span.flatpickr-day:hover {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
max-width: none;
|
||||||
|
color: rgba(255,255,255,0.3);
|
||||||
|
background: transparent;
|
||||||
|
cursor: default;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.flatpickr-innerContainer {
|
||||||
|
display: block;
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.flatpickr-rContainer {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.flatpickr-time {
|
||||||
|
text-align: center;
|
||||||
|
outline: 0;
|
||||||
|
display: block;
|
||||||
|
height: 0;
|
||||||
|
line-height: 40px;
|
||||||
|
max-height: 40px;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.flatpickr-time:after {
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
.flatpickr-time .numInputWrapper {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-webkit-flex: 1;
|
||||||
|
-ms-flex: 1;
|
||||||
|
flex: 1;
|
||||||
|
width: 40%;
|
||||||
|
height: 40px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.flatpickr-time .numInputWrapper span.arrowUp:after {
|
||||||
|
border-bottom-color: rgba(255,255,255,0.95);
|
||||||
|
}
|
||||||
|
.flatpickr-time .numInputWrapper span.arrowDown:after {
|
||||||
|
border-top-color: rgba(255,255,255,0.95);
|
||||||
|
}
|
||||||
|
.flatpickr-time.hasSeconds .numInputWrapper {
|
||||||
|
width: 26%;
|
||||||
|
}
|
||||||
|
.flatpickr-time.time24hr .numInputWrapper {
|
||||||
|
width: 49%;
|
||||||
|
}
|
||||||
|
.flatpickr-time input {
|
||||||
|
background: transparent;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
text-align: center;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
color: rgba(255,255,255,0.95);
|
||||||
|
font-size: 14px;
|
||||||
|
position: relative;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
-webkit-appearance: textfield;
|
||||||
|
-moz-appearance: textfield;
|
||||||
|
appearance: textfield;
|
||||||
|
}
|
||||||
|
.flatpickr-time input.flatpickr-hour {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.flatpickr-time input.flatpickr-minute,
|
||||||
|
.flatpickr-time input.flatpickr-second {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
.flatpickr-time input:focus {
|
||||||
|
outline: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
.flatpickr-time .flatpickr-time-separator,
|
||||||
|
.flatpickr-time .flatpickr-am-pm {
|
||||||
|
height: inherit;
|
||||||
|
float: left;
|
||||||
|
line-height: inherit;
|
||||||
|
color: rgba(255,255,255,0.95);
|
||||||
|
font-weight: bold;
|
||||||
|
width: 2%;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-align-self: center;
|
||||||
|
-ms-flex-item-align: center;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
.flatpickr-time .flatpickr-am-pm {
|
||||||
|
outline: 0;
|
||||||
|
width: 18%;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
.flatpickr-time input:hover,
|
||||||
|
.flatpickr-time .flatpickr-am-pm:hover,
|
||||||
|
.flatpickr-time input:focus,
|
||||||
|
.flatpickr-time .flatpickr-am-pm:focus {
|
||||||
|
background: #6a7395;
|
||||||
|
}
|
||||||
|
.flatpickr-input[readonly] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
@-webkit-keyframes fpFadeInDown {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
-webkit-transform: translate3d(0, -20px, 0);
|
||||||
|
transform: translate3d(0, -20px, 0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
-webkit-transform: translate3d(0, 0, 0);
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fpFadeInDown {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
-webkit-transform: translate3d(0, -20px, 0);
|
||||||
|
transform: translate3d(0, -20px, 0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
-webkit-transform: translate3d(0, 0, 0);
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,7 @@
|
||||||
|
.click-row {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
margin-left: 7rem;
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 629 B |
Binary file not shown.
After Width: | Height: | Size: 866 B |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,78 @@
|
||||||
|
(function() {
|
||||||
|
flatpickr('[type="date"]', {
|
||||||
|
altInput: true,
|
||||||
|
altFormat: "F j, Y at H:i",
|
||||||
|
dateFormat: "U",
|
||||||
|
enableTime: true,
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
function ajax(method, url, callback) {
|
||||||
|
let xmlhttp = new XMLHttpRequest();
|
||||||
|
xmlhttp.onreadystatechange = function() {
|
||||||
|
if (xmlhttp.readyState === XMLHttpRequest.DONE) { // XMLHttpRequest.DONE == 4
|
||||||
|
callback(xmlhttp.status, xmlhttp.responseText);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xmlhttp.open(method, url, true);
|
||||||
|
xmlhttp.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function formURI(formData) {
|
||||||
|
let pairs = [];
|
||||||
|
for (let data of formData.entries()) {
|
||||||
|
pairs.push(encodeURIComponent(data[0]) + '=' + encodeURIComponent(data[1]))
|
||||||
|
}
|
||||||
|
return pairs.join("&").replace(/%20/g, '+');
|
||||||
|
}
|
||||||
|
|
||||||
|
function elementHTML(id, html) {
|
||||||
|
document.getElementById(id).innerHTML = html
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadCSV(csv, filename) {
|
||||||
|
let csvFile;
|
||||||
|
let downloadLink;
|
||||||
|
|
||||||
|
// CSV file
|
||||||
|
csvFile = new Blob([csv], {type: "text/csv"});
|
||||||
|
|
||||||
|
// Download link
|
||||||
|
downloadLink = document.createElement("a");
|
||||||
|
|
||||||
|
// File name
|
||||||
|
downloadLink.download = filename;
|
||||||
|
|
||||||
|
// Create a link to the file
|
||||||
|
downloadLink.href = window.URL.createObjectURL(csvFile);
|
||||||
|
|
||||||
|
// Hide download link
|
||||||
|
downloadLink.style.display = "none";
|
||||||
|
|
||||||
|
// Add the link to DOM
|
||||||
|
document.body.appendChild(downloadLink);
|
||||||
|
|
||||||
|
// Click download link
|
||||||
|
downloadLink.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportTableToCSV(filename, elementId) {
|
||||||
|
let csv = [];
|
||||||
|
let selector = "table tr";
|
||||||
|
if (elementId !== "") {
|
||||||
|
selector = "#" + elementId + " tr"
|
||||||
|
}
|
||||||
|
let rows = document.querySelectorAll(selector);
|
||||||
|
|
||||||
|
for (let i = 0; i < rows.length; i++) {
|
||||||
|
let row = [], cols = rows[i].querySelectorAll("td, th");
|
||||||
|
|
||||||
|
for (let j = 0; j < cols.length; j++)
|
||||||
|
row.push('"' + cols[j].innerText + '"');
|
||||||
|
|
||||||
|
csv.push(row.join(","));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Download CSV file
|
||||||
|
downloadCSV(csv.join("\n"), filename);
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
{% extends "coreprotect/base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
{% block head %}
|
||||||
|
<link rel="shortcut icon" type="image/png" href="{% static 'coreprotect/img/ymca.png' %}"/>
|
||||||
|
{% endblock %}
|
||||||
|
{% block body %}
|
||||||
|
<div class="block"></div>
|
||||||
|
<div class="has-text-centered">
|
||||||
|
<h1 class="title">CoreProtect Activity Monitor</h1>
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
<div class="columns">
|
||||||
|
<form id="coreprotect_form" name="coreprotect_form" class="has-text-left column is-one-fifth">
|
||||||
|
<h4 class="title is-5 has-text-primary">
|
||||||
|
Players
|
||||||
|
</h4>
|
||||||
|
<div class="field tooltip" data-tooltip="Accepts full or partial names. Separated by commas.">
|
||||||
|
<input class="input" id="players" name="players" type="text" placeholder="Player Names" value="{{form.players}}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<h4 class="title is-5 has-text-primary">
|
||||||
|
Date and Time
|
||||||
|
</h4>
|
||||||
|
<div class="field tooltip" data-tooltip="Click to open date/time picker.">
|
||||||
|
<p class="control">
|
||||||
|
<input type="date" id="date_from" name="date_from" placeholder="Date From" value="{{form.date_from}}">
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="field tooltip" data-tooltip="Click to open date/time picker.">
|
||||||
|
<p class="control">
|
||||||
|
<input type="date" id="date_to" name="date_to" placeholder="Date To" value="{{form.date_to}}">
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<div class="field is-grouped">
|
||||||
|
<p class="control">
|
||||||
|
<button class="button is-primary" id="search" type="button">Search</button>
|
||||||
|
</p>
|
||||||
|
<p class="control">
|
||||||
|
<button class="button is-dark" id="clear" type="button">Clear</button>
|
||||||
|
</p>
|
||||||
|
<p class="control">
|
||||||
|
<button class="button is-info" id="export" type="button">Export</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div class="column is-three-fifths" id="results">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
{% block script %}
|
||||||
|
<script>
|
||||||
|
|
||||||
|
document.getElementById("search").addEventListener("click", function() {
|
||||||
|
elementHTML("results", 'Querying Database...<br/><progress class="progress is-primary"></progress>');
|
||||||
|
|
||||||
|
let form = document.getElementById("coreprotect_form");
|
||||||
|
let formData = new FormData(form);
|
||||||
|
ajax("GET", "{% url "coreprotect_activity_query" %}?" + formURI(formData), function(status, data) {
|
||||||
|
elementHTML("results", data);
|
||||||
|
});
|
||||||
|
window.history.pushState("", "", "{% url "coreprotect_activity" %}?" + formURI(formData));
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("clear").addEventListener("click", function() {
|
||||||
|
|
||||||
|
// Players
|
||||||
|
document.getElementById("players").value = "";
|
||||||
|
|
||||||
|
// Date and Time
|
||||||
|
document.getElementById("date_from")._flatpickr.setDate();
|
||||||
|
document.getElementById("date_to")._flatpickr.setDate();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("export").addEventListener("click", function() {
|
||||||
|
exportTableToCSV("activity.csv", "results");
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,23 @@
|
||||||
|
{% load static %}
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>CoreProtect Web Interface</title>
|
||||||
|
{% block head %}{% endblock %}
|
||||||
|
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Ubuntu"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static 'coreprotect/css/bulma.min.css' %}"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static 'coreprotect/css/bulma.dark.css' %}"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static 'coreprotect/css/bulma-extensions.min.css' %}"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static 'coreprotect/css/flatpickr.min.css' %}"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static 'coreprotect/css/flatpickr.dark.css' %}"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static 'coreprotect/css/main.css' %}"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
{% block body %}{% endblock %}
|
||||||
|
</body>
|
||||||
|
<script src="{% static 'coreprotect/js/bulma-extensions.min.js' %}"></script>
|
||||||
|
<script src="{% static 'coreprotect/js/flatpickr.js' %}"></script>
|
||||||
|
<script src="{% static 'coreprotect/js/main.js' %}"></script>
|
||||||
|
{% block script %}{% endblock %}
|
||||||
|
</html>
|
|
@ -0,0 +1,282 @@
|
||||||
|
{% extends "coreprotect/base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
{% block head %}
|
||||||
|
<link rel="shortcut icon" type="image/png" href="{% static 'coreprotect/img/intelli.png' %}"/>
|
||||||
|
{% endblock %}
|
||||||
|
{% block body %}
|
||||||
|
<div class="block"></div>
|
||||||
|
<div class="has-text-centered">
|
||||||
|
<h1 class="title">CoreProtect GUI</h1>
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
<div class="columns">
|
||||||
|
<form id="coreprotect_form" name="coreprotect_form" class="has-text-left column is-one-third">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column is-one-half">
|
||||||
|
<h4 class="title is-5 has-text-primary">
|
||||||
|
Actions
|
||||||
|
</h4>
|
||||||
|
<div class="field">
|
||||||
|
<input class="is-checkradio is-block is-info" id="block_break" name="block_break" type="checkbox" {% if form.block_break %}checked{% endif %}>
|
||||||
|
<label for="block_break">Block Break</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<input class="is-checkradio is-block is-info" id="block_place" name="block_place" type="checkbox" {% if form.block_place %}checked{% endif %}>
|
||||||
|
<label for="block_place">Block Place</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<input class="is-checkradio is-block is-info" id="chest_use" name="chest_use" type="checkbox" {% if form.chest_use %}checked{% endif %}>
|
||||||
|
<label for="chest_use">Chest Use</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<input class="is-checkradio is-block is-info" id="interact" name="interact" type="checkbox" {% if form.interact %}checked{% endif %}>
|
||||||
|
<label for="interact">Interact</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<input class="is-checkradio is-block is-info" id="login_logout" name="login_logout" type="checkbox" {% if form.login_logout %}checked{% endif %}>
|
||||||
|
<label for="login_logout">Login/Logout</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<input class="is-checkradio is-block is-info" id="sign_place" name="sign_place" type="checkbox" {% if form.sign_place %}checked{% endif %}>
|
||||||
|
<label for="sign_place">Sign Place</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<h4 class="title is-5 has-text-primary">
|
||||||
|
Worlds
|
||||||
|
</h4>
|
||||||
|
{% for world in form.worlds %}
|
||||||
|
<div class="field">
|
||||||
|
<input class="is-checkradio is-block is-info" id="{{world.world_id}}" name="world" value="{{world.id}}" type="checkbox" {% if world.checked %}checked{% endif %}>
|
||||||
|
<label for="{{world.world_id}}">{{world.name}}</label>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<h4 class="title is-5 has-text-primary">
|
||||||
|
Options
|
||||||
|
</h4>
|
||||||
|
<div class="field">
|
||||||
|
<input class="is-checkradio is-block is-info" id="ignore_environment" name="ignore_environment" type="checkbox" {% if form.ignore_environment %}checked{% endif %}>
|
||||||
|
<label for="ignore_environment">Ignore Environment</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<input class="is-checkradio is-block is-info" id="oldest_first" name="oldest_first" type="checkbox" {% if form.oldest_first %}checked{% endif %}>
|
||||||
|
<label for="oldest_first">Oldest Results First</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<h4 class="title is-5 has-text-primary">
|
||||||
|
Page Size
|
||||||
|
</h4>
|
||||||
|
<div class="field">
|
||||||
|
<p class="control">
|
||||||
|
<span class="select">
|
||||||
|
<select id="page_size" name="page_size">
|
||||||
|
<option value="20" {% if form.page_size == "20" %}selected{% endif %}>20</option>
|
||||||
|
<option value="50" {% if form.page_size == "50" %}selected{% endif %}>50</option>
|
||||||
|
<option value="100" {% if form.page_size == "100" %}selected{% endif %}>100</option>
|
||||||
|
<option value="200" {% if form.page_size == "200" %}selected{% endif %}>200</option>
|
||||||
|
<option value="500" {% if form.page_size == "500" %}selected{% endif %}>500</option>
|
||||||
|
<option value="1000" {% if form.page_size == "1000" %}selected{% endif %}>1000</option>
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" id="page" name="page" value="{{form.page}}"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="column is-one-half">
|
||||||
|
<h4 class="title is-5 has-text-primary">
|
||||||
|
Players
|
||||||
|
</h4>
|
||||||
|
<div class="field tooltip" data-tooltip="Accepts full or partial names. Separated by commas.">
|
||||||
|
<input class="input" id="players" name="players" type="text" placeholder="Player Names" value="{{form.players}}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<h4 class="title is-5 has-text-primary">
|
||||||
|
Coordinates
|
||||||
|
</h4>
|
||||||
|
<div class="field has-addons tooltip" data-tooltip="Whole numbers only.">
|
||||||
|
<p class="control">
|
||||||
|
<input class="input" id="x" name="x" type="text" placeholder="X" value="{{form.x}}">
|
||||||
|
</p>
|
||||||
|
<p class="control">
|
||||||
|
<input class="input" id="y" name="y" type="text" placeholder="Y" value="{{form.y}}">
|
||||||
|
</p>
|
||||||
|
<p class="control">
|
||||||
|
<input class="input" id="z" name="z" type="text" placeholder="Z" value="{{form.z}}">
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="field tooltip" data-tooltip="Whole numbers only.">
|
||||||
|
<p class="control">
|
||||||
|
<input class="input" id="radius" name="radius" type="text" placeholder="Radius" value="{{form.radius}}">
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<h4 class="title is-5 has-text-primary">
|
||||||
|
Blocks
|
||||||
|
</h4>
|
||||||
|
<div class="field tooltip is-tooltip-multiline" data-tooltip="Accepts full or partial names. Separated by commas.">
|
||||||
|
<input class="input is-4" id="blocks" name="blocks" type="text" placeholder="Block Names" value="{{form.blocks}}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<h4 class="title is-5 has-text-primary">
|
||||||
|
Date and Time
|
||||||
|
</h4>
|
||||||
|
<div class="field tooltip" data-tooltip="Click to open date/time picker.">
|
||||||
|
<p class="control">
|
||||||
|
<input type="date" id="date_from" name="date_from" placeholder="Date From" value="{{form.date_from}}">
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="field tooltip" data-tooltip="Click to open date/time picker.">
|
||||||
|
<p class="control">
|
||||||
|
<input type="date" id="date_to" name="date_to" placeholder="Date To" value="{{form.date_to}}">
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<div class="field is-grouped">
|
||||||
|
<p class="control">
|
||||||
|
<button class="button is-primary" id="search" type="button">Search</button>
|
||||||
|
</p>
|
||||||
|
<p class="control">
|
||||||
|
<button class="button is-dark" id="clear" type="button">Clear</button>
|
||||||
|
</p>
|
||||||
|
<p class="control">
|
||||||
|
<button class="button is-info" id="export" type="button">Export</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div class="column is-three-fifths" id="results">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
{% block script %}
|
||||||
|
<script>
|
||||||
|
let text = "Copy the below command to teleport";
|
||||||
|
function attachClickRows() {
|
||||||
|
Array.from(document.querySelectorAll(".click-row")).forEach(elem => {
|
||||||
|
elem.addEventListener("click", function() {
|
||||||
|
prompt(text, elem.getAttribute("data-prompt"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let url = new URL(window.location);
|
||||||
|
let pageParam = url.searchParams.get("page");
|
||||||
|
let page = 0;
|
||||||
|
if (pageParam !== "") {
|
||||||
|
page = parseInt(pageParam);
|
||||||
|
if (isNaN(page)) {
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function attachPagination() {
|
||||||
|
let prev = document.getElementById("prev");
|
||||||
|
if (prev.getAttribute("disabled") == null) {
|
||||||
|
prev.addEventListener("click", function () {
|
||||||
|
document.getElementById("page").value = (--page).toString();
|
||||||
|
search(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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>');
|
||||||
|
|
||||||
|
if (resetPage) {
|
||||||
|
page = 0;
|
||||||
|
document.getElementById("page").value = "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
let form = document.getElementById("coreprotect_form");
|
||||||
|
let formData = new FormData(form);
|
||||||
|
ajax("GET", "{% url "coreprotect_gui_query" %}?" + formURI(formData), function(status, data) {
|
||||||
|
elementHTML("results", data);
|
||||||
|
attachClickRows();
|
||||||
|
attachPagination();
|
||||||
|
});
|
||||||
|
window.history.pushState("", "", "{% url "coreprotect_gui" %}?" + formURI(formData));
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("search").addEventListener("click", function() {
|
||||||
|
search(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("clear").addEventListener("click", function() {
|
||||||
|
// Actions
|
||||||
|
document.getElementById("block_break").checked = false;
|
||||||
|
document.getElementById("block_place").checked = false;
|
||||||
|
document.getElementById("chat").checked = false;
|
||||||
|
document.getElementById("chest_use").checked = false;
|
||||||
|
document.getElementById("command").checked = false;
|
||||||
|
document.getElementById("interact").checked = false;
|
||||||
|
document.getElementById("login_logout").checked = false;
|
||||||
|
document.getElementById("sign_place").checked = false;
|
||||||
|
|
||||||
|
// Worlds
|
||||||
|
{% for world in form.worlds %}
|
||||||
|
document.getElementById("{{world.world_id}}").checked = false;
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
// Options
|
||||||
|
document.getElementById("ignore_environment").checked = false;
|
||||||
|
document.getElementById("oldest_first").checked = false;
|
||||||
|
|
||||||
|
// Page Size
|
||||||
|
document.getElementById("page_size").selectedIndex = "0";
|
||||||
|
document.getElementById("page").value = "1";
|
||||||
|
|
||||||
|
// Players
|
||||||
|
document.getElementById("players").value = "";
|
||||||
|
|
||||||
|
// Coordinates
|
||||||
|
document.getElementById("x").value = "";
|
||||||
|
document.getElementById("y").value = "";
|
||||||
|
document.getElementById("z").value = "";
|
||||||
|
document.getElementById("radius").value = "";
|
||||||
|
|
||||||
|
// Blocks
|
||||||
|
document.getElementById("blocks").value = "";
|
||||||
|
|
||||||
|
// Date and Time
|
||||||
|
document.getElementById("date_from")._flatpickr.setDate();
|
||||||
|
document.getElementById("date_to")._flatpickr.setDate();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("export").addEventListener("click", function() {
|
||||||
|
exportTableToCSV("coreprotect.csv", "results");
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<table class="table is-fullwidth is-striped is-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Player</th>
|
||||||
|
<th>Time</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for result in results %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ result.player }}</td>
|
||||||
|
<td>{{ result.time_display }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<table class="table is-fullwidth is-striped is-bordered is-hoverable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Time</th>
|
||||||
|
<th>Player</th>
|
||||||
|
<th>Action</th>
|
||||||
|
<th>Data</th>
|
||||||
|
<th>X</th>
|
||||||
|
<th>Y</th>
|
||||||
|
<th>Z</th>
|
||||||
|
<th>World</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for result in results %}
|
||||||
|
<tr {% if result.x %}class="click-row" data-prompt="/tp {{ result.x }} {{ result.y }} {{ result.z }}"{% endif %}>
|
||||||
|
<td>{{ result.display_time }}</td>
|
||||||
|
<td>{{ result.player }}</td>
|
||||||
|
<td>{{ result.display_action }}</td>
|
||||||
|
<td>{{ result.display_data }}</td>
|
||||||
|
<td>{{ result.x }}</td>
|
||||||
|
<td>{{ result.y }}</td>
|
||||||
|
<td>{{ result.z }}</td>
|
||||||
|
<td>{{ result.world }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<nav class="pagination is-rounded is-right" role="navigation">
|
||||||
|
<a class="pagination-previous" id="prev" {% if not prev %}disabled{% endif %}>Previous</a>
|
||||||
|
<a class="pagination-next" id="next" {% if not next %}disabled{% endif %}>Next</a>
|
||||||
|
<ul class="pagination-list"></ul>
|
||||||
|
</nav>
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
|
@ -0,0 +1,10 @@
|
||||||
|
from django.urls import path
|
||||||
|
from django.contrib.auth.decorators import permission_required
|
||||||
|
from django_coreprotect.views import GUI, GUIQuery, Activity, ActivityQuery
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
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"),
|
||||||
|
]
|
|
@ -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
|
|
@ -0,0 +1,63 @@
|
||||||
|
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.utils import safe_int
|
||||||
|
|
||||||
|
|
||||||
|
class GUI(View):
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
form = gui_data(request)
|
||||||
|
return render(request, "coreprotect/coreprotect.html", {"form": form})
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class GUIQuery(View):
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
form = gui_data(request)
|
||||||
|
results = gui_results(form)
|
||||||
|
|
||||||
|
if "format" in request.GET and request.GET["format"] == "json":
|
||||||
|
return JsonResponse(results)
|
||||||
|
|
||||||
|
prev_page, next_page = False, False
|
||||||
|
if safe_int(form.page) > 0:
|
||||||
|
prev_page = True
|
||||||
|
if len(results) == safe_int(form.page_size):
|
||||||
|
next_page = True
|
||||||
|
|
||||||
|
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
|
||||||
|
|
Loading…
Reference in New Issue