From 20634c3af10814bcb3bb1c5291725f70ab3b4c3c Mon Sep 17 00:00:00 2001 From: Ant Zucaro Date: Sun, 30 Oct 2016 13:31:22 -0400 Subject: [PATCH] Format all code in the models package. --- xonstat/models/__init__.py | 10 +++ xonstat/models/game.py | 126 ++++++++++++++++++++++++---------- xonstat/models/main.py | 38 ++++++++--- xonstat/models/map.py | 62 ++++++++++------- xonstat/models/player.py | 136 ++++++++++++++++++++++++++++--------- xonstat/models/server.py | 18 ++++- 6 files changed, 285 insertions(+), 105 deletions(-) diff --git a/xonstat/models/__init__.py b/xonstat/models/__init__.py index a077c81..884ba05 100644 --- a/xonstat/models/__init__.py +++ b/xonstat/models/__init__.py @@ -1,3 +1,7 @@ +""" +Model initialization and mapping. +""" + from sqlalchemy import MetaData from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import scoped_session, sessionmaker, mapper @@ -13,6 +17,12 @@ Base = declarative_base() def initialize_db(engine=None): + """ + Initialize the database using reflection. + + :param engine: The SQLAlchemy engine instance to bind. + :return: None + """ DBSession.configure(bind=engine) Base.metadata.bind = engine diff --git a/xonstat/models/game.py b/xonstat/models/game.py index 2462045..370d91f 100644 --- a/xonstat/models/game.py +++ b/xonstat/models/game.py @@ -1,9 +1,17 @@ +""" +Models related to games. +""" + from calendar import timegm from xonstat.util import pretty_date, strip_colors, html_colors class Game(object): + """ + An individual game. + """ + def __init__(self, game_id=None, start_dt=None, game_type_cd=None, server_id=None, map_id=None, winner=None): self.game_id = game_id @@ -14,11 +22,16 @@ class Game(object): self.winner = winner def __repr__(self): - return "" % (self.game_id, self.start_dt, self.game_type_cd, self.server_id) + return ("" + .format(self.game_id, self.start_dt, self.game_type_cd, self.server_id)) def to_dict(self): - return {'game_id':self.game_id, 'start':self.start_dt.strftime('%Y-%m-%dT%H:%M:%SZ'), - 'game_type_cd':self.game_type_cd, 'server_id':self.server_id} + return { + 'game_id': self.game_id, + 'start': self.start_dt.strftime('%Y-%m-%dT%H:%M:%SZ'), + 'game_type_cd': self.game_type_cd, + 'server_id': self.server_id + } def fuzzy_date(self): return pretty_date(self.start_dt) @@ -28,17 +41,27 @@ class Game(object): class PlayerGameStat(object): + """ + The individual statistics a player has gained/lost during a game. + """ + def __init__(self, player_game_stat_id=None, create_dt=None): self.player_game_stat_id = player_game_stat_id self.create_dt = create_dt def __repr__(self): - return "" % (self.player_id, self.game_id, self.create_dt) + return "".format(self.player_id, self.game_id, self.create_dt) def to_dict(self): - return {'player_id':self.player_id, 'game_id':self.game_id, - 'create_dt':self.create_dt.strftime('%Y-%m-%dT%H:%M:%SZ'), - 'alivetime':self.alivetime, 'rank':self.rank, 'score':self.score, 'team':self.team} + return { + 'player_id': self.player_id, + 'game_id': self.game_id, + 'create_dt': self.create_dt.strftime('%Y-%m-%dT%H:%M:%SZ'), + 'alivetime': self.alivetime, + 'rank': self.rank, + 'score': self.score, + 'team': self.team + } def nick_stripped(self): if self.nick is None: @@ -64,6 +87,10 @@ class PlayerGameStat(object): class PlayerWeaponStat(object): + """ + The metrics for a single weapon in a game for a player. + """ + def __init__(self, player_id=None, game_id=None, weapon_cd=None): self.player_id = player_id self.game_id = game_id @@ -75,41 +102,47 @@ class PlayerWeaponStat(object): self.frags = 0 def __repr__(self): - return "" % (self.player_weapon_stats_id, self.player_id, self.game_id) + return ("" + .format(self.player_weapon_stats_id, self.player_id, self.game_id)) def to_dict(self): return { - 'weapon_cd':self.weapon_cd, - 'player_weapon_stats_id':self.player_weapon_stats_id, - 'player_id':self.player_id, - 'game_id':self.game_id, - 'fired':self.fired, - 'max':self.max, - 'hit':self.hit, - 'actual':self.actual, - 'frags':self.frags, + 'weapon_cd': self.weapon_cd, + 'player_weapon_stats_id': self.player_weapon_stats_id, + 'player_id': self.player_id, + 'game_id': self.game_id, + 'fired': self.fired, + 'max': self.max, + 'hit': self.hit, + 'actual': self.actual, + 'frags': self.frags, } class TeamGameStat(object): + """ + Team level metrics. + """ + def __init__(self, team_game_stat_id=None, create_dt=None): self.team_game_stat_id = team_game_stat_id self.create_dt = create_dt def __repr__(self): - return "" % (self.team_game_stat_id, self.game_id, self.team) + return "".format(self.team_game_stat_id, self.game_id, self.team) def to_dict(self): return { - 'team_game_stat_id':self.team_game_stat_id, - 'game_id':self.game_id, - 'team':self.team, - 'score':self.score, - 'rounds':self.rounds, - 'caps':self.caps, - 'create_dt':self.create_dt.strftime('%Y-%m-%dT%H:%M:%SZ'), + 'team_game_stat_id': self.team_game_stat_id, + 'game_id': self.game_id, + 'team': self.team, + 'score': self.score, + 'rounds': self.rounds, + 'caps': self.caps, + 'create_dt': self.create_dt.strftime('%Y-%m-%dT%H:%M:%SZ'), } + # TODO: move this function to util def team_html_color(self): if self.team == 5: return "red" @@ -122,29 +155,48 @@ class TeamGameStat(object): class PlayerGameAnticheat(object): - def __init__(self, player_id=None, game_id=None, key=None, - value=None, create_dt=None): - self.player_id = player_id - self.game_id = game_id - self.key = key - self.value = value - self.create_dt = create_dt + """ + Anticheat metrics sent by the server to identify odd patterns. + """ + + def __init__(self, player_id=None, game_id=None, key=None, value=None, create_dt=None): + self.player_id = player_id + self.game_id = game_id + self.key = key + self.value = value + self.create_dt = create_dt def __repr__(self): - return "" % (self.key, self.value) + return "".format(self.key, self.value) class GameType(object): + """ + A particular type of game. + """ + def __repr__(self): - return "" % (self.game_type_cd, self.descr, self.active_ind) + return "".format(self.game_type_cd, self.descr, self.active_ind) def to_dict(self): - return {'game_type_cd':self.game_type_cd, 'name':self.descr, 'active':self.active_ind} + return { + 'game_type_cd': self.game_type_cd, + 'name': self.descr, + 'active': self.active_ind, + } class Weapon(object): + """ + A particular type of weapon. + """ + def __repr__(self): - return "" % (self.weapon_cd, self.descr, self.active_ind) + return "".format(self.weapon_cd, self.descr, self.active_ind) def to_dict(self): - return {'weapon_cd':self.weapon_cd, 'name':self.descr, 'active':self.active_ind} \ No newline at end of file + return { + 'weapon_cd': self.weapon_cd, + 'name': self.descr, + 'active': self.active_ind, + } \ No newline at end of file diff --git a/xonstat/models/main.py b/xonstat/models/main.py index 4f2ab22..fbb0049 100644 --- a/xonstat/models/main.py +++ b/xonstat/models/main.py @@ -1,14 +1,26 @@ +""" +Models related to the main index page. +""" + from xonstat.util import html_colors class SummaryStat(object): + """ + The high level summary line that is shown on the main page. + """ + def __repr__(self): - return "" % (self.total_players, self.total_games, self.total_servers) + return ("" + .format(self.total_players, self.total_games, self.total_servers)) class ActivePlayer(object): - def __init__(self, sort_order=None, player_id=None, nick=None, - alivetime=None): + """ + A record in the "Most Active Players" list. + """ + + def __init__(self, sort_order=None, player_id=None, nick=None, alivetime=None): self.sort_order = sort_order self.player_id = player_id self.nick = nick @@ -18,28 +30,34 @@ class ActivePlayer(object): return html_colors(self.nick) def __repr__(self): - return "" % (self.sort_order, self.player_id) + return "".format(self.sort_order, self.player_id) class ActiveServer(object): - def __init__(self, sort_order=None, server_id=None, server_name=None, - games=None): + """ + A record in the "Most Active Servers" list. + """ + + def __init__(self, sort_order=None, server_id=None, server_name=None, games=None): self.sort_order = sort_order self.server_id = server_id self.server_name = server_name self.games = games def __repr__(self): - return "" % (self.sort_order, self.server_id) + return "".format(self.sort_order, self.server_id) class ActiveMap(object): - def __init__(self, sort_order=None, map_id=None, map_name=None, - games=None): + """ + A record in the "Most Active Maps" list. + """ + + def __init__(self, sort_order=None, map_id=None, map_name=None, games=None): self.sort_order = sort_order self.map_id = map_id self.map_name = map_name self.games = games def __repr__(self): - return "" % (self.sort_order, self.map_id) \ No newline at end of file + return "".format(self.sort_order, self.map_id) diff --git a/xonstat/models/map.py b/xonstat/models/map.py index 3367402..176e23f 100644 --- a/xonstat/models/map.py +++ b/xonstat/models/map.py @@ -1,17 +1,29 @@ +""" +Models related to maps. +""" + from calendar import timegm from xonstat.util import pretty_date, strip_colors, html_colors class Map(object): + """ + A playable map. Roughly equivalent to a pk3 file, but distinguished by name instead. + """ + def __init__(self, name=None): self.name = name def __repr__(self): - return "" % (self.map_id, self.name, self.version) + return "".format(self.map_id, self.name, self.version) def to_dict(self): - return {'map_id':self.map_id, 'name':self.name, 'version':self.version,} + return { + 'map_id': self.map_id, + 'name': self.name, + 'version': self.version, + } def fuzzy_date(self): return pretty_date(self.create_dt) @@ -20,30 +32,34 @@ class Map(object): return timegm(self.create_dt.timetuple()) +# TODO: investigate if this model is truly a model, or really just a query (i.e. namedtuple) class MapCapTime(object): - """Fastest flag capture times per map, assembled from a SQLAlchemy query""" + """ + Fastest flag capture times per map. + """ + def __init__(self, row): - self.fastest_cap = row.fastest_cap - self.create_dt = row.create_dt - self.create_dt_epoch = timegm(row.create_dt.timetuple()) - self.create_dt_fuzzy = pretty_date(row.create_dt) - self.player_id = row.player_id - self.player_nick = row.player_nick + self.fastest_cap = row.fastest_cap + self.create_dt = row.create_dt + self.create_dt_epoch = timegm(row.create_dt.timetuple()) + self.create_dt_fuzzy = pretty_date(row.create_dt) + self.player_id = row.player_id + self.player_nick = row.player_nick self.player_nick_stripped = strip_colors(row.player_nick) - self.player_nick_html = html_colors(row.player_nick) - self.game_id = row.game_id - self.server_id = row.server_id - self.server_name = row.server_name + self.player_nick_html = html_colors(row.player_nick) + self.game_id = row.game_id + self.server_id = row.server_id + self.server_name = row.server_name def to_dict(self): return { - "fastest_cap" : self.fastest_cap.total_seconds(), - "create_dt_epoch" : self.create_dt_epoch, - "create_dt_fuzzy" : self.create_dt_fuzzy, - "player_id" : self.player_id, - "player_nick" : self.player_nick, - "player_nick_stripped" : self.player_nick_stripped, - "game_id" : self.game_id, - "server_id" : self.server_id, - "server_name" : self.server_name, - } \ No newline at end of file + "fastest_cap": self.fastest_cap.total_seconds(), + "create_dt_epoch": self.create_dt_epoch, + "create_dt_fuzzy": self.create_dt_fuzzy, + "player_id": self.player_id, + "player_nick": self.player_nick, + "player_nick_stripped": self.player_nick_stripped, + "game_id": self.game_id, + "server_id": self.server_id, + "server_name": self.server_name, + } diff --git a/xonstat/models/player.py b/xonstat/models/player.py index bc4cb45..0fb18d8 100644 --- a/xonstat/models/player.py +++ b/xonstat/models/player.py @@ -1,9 +1,17 @@ +""" +Models related to players. +""" + from calendar import timegm from xonstat.util import html_colors, strip_colors, pretty_date, qfont_decode class Player(object): + """ + A player, which can represent either a human or a bot. + """ + def nick_html_colors(self, limit=None): if self.nick is None: return "Anonymous Player" @@ -20,49 +28,93 @@ class Player(object): return pretty_date(self.create_dt) def __repr__(self): - return "" % (self.player_id, self.nick.encode('utf-8')) + return "".format(self.player_id, self.nick.encode('utf-8')) def to_dict(self): - return {'player_id':self.player_id, 'nick':self.nick, - 'joined':self.create_dt.strftime('%Y-%m-%dT%H:%M:%SZ'), - 'active_ind':self.active_ind, 'location':self.location, - 'stripped_nick':qfont_decode(self.stripped_nick)} + return { + 'player_id': self.player_id, + 'nick': self.nick, + 'joined': self.create_dt.strftime('%Y-%m-%dT%H:%M:%SZ'), + 'active_ind': self.active_ind, + 'location': self.location, + 'stripped_nick': qfont_decode(self.stripped_nick), + } def epoch(self): return timegm(self.create_dt.timetuple()) +class Achievement(object): + """ + A type of achievement. Referenced implicitly in PlayerAchievement. + """ + + def __repr__(self): + return "".format(self.achievement_cd, self.descr, self.limit) + + def to_dict(self): + return { + 'achievement_cd': self.achievement_cd, + 'name': self.descr, + 'limit':self.limit, + } + + class PlayerAchievement(object): + """ + Achievements a player has earned. + """ + def __repr__(self): - return "" % (self.player_id, self.achievement_cd) + return "".format(self.player_id, self.achievement_cd) def to_dict(self): - return {'player_id':self.player_id, 'achievement_cd':self.achievement_cd} + return { + 'player_id': self.player_id, + 'achievement_cd': self.achievement_cd, + } class Hashkey(object): + """ + A player's identifying key from the d0_blind_id library. + """ + def __init__(self, player_id=None, hashkey=None): self.player_id = player_id self.hashkey = hashkey def __repr__(self): - return "" % (self.player_id, self.hashkey) + return "".format(self.player_id, self.hashkey) def to_dict(self): - return {'player_id':self.player_id, 'hashkey':self.hashkey} + return { + 'player_id': self.player_id, + 'hashkey': self.hashkey + } class PlayerNick(object): + """ + A single nickname a player has used in a game. + """ + def __repr__(self): - return "" % (self.player_id, qfont_decode(self.stripped_nick)) + return "".format(self.player_id, qfont_decode(self.stripped_nick)) def to_dict(self): - return {'player_id':self.player_id, 'name':qfont_decode(self.stripped_nick)} + return { + 'player_id': self.player_id, + 'name': qfont_decode(self.stripped_nick), + } class PlayerElo(object): - def __init__(self, player_id=None, game_type_cd=None, elo=None): + """ + A player's skill for a particular game type, as determined by a modified Elo algorithm. + """ + def __init__(self, player_id=None, game_type_cd=None, elo=None): self.player_id = player_id self.game_type_cd = game_type_cd self.elo = elo @@ -70,13 +122,22 @@ class PlayerElo(object): self.games = 0 def __repr__(self): - return "" % (self.player_id, self.game_type_cd, self.elo, self.games) + return ("" + .format(self.player_id, self.game_type_cd, self.elo, self.games)) def to_dict(self): - return {'player_id':self.player_id, 'game_type_cd':self.game_type_cd, 'elo':self.elo, 'games':self.games} + return { + 'player_id': self.player_id, + 'game_type_cd': self.game_type_cd, + 'elo': self.elo, + 'games': self.games, + } class PlayerRank(object): + """ + A player's rank for a given game type. + """ def nick_html_colors(self, limit=None): if self.nick is None: @@ -85,15 +146,23 @@ class PlayerRank(object): return html_colors(self.nick, limit) def __repr__(self): - return "" % (self.player_id, self.game_type_cd, self.rank) + return ("" + .format(self.player_id, self.game_type_cd, self.rank)) def to_dict(self): - return {'player_id':self.player_id, 'game_type_cd':self.game_type_cd, 'rank':self.rank} + return { + 'player_id': self.player_id, + 'game_type_cd': self.game_type_cd, + 'rank': self.rank + } class PlayerCaptime(object): - def __init__(self, player_id=None, game_id=None, map_id=None, - fastest_cap=None, mod=None): + """ + A flag capture time for a player on a given map. + """ + + def __init__(self, player_id=None, game_id=None, map_id=None, fastest_cap=None, mod=None): self.player_id = player_id self.game_id = game_id self.map_id = map_id @@ -101,8 +170,8 @@ class PlayerCaptime(object): self.mod = mod def __repr__(self): - return "" % (self.player_id, - self.map_id, self.mod) + return ("" + .format(self.player_id, self.map_id, self.mod)) def fuzzy_date(self): return pretty_date(self.create_dt) @@ -112,16 +181,24 @@ class PlayerCaptime(object): class PlayerGroups(object): + """ + An authorization group a player belongs to. Used to control access. + """ + def __init__(self, player_id=None, group_name=None): self.player_id = player_id self.group_name = group_name def __repr__(self): - return "" % (self.player_id, self.group_name) + return "".format(self.player_id, self.group_name) +# TODO: determine if this is a real model (it is very similar to PlayerCaptime from above) class PlayerCapTime(object): - """Fastest flag capture times per player, assembled from a SQLAlchemy query""" + """ + Fastest flag capture times per player. + """ + def __init__(self, row): self.fastest_cap = row.fastest_cap self.create_dt = row.create_dt @@ -144,18 +221,13 @@ class PlayerCapTime(object): "map_name": self.map_name, "server_id": self.server_id, "server_name": self.server_name, - } + } class PlayerMedal(object): - def __repr__(self): - return "" % (self.player_id, - self.place, self.alt) - + """ + A medal a player has earned in a large tournament. + """ -class Achievement(object): def __repr__(self): - return "" % (self.achievement_cd, self.descr, self.limit) - - def to_dict(self): - return {'achievement_cd':self.achievement_cd, 'name':self.descr, 'limit':self.limit} \ No newline at end of file + return "".format(self.player_id, self.place, self.alt) diff --git a/xonstat/models/server.py b/xonstat/models/server.py index 7df45a0..20f8c11 100644 --- a/xonstat/models/server.py +++ b/xonstat/models/server.py @@ -1,3 +1,7 @@ +""" +Models related to servers. +""" + from calendar import timegm from datetime import datetime as dt @@ -5,6 +9,10 @@ from xonstat.util import pretty_date class Server(object): + """ + A Xonotic server, identifiable by name and (when there's a conflict) hashkey. + """ + def __init__(self, name=None, hashkey=None, ip_addr=None): self.name = name self.hashkey = hashkey @@ -12,11 +20,15 @@ class Server(object): self.create_dt = dt.utcnow() def __repr__(self): - return "" % (self.server_id, self.name.encode('utf-8')) + return "".format(self.server_id, self.name.encode('utf-8')) def to_dict(self): - return {'server_id':self.server_id, 'name':self.name, - 'ip_addr':self.ip_addr, 'location':self.location} + return { + 'server_id': self.server_id, + 'name': self.name, + 'ip_addr': self.ip_addr, + 'location': self.location, + } def fuzzy_date(self): return pretty_date(self.create_dt) -- 2.39.2