Python 3 changes, add LICENSE, update README #5
|
@ -0,0 +1,7 @@
|
|||
Copyright 2021 John Olheiser
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27
README.md
27
README.md
|
@ -1 +1,26 @@
|
|||
# DjangoCoreProtect
|
||||
# Django CoreProtect
|
||||
|
||||
## Settings
|
||||
|
||||
```python
|
||||
INSTALLED_APPS = [
|
||||
'django_coreprotect',
|
||||
]
|
||||
|
||||
DATABASE_ROUTERS = [
|
||||
'django_coreprotect.router.CoreProtectRouter'
|
||||
]
|
||||
DATABASES = {
|
||||
'django_coreprotect': {
|
||||
'ENGINE': 'django.db.backends.mysql',
|
||||
'NAME': '...',
|
||||
'USER': '...',
|
||||
'PASSWORD': '...',
|
||||
'HOST': '127.0.0.1',
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
15
activity.py
15
activity.py
|
@ -1,6 +1,7 @@
|
|||
from django_coreprotect.models import SessionResult, ActivityResult
|
||||
from django_coreprotect.utils import safe_int
|
||||
from datetime import datetime
|
||||
from typing import List
|
||||
|
||||
|
||||
class ActivityForm:
|
||||
|
@ -25,7 +26,7 @@ def activity_data(request):
|
|||
return form
|
||||
|
||||
|
||||
def activity_results(form):
|
||||
def activity_results(form) -> List[ActivityResult]:
|
||||
query = ""
|
||||
|
||||
players_clause = ""
|
||||
|
@ -33,7 +34,8 @@ def activity_results(form):
|
|||
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]))
|
||||
clause = " OR ".join([f"cu.user LIKE '%%{p}%%'" for p in players])
|
||||
players_clause = f" WHERE ({clause}) "
|
||||
|
||||
time_clause = ""
|
||||
if form.date_from or form.date_to:
|
||||
|
@ -45,16 +47,15 @@ def activity_results(form):
|
|||
time_clause = " HAVING unix BETWEEN {} AND {} ".format(df, dt)
|
||||
|
||||
if players_clause or time_clause:
|
||||
query = '''SELECT
|
||||
query = f'''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)
|
||||
{players_clause}
|
||||
{time_clause}
|
||||
'''
|
||||
|
||||
if query:
|
||||
print(query)
|
||||
sessions = SessionResult.objects.raw(query)
|
||||
activity = {}
|
||||
last_session = {}
|
||||
|
|
116
gui.py
116
gui.py
|
@ -1,6 +1,8 @@
|
|||
from datetime import datetime
|
||||
|
||||
from django.db import connection
|
||||
from django.db.models.query import RawQuerySet
|
||||
from django.http import HttpRequest
|
||||
|
||||
from django_coreprotect.models import CoWorld, GUIResult
|
||||
from django_coreprotect.utils import safe_int, checkbox, time_to_form
|
||||
|
@ -33,7 +35,7 @@ class GUIForm:
|
|||
self.date_to = ""
|
||||
|
||||
|
||||
def gui_data(request):
|
||||
def gui_data(request: HttpRequest) -> GUIForm:
|
||||
request_data = request.GET
|
||||
form = GUIForm()
|
||||
worlds = CoWorld.objects.all()
|
||||
|
@ -56,7 +58,7 @@ def gui_data(request):
|
|||
# Worlds
|
||||
request_worlds = request_data.getlist("world")
|
||||
for world in worlds:
|
||||
world_id = "world_{}".format(world.id)
|
||||
world_id = f"world_{world.id}"
|
||||
w = {
|
||||
"id": str(world.id),
|
||||
"world_id": world_id,
|
||||
|
@ -99,7 +101,7 @@ def gui_data(request):
|
|||
return form
|
||||
|
||||
|
||||
def gui_results(form):
|
||||
def gui_results(form: GUIForm) -> RawQuerySet:
|
||||
queries = []
|
||||
ignore_environment = " AND cu.user NOT LIKE '#%%' " if form.ignore_environment else ""
|
||||
oldest_first = " ASC " if form.oldest_first else " DESC "
|
||||
|
@ -107,21 +109,23 @@ def gui_results(form):
|
|||
coords = []
|
||||
radius = form.radius if form.radius else "0"
|
||||
if form.x:
|
||||
coords.append(" x BETWEEN {0} - {1} AND {0} + {1}".format(form.x, radius))
|
||||
coords.append(f" x BETWEEN {form.x} - {radius} AND {form.x} + {radius}")
|
||||
if form.y:
|
||||
coords.append(" y BETWEEN {0} - {1} AND {0} + {1}".format(form.y, radius))
|
||||
coords.append(f" y BETWEEN {form.y} - {radius} AND {form.y} + {radius}")
|
||||
if form.z:
|
||||
coords.append(" z BETWEEN {0} - {1} AND {0} + {1}".format(form.z, radius))
|
||||
coords.append(f" z BETWEEN {form.z} - {radius} AND {form.z} + {radius}")
|
||||
coords_clause = ""
|
||||
if coords:
|
||||
coords_clause = " AND ({})".format(" AND ".join(coords))
|
||||
clause = " AND ".join(coords)
|
||||
coords_clause = f" AND ({clause})"
|
||||
|
||||
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]))
|
||||
clause = " OR ".join([f"cu.user LIKE '{p}%%'" for p in players])
|
||||
players_clause = f" AND ({clause})"
|
||||
|
||||
blocks = []
|
||||
blocks_clause = ""
|
||||
|
@ -130,14 +134,18 @@ def gui_results(form):
|
|||
if form.blocks:
|
||||
for block in form.blocks.split(","):
|
||||
blocks.append(block.strip())
|
||||
blocks_clause = " AND ({})".format(" OR ".join(["cmm.material LIKE 'minecraft:{}%%'".format(b) for b in blocks]))
|
||||
chat_clause = " AND ({})".format(" OR ".join(["cc.message LIKE '%%{}%%'".format(b) for b in blocks]))
|
||||
command_clause = " AND ({})".format(" OR ".join(["cc.message LIKE '%%{}%%'".format(b) for b in blocks]))
|
||||
clause = " OR ".join([f"cmm.material LIKE 'minecraft:{b}%%'" for b in blocks])
|
||||
blocks_clause = f" AND ({clause})"
|
||||
clause = " OR ".join([f"cc.message LIKE '%%{b}%%'" for b in blocks])
|
||||
chat_clause = f" AND ({clause})"
|
||||
clause = " OR ".join([f"cc.message LIKE '%%{b}%%'" for b in blocks])
|
||||
command_clause = f" AND ({clause})"
|
||||
|
||||
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))
|
||||
clause = ",".join(worlds)
|
||||
worlds_clause = f" AND cw.rowid IN ({clause})"
|
||||
|
||||
time_clause = ""
|
||||
if form.date_from or form.date_to:
|
||||
|
@ -146,7 +154,7 @@ def gui_results(form):
|
|||
dt = datetime.now().timestamp()
|
||||
if form.date_to and not form.date_from:
|
||||
df = datetime.now().timestamp()
|
||||
time_clause = " GROUP BY unix HAVING unix BETWEEN {} AND {} ".format(df, dt)
|
||||
time_clause = f" GROUP BY unix HAVING unix BETWEEN {df} AND {dt} "
|
||||
|
||||
# Block Break, Block Place, and Interact
|
||||
block_actions = []
|
||||
|
@ -157,97 +165,95 @@ def gui_results(form):
|
|||
if form.interact:
|
||||
block_actions.append("2")
|
||||
if len(block_actions):
|
||||
queries.append('''SELECT
|
||||
queries.append(f'''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})
|
||||
WHERE cb.action IN ({",".join(block_actions)})
|
||||
{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))
|
||||
{players_clause}
|
||||
{coords_clause}
|
||||
{blocks_clause}
|
||||
{worlds_clause}
|
||||
{time_clause}
|
||||
''')
|
||||
|
||||
# Chat
|
||||
if form.chat:
|
||||
queries.append('''SELECT
|
||||
queries.append(f'''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}
|
||||
{chat}
|
||||
{time}
|
||||
'''.format(players=players_clause, chat=chat_clause, time=time_clause))
|
||||
{players_clause}
|
||||
{chat_clause}
|
||||
{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
|
||||
queries.append(f'''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))
|
||||
{worlds_clause}
|
||||
{players_clause}
|
||||
{coords_clause}
|
||||
{blocks_clause}
|
||||
{time_clause}
|
||||
''')
|
||||
|
||||
# Commands
|
||||
if form.command:
|
||||
queries.append('''SELECT
|
||||
queries.append(f'''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}
|
||||
{command}
|
||||
{coords}
|
||||
{time}
|
||||
'''.format(players=players_clause, command=command_clause, coords=coords_clause, time=time_clause))
|
||||
{players_clause}
|
||||
{command_clause}
|
||||
{coords_clause}
|
||||
{time_clause}
|
||||
''')
|
||||
|
||||
# Login/Logout
|
||||
if form.login_logout:
|
||||
queries.append('''SELECT
|
||||
queries.append(f'''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))
|
||||
{worlds_clause}
|
||||
{players_clause}
|
||||
{coords_clause}
|
||||
{time_clause}
|
||||
''')
|
||||
|
||||
# Sign Place
|
||||
if form.sign_place:
|
||||
queries.append('''SELECT
|
||||
queries.append(f'''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))
|
||||
{worlds_clause}
|
||||
{players_clause}
|
||||
{coords_clause}
|
||||
{time_clause}
|
||||
''')
|
||||
|
||||
query = " UNION ALL ".join(queries)
|
||||
if query:
|
||||
query += " ORDER BY unix {} LIMIT {}, {}".format(oldest_first, form.start, form.page_size)
|
||||
if query:
|
||||
query += f" ORDER BY unix {oldest_first} LIMIT {form.start}, {form.page_size}"
|
||||
return GUIResult.objects.raw(query)
|
||||
return []
|
||||
return GUIResult.objects.none()
|
||||
|
|
|
@ -8,7 +8,6 @@ from django_coreprotect.utils import safe_int
|
|||
|
||||
|
||||
class CoreProtectUser(User):
|
||||
|
||||
class Meta:
|
||||
proxy = True
|
||||
permissions = (
|
||||
|
@ -318,7 +317,7 @@ class Preset(models.Model):
|
|||
enabled = models.BooleanField(default=True)
|
||||
|
||||
@property
|
||||
def link(self):
|
||||
def link(self) -> str:
|
||||
url = reverse("coreprotect_gui") + "?"
|
||||
params = []
|
||||
if self.block_break:
|
||||
|
@ -385,7 +384,8 @@ class GUIResult(models.Model):
|
|||
@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"
|
||||
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":
|
||||
|
@ -445,4 +445,4 @@ class ActivityResult:
|
|||
hours = time % 24
|
||||
time //= 24
|
||||
days = time
|
||||
return "{}d, {}h, {}m, {}s".format(days, hours, minutes, seconds)
|
||||
return f"{days}d, {hours}h, {minutes}m, {seconds}s"
|
||||
|
|
3
urls.py
3
urls.py
|
@ -1,5 +1,6 @@
|
|||
from django.urls import path
|
||||
from django.contrib.auth.decorators import permission_required
|
||||
from django.urls import path
|
||||
|
||||
from django_coreprotect.views import GUI, GUIQuery, Activity, ActivityQuery
|
||||
|
||||
urlpatterns = [
|
||||
|
|
9
utils.py
9
utils.py
|
@ -1,19 +1,20 @@
|
|||
import ast
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, Optional
|
||||
|
||||
|
||||
def checkbox(value):
|
||||
def checkbox(value: str) -> bool:
|
||||
return True if value == "on" else False
|
||||
|
||||
|
||||
def safe_int(value):
|
||||
def safe_int(value: Any) -> int:
|
||||
try:
|
||||
return int(value)
|
||||
except:
|
||||
return 0
|
||||
|
||||
|
||||
def time_to_form(date_time):
|
||||
def time_to_form(date_time: str) -> Optional[datetime]:
|
||||
if date_time == "~T":
|
||||
return datetime.today()
|
||||
elif date_time == "~N":
|
||||
|
@ -21,7 +22,7 @@ def time_to_form(date_time):
|
|||
elif date_time == "~Y":
|
||||
return datetime.today() - timedelta(days=1)
|
||||
elif date_time == "":
|
||||
return ""
|
||||
return None
|
||||
else:
|
||||
return datetime.utcfromtimestamp(float(date_time))
|
||||
|
||||
|
|
3
views.py
3
views.py
|
@ -1,6 +1,7 @@
|
|||
from django.http.response import JsonResponse
|
||||
from django.shortcuts import render
|
||||
from django.views.generic import View
|
||||
from django.core import serializers
|
||||
|
||||
from django_coreprotect.activity import activity_data, activity_results
|
||||
from django_coreprotect.gui import gui_data, gui_results
|
||||
|
@ -25,7 +26,7 @@ class GUIQuery(View):
|
|||
results = gui_results(form)
|
||||
|
||||
if "format" in request.GET and request.GET["format"] == "json":
|
||||
return JsonResponse(results)
|
||||
return serializers.serialize('json', results)
|
||||
|
||||
prev_page, next_page = False, False
|
||||
if safe_int(form.page) > 0:
|
||||
|
|
Loading…
Reference in New Issue