mirror of
https://github.com/FAUSheppy/open-web-leaderboard.git
synced 2025-12-06 07:01:36 +01:00
implement simplistic round overview
This commit is contained in:
11
Round.py
11
Round.py
@@ -1,5 +1,6 @@
|
||||
import json
|
||||
import datetime
|
||||
import player
|
||||
|
||||
class Round:
|
||||
def __init__(self, dbRow):
|
||||
@@ -11,9 +12,11 @@ class Round:
|
||||
losersParsed = json.loads(losers)
|
||||
|
||||
self.startTime = startTime
|
||||
self.winners = winners
|
||||
self.losers = losers
|
||||
self.winners = [ player.playerFromDict(wp) for wp in winnersParsed ]
|
||||
self.losers = [ player.playerFromDict(lp) for lp in losersParsed ]
|
||||
self.winnerSide = winnerSide
|
||||
self.duration = datetime.timedelta(seconds=int(duration))
|
||||
|
||||
if winnerSide == 2:
|
||||
self.winnerSideString = "Security"
|
||||
self.loserSideString = "Insurgent"
|
||||
@@ -24,11 +27,11 @@ class Round:
|
||||
self.mapName = mapName
|
||||
else:
|
||||
self.mapName = "unavailiable"
|
||||
self.duration = datetime.timedelta(seconds=int(duration))
|
||||
|
||||
self.confidence = int(confidence * 100)
|
||||
if prediction == 0:
|
||||
self.prediction = self.winnerSideString
|
||||
elif prediction == 1:
|
||||
self.prediction = self.loserSideString
|
||||
else:
|
||||
self.prediction = "Error"
|
||||
self.confidence = int(confidence * 100)
|
||||
|
||||
36
database.py
36
database.py
@@ -133,3 +133,39 @@ class DatabaseConnection:
|
||||
for row in cursor:
|
||||
rounds += [Round.Round(row)]
|
||||
return rounds
|
||||
|
||||
def calcRatingChanges(self, roundObj):
|
||||
'''Calculates and sets rating changes in the player objects of this round'''
|
||||
|
||||
cursorHist = self.connHistorical.cursor()
|
||||
for p in roundObj.winners + roundObj.losers:
|
||||
cursorHist.execute('''SELECT mu,sima FROM playerHistoricalData
|
||||
WHERE timestamp < ? AND id = ? LIMIT 1 ''',
|
||||
(roundObj.startTime.timestamp(), p.playerId))
|
||||
tupelPrev = cursorHist.fetchone()
|
||||
cursorHist.execute('''SELECT mu,sima FROM playerHistoricalData
|
||||
WHERE timestamp == ? AND id = ? LIMIT 1''',
|
||||
(roundObj.startTime.timestamp(), p.playerId))
|
||||
tupelAfter = cursorHist.fetchone()
|
||||
if tupelPrev and tupelAfter:
|
||||
muPrev, sigmaPrev = tupelPrev
|
||||
muAfter, sigmaAfter = tupelAfter
|
||||
p.mu = muPrev
|
||||
p.sigma = sigmaPrev
|
||||
p.muChange = muAfter - muPrev
|
||||
p.sigmaChange = sigmaAfter - sigmaPrev
|
||||
p.ratingChangeString = str( ( muAfter-2*sigmaAfter ) - ( muPrev-2*sigmaPrev) )
|
||||
|
||||
return roundObj
|
||||
|
||||
def getRoundByTimestamp(self, timestamp):
|
||||
'''Get a round by it's start time (more or less it primary key)'''
|
||||
|
||||
cursorRounds = self.connRounds.cursor()
|
||||
cursorRounds.execute('''SELECT * from rounds where timestamp = ?''', (timestamp,))
|
||||
row = cursorRounds.fetchone()
|
||||
if not row:
|
||||
return None
|
||||
return Round.Round(row)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#!/usr/bin/python3
|
||||
import flask
|
||||
|
||||
def playerFromDict(d):
|
||||
return PlayerInLeaderboard([d["id"], d["name"], None, 0, 0, 0, 0])
|
||||
|
||||
class PlayerInLeaderboard:
|
||||
def __init__(self, dbRow):
|
||||
'''Initialize a player object later to be serialized to HTML'''
|
||||
@@ -19,6 +22,10 @@ class PlayerInLeaderboard:
|
||||
self.rank = None
|
||||
self.lastGame = lastGame
|
||||
|
||||
self.muChange = None
|
||||
self.sigmaChange = None
|
||||
self.ratingChangeString = "--"
|
||||
|
||||
# determine winratio #
|
||||
if self.games == 0:
|
||||
self.winratio = "N/A"
|
||||
|
||||
17
server.py
17
server.py
@@ -28,7 +28,24 @@ def prettifyMinMaxY(computedMin, computedMax):
|
||||
else:
|
||||
return (computedMin - 100, 4000)
|
||||
|
||||
@app.route("/round-info")
|
||||
def singleRound():
|
||||
'''Display info about a single round itdentified by it's timestamp'''
|
||||
|
||||
timestamp = flask.request.args.get("id")
|
||||
if not timestamp:
|
||||
return ("", 404)
|
||||
db = DatabaseConnection(app.config["DB_PATH"])
|
||||
r = db.getRoundByTimestamp(timestamp)
|
||||
r = db.calcRatingChanges(r)
|
||||
|
||||
if not r:
|
||||
return ("", 404)
|
||||
|
||||
return flask.render_template("single_round.html", r=r)
|
||||
|
||||
@app.route("/rounds-by-timestamp")
|
||||
@app.route("/rounds")
|
||||
def rounds():
|
||||
'''Show rounds played on the server'''
|
||||
|
||||
|
||||
37
templates/single_round.html
Normal file
37
templates/single_round.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Rounds Played</title>
|
||||
<meta name="Description" content="Insurgency games played on the AtlantisHQ">
|
||||
<link rel="stylesheet" type="text/css" href="/static/site.css">
|
||||
<link rel="shortcut icon" href="/static/defaultFavicon.ico">
|
||||
|
||||
<!-- needed for @media-css mofiers -->
|
||||
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css">
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Material Design Bootstrap -->
|
||||
<link href="static/bootstrap/css/mdb.min.css" rel="stylesheet">
|
||||
|
||||
<script src="static/bootstrap/js/jquery.js"></script>
|
||||
<script src="static/bootstrap/js/popper.js"></script>
|
||||
<script src="static/bootstrap/js/bootstrap.js"></script>
|
||||
<script src="static/bootstrap/js/mdb.min.js"></script>
|
||||
|
||||
</head>
|
||||
<body class="bg-special">
|
||||
{% include 'navbar.html' %}
|
||||
<div class="container mt-3 mb-3" role="main">
|
||||
{% for p in r.winners %}
|
||||
<h4>{{ p.name }}{{ p.ratingChangeString }}</h4>
|
||||
{% endfor %}
|
||||
{% for p in r.losers %}
|
||||
<h4>{{ p.name }}{{ p.ratingChangeString }}</h4>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% include 'footer.html' %}
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user