From 7c86b7bd25a2f82a904c5f80155788e40c9210f2 Mon Sep 17 00:00:00 2001 From: Ant Zucaro Date: Fri, 28 Oct 2016 19:55:20 -0400 Subject: [PATCH] Make models a package instead of being a single (huge) module. --- xonstat/batch/badges/gen_badges.py | 15 +- xonstat/batch/badges/playerdata.py | 4 +- xonstat/elo.py | 4 +- xonstat/models.py | 493 ----------------------------- xonstat/models/__init__.py | 75 +++++ xonstat/models/game.py | 150 +++++++++ xonstat/models/main.py | 45 +++ xonstat/models/map.py | 49 +++ xonstat/models/player.py | 161 ++++++++++ xonstat/models/server.py | 25 ++ xonstat/views/admin.py | 8 +- xonstat/views/game.py | 14 +- xonstat/views/helpers.py | 8 +- xonstat/views/main.py | 15 +- xonstat/views/map.py | 11 +- xonstat/views/player.py | 15 +- xonstat/views/search.py | 15 +- xonstat/views/submission.py | 12 +- 18 files changed, 556 insertions(+), 563 deletions(-) delete mode 100644 xonstat/models.py create mode 100644 xonstat/models/__init__.py create mode 100644 xonstat/models/game.py create mode 100644 xonstat/models/main.py create mode 100644 xonstat/models/map.py create mode 100644 xonstat/models/player.py create mode 100644 xonstat/models/server.py diff --git a/xonstat/batch/badges/gen_badges.py b/xonstat/batch/badges/gen_badges.py index d0d6fb2..908aba0 100644 --- a/xonstat/batch/badges/gen_badges.py +++ b/xonstat/batch/badges/gen_badges.py @@ -1,17 +1,14 @@ #-*- coding: utf-8 -*- import sys -from datetime import datetime -import sqlalchemy as sa -import sqlalchemy.sql.functions as func -from sqlalchemy import distinct -from pyramid.paster import bootstrap -from xonstat.models import * -from xonstat.util import datetime_seconds +from datetime import datetime, timedelta -from skin import Skin from playerdata import PlayerData - +from pyramid.paster import bootstrap +from skin import Skin +from sqlalchemy import distinct +from xonstat.models import DBSession, PlayerGameStat, Player, PlayerElo +from xonstat.util import datetime_seconds # maximal number of query results (for testing, set to None to get all) NUM_PLAYERS = None diff --git a/xonstat/batch/badges/playerdata.py b/xonstat/batch/badges/playerdata.py index ed4fca4..b353e26 100644 --- a/xonstat/batch/badges/playerdata.py +++ b/xonstat/batch/badges/playerdata.py @@ -1,6 +1,4 @@ -import sqlalchemy as sa -import sqlalchemy.sql.functions as func -from xonstat.models import * +from xonstat.models import DBSession, Player from xonstat.views.player import get_games_played, get_overall_stats, get_ranks, get_elos diff --git a/xonstat/elo.py b/xonstat/elo.py index f9b289d..01a1e8a 100644 --- a/xonstat/elo.py +++ b/xonstat/elo.py @@ -1,10 +1,8 @@ import datetime import logging import math -import random -import sys -from xonstat.models import * +from xonstat.models import PlayerElo log = logging.getLogger(__name__) diff --git a/xonstat/models.py b/xonstat/models.py deleted file mode 100644 index 56f4260..0000000 --- a/xonstat/models.py +++ /dev/null @@ -1,493 +0,0 @@ -import json -import logging -import math -import sqlalchemy -import sqlalchemy.sql.functions as sfunc -from calendar import timegm -from datetime import datetime as dt -from datetime import timedelta -from sqlalchemy.orm import mapper -from sqlalchemy.orm import scoped_session -from sqlalchemy.orm import sessionmaker -from sqlalchemy.ext.declarative import declarative_base -from xonstat.util import qfont_decode, strip_colors, html_colors, pretty_date - -log = logging.getLogger(__name__) - -DBSession = scoped_session(sessionmaker()) -Base = declarative_base() - -# define objects for all tables -class Player(object): - def nick_html_colors(self, limit=None): - if self.nick is None: - return "Anonymous Player" - else: - return html_colors(self.nick, limit) - - def nick_strip_colors(self): - if self.nick is None: - return "Anonymous Player" - else: - return strip_colors(self.nick) - - def joined_pretty_date(self): - return pretty_date(self.create_dt) - - def __repr__(self): - return "" % (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)} - - def epoch(self): - return timegm(self.create_dt.timetuple()) - - -class GameType(object): - def __repr__(self): - return "" % (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} - - -class Weapon(object): - def __repr__(self): - return "" % (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} - - -class Server(object): - def __init__(self, name=None, hashkey=None, ip_addr=None): - self.name = name - self.hashkey = hashkey - self.ip_addr = ip_addr - self.create_dt = dt.utcnow() - - def __repr__(self): - return "" % (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} - - def fuzzy_date(self): - return pretty_date(self.create_dt) - - def epoch(self): - return timegm(self.create_dt.timetuple()) - - -class Map(object): - def __init__(self, name=None): - self.name = name - - def __repr__(self): - return "" % (self.map_id, self.name, self.version) - - def to_dict(self): - return {'map_id':self.map_id, 'name':self.name, 'version':self.version,} - - def fuzzy_date(self): - return pretty_date(self.create_dt) - - def epoch(self): - return timegm(self.create_dt.timetuple()) - - -class Game(object): - 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 - self.start_dt = start_dt - self.game_type_cd = game_type_cd - self.server_id = server_id - self.map_id = map_id - self.winner = winner - - def __repr__(self): - return "" % (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} - - def fuzzy_date(self): - return pretty_date(self.start_dt) - - def epoch(self): - return timegm(self.start_dt.timetuple()) - - -class PlayerGameStat(object): - 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) - - 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} - - def nick_stripped(self): - if self.nick is None: - return "Anonymous Player" - else: - return strip_colors(self.nick) - - def nick_html_colors(self, limit=None): - if self.nick is None: - return "Anonymous Player" - else: - return html_colors(self.nick, limit) - - def team_html_color(self): - if self.team == 5: - return "red" - if self.team == 14: - return "blue" - if self.team == 13: - return "yellow" - if self.team == 10: - return "pink" - - -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} - - -class PlayerAchievement(object): - def __repr__(self): - return "" % (self.player_id, self.achievement_cd) - - def to_dict(self): - return {'player_id':self.player_id, 'achievement_cd':self.achievement_cd} - - -class PlayerWeaponStat(object): - def __init__(self, player_id=None, game_id=None, weapon_cd=None): - self.player_id = player_id - self.game_id = game_id - self.weapon_cd = weapon_cd - self.fired = 0 - self.max = 0 - self.hit = 0 - self.actual = 0 - self.frags = 0 - - def __repr__(self): - return "" % (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, - } - - -class Hashkey(object): - 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) - - def to_dict(self): - return {'player_id':self.player_id, 'hashkey':self.hashkey} - - -class PlayerNick(object): - def __repr__(self): - return "" % (self.player_id, qfont_decode(self.stripped_nick)) - - def to_dict(self): - 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): - - self.player_id = player_id - self.game_type_cd = game_type_cd - self.elo = elo - self.score = 0 - self.games = 0 - - def __repr__(self): - return "" % (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} - - -class PlayerRank(object): - - def nick_html_colors(self, limit=None): - if self.nick is None: - return "Anonymous Player" - else: - return html_colors(self.nick, limit) - - def __repr__(self): - return "" % (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} - - -class PlayerCaptime(object): - 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 - self.fastest_cap = fastest_cap - self.mod = mod - - def __repr__(self): - return "" % (self.player_id, - self.map_id, self.mod) - - def fuzzy_date(self): - return pretty_date(self.create_dt) - - def epoch(self): - return timegm(self.create_dt.timetuple()) - - -class SummaryStat(object): - def __repr__(self): - return "" % (self.total_players, self.total_games, self.total_servers) - - -class TeamGameStat(object): - 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) - - 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'), - } - - def team_html_color(self): - if self.team == 5: - return "red" - if self.team == 14: - return "blue" - if self.team == 13: - return "yellow" - if self.team == 10: - return "pink" - - -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 - - def __repr__(self): - return "" % (self.key, self.value) - - -class PlayerGroups(object): - 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) - - -class MapCapTime(object): - """Fastest flag capture times per map, assembled from a SQLAlchemy query""" - 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.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 - - 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, - } - - -class PlayerCapTime(object): - """Fastest flag capture times per player, assembled from a SQLAlchemy query""" - 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.game_id = row.game_id - self.map_id = row.map_id - self.map_name = row.map_name - 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, - "game_id":self.game_id, - "map_id": self.map_id, - "map_name": self.map_name, - "server_id": self.server_id, - "server_name": self.server_name, - } - - -class ActivePlayer(object): - 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 - self.alivetime = alivetime - - def nick_html_colors(self): - return html_colors(self.nick) - - def __repr__(self): - return "" % (self.sort_order, self.player_id) - - -class ActiveServer(object): - 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) - - -class ActiveMap(object): - 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) - - -class PlayerMedal(object): - def __repr__(self): - return "" % (self.player_id, - self.place, self.alt) - - -def initialize_db(engine=None): - DBSession.configure(bind=engine) - Base.metadata.bind = engine - Base.metadata.create_all(engine) - MetaData = sqlalchemy.MetaData(bind=engine) - MetaData.reflect() - - # assign all those tables to an object - achievements_table = MetaData.tables['achievements'] - cd_achievement_table = MetaData.tables['cd_achievement'] - cd_game_type_table = MetaData.tables['cd_game_type'] - cd_weapon_table = MetaData.tables['cd_weapon'] - db_version_table = MetaData.tables['db_version'] - games_table = MetaData.tables['games'] - hashkeys_table = MetaData.tables['hashkeys'] - maps_table = MetaData.tables['maps'] - player_game_stats_table = MetaData.tables['player_game_stats'] - players_table = MetaData.tables['players'] - player_weapon_stats_table = MetaData.tables['player_weapon_stats'] - servers_table = MetaData.tables['servers'] - player_nicks_table = MetaData.tables['player_nicks'] - player_elos_table = MetaData.tables['player_elos'] - player_ranks_table = MetaData.tables['player_ranks'] - player_captimes_table = MetaData.tables['player_map_captimes'] - summary_stats_table = MetaData.tables['summary_stats'] - team_game_stats_table = MetaData.tables['team_game_stats'] - player_game_anticheats_table = MetaData.tables['player_game_anticheats'] - player_groups_table = MetaData.tables['player_groups'] - active_players_table = MetaData.tables['active_players_mv'] - active_servers_table = MetaData.tables['active_servers_mv'] - active_maps_table = MetaData.tables['active_maps_mv'] - player_medals_table = MetaData.tables['player_medals'] - - # now map the tables and the objects together - mapper(PlayerAchievement, achievements_table) - mapper(Achievement, cd_achievement_table) - mapper(GameType, cd_game_type_table) - mapper(Weapon, cd_weapon_table) - mapper(Game, games_table) - mapper(Hashkey, hashkeys_table) - mapper(Map, maps_table) - mapper(PlayerGameStat, player_game_stats_table) - mapper(Player, players_table) - mapper(PlayerWeaponStat, player_weapon_stats_table) - mapper(Server, servers_table) - mapper(PlayerNick, player_nicks_table) - mapper(PlayerElo, player_elos_table) - mapper(PlayerRank, player_ranks_table) - mapper(PlayerCaptime, player_captimes_table) - mapper(SummaryStat, summary_stats_table) - mapper(TeamGameStat, team_game_stats_table) - mapper(PlayerGameAnticheat, player_game_anticheats_table) - mapper(PlayerGroups, player_groups_table) - mapper(ActivePlayer, active_players_table) - mapper(ActiveServer, active_servers_table) - mapper(ActiveMap, active_maps_table) - mapper(PlayerMedal, player_medals_table) diff --git a/xonstat/models/__init__.py b/xonstat/models/__init__.py new file mode 100644 index 0000000..a077c81 --- /dev/null +++ b/xonstat/models/__init__.py @@ -0,0 +1,75 @@ +from sqlalchemy import MetaData +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import scoped_session, sessionmaker, mapper + +from xonstat.models.game import * +from xonstat.models.main import * +from xonstat.models.map import * +from xonstat.models.player import * +from xonstat.models.server import * + +DBSession = scoped_session(sessionmaker()) +Base = declarative_base() + + +def initialize_db(engine=None): + DBSession.configure(bind=engine) + + Base.metadata.bind = engine + Base.metadata.create_all(engine) + + # Since the schema is actually defined elsewhere, we use reflection to determine the + # structure of the models instead of specifying them over again in Python. + metadata = MetaData(bind=engine) + metadata.reflect() + + # Assign all the tables to objects + achievements_table = metadata.tables['achievements'] + cd_achievement_table = metadata.tables['cd_achievement'] + cd_game_type_table = metadata.tables['cd_game_type'] + cd_weapon_table = metadata.tables['cd_weapon'] + db_version_table = metadata.tables['db_version'] + games_table = metadata.tables['games'] + hashkeys_table = metadata.tables['hashkeys'] + maps_table = metadata.tables['maps'] + player_game_stats_table = metadata.tables['player_game_stats'] + players_table = metadata.tables['players'] + player_weapon_stats_table = metadata.tables['player_weapon_stats'] + servers_table = metadata.tables['servers'] + player_nicks_table = metadata.tables['player_nicks'] + player_elos_table = metadata.tables['player_elos'] + player_ranks_table = metadata.tables['player_ranks'] + player_captimes_table = metadata.tables['player_map_captimes'] + summary_stats_table = metadata.tables['summary_stats'] + team_game_stats_table = metadata.tables['team_game_stats'] + player_game_anticheats_table = metadata.tables['player_game_anticheats'] + player_groups_table = metadata.tables['player_groups'] + active_players_table = metadata.tables['active_players_mv'] + active_servers_table = metadata.tables['active_servers_mv'] + active_maps_table = metadata.tables['active_maps_mv'] + player_medals_table = metadata.tables['player_medals'] + + # Map the tables and the objects together + mapper(PlayerAchievement, achievements_table) + mapper(Achievement, cd_achievement_table) + mapper(GameType, cd_game_type_table) + mapper(Weapon, cd_weapon_table) + mapper(Game, games_table) + mapper(Hashkey, hashkeys_table) + mapper(Map, maps_table) + mapper(PlayerGameStat, player_game_stats_table) + mapper(Player, players_table) + mapper(PlayerWeaponStat, player_weapon_stats_table) + mapper(Server, servers_table) + mapper(PlayerNick, player_nicks_table) + mapper(PlayerElo, player_elos_table) + mapper(PlayerRank, player_ranks_table) + mapper(PlayerCaptime, player_captimes_table) + mapper(SummaryStat, summary_stats_table) + mapper(TeamGameStat, team_game_stats_table) + mapper(PlayerGameAnticheat, player_game_anticheats_table) + mapper(PlayerGroups, player_groups_table) + mapper(ActivePlayer, active_players_table) + mapper(ActiveServer, active_servers_table) + mapper(ActiveMap, active_maps_table) + mapper(PlayerMedal, player_medals_table) diff --git a/xonstat/models/game.py b/xonstat/models/game.py new file mode 100644 index 0000000..2462045 --- /dev/null +++ b/xonstat/models/game.py @@ -0,0 +1,150 @@ +from calendar import timegm + +from xonstat.util import pretty_date, strip_colors, html_colors + + +class Game(object): + 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 + self.start_dt = start_dt + self.game_type_cd = game_type_cd + self.server_id = server_id + self.map_id = map_id + self.winner = winner + + def __repr__(self): + return "" % (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} + + def fuzzy_date(self): + return pretty_date(self.start_dt) + + def epoch(self): + return timegm(self.start_dt.timetuple()) + + +class PlayerGameStat(object): + 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) + + 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} + + def nick_stripped(self): + if self.nick is None: + return "Anonymous Player" + else: + return strip_colors(self.nick) + + def nick_html_colors(self, limit=None): + if self.nick is None: + return "Anonymous Player" + else: + return html_colors(self.nick, limit) + + def team_html_color(self): + if self.team == 5: + return "red" + if self.team == 14: + return "blue" + if self.team == 13: + return "yellow" + if self.team == 10: + return "pink" + + +class PlayerWeaponStat(object): + def __init__(self, player_id=None, game_id=None, weapon_cd=None): + self.player_id = player_id + self.game_id = game_id + self.weapon_cd = weapon_cd + self.fired = 0 + self.max = 0 + self.hit = 0 + self.actual = 0 + self.frags = 0 + + def __repr__(self): + return "" % (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, + } + + +class TeamGameStat(object): + 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) + + 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'), + } + + def team_html_color(self): + if self.team == 5: + return "red" + if self.team == 14: + return "blue" + if self.team == 13: + return "yellow" + if self.team == 10: + return "pink" + + +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 + + def __repr__(self): + return "" % (self.key, self.value) + + +class GameType(object): + def __repr__(self): + return "" % (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} + + +class Weapon(object): + def __repr__(self): + return "" % (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 diff --git a/xonstat/models/main.py b/xonstat/models/main.py new file mode 100644 index 0000000..4f2ab22 --- /dev/null +++ b/xonstat/models/main.py @@ -0,0 +1,45 @@ +from xonstat.util import html_colors + + +class SummaryStat(object): + def __repr__(self): + return "" % (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): + self.sort_order = sort_order + self.player_id = player_id + self.nick = nick + self.alivetime = alivetime + + def nick_html_colors(self): + return html_colors(self.nick) + + def __repr__(self): + return "" % (self.sort_order, self.player_id) + + +class ActiveServer(object): + 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) + + +class ActiveMap(object): + 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 diff --git a/xonstat/models/map.py b/xonstat/models/map.py new file mode 100644 index 0000000..3367402 --- /dev/null +++ b/xonstat/models/map.py @@ -0,0 +1,49 @@ +from calendar import timegm + +from xonstat.util import pretty_date, strip_colors, html_colors + + +class Map(object): + def __init__(self, name=None): + self.name = name + + def __repr__(self): + return "" % (self.map_id, self.name, self.version) + + def to_dict(self): + return {'map_id':self.map_id, 'name':self.name, 'version':self.version,} + + def fuzzy_date(self): + return pretty_date(self.create_dt) + + def epoch(self): + return timegm(self.create_dt.timetuple()) + + +class MapCapTime(object): + """Fastest flag capture times per map, assembled from a SQLAlchemy query""" + 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.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 + + 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 diff --git a/xonstat/models/player.py b/xonstat/models/player.py new file mode 100644 index 0000000..bc4cb45 --- /dev/null +++ b/xonstat/models/player.py @@ -0,0 +1,161 @@ +from calendar import timegm + +from xonstat.util import html_colors, strip_colors, pretty_date, qfont_decode + + +class Player(object): + def nick_html_colors(self, limit=None): + if self.nick is None: + return "Anonymous Player" + else: + return html_colors(self.nick, limit) + + def nick_strip_colors(self): + if self.nick is None: + return "Anonymous Player" + else: + return strip_colors(self.nick) + + def joined_pretty_date(self): + return pretty_date(self.create_dt) + + def __repr__(self): + return "" % (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)} + + def epoch(self): + return timegm(self.create_dt.timetuple()) + + +class PlayerAchievement(object): + def __repr__(self): + return "" % (self.player_id, self.achievement_cd) + + def to_dict(self): + return {'player_id':self.player_id, 'achievement_cd':self.achievement_cd} + + +class Hashkey(object): + 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) + + def to_dict(self): + return {'player_id':self.player_id, 'hashkey':self.hashkey} + + +class PlayerNick(object): + def __repr__(self): + return "" % (self.player_id, qfont_decode(self.stripped_nick)) + + def to_dict(self): + 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): + + self.player_id = player_id + self.game_type_cd = game_type_cd + self.elo = elo + self.score = 0 + self.games = 0 + + def __repr__(self): + return "" % (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} + + +class PlayerRank(object): + + def nick_html_colors(self, limit=None): + if self.nick is None: + return "Anonymous Player" + else: + return html_colors(self.nick, limit) + + def __repr__(self): + return "" % (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} + + +class PlayerCaptime(object): + 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 + self.fastest_cap = fastest_cap + self.mod = mod + + def __repr__(self): + return "" % (self.player_id, + self.map_id, self.mod) + + def fuzzy_date(self): + return pretty_date(self.create_dt) + + def epoch(self): + return timegm(self.create_dt.timetuple()) + + +class PlayerGroups(object): + 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) + + +class PlayerCapTime(object): + """Fastest flag capture times per player, assembled from a SQLAlchemy query""" + 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.game_id = row.game_id + self.map_id = row.map_id + self.map_name = row.map_name + 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, + "game_id":self.game_id, + "map_id": self.map_id, + "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) + + +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 diff --git a/xonstat/models/server.py b/xonstat/models/server.py new file mode 100644 index 0000000..7df45a0 --- /dev/null +++ b/xonstat/models/server.py @@ -0,0 +1,25 @@ +from calendar import timegm +from datetime import datetime as dt + +from xonstat.util import pretty_date + + +class Server(object): + def __init__(self, name=None, hashkey=None, ip_addr=None): + self.name = name + self.hashkey = hashkey + self.ip_addr = ip_addr + self.create_dt = dt.utcnow() + + def __repr__(self): + return "" % (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} + + def fuzzy_date(self): + return pretty_date(self.create_dt) + + def epoch(self): + return timegm(self.create_dt.timetuple()) \ No newline at end of file diff --git a/xonstat/views/admin.py b/xonstat/views/admin.py index 84ecb4d..9186d50 100644 --- a/xonstat/views/admin.py +++ b/xonstat/views/admin.py @@ -1,9 +1,9 @@ -from pyramid.response import Response -from pyramid.httpexceptions import HTTPForbidden, HTTPFound -from pyramid.security import remember, forget +from pyramid.httpexceptions import HTTPFound +from pyramid.security import remember from pyramid.session import check_csrf_token from pyramid_persona.views import verify_login -from xonstat.models import * +from xonstat.models import DBSession, Player + def forbidden(request): '''A simple forbidden view. Does nothing more than set the status and then diff --git a/xonstat/views/game.py b/xonstat/views/game.py index 7af7c14..3df051f 100644 --- a/xonstat/views/game.py +++ b/xonstat/views/game.py @@ -1,18 +1,14 @@ -import datetime import logging -import re -import time from collections import OrderedDict + from pyramid import httpexceptions -from pyramid.response import Response -from sqlalchemy import desc, func, over from sqlalchemy.orm.exc import * -from webhelpers.paginate import Page, PageURL -from xonstat.models import * +from webhelpers.paginate import Page +from xonstat.models import DBSession, Server, Map, Game, PlayerGameStat, PlayerWeaponStat +from xonstat.models import TeamGameStat, PlayerRank, GameType, Weapon from xonstat.util import page_url from xonstat.views.helpers import RecentGame, recent_games_q - log = logging.getLogger(__name__) @@ -85,7 +81,7 @@ def _game_info_data(request): raise httpexceptions.HTTPNotFound("Could not find that game!") except Exception as e: - raise inst + raise e return {'game':game, 'server':server, diff --git a/xonstat/views/helpers.py b/xonstat/views/helpers.py index afaf914..82ae656 100644 --- a/xonstat/views/helpers.py +++ b/xonstat/views/helpers.py @@ -1,9 +1,11 @@ import logging -import sqlalchemy.sql.expression as expr +from calendar import timegm from datetime import datetime + +import sqlalchemy.sql.expression as expr from sqlalchemy.orm import aliased -from xonstat.models import * -from xonstat.util import * +from xonstat.models import DBSession, Server, Map, Game, PlayerGameStat, GameType +from xonstat.util import pretty_date, html_colors log = logging.getLogger(__name__) diff --git a/xonstat/views/main.py b/xonstat/views/main.py index 98973a7..c842a55 100644 --- a/xonstat/views/main.py +++ b/xonstat/views/main.py @@ -1,16 +1,9 @@ import logging -import sqlalchemy as sa -import sqlalchemy.sql.functions as func -import sqlalchemy.sql.expression as expr -from beaker.cache import cache_regions, cache_region -from collections import namedtuple from datetime import datetime, timedelta -from pyramid.response import Response -from xonstat.models import * -from xonstat.util import * -from xonstat.views.helpers import RecentGame, recent_games_q -from webhelpers.paginate import Page +from beaker.cache import cache_region +from xonstat.models import DBSession, PlayerRank, ActivePlayer, ActiveServer, ActiveMap +from xonstat.views.helpers import RecentGame, recent_games_q log = logging.getLogger(__name__) @@ -82,8 +75,8 @@ def get_summary_stats(scope="all"): ) except Exception as e: - raise e stat_line = None + raise e return stat_line diff --git a/xonstat/views/map.py b/xonstat/views/map.py index 506dcd9..9a9b4e7 100644 --- a/xonstat/views/map.py +++ b/xonstat/views/map.py @@ -1,10 +1,13 @@ import logging -import sqlalchemy.sql.functions as func -import sqlalchemy.sql.expression as expr from collections import namedtuple from datetime import datetime, timedelta + +import sqlalchemy.sql.expression as expr +import sqlalchemy.sql.functions as func +from pyramid import httpexceptions from webhelpers.paginate import Page -from xonstat.models import * +from xonstat.models import DBSession, Server, Map, Game, PlayerGameStat, Player, PlayerCaptime +from xonstat.models.map import MapCapTime from xonstat.util import page_url, html_colors from xonstat.views.helpers import RecentGame, recent_games_q @@ -186,7 +189,7 @@ def map_captimes_data(request): order_by(expr.asc(PlayerCaptime.fastest_cap)) except Exception as e: - raise pyramid.httpexceptions.HTTPNotFound + raise httpexceptions.HTTPNotFound map_captimes = Page(mct_q, current_page, items_per_page=20, url=page_url) diff --git a/xonstat/views/player.py b/xonstat/views/player.py index ff3a33f..41af4f1 100644 --- a/xonstat/views/player.py +++ b/xonstat/views/player.py @@ -1,17 +1,20 @@ import datetime import logging +from calendar import timegm +from collections import namedtuple +from urllib import unquote + import pyramid.httpexceptions import sqlalchemy as sa -import sqlalchemy.sql.functions as func import sqlalchemy.sql.expression as expr -from calendar import timegm -from collections import namedtuple +import sqlalchemy.sql.functions as func from webhelpers.paginate import Page -from xonstat.models import * -from xonstat.util import page_url, to_json, pretty_date, datetime_seconds +from xonstat.models import DBSession, Server, Map, Game, PlayerWeaponStat, Player, Hashkey +from xonstat.models import PlayerElo, PlayerCaptime, PlayerMedal, GameType +from xonstat.models.player import PlayerCapTime from xonstat.util import is_cake_day, verify_request +from xonstat.util import page_url, to_json, pretty_date, datetime_seconds from xonstat.views.helpers import RecentGame, recent_games_q -from urllib import unquote log = logging.getLogger(__name__) diff --git a/xonstat/views/search.py b/xonstat/views/search.py index 13700b6..b9d4675 100644 --- a/xonstat/views/search.py +++ b/xonstat/views/search.py @@ -1,16 +1,9 @@ -import datetime import logging -import pyramid.httpexceptions -import re -import time -from pyramid.response import Response -from sqlalchemy import desc -from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound + from sqlalchemy import func -from xonstat.models import * -from xonstat.util import strip_colors, qfont_decode -from xonstat.util import page_url, html_colors -from webhelpers.paginate import Page, PageURL +from webhelpers.paginate import Page +from xonstat.models import DBSession, Server, Map, Game, PlayerGameStat, Player +from xonstat.util import page_url log = logging.getLogger(__name__) diff --git a/xonstat/views/submission.py b/xonstat/views/submission.py index f63fbd2..74e2d3c 100644 --- a/xonstat/views/submission.py +++ b/xonstat/views/submission.py @@ -1,19 +1,17 @@ import datetime import logging -import os -import pyramid.httpexceptions import re -import time + +import pyramid.httpexceptions import sqlalchemy.sql.expression as expr -from calendar import timegm -from pyramid.response import Response from sqlalchemy import Sequence from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound from xonstat.elo import EloProcessor -from xonstat.models import * +from xonstat.models import DBSession, Server, Map, Game, PlayerGameStat, PlayerWeaponStat +from xonstat.models import PlayerRank, PlayerCaptime +from xonstat.models import TeamGameStat, PlayerGameAnticheat, Player, Hashkey, PlayerNick from xonstat.util import strip_colors, qfont_decode, verify_request, weapon_map - log = logging.getLogger(__name__) -- 2.39.2