wip: index & mapnames

This commit is contained in:
2023-06-10 18:21:30 +02:00
parent b90ae05505
commit 34ca33f71a
5 changed files with 99 additions and 41 deletions

View File

@@ -27,6 +27,30 @@ class Map(db.Model):
map_uid = Column(String, primary_key=True) map_uid = Column(String, primary_key=True)
mapname = Column(String) mapname = Column(String)
def get_best_replay(self):
q = db.session.query(ParsedReplay).filter(ParsedReplay.map_uid == self.map_uid)
r = q.order_by(asc(ParsedReplay.race_time)).first()
return r
def get_best_replay_for_player(self, player):
q = db.session.query(ParsedReplay).filter(ParsedReplay.map_uid == self.map_uid)
r = q.filter(or_(ParsedReplay.uploader == player, ParsedReplay.login == player)).first()
return r
def get_best_replay_repr(self):
r = self.get_best_replay()
if not r:
return "-"
return str(r)
def get_best_replay_age(self):
parsed = datetime.datetime.fromisoformat(self.get_best_replay().upload_dt)
delta = datetime.datetime.now() - parsed
return delta.days
class ParsedReplay(db.Model): class ParsedReplay(db.Model):
__tablename__ = "replays" __tablename__ = "replays"
@@ -56,9 +80,9 @@ class ParsedReplay(db.Model):
return t_string[:-4] return t_string[:-4]
def __repr__(self): def __repr__(self):
return "{time} on {map_n} by {login}/{uploader}".format( return "{time} on {map_n} by {login}".format(
time=self.get_human_readable_time(), time=self.get_human_readable_time(),
map_n=self.guess_map(), login=self.login, uploader=self.uploader) map_n=self.guess_map(), login=self.login)
def to_dict(self): def to_dict(self):
d = dict() d = dict()
@@ -87,10 +111,10 @@ class DataTable():
# oder variable for use with sqlalchemy # oder variable for use with sqlalchemy
if self.orderAsc: if self.orderAsc:
self.orderAscDbClass = sqlalchemy.asc self.orderAscDbClass = sqlalchemy.asc
self.orderAscDbClassReverse = sqlalchemy.desc self.orderAscDbClassReverse = sqlalchemy.asc
else: else:
self.orderAscDbClass = sqlalchemy.desc self.orderAscDbClass = sqlalchemy.desc
self.orderAscDbClassReverse = sqlalchemy.asc self.orderAscDbClassReverse = sqlalchemy.desc
def __build(self, results, total, filtered): def __build(self, results, total, filtered):
@@ -170,7 +194,8 @@ def replay_from_path(fullpath, uploader=None):
race_time=ghost.race_time, race_time=ghost.race_time,
uploader=uploader, uploader=uploader,
filepath=fullpath, filepath=fullpath,
map_uid=ghost.uid, #map_uid=ghost.uid,
map_uid=os.path.basename(fullpath).split("_")[1].split(".Replay")[0],
ghost_id=ghost.id, ghost_id=ghost.id,
login=ghost.login, login=ghost.login,
upload_dt=datetime.datetime.now().isoformat(), upload_dt=datetime.datetime.now().isoformat(),
@@ -183,25 +208,24 @@ def replay_from_path(fullpath, uploader=None):
return replay return replay
@app.route("/map") @app.route("/map-info")
def list(): def list():
# TODO list maps by mapnames
# TODO list replays by mapnames
# TODO list by user
# TODO show all/show only best
header_col = ["Player", "Time", "Date", "Replay"] header_col = ["Player", "Time", "Date", "Replay"]
map_uid = flask.request.args.get("map_uid") map_uid = flask.request.args.get("map_uid")
return flask.render_template("index.html", header_col=header_col, map_uid=map_uid) return flask.render_template("map-info.html", header_col=header_col, map_uid=map_uid)
@app.route("/") @app.route("/")
def mapnames(): def mapnames():
# TODO list by user
maps = db.session.query(Map).order_by(asc(Map.mapname)).all()
return flask.render_template("index.html", maps=maps)
@app.route("/data-source<path:path>", methods=["POST"]) @app.route("/data-source/<path:map_uid>", methods=["POST"])
def source(): def source(map_uid):
# path = map_uid # path = map_uid
dt = DataTable(flask.request.form.to_dict(), ["login", "race_time", "upload_dt", "filepath" ]) dt = DataTable(flask.request.form.to_dict(), ["login", "race_time", "upload_dt", "filepath" ])
jsonDict = dt.get(path) jsonDict = dt.get(map_uid=map_uid)
return flask.Response(json.dumps(jsonDict), 200, mimetype='application/json') return flask.Response(json.dumps(jsonDict), 200, mimetype='application/json')
@app.route("/upload", methods = ['GET', 'POST']) @app.route("/upload", methods = ['GET', 'POST'])

View File

@@ -16,7 +16,7 @@
dt = $('#tableMain').DataTable({ dt = $('#tableMain').DataTable({
serverSide: true, serverSide: true,
ajax: { ajax: {
url: '/data-source', url: '/data-source/{{ map_uid }}',
type: 'POST' type: 'POST'
}, },
"columnDefs": [ "columnDefs": [

28
templates/head.html Normal file
View File

@@ -0,0 +1,28 @@
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="Image factory providing automatically resized and re-encoded images.">
<meta name="author" content="Yannik Schmidt">
<meta name="title" content="TM Replays">
<meta property="og:type" content="website" />
<meta property="og:title" content="Trackmania Replay Server" />
<meta property="og:description" content="TM Replay Server developed by Yannik Schmidt" />
<meta property="og:url" content="/" />
<link rel="shortcut icon" href="/defaultFavicon.ico">
<!-- Bootstrap core JS -->
<script src="https://cdn.atlantishq.de/js/jquery.min.js"></script>
<!-- Bootstrap core CSS -->
<link href="https://cdn.atlantishq.de/fontawesome/css/all.css" rel="stylesheet">
<link href="https://cdn.atlantishq.de/css/bootstrap.min.css" rel="stylesheet">
<script defer src="https://cdn.atlantishq.de/js/bootstrap.min.js"></script>
<script defer src="https://cdn.atlantishq.de/js/addons/datatables.min.js"></script>
<!-- mdb -->
<link href="https://cdn.atlantishq.de/css/mdb.min.css" rel="stylesheet">
<script defer src="https://cdn.atlantishq.de/js/mdb.min.js"></script>
</head>

31
templates/index.html Normal file
View File

@@ -0,0 +1,31 @@
<head>
{% include "head.html" %}
</head>
<body>
<table>
<thead>
<tr>
<th class="px-2">Map</th>
{% if player %}
<th class="px-2">Personal Best</th>
{% endif %}
<th class="px-2">Record</th>
<th class="px-2">Record Age</th>
</tr>
</thead>
<tbody>
{% for map in maps %}
<tr>
<td class="px-2">
<a href="/map-info?map_uid={{ map.map_uid }}">{{ map.mapname }}</a>
</td>
{% if player %}
<td class="px-2">{{ map.get_best_for_player(player) }}</td>
{% endif %}
<td class="px-2">{{ map.get_best_replay_repr() }}</td>
<td class="px-2">{{ map.get_best_replay_age() }} days</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>

View File

@@ -1,30 +1,5 @@
<head> <head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> {% include "head.html" %}
<meta name="description" content="Image factory providing automatically resized and re-encoded images.">
<meta name="author" content="Yannik Schmidt">
<meta name="title" content="TM Replays">
<meta property="og:type" content="website" />
<meta property="og:title" content="Trackmania Replay Server" />
<meta property="og:description" content="TM Replay Server developed by Yannik Schmidt" />
<meta property="og:url" content="/" />
<link rel="shortcut icon" href="/defaultFavicon.ico">
<!-- Bootstrap core JS -->
<script src="https://cdn.atlantishq.de/js/jquery.min.js"></script>
<!-- Bootstrap core CSS -->
<link href="https://cdn.atlantishq.de/fontawesome/css/all.css" rel="stylesheet">
<link href="https://cdn.atlantishq.de/css/bootstrap.min.css" rel="stylesheet">
<script defer src="https://cdn.atlantishq.de/js/bootstrap.min.js"></script>
<script defer src="https://cdn.atlantishq.de/js/addons/datatables.min.js"></script>
<!-- mdb -->
<link href="https://cdn.atlantishq.de/css/mdb.min.css" rel="stylesheet">
<script defer src="https://cdn.atlantishq.de/js/mdb.min.js"></script>
</head> </head>
<body> <body>
{% include "datatable.html" %} {% include "datatable.html" %}