X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=xonstat%2Fviews.py;h=b78d97c41f9b5e424c02a1544e7a999cf0b8f14d;hb=e9efaeed8821c757bdcd3d9631ebac468ab68339;hp=532f2e6e57a1604719e4ad95c62f9bc771a38433;hpb=876f4901fa03efe43dc808004af04ec729c46756;p=xonotic%2Fxonstat.git diff --git a/xonstat/views.py b/xonstat/views.py index 532f2e6..b78d97c 100755 --- a/xonstat/views.py +++ b/xonstat/views.py @@ -1,10 +1,14 @@ import datetime +import time import re from pyramid.response import Response from pyramid.view import view_config +from webhelpers.paginate import Page, PageURL from xonstat.models import * +from xonstat.util import page_url from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound +from sqlalchemy import desc import logging @@ -25,6 +29,7 @@ def main_index(request): @view_config(renderer='player_index.mako') def player_index(request): players = DBSession.query(Player) + log.debug("testing logging; entered PlayerHandler.index()") return {'players':players} @@ -33,35 +38,121 @@ def player_info(request): player_id = request.matchdict['id'] try: player = DBSession.query(Player).filter_by(player_id=player_id).one() - recent_games = DBSession.query("game_id", "server_name", "map_name").\ - from_statement("select g.game_id, s.name as server_name, m.name as map_name " - "from player_game_stats gs, games g, servers s, maps m " - "where gs.player_id=:player_id " - "and gs.game_id = g.game_id " - "and g.server_id = s.server_id " - "and g.map_id = m.map_id " - "order by g.start_dt desc " - "limit 10 offset 1").\ - params(player_id=player_id).all() + recent_games = DBSession.query(PlayerGameStat, Game, Server, Map).\ + filter(PlayerGameStat.player_id == player_id).\ + filter(PlayerGameStat.game_id == Game.game_id).\ + filter(Game.server_id == Server.server_id).\ + filter(Game.map_id == Map.map_id).\ + order_by(Game.game_id.desc())[0:10] - log.debug(recent_games) except Exception as e: - raise e player = None - return {'player':player, 'recent_games':recent_games} + recent_games = None + return {'player':player, + 'recent_games':recent_games} + + +def player_game_index(request): + player_id = request.matchdict['player_id'] + current_page = request.matchdict['page'] + + try: + player = DBSession.query(Player).filter_by(player_id=player_id).one() + + games_q = DBSession.query(PlayerGameStat, Game, Server, Map).\ + filter(PlayerGameStat.player_id == player_id).\ + filter(PlayerGameStat.game_id == Game.game_id).\ + filter(Game.server_id == Server.server_id).\ + filter(Game.map_id == Map.map_id).\ + order_by(Game.game_id.desc()) + + games = Page(games_q, current_page, url=page_url) + + + except Exception as e: + player = None + games = None + raise e + + return {'player':player, + 'games':games} + + +def player_weapon_stats(request): + game_id = request.matchdict['game_id'] + pgstat_id = request.matchdict['pgstat_id'] + try: + pwstats = DBSession.query(PlayerWeaponStat).\ + filter_by(game_id=game_id).\ + filter_by(player_game_stat_id=pgstat_id).\ + order_by(PlayerWeaponStat.weapon_cd).\ + all() + + except Exception as e: + pwstats = None + return {'pwstats':pwstats} ########################################################################## # This is the game views area - only views pertaining to Xonotic # games and their related information goes here ########################################################################## +def game_index(request): + if 'page' in request.matchdict: + current_page = request.matchdict['page'] + else: + current_page = 1 + + games_q = DBSession.query(Game, Server, Map).\ + filter(Game.server_id == Server.server_id).\ + filter(Game.map_id == Map.map_id).\ + order_by(Game.game_id.desc()) + + games = Page(games_q, current_page, url=page_url) + + return {'games':games} + + def game_info(request): game_id = request.matchdict['id'] try: - game = DBSession.query(Game).filter_by(game_id=game_id).one() - except: - game = None - return {'game':game} + notfound = False + + (start_dt, game_type_cd, server_id, server_name, map_id, map_name) = \ + DBSession.query("start_dt", "game_type_cd", "server_id", + "server_name", "map_id", "map_name").\ + from_statement("select g.start_dt, g.game_type_cd, " + "g.server_id, s.name as server_name, g.map_id, " + "m.name as map_name " + "from games g, servers s, maps m " + "where g.game_id = :game_id " + "and g.server_id = s.server_id " + "and g.map_id = m.map_id").\ + params(game_id=game_id).one() + + player_game_stats = DBSession.query(PlayerGameStat).\ + from_statement("select * from player_game_stats " + "where game_id = :game_id " + "order by score desc").\ + params(game_id=game_id).all() + except Exception as inst: + notfound = True + start_dt = None + game_type_cd = None + server_id = None + server_name = None + map_id = None + map_name = None + player_game_stats = None + + return {'notfound':notfound, + 'start_dt':start_dt, + 'game_type_cd':game_type_cd, + 'server_id':server_id, + 'server_name':server_name, + 'map_id':map_id, + 'map_name':map_name, + 'player_game_stats':player_game_stats} ########################################################################## @@ -72,9 +163,40 @@ def server_info(request): server_id = request.matchdict['id'] try: server = DBSession.query(Server).filter_by(server_id=server_id).one() - except: + recent_games = DBSession.query(Game, Server, Map).\ + filter(Game.server_id == server_id).\ + filter(Game.server_id == Server.server_id).\ + filter(Game.map_id == Map.map_id).\ + order_by(Game.game_id.desc())[0:10] + + except Exception as e: server = None - return {'server':server} + recent_games = None + return {'server':server, + 'recent_games':recent_games} + + +def server_game_index(request): + server_id = request.matchdict['server_id'] + current_page = request.matchdict['page'] + + try: + server = DBSession.query(Server).filter_by(server_id=server_id).one() + + games_q = DBSession.query(Game, Server, Map).\ + filter(Game.server_id == server_id).\ + filter(Game.server_id == Server.server_id).\ + filter(Game.map_id == Map.map_id).\ + order_by(Game.game_id.desc()) + + games = Page(games_q, current_page, url=page_url) + except Exception as e: + server = None + games = None + raise e + + return {'games':games, + 'server':server} ########################################################################## @@ -240,38 +362,39 @@ def create_player_game_stat(session=None, player=None, def create_player_weapon_stats(session=None, player=None, - game=None, player_events=None): + game=None, pgstat=None, player_events=None): pwstats = [] for (key,value) in player_events.items(): matched = re.search("acc-(.*?)-cnt-fired", key) if matched: - log.debug("Matched key: {0}".format(key)) weapon_cd = matched.group(1) pwstat = PlayerWeaponStat() pwstat.player_id = player.player_id pwstat.game_id = game.game_id + pwstat.player_game_stat_id = pgstat.player_game_stat_id pwstat.weapon_cd = weapon_cd - try: - pwstat.max = int(player_events['acc-' + weapon_cd + '-fired']) - except: - pwstat.max = 0 - try: - pwstat.actual = int(player_events['acc-' + weapon_cd + '-hit']) - except: - pwstat.actual = 0 - try: - pwstat.fired = int(player_events['acc-' + weapon_cd + '-cnt-fired']) - except: - pwstat.fired = 0 - try: - pwstat.hit = int(player_events['acc-' + weapon_cd + '-cnt-hit']) - except: - pwstat.hit = 0 - try: - pwstat.frags = int(player_events['acc-' + weapon_cd + '-frags']) - except: - pwstat.frags = 0 + + if 'n' in player_events: + pwstat.nick = player_events['n'] + else: + pwstat.nick = player_events['P'] + + if 'acc-' + weapon_cd + '-cnt-fired' in player_events: + pwstat.fired = int(round(float( + player_events['acc-' + weapon_cd + '-cnt-fired']))) + if 'acc-' + weapon_cd + '-fired' in player_events: + pwstat.max = int(round(float( + player_events['acc-' + weapon_cd + '-fired']))) + if 'acc-' + weapon_cd + '-cnt-hit' in player_events: + pwstat.hit = int(round(float( + player_events['acc-' + weapon_cd + '-cnt-hit']))) + if 'acc-' + weapon_cd + '-hit' in player_events: + pwstat.actual = int(round(float( + player_events['acc-' + weapon_cd + '-hit']))) + if 'acc-' + weapon_cd + '-frags' in player_events: + pwstat.frags = int(round(float( + player_events['acc-' + weapon_cd + '-frags']))) session.add(pwstat) pwstats.append(pwstat) @@ -295,24 +418,22 @@ def parse_body(request): if key in 'V' 'T' 'G' 'M' 'S' 'C' 'R' 'W': game_meta[key] = value - if key == 't': - current_team = value - if key == 'P': # if we were working on a player record already, append # it and work on a new one (only set team info) if len(player_events) != 0: players.append(player_events) - player_events = {'t':current_team} + player_events = {} player_events[key] = value - + if key == 'e': (subkey, subvalue) = value.split(' ', 1) player_events[subkey] = subvalue - if key == 'n': player_events[key] = value + if key == 't': + player_events[key] = value except: # no key/value pair - move on to the next line pass @@ -324,6 +445,18 @@ def parse_body(request): return (game_meta, players) +def create_player_stats(session=None, player=None, game=None, + player_events=None): + if 'joins' in player_events and 'matches' in player_events\ + and 'scoreboardvalid' in player_events: + pgstat = create_player_game_stat(session=session, + player=player, game=game, player_events=player_events) + if not re.search('^bot#\d+$', player_events['P']): + create_player_weapon_stats(session=session, + player=player, game=game, pgstat=pgstat, + player_events=player_events) + + @view_config(renderer='stats_submit.mako') def stats_submit(request): try: @@ -338,8 +471,18 @@ def stats_submit(request): 'S' not in game_meta: log.debug("Required game meta fields (T, G, M, or S) missing. "\ "Can't continue.") - raise Exception + raise Exception("Required game meta fields (T, G, M, or S) missing.") + has_real_players = False + for player_events in players: + if not player_events['P'].startswith('bot'): + if 'joins' in player_events and 'matches' in player_events\ + and 'scoreboardvalid' in player_events: + has_real_players = True + + if not has_real_players: + raise Exception("No real players found. Stats ignored.") + server = get_or_create_server(session=session, name=game_meta['S']) gmap = get_or_create_map(session=session, name=game_meta['M']) @@ -348,35 +491,25 @@ def stats_submit(request): else: winner = None - # FIXME: don't use python now() here, convert from epoch T value - game = create_game(session=session, start_dt=datetime.datetime.now(), + game = create_game(session=session, + start_dt=datetime.datetime( + *time.gmtime(float(game_meta['T']))[:6]), server_id=server.server_id, game_type_cd=game_meta['G'], map_id=gmap.map_id, winner=winner) # find or create a record for each player # and add stats for each if they were present at the end # of the game - has_real_players = False for player_events in players: - if not player_events['P'].startswith('bot'): - has_real_players = True player = get_or_create_player(session=session, hashkey=player_events['P']) - if 'joins' in player_events and 'matches' in player_events\ - and 'scoreboardvalid' in player_events: - pgstat = create_player_game_stat(session=session, - player=player, game=game, player_events=player_events) - #pwstats = create_player_weapon_stats(session=session, - #player=player, game=game, player_events=player_events) + log.debug('Creating stats for %s' % player_events['P']) + create_player_stats(session=session, player=player, game=game, + player_events=player_events) - if has_real_players: - session.commit() - log.debug('Success! Stats recorded.') - return Response('200 OK') - else: - session.rollback() - log.debug('No real players found. Stats ignored.') - return {'msg':'No real players found. Stats ignored.'} + session.commit() + log.debug('Success! Stats recorded.') + return Response('200 OK') except Exception as e: session.rollback() raise e