mirror of
https://github.com/FAUSheppy/open-web-leaderboard.git
synced 2025-12-06 15:11:35 +01:00
implement simplistic round overview
This commit is contained in:
11
Round.py
11
Round.py
@@ -1,5 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
|
import player
|
||||||
|
|
||||||
class Round:
|
class Round:
|
||||||
def __init__(self, dbRow):
|
def __init__(self, dbRow):
|
||||||
@@ -11,9 +12,11 @@ class Round:
|
|||||||
losersParsed = json.loads(losers)
|
losersParsed = json.loads(losers)
|
||||||
|
|
||||||
self.startTime = startTime
|
self.startTime = startTime
|
||||||
self.winners = winners
|
self.winners = [ player.playerFromDict(wp) for wp in winnersParsed ]
|
||||||
self.losers = losers
|
self.losers = [ player.playerFromDict(lp) for lp in losersParsed ]
|
||||||
self.winnerSide = winnerSide
|
self.winnerSide = winnerSide
|
||||||
|
self.duration = datetime.timedelta(seconds=int(duration))
|
||||||
|
|
||||||
if winnerSide == 2:
|
if winnerSide == 2:
|
||||||
self.winnerSideString = "Security"
|
self.winnerSideString = "Security"
|
||||||
self.loserSideString = "Insurgent"
|
self.loserSideString = "Insurgent"
|
||||||
@@ -24,11 +27,11 @@ class Round:
|
|||||||
self.mapName = mapName
|
self.mapName = mapName
|
||||||
else:
|
else:
|
||||||
self.mapName = "unavailiable"
|
self.mapName = "unavailiable"
|
||||||
self.duration = datetime.timedelta(seconds=int(duration))
|
|
||||||
|
self.confidence = int(confidence * 100)
|
||||||
if prediction == 0:
|
if prediction == 0:
|
||||||
self.prediction = self.winnerSideString
|
self.prediction = self.winnerSideString
|
||||||
elif prediction == 1:
|
elif prediction == 1:
|
||||||
self.prediction = self.loserSideString
|
self.prediction = self.loserSideString
|
||||||
else:
|
else:
|
||||||
self.prediction = "Error"
|
self.prediction = "Error"
|
||||||
self.confidence = int(confidence * 100)
|
|
||||||
|
|||||||
36
database.py
36
database.py
@@ -133,3 +133,39 @@ class DatabaseConnection:
|
|||||||
for row in cursor:
|
for row in cursor:
|
||||||
rounds += [Round.Round(row)]
|
rounds += [Round.Round(row)]
|
||||||
return rounds
|
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
|
#!/usr/bin/python3
|
||||||
import flask
|
import flask
|
||||||
|
|
||||||
|
def playerFromDict(d):
|
||||||
|
return PlayerInLeaderboard([d["id"], d["name"], None, 0, 0, 0, 0])
|
||||||
|
|
||||||
class PlayerInLeaderboard:
|
class PlayerInLeaderboard:
|
||||||
def __init__(self, dbRow):
|
def __init__(self, dbRow):
|
||||||
'''Initialize a player object later to be serialized to HTML'''
|
'''Initialize a player object later to be serialized to HTML'''
|
||||||
@@ -19,6 +22,10 @@ class PlayerInLeaderboard:
|
|||||||
self.rank = None
|
self.rank = None
|
||||||
self.lastGame = lastGame
|
self.lastGame = lastGame
|
||||||
|
|
||||||
|
self.muChange = None
|
||||||
|
self.sigmaChange = None
|
||||||
|
self.ratingChangeString = "--"
|
||||||
|
|
||||||
# determine winratio #
|
# determine winratio #
|
||||||
if self.games == 0:
|
if self.games == 0:
|
||||||
self.winratio = "N/A"
|
self.winratio = "N/A"
|
||||||
|
|||||||
17
server.py
17
server.py
@@ -28,7 +28,24 @@ def prettifyMinMaxY(computedMin, computedMax):
|
|||||||
else:
|
else:
|
||||||
return (computedMin - 100, 4000)
|
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-by-timestamp")
|
||||||
|
@app.route("/rounds")
|
||||||
def rounds():
|
def rounds():
|
||||||
'''Show rounds played on the server'''
|
'''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