Merge pull request 'ONGEKI Rival Functionality' (#36) from 2TT/artemis:develop into develop
Reviewed-on: https://gitea.tendokyu.moe/Hay1tsme/artemis/pulls/36
This commit is contained in:
commit
91791813dc
@ -21,6 +21,7 @@ class IUserSession(Interface):
|
||||
userId = Attribute("User's ID")
|
||||
current_ip = Attribute("User's current ip address")
|
||||
permissions = Attribute("User's permission level")
|
||||
ongeki_version = Attribute("User's selected Ongeki Version")
|
||||
|
||||
class PermissionOffset(Enum):
|
||||
USER = 0 # Regular user
|
||||
@ -36,6 +37,7 @@ class UserSession(object):
|
||||
self.userId = 0
|
||||
self.current_ip = "0.0.0.0"
|
||||
self.permissions = 0
|
||||
self.ongeki_version = 7
|
||||
|
||||
|
||||
class FrontendServlet(resource.Resource):
|
||||
|
@ -4,6 +4,7 @@
|
||||
<title>{{ title }}</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
|
||||
<style>
|
||||
html {
|
||||
background-color: #181a1b !important;
|
||||
@ -77,6 +78,9 @@
|
||||
margin-bottom: 10px;
|
||||
width: 15%;
|
||||
}
|
||||
.modal-content {
|
||||
background-color: #181a1b;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -2,9 +2,11 @@ from titles.ongeki.index import OngekiServlet
|
||||
from titles.ongeki.const import OngekiConstants
|
||||
from titles.ongeki.database import OngekiData
|
||||
from titles.ongeki.read import OngekiReader
|
||||
from titles.ongeki.frontend import OngekiFrontend
|
||||
|
||||
index = OngekiServlet
|
||||
database = OngekiData
|
||||
reader = OngekiReader
|
||||
frontend = OngekiFrontend
|
||||
game_codes = [OngekiConstants.GAME_CODE]
|
||||
current_schema_version = 5
|
||||
|
@ -978,35 +978,38 @@ class OngekiBase:
|
||||
"""
|
||||
Added in Bright
|
||||
"""
|
||||
rival_list = self.data.profile.get_rivals(data["userId"])
|
||||
if rival_list is None or len(rival_list) < 1:
|
||||
|
||||
rival_list = []
|
||||
user_rivals = self.data.profile.get_rivals(data["userId"])
|
||||
for rival in user_rivals:
|
||||
tmp = {}
|
||||
tmp["rivalUserId"] = rival[0]
|
||||
rival_list.append(tmp)
|
||||
|
||||
if user_rivals is None or len(rival_list) < 1:
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"length": 0,
|
||||
"userRivalList": [],
|
||||
}
|
||||
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"length": len(rival_list),
|
||||
"userRivalList": rival_list._asdict(),
|
||||
"userRivalList": rival_list,
|
||||
}
|
||||
|
||||
def handle_get_user_rival_data_api_reqiest(self, data: Dict) -> Dict:
|
||||
def handle_get_user_rival_data_api_request(self, data: Dict) -> Dict:
|
||||
"""
|
||||
Added in Bright
|
||||
"""
|
||||
rivals = []
|
||||
|
||||
for rival in data["userRivalList"]:
|
||||
name = self.data.profile.get_profile_name(
|
||||
rival["rivalUserId"], self.version
|
||||
)
|
||||
if name is None:
|
||||
continue
|
||||
|
||||
rivals.append({"rivalUserId": rival["rival"], "rivalUserName": name})
|
||||
|
||||
rivals.append({"rivalUserId": rival["rivalUserId"], "rivalUserName": name})
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"length": len(rivals),
|
||||
@ -1027,7 +1030,6 @@ class OngekiBase:
|
||||
for song in music["userMusicList"]:
|
||||
song["userRivalMusicDetailList"] = song["userMusicDetailList"]
|
||||
song.pop("userMusicDetailList")
|
||||
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"rivalUserId": rival_id,
|
||||
|
87
titles/ongeki/frontend.py
Normal file
87
titles/ongeki/frontend.py
Normal file
@ -0,0 +1,87 @@
|
||||
import yaml
|
||||
import jinja2
|
||||
from twisted.web.http import Request
|
||||
from os import path
|
||||
from twisted.web.util import redirectTo
|
||||
from twisted.web.server import Session
|
||||
|
||||
from core.frontend import FE_Base, IUserSession
|
||||
from core.config import CoreConfig
|
||||
|
||||
from titles.ongeki.config import OngekiConfig
|
||||
from titles.ongeki.const import OngekiConstants
|
||||
from titles.ongeki.database import OngekiData
|
||||
from titles.ongeki.base import OngekiBase
|
||||
|
||||
|
||||
class OngekiFrontend(FE_Base):
|
||||
def __init__(
|
||||
self, cfg: CoreConfig, environment: jinja2.Environment, cfg_dir: str
|
||||
) -> None:
|
||||
super().__init__(cfg, environment)
|
||||
self.data = OngekiData(cfg)
|
||||
self.game_cfg = OngekiConfig()
|
||||
if path.exists(f"{cfg_dir}/{OngekiConstants.CONFIG_NAME}"):
|
||||
self.game_cfg.update(
|
||||
yaml.safe_load(open(f"{cfg_dir}/{OngekiConstants.CONFIG_NAME}"))
|
||||
)
|
||||
self.nav_name = "O.N.G.E.K.I."
|
||||
self.version_list = OngekiConstants.VERSION_NAMES
|
||||
|
||||
def render_GET(self, request: Request) -> bytes:
|
||||
template = self.environment.get_template(
|
||||
"titles/ongeki/frontend/ongeki_index.jinja"
|
||||
)
|
||||
sesh: Session = request.getSession()
|
||||
usr_sesh = IUserSession(sesh)
|
||||
self.version = usr_sesh.ongeki_version
|
||||
if getattr(usr_sesh, "userId", 0) != 0:
|
||||
profile_data =self.data.profile.get_profile_data(usr_sesh.userId, self.version)
|
||||
rival_list = self.data.profile.get_rivals(usr_sesh.userId)
|
||||
rival_data = {
|
||||
"userRivalList": rival_list,
|
||||
"userId": usr_sesh.userId
|
||||
}
|
||||
rival_info = OngekiBase.handle_get_user_rival_data_api_request(self, rival_data)
|
||||
|
||||
return template.render(
|
||||
data=self.data.profile,
|
||||
title=f"{self.core_config.server.name} | {self.nav_name}",
|
||||
game_list=self.environment.globals["game_list"],
|
||||
gachas=self.game_cfg.gachas.enabled_gachas,
|
||||
profile_data=profile_data,
|
||||
rival_info=rival_info["userRivalDataList"],
|
||||
version_list=self.version_list,
|
||||
version=self.version,
|
||||
sesh=vars(usr_sesh)
|
||||
).encode("utf-16")
|
||||
else:
|
||||
return redirectTo(b"/gate/", request)
|
||||
|
||||
def render_POST(self, request: Request):
|
||||
uri = request.uri.decode()
|
||||
sesh: Session = request.getSession()
|
||||
usr_sesh = IUserSession(sesh)
|
||||
if hasattr(usr_sesh, "userId"):
|
||||
if uri == "/game/ongeki/rival.add":
|
||||
rival_id = request.args[b"rivalUserId"][0].decode()
|
||||
self.data.profile.put_rival(usr_sesh.userId, rival_id)
|
||||
# self.logger.info(f"{usr_sesh.userId} added a rival")
|
||||
return redirectTo(b"/game/ongeki/", request)
|
||||
|
||||
elif uri == "/game/ongeki/rival.delete":
|
||||
rival_id = request.args[b"rivalUserId"][0].decode()
|
||||
self.data.profile.delete_rival(usr_sesh.userId, rival_id)
|
||||
# self.logger.info(f"{response}")
|
||||
return redirectTo(b"/game/ongeki/", request)
|
||||
|
||||
elif uri == "/game/ongeki/version.change":
|
||||
ongeki_version=request.args[b"version"][0].decode()
|
||||
if(ongeki_version.isdigit()):
|
||||
usr_sesh.ongeki_version=int(ongeki_version)
|
||||
return redirectTo(b"/game/ongeki/", request)
|
||||
|
||||
else:
|
||||
return b"Something went wrong"
|
||||
else:
|
||||
return b"User is not logged in"
|
24
titles/ongeki/frontend/js/ongeki_scripts.js
Normal file
24
titles/ongeki/frontend/js/ongeki_scripts.js
Normal file
@ -0,0 +1,24 @@
|
||||
function deleteRival(rivalUserId){
|
||||
|
||||
$(document).ready(function () {
|
||||
$.post("/game/ongeki/rival.delete",
|
||||
{
|
||||
rivalUserId
|
||||
},
|
||||
function(data,status){
|
||||
window.location.replace("/game/ongeki/")
|
||||
})
|
||||
});
|
||||
}
|
||||
function changeVersion(sel){
|
||||
|
||||
$(document).ready(function () {
|
||||
$.post("/game/ongeki/version.change",
|
||||
{
|
||||
version: sel.value
|
||||
},
|
||||
function(data,status){
|
||||
window.location.replace("/game/ongeki/")
|
||||
})
|
||||
});
|
||||
}
|
83
titles/ongeki/frontend/ongeki_index.jinja
Normal file
83
titles/ongeki/frontend/ongeki_index.jinja
Normal file
@ -0,0 +1,83 @@
|
||||
{% extends "core/frontend/index.jinja" %}
|
||||
{% block content %}
|
||||
|
||||
{% if sesh is defined and sesh["userId"] > 0 %}
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<h2> Profile </h2>
|
||||
<h3>Version:
|
||||
<select name="version" id="version" onChange="changeVersion(this)">
|
||||
{% for ver in version_list %}
|
||||
<option value={{loop.index0}} {{ "selected" if loop.index0==version else "" }} >{{ver}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</h3>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h2> Name: {{ profile_data.userName if profile_data.userName is defined else "Profile not found" }}</h2>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4> ID: {{ profile_data.user if profile_data.user is defined else 'Profile not found' }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<h2> Rivals <button class="btn btn-success" data-bs-toggle="modal" data-bs-target="#rival_add">Add</button></h2>
|
||||
</div>
|
||||
<div class="row">
|
||||
<table class="table table-dark table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for rival in rival_info%}
|
||||
<tr id="{{rival.rivalUserId}}">
|
||||
<td>{{rival.rivalUserId}}</td>
|
||||
<td>{{rival.rivalUserName}}</td>
|
||||
<td><button class="btn-danger btn btn-sm" onclick="deleteRival({{rival.rivalUserId}})">Delete</button></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal fade" id="rival_add" tabindex="-1" aria-labelledby="card_add_label" data-bs-theme="dark" aria-hidden="true">
|
||||
<form id="rival" action="/game/ongeki/rival.add" method="post">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Modal title</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Note:<br>
|
||||
Please use the ID show next to your name in the profile page.
|
||||
<br>
|
||||
<label for="rivalUserId">ID: </label><input form="rival" id="rivalUserId" name="rivalUserId" maxlength="5" type="number" required>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<input type=submit class="btn btn-primary" type="button" form="rival" value="Add">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
{% include 'titles/ongeki/frontend/js/ongeki_scripts.js' %}
|
||||
</script>
|
||||
{% else %}
|
||||
<h2>Not Currently Logged In</h2>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
@ -3,7 +3,7 @@ from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, an
|
||||
from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON, BigInteger
|
||||
from sqlalchemy.engine.base import Connection
|
||||
from sqlalchemy.schema import ForeignKey
|
||||
from sqlalchemy.sql import func, select
|
||||
from sqlalchemy.sql import func, select, delete
|
||||
from sqlalchemy.engine import Row
|
||||
from sqlalchemy.dialects.mysql import insert
|
||||
|
||||
@ -269,7 +269,7 @@ class OngekiProfileData(BaseData):
|
||||
return None
|
||||
|
||||
return row["userName"]
|
||||
|
||||
|
||||
def get_profile_preview(self, aime_id: int, version: int) -> Optional[Row]:
|
||||
sql = (
|
||||
select([profile, option])
|
||||
@ -499,7 +499,7 @@ class OngekiProfileData(BaseData):
|
||||
def put_rival(self, aime_id: int, rival_id: int) -> Optional[int]:
|
||||
sql = insert(rival).values(user=aime_id, rivalUserId=rival_id)
|
||||
|
||||
conflict = sql.on_duplicate_key_update(rival=rival_id)
|
||||
conflict = sql.on_duplicate_key_update(rivalUserId=rival_id)
|
||||
|
||||
result = self.execute(conflict)
|
||||
if result is None:
|
||||
@ -508,3 +508,10 @@ class OngekiProfileData(BaseData):
|
||||
)
|
||||
return None
|
||||
return result.lastrowid
|
||||
def delete_rival(self, aime_id: int, rival_id: int) -> Optional[int]:
|
||||
sql = delete(rival).where(rival.c.user==aime_id, rival.c.rivalUserId==rival_id)
|
||||
result = self.execute(sql)
|
||||
if result is None:
|
||||
self.logger.error(f"delete_rival: failed to delete! aime_id: {aime_id}, rival_id: {rival_id}")
|
||||
else:
|
||||
return result.rowcount
|
Loading…
Reference in New Issue
Block a user