forked from Hay1tsme/artemis
mai2: add event editing for sysops
This commit is contained in:
parent
44fb6037cf
commit
9b5283d389
@ -234,11 +234,11 @@ class ChuniFrontend(FE_Base):
|
||||
if usr_sesh.user_id > 0:
|
||||
form_data = await request.form()
|
||||
chunithm_version = form_data.get("version")
|
||||
self.logger.info(f"version change to: {chunithm_version}")
|
||||
self.logger.debug(f"version change to: {chunithm_version}")
|
||||
if(chunithm_version.isdigit()):
|
||||
usr_sesh.chunithm_version=int(chunithm_version)
|
||||
encoded_sesh = self.encode_session(usr_sesh)
|
||||
self.logger.info(f"Created session with JWT {encoded_sesh}")
|
||||
self.logger.debug(f"Created session with JWT {encoded_sesh}")
|
||||
resp = RedirectResponse("/game/chuni/", 303)
|
||||
resp.set_cookie("ARTEMIS_SESH", encoded_sesh)
|
||||
return resp
|
||||
|
@ -5,8 +5,9 @@ from starlette.responses import Response, RedirectResponse
|
||||
from os import path
|
||||
import yaml
|
||||
import jinja2
|
||||
from datetime import datetime
|
||||
|
||||
from core.frontend import FE_Base, UserSession
|
||||
from core.frontend import FE_Base, UserSession, PermissionOffset
|
||||
from core.config import CoreConfig
|
||||
from .database import Mai2Data
|
||||
from .config import Mai2Config
|
||||
@ -32,6 +33,12 @@ class Mai2Frontend(FE_Base):
|
||||
Route("/", self.render_GET_playlog, methods=['GET']),
|
||||
Route("/{index}", self.render_GET_playlog, methods=['GET']),
|
||||
]),
|
||||
Mount("/events", routes=[
|
||||
Route("/", self.render_events, methods=['GET']),
|
||||
Route("/{event_id:int}", self.render_event_edit, methods=['GET']),
|
||||
Route("/update", self.update_event, methods=['POST']),
|
||||
Route("/version.change", self.version_change, methods=['POST']),
|
||||
]),
|
||||
Route("/update.name", self.update_name, methods=['POST']),
|
||||
Route("/version.change", self.version_change, methods=['POST']),
|
||||
]
|
||||
@ -43,13 +50,15 @@ class Mai2Frontend(FE_Base):
|
||||
usr_sesh = self.validate_session(request)
|
||||
if not usr_sesh:
|
||||
usr_sesh = UserSession()
|
||||
|
||||
incoming_ver = usr_sesh.maimai_version
|
||||
|
||||
if usr_sesh.user_id > 0:
|
||||
versions = await self.data.profile.get_all_profile_versions(usr_sesh.user_id)
|
||||
profile = []
|
||||
if versions:
|
||||
# maimai_version is -1 means it is not initialized yet, select a default version from existing.
|
||||
if usr_sesh.maimai_version < 0:
|
||||
if incoming_ver < 0:
|
||||
usr_sesh.maimai_version = versions[0]['version']
|
||||
profile = await self.data.profile.get_profile_detail(usr_sesh.user_id, usr_sesh.maimai_version)
|
||||
versions = [x['version'] for x in versions]
|
||||
@ -65,7 +74,7 @@ class Mai2Frontend(FE_Base):
|
||||
cur_version=usr_sesh.maimai_version
|
||||
), media_type="text/html; charset=utf-8")
|
||||
|
||||
if usr_sesh.maimai_version >= 0:
|
||||
if incoming_ver < 0:
|
||||
encoded_sesh = self.encode_session(usr_sesh)
|
||||
resp.delete_cookie("ARTEMIS_SESH")
|
||||
resp.set_cookie("ARTEMIS_SESH", encoded_sesh)
|
||||
@ -80,12 +89,10 @@ class Mai2Frontend(FE_Base):
|
||||
)
|
||||
usr_sesh = self.validate_session(request)
|
||||
if not usr_sesh:
|
||||
print("wtf")
|
||||
usr_sesh = UserSession()
|
||||
|
||||
if usr_sesh.user_id > 0:
|
||||
if usr_sesh.maimai_version < 0:
|
||||
print(usr_sesh.maimai_version)
|
||||
return RedirectResponse("/game/mai2/", 303)
|
||||
path_index = request.path_params.get('index')
|
||||
if not path_index or int(path_index) < 1:
|
||||
@ -175,6 +182,11 @@ class Mai2Frontend(FE_Base):
|
||||
if not usr_sesh:
|
||||
usr_sesh = UserSession()
|
||||
|
||||
if "/events/" in request.url.path:
|
||||
resp = RedirectResponse("/game/mai2/events/", 303)
|
||||
else:
|
||||
resp = RedirectResponse("/game/mai2/", 303)
|
||||
|
||||
if usr_sesh.user_id > 0:
|
||||
form_data = await request.form()
|
||||
maimai_version = form_data.get("version")
|
||||
@ -182,9 +194,108 @@ class Mai2Frontend(FE_Base):
|
||||
if(maimai_version.isdigit()):
|
||||
usr_sesh.maimai_version=int(maimai_version)
|
||||
encoded_sesh = self.encode_session(usr_sesh)
|
||||
self.logger.info(f"Created session with JWT {encoded_sesh}")
|
||||
resp = RedirectResponse("/game/mai2/", 303)
|
||||
self.logger.debug(f"Created session with JWT {encoded_sesh}")
|
||||
resp.set_cookie("ARTEMIS_SESH", encoded_sesh)
|
||||
return resp
|
||||
else:
|
||||
return RedirectResponse("/gate/", 303)
|
||||
return RedirectResponse("/gate/", 303)
|
||||
|
||||
async def render_events(self, request: Request) -> Response:
|
||||
usr_sesh = self.validate_session(request)
|
||||
if not usr_sesh:
|
||||
return RedirectResponse("/gate/", 303)
|
||||
|
||||
if not self.test_perm(usr_sesh.permissions, PermissionOffset.SYSADMIN):
|
||||
return RedirectResponse("/game/mai2/", 303)
|
||||
|
||||
template = self.environment.get_template(
|
||||
"titles/mai2/templates/events/mai2_events.jinja"
|
||||
)
|
||||
|
||||
incoming_ver = usr_sesh.maimai_version
|
||||
evts = []
|
||||
|
||||
if incoming_ver < 0:
|
||||
usr_sesh.maimai_version = Mai2Constants.VER_MAIMAI_DX
|
||||
|
||||
event_list = await self.data.static.get_game_events(usr_sesh.maimai_version)
|
||||
self.logger.info(f"Get events for v{usr_sesh.maimai_version}")
|
||||
|
||||
for event in event_list:
|
||||
evts.append({
|
||||
"id": event['id'],
|
||||
"version": event['version'],
|
||||
"eventId": event['eventId'],
|
||||
"eventType": event['type'],
|
||||
"name": event['name'],
|
||||
"startDate": event['startDate'].strftime("%x %X"),
|
||||
"enabled": "true" if event['enabled'] else "false",
|
||||
})
|
||||
|
||||
resp = Response(template.render(
|
||||
title=f"{self.core_config.server.name} | {self.nav_name} Events",
|
||||
game_list=self.environment.globals["game_list"],
|
||||
sesh=vars(usr_sesh),
|
||||
version_list=Mai2Constants.VERSION_STRING,
|
||||
events=evts
|
||||
), media_type="text/html; charset=utf-8")
|
||||
|
||||
if incoming_ver < 0:
|
||||
encoded_sesh = self.encode_session(usr_sesh)
|
||||
resp.delete_cookie("ARTEMIS_SESH")
|
||||
resp.set_cookie("ARTEMIS_SESH", encoded_sesh)
|
||||
|
||||
return resp
|
||||
|
||||
async def render_event_edit(self, request: Request) -> Response:
|
||||
usr_sesh = self.validate_session(request)
|
||||
if not usr_sesh:
|
||||
return RedirectResponse("/gate/", 303)
|
||||
|
||||
if not self.test_perm(usr_sesh.permissions, PermissionOffset.SYSADMIN):
|
||||
return RedirectResponse("/game/mai2/", 303)
|
||||
|
||||
template = self.environment.get_template(
|
||||
"titles/mai2/templates/events/mai2_event_edit.jinja"
|
||||
)
|
||||
|
||||
evt_id = request.path_params.get("event_id")
|
||||
|
||||
event_id = await self.data.static.get_event_by_id(evt_id)
|
||||
if not event_id:
|
||||
return RedirectResponse("/game/mai2/events/", 303)
|
||||
|
||||
return Response(template.render(
|
||||
title=f"{self.core_config.server.name} | {self.nav_name} Edit Event {evt_id}",
|
||||
game_list=self.environment.globals["game_list"],
|
||||
sesh=vars(usr_sesh),
|
||||
user_id=usr_sesh.user_id,
|
||||
version_list=Mai2Constants.VERSION_STRING,
|
||||
cur_version=usr_sesh.maimai_version,
|
||||
event=event_id._asdict()
|
||||
), media_type="text/html; charset=utf-8")
|
||||
|
||||
async def update_event(self, request: Request) -> RedirectResponse:
|
||||
usr_sesh = self.validate_session(request)
|
||||
if not usr_sesh:
|
||||
return RedirectResponse("/gate/", 303)
|
||||
|
||||
if not self.test_perm(usr_sesh.permissions, PermissionOffset.SYSADMIN):
|
||||
return RedirectResponse("/game/mai2/", 303)
|
||||
|
||||
form_data = await request.form()
|
||||
print(form_data)
|
||||
event_id: int = form_data.get("evtId", None)
|
||||
new_enabled: bool = bool(form_data.get("evtEnabled", False))
|
||||
try:
|
||||
new_start_date: datetime = datetime.strptime(form_data.get("evtStart", None), "%Y-%m-%dT%H:%M:%S")
|
||||
except:
|
||||
new_start_date = None
|
||||
|
||||
print(f"{event_id} {new_enabled} {new_start_date}")
|
||||
if event_id is None or new_start_date is None:
|
||||
return RedirectResponse("/game/mai2/events/?e=4", 303)
|
||||
|
||||
await self.data.static.update_event_by_id(int(event_id), new_enabled, new_start_date)
|
||||
|
||||
return RedirectResponse("/game/mai2/events/?s=1", 303)
|
||||
|
@ -7,6 +7,7 @@ from sqlalchemy.schema import ForeignKey
|
||||
from sqlalchemy.sql import func, select
|
||||
from sqlalchemy.engine import Row
|
||||
from sqlalchemy.dialects.mysql import insert
|
||||
from datetime import datetime
|
||||
|
||||
event = Table(
|
||||
"mai2_static_event",
|
||||
@ -248,3 +249,18 @@ class Mai2StaticData(BaseData):
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
async def get_event_by_id(self, table_id: int) -> Optional[Row]:
|
||||
result = await self.execute(event.select(event.c.id == table_id))
|
||||
if result:
|
||||
return result.fetchone()
|
||||
|
||||
async def get_events_by_event_id(self, event_id: int) -> Optional[List[Row]]:
|
||||
result = await self.execute(event.select(event.c.eventId == event_id))
|
||||
if result:
|
||||
return result.fetchall()
|
||||
|
||||
async def update_event_by_id(self, table_id: int, is_enable: bool, start_date: datetime) -> None:
|
||||
result = await self.execute(event.update(event.c.id == table_id).values(enabled=is_enable, startDate = start_date))
|
||||
if not result:
|
||||
self.logger.error(f"Failed to update event {table_id} - {is_enable} {start_date}")
|
||||
|
16
titles/mai2/templates/events/mai2_event_edit.jinja
Normal file
16
titles/mai2/templates/events/mai2_event_edit.jinja
Normal file
@ -0,0 +1,16 @@
|
||||
{% extends "core/templates/index.jinja" %}
|
||||
{% block content %}
|
||||
<!-- TODO: This can probably just be a modal on the main event page -->
|
||||
<form id="frmEvent" method="post" action="/game/mai2/events/update">
|
||||
<h3>Event {{ event.eventId }} for {{ version_list[event.version] }}: {{ event.name }}</h3>
|
||||
<input type="hidden" readonly value="{{event.id}}" id="evtId" name="evtId">
|
||||
<label for="evtEnabled" class="form-label">Enabled</label><br>
|
||||
<input class="form-check-input" type="checkbox" {{ 'checked' if event.enabled else ''}} id="evtEnabled" name="evtEnabled"><br><br>
|
||||
|
||||
<label for="evtStart" class="form-label">Start Date</label><br>
|
||||
<input class="form-input" type="datetime-local" id="evtStart" name="evtStart" value="{{ event.startDate }}"><br><br>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Update</button>
|
||||
<button type="cancel" class="btn btn-danger">Delete</button>
|
||||
</form>
|
||||
{% endblock content %}
|
156
titles/mai2/templates/events/mai2_events.jinja
Normal file
156
titles/mai2/templates/events/mai2_events.jinja
Normal file
@ -0,0 +1,156 @@
|
||||
{% extends "core/templates/index.jinja" %}
|
||||
{% block content %}
|
||||
<h1>Events</h1>
|
||||
<form id="verForm" method="POST" action="/game/mai2/events/version.change">
|
||||
<select id="version" name="version" onchange="updateVer()" form="verForm">
|
||||
{% for ver in range(version_list|length) %}
|
||||
<option value="{{ver}}">{{ version_list[ver] }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</form>
|
||||
<table class="table table-dark table-striped-columns" id="tbl_events">
|
||||
<caption>Viewing all events</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Version</th>
|
||||
<th>Event ID</th>
|
||||
<th>Event Type</th>
|
||||
<th>Name</th>
|
||||
<th>Start Date</th>
|
||||
<th>Enabled</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% if events is not defined or events|length == 0 %}
|
||||
<tr>
|
||||
<td colspan="11" style="text-align:center"><i>No Events</i></td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
<div id="div_tbl_ctrl">
|
||||
<select id="sel_per_page" onchange="update_tbl()">
|
||||
<option value="10" selected>10</option>
|
||||
<option value="25">25</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
|
||||
<button class="btn btn-primary" id="btn_prev" disabled onclick="chg_page(-1)"><<</button>
|
||||
<button class="btn btn-primary" id="btn_next" onclick="chg_page(1)">>></button>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
{% if events is defined %}
|
||||
const TBL_DATA = {{events}};
|
||||
{% else %}
|
||||
const TBL_DATA = [];
|
||||
{% endif %}
|
||||
|
||||
document.getElementById("version").value = {{ sesh.maimai_version }};
|
||||
|
||||
var per_page = 0;
|
||||
var page = 0;
|
||||
|
||||
function updateVer() {
|
||||
var sel = document.getElementById("version");
|
||||
var frm = document.getElementById("verForm");
|
||||
|
||||
if (sel.value == {{ sesh.maimai_version }}) {
|
||||
return;
|
||||
}
|
||||
|
||||
frm.submit();
|
||||
}
|
||||
|
||||
function update_tbl() {
|
||||
if (TBL_DATA.length == 0) { return; }
|
||||
var tbl = document.getElementById("tbl_events");
|
||||
|
||||
for (var i = 0; i < per_page; i++) {
|
||||
try{
|
||||
tbl.deleteRow(1);
|
||||
} catch {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
per_page = document.getElementById("sel_per_page").value;
|
||||
|
||||
if (per_page >= TBL_DATA.length) {
|
||||
page = 0;
|
||||
document.getElementById("btn_next").disabled = true;
|
||||
document.getElementById("btn_prev").disabled = true;
|
||||
}
|
||||
|
||||
for (var i = 0; i < per_page; i++) {
|
||||
let off = (page * per_page) + i;
|
||||
if (off >= TBL_DATA.length) {
|
||||
if (page != 0) {
|
||||
document.getElementById("btn_next").disabled = true;
|
||||
document.getElementById("btn_prev").disabled = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var data = TBL_DATA[off];
|
||||
var row = tbl.insertRow(i + 1);
|
||||
|
||||
var cell_id = row.insertCell(0);
|
||||
cell_id.innerHTML = data.id;
|
||||
|
||||
var cell_ver = row.insertCell(1);
|
||||
cell_ver.innerHTML = data.version;
|
||||
|
||||
var cell_evtid = row.insertCell(2);
|
||||
cell_evtid.innerHTML = data.eventId;
|
||||
|
||||
var cell_evttype = row.insertCell(3);
|
||||
cell_evttype.innerHTML = data.eventType;
|
||||
|
||||
var cell_name = row.insertCell(4);
|
||||
cell_name.innerHTML = data.name;
|
||||
|
||||
var cell_date = row.insertCell(5);
|
||||
cell_date.innerHTML = data.startDate;
|
||||
|
||||
var call_enabled = row.insertCell(6);
|
||||
if (data.enabled === "true")
|
||||
call_enabled.innerHTML = "✔"
|
||||
else
|
||||
call_enabled.innerHTML = "✖"
|
||||
|
||||
var cell_action = row.insertCell(7);
|
||||
cell_action.innerHTML = "<a href=/game/mai2/events/" + data.id +"><button class='btn btn-primary'>🖉</button></a>"
|
||||
}
|
||||
}
|
||||
|
||||
function chg_page(num) {
|
||||
var max_page = TBL_DATA.length / per_page;
|
||||
console.log(max_page);
|
||||
page = page + num;
|
||||
|
||||
|
||||
if (page > max_page && max_page >= 1) {
|
||||
page = max_page;
|
||||
document.getElementById("btn_next").disabled = true;
|
||||
document.getElementById("btn_prev").disabled = false;
|
||||
return;
|
||||
} else if (page < 0) {
|
||||
page = 0;
|
||||
document.getElementById("btn_next").disabled = false;
|
||||
document.getElementById("btn_prev").disabled = true;
|
||||
return;
|
||||
} else if (page == 0) {
|
||||
document.getElementById("btn_next").disabled = false;
|
||||
document.getElementById("btn_prev").disabled = true;
|
||||
} else {
|
||||
document.getElementById("btn_next").disabled = false;
|
||||
document.getElementById("btn_prev").disabled = false;
|
||||
}
|
||||
|
||||
update_tbl();
|
||||
}
|
||||
|
||||
update_tbl();
|
||||
</script>
|
||||
{% endblock content %}
|
@ -3,6 +3,9 @@
|
||||
<ul class="mai2-navi">
|
||||
<li><a class="nav-link" href="/game/mai2/">PROFILE</a></li>
|
||||
<li><a class="nav-link" href="/game/mai2/playlog/">RECORD</a></li>
|
||||
{% if sesh is defined and sesh is not none and "{:08b}".format(sesh.permissions)[4] == "1" %}
|
||||
<li><a class="nav-link" href="/game/mai2/events/">EVENTS</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
<script>
|
||||
@ -12,6 +15,8 @@
|
||||
$('.nav-link[href="/game/mai2/"]').addClass('active');
|
||||
} else if (currentPath.startsWith('/game/mai2/playlog/')) {
|
||||
$('.nav-link[href="/game/mai2/playlog/"]').addClass('active');
|
||||
}
|
||||
} {% if sesh is defined and sesh is not none and "{:08b}".format(sesh.permissions)[4] == "1" %}else if (currentPath.startsWith('/game/mai2/events/')) {
|
||||
$('.nav-link[href="/game/mai2/events/"]').addClass('active');
|
||||
} {% endif %}
|
||||
});
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user