From: antzucaro Date: Sun, 20 Nov 2011 00:40:37 +0000 (-0800) Subject: Merge pull request #2 from dmazary/master X-Git-Url: http://git.xonotic.org/?a=commitdiff_plain;h=72463913d890ee0db8fe3a2b27f7bb95eed0303d;hp=9ca1a02569d3e529c64b9ff0f2208f01a280c956;p=xonotic%2Fxonstat.git Merge pull request #2 from dmazary/master Add function to utils.py to decode Quake's qfont into ascii --- diff --git a/xonstat/static/css/img/web_background_l2.png b/xonstat/static/css/img/web_background_l2.png index 37a42f8..bf7e81f 100644 Binary files a/xonstat/static/css/img/web_background_l2.png and b/xonstat/static/css/img/web_background_l2.png differ diff --git a/xonstat/static/css/style.css b/xonstat/static/css/style.css index ff25ef7..c275ff6 100755 --- a/xonstat/static/css/style.css +++ b/xonstat/static/css/style.css @@ -118,7 +118,7 @@ input { font-family: 'Xolonium', 'Arial', 'Helvetica'; } width:1052px; background: transparent url('img/web_background_l2.png') no-repeat center top; margin:0 auto; - padding-top:244px; + padding-top:200px; } #content { position:relative; @@ -368,7 +368,12 @@ input[type=text]:hover, .textbox:hover { background-position:-128px -32px; } margin-bottom: 10px; width:100%; } - +#player-index-table, #server-index-table{ + width: 600px; +} +#map-index-table { + width: 300px; +} #recent-games { width: 950px; } @@ -405,6 +410,11 @@ tr.even.blue { background-color:#000F4C; } +/* column-specific table widths */ +.create-dt{ + width: 150px; +} + /* Containers */ #filter { float:left; diff --git a/xonstat/static/images/rifle.png b/xonstat/static/images/rifle.png new file mode 100755 index 0000000..71041ef Binary files /dev/null and b/xonstat/static/images/rifle.png differ diff --git a/xonstat/static/images/sniperrifle.png b/xonstat/static/images/sniperrifle.png deleted file mode 100755 index 71041ef..0000000 Binary files a/xonstat/static/images/sniperrifle.png and /dev/null differ diff --git a/xonstat/static/js/default.js b/xonstat/static/js/default.js index 18dc39a..af05cd4 100644 --- a/xonstat/static/js/default.js +++ b/xonstat/static/js/default.js @@ -52,7 +52,8 @@ function init_datatables() { "bFilter": false, "bSort": true, "bInfo": false, - "bAutoWidth": false + "bAutoWidth": false, + "aaSorting": [] }); } if ($("#recent-games").length) { @@ -66,7 +67,7 @@ function init_datatables() { "oLanguage": { "sSearch": "_INPUT_" }, - "aaSorting": [[ 0, "desc" ]] + "aaSorting": [] }); } if ($("table.scoreboard").length) { @@ -76,7 +77,8 @@ function init_datatables() { "bFilter": false, "bSort": true, "bInfo": false, - "bAutoWidth": false + "bAutoWidth": false, + "aaSorting": [] }); } if ($("table.accuracy").length) { @@ -86,7 +88,8 @@ function init_datatables() { "bFilter": false, "bSort": true, "bInfo": false, - "bAutoWidth": false + "bAutoWidth": false, + "aaSorting": [] }); } if ($(".recent_game_box").length) { diff --git a/xonstat/templates/map_index.mako b/xonstat/templates/map_index.mako index ad47b60..7598a4d 100755 --- a/xonstat/templates/map_index.mako +++ b/xonstat/templates/map_index.mako @@ -9,14 +9,12 @@ Map Index - ${parent.title()} % else:

Map Index

- +
- % for map in maps: - % endfor diff --git a/xonstat/templates/player_index.mako b/xonstat/templates/player_index.mako index 7041705..b8a68c7 100755 --- a/xonstat/templates/player_index.mako +++ b/xonstat/templates/player_index.mako @@ -9,15 +9,13 @@ Player Index - ${parent.title()} % else:

Player Index

-
# Name
${map.map_id} ${map.name}
+
- - + % for player in players: - diff --git a/xonstat/templates/server_index.mako b/xonstat/templates/server_index.mako index 93b6f09..dd67c24 100755 --- a/xonstat/templates/server_index.mako +++ b/xonstat/templates/server_index.mako @@ -9,16 +9,15 @@ Map Index - ${parent.title()} % else:

Server Index

-
# NickJoinedJoined
${player.player_id} ${player.nick_html_colors()|n} ${player.create_dt.strftime('%m/%d/%Y at %H:%M')}
+
- - + % for server in servers: - % endfor
# NameIP AddressAdded
${server.server_id} ${server.name} + ${server.create_dt.strftime('%m/%d/%Y at %H:%M')}
diff --git a/xonstat/views/main.py b/xonstat/views/main.py index d81487c..22b1291 100755 --- a/xonstat/views/main.py +++ b/xonstat/views/main.py @@ -2,7 +2,6 @@ import logging import sqlalchemy.sql.functions as func import sqlalchemy.sql.expression as expr from datetime import datetime, timedelta -from pyramid.config import get_current_registry from pyramid.response import Response from xonstat.models import * from xonstat.util import * @@ -10,10 +9,9 @@ from xonstat.util import * log = logging.getLogger(__name__) def main_index(request): - settings = get_current_registry().settings try: leaderboard_lifetime = int( - settings['xonstat.leaderboard_lifetime']) + request.registry.settings['xonstat.leaderboard_lifetime']) except: leaderboard_lifetime = 30 @@ -26,7 +24,7 @@ def main_index(request): filter(Player.player_id == PlayerGameStat.player_id).\ filter(Player.player_id > 2).\ filter(PlayerGameStat.create_dt > - (datetime.now() - timedelta(days=leaderboard_lifetime))).\ + (datetime.utcnow() - timedelta(days=leaderboard_lifetime))).\ order_by(expr.desc(func.sum(PlayerGameStat.alivetime))).\ group_by(Player.nick).\ group_by(Player.player_id).all()[0:10] @@ -42,7 +40,7 @@ def main_index(request): func.count()).\ filter(Game.server_id==Server.server_id).\ filter(Game.create_dt > - (datetime.now() - timedelta(days=leaderboard_lifetime))).\ + (datetime.utcnow() - timedelta(days=leaderboard_lifetime))).\ order_by(expr.desc(func.count(Game.game_id))).\ group_by(Server.server_id).\ group_by(Server.name).all()[0:10] @@ -55,7 +53,7 @@ def main_index(request): func.count()).\ filter(Map.map_id==Game.map_id).\ filter(Game.create_dt > - (datetime.now() - timedelta(days=leaderboard_lifetime))).\ + (datetime.utcnow() - timedelta(days=leaderboard_lifetime))).\ order_by(expr.desc(func.count())).\ group_by(Game.map_id).\ group_by(Map.name).all()[0:10] diff --git a/xonstat/views/map.py b/xonstat/views/map.py index aca27d6..659f04f 100755 --- a/xonstat/views/map.py +++ b/xonstat/views/map.py @@ -1,5 +1,6 @@ import logging from pyramid.response import Response +from sqlalchemy import desc from webhelpers.paginate import Page, PageURL from xonstat.models import * from xonstat.util import page_url @@ -17,7 +18,7 @@ def map_index(request): try: map_q = DBSession.query(Map).\ - order_by(Map.name) + order_by(Map.map_id.desc()) maps = Page(map_q, current_page, url=page_url) diff --git a/xonstat/views/player.py b/xonstat/views/player.py index 22febaa..239cf06 100755 --- a/xonstat/views/player.py +++ b/xonstat/views/player.py @@ -23,7 +23,7 @@ def player_index(request): try: player_q = DBSession.query(Player).\ filter(Player.player_id > 2).\ - order_by(Player.player_id) + order_by(Player.player_id.desc()) players = Page(player_q, current_page, url=page_url) diff --git a/xonstat/views/server.py b/xonstat/views/server.py index a706dc2..8e4a7c6 100755 --- a/xonstat/views/server.py +++ b/xonstat/views/server.py @@ -3,7 +3,6 @@ import sqlalchemy.sql.functions as func import sqlalchemy.sql.expression as expr import time from datetime import datetime, timedelta -from pyramid.config import get_current_registry from pyramid.response import Response from sqlalchemy import desc from webhelpers.paginate import Page, PageURL @@ -23,7 +22,7 @@ def server_index(request): try: server_q = DBSession.query(Server).\ - order_by(Server.name) + order_by(Server.server_id.desc()) servers = Page(server_q, current_page, url=page_url) @@ -40,11 +39,9 @@ def server_info(request): """ server_id = request.matchdict['id'] - # get settings specific to this view - settings = get_current_registry().settings try: leaderboard_lifetime = int( - settings['xonstat.leaderboard_lifetime']) + request.registry.settings['xonstat.leaderboard_lifetime']) except: leaderboard_lifetime = 30 @@ -60,7 +57,7 @@ def server_info(request): filter(Map.map_id==Game.map_id).\ filter(Game.server_id==server.server_id).\ filter(Game.create_dt > - (datetime.now() - timedelta(days=leaderboard_lifetime))).\ + (datetime.utcnow() - timedelta(days=leaderboard_lifetime))).\ order_by(expr.desc(func.count())).\ group_by(Game.map_id).\ group_by(Map.name).all()[0:10] @@ -76,7 +73,7 @@ def server_info(request): filter(Game.server_id == server.server_id).\ filter(Player.player_id > 2).\ filter(PlayerGameStat.create_dt > - (datetime.now() - timedelta(days=leaderboard_lifetime))).\ + (datetime.utcnow() - timedelta(days=leaderboard_lifetime))).\ order_by(expr.desc(func.sum(PlayerGameStat.score))).\ group_by(Player.nick).\ group_by(Player.player_id).all()[0:10] @@ -95,7 +92,7 @@ def server_info(request): filter(Game.server_id == server.server_id).\ filter(Player.player_id > 2).\ filter(PlayerGameStat.create_dt > - (datetime.now() - timedelta(days=leaderboard_lifetime))).\ + (datetime.utcnow() - timedelta(days=leaderboard_lifetime))).\ order_by(expr.desc(func.sum(PlayerGameStat.alivetime))).\ group_by(Player.nick).\ group_by(Player.player_id).all()[0:10] diff --git a/xonstat/views/submission.py b/xonstat/views/submission.py index 1cf3493..6f776a2 100755 --- a/xonstat/views/submission.py +++ b/xonstat/views/submission.py @@ -3,7 +3,6 @@ import logging import pyramid.httpexceptions import re import time -from pyramid.config import get_current_registry from pyramid.response import Response from sqlalchemy import Sequence from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound @@ -38,7 +37,7 @@ def verify_request(request): return (idfp, status) -def has_minimum_real_players(player_events): +def has_minimum_real_players(settings, player_events): """ Determines if the collection of player events has enough "real" players to store in the database. The minimum setting comes from the config file @@ -46,7 +45,6 @@ def has_minimum_real_players(player_events): """ flg_has_min_real_players = True - settings = get_current_registry().settings try: minimum_required_players = int( settings['xonstat.minimum_required_players']) @@ -119,14 +117,15 @@ def register_new_nick(session, player, new_nick): # player_id/stripped_nick not found, create one # but we don't store "Anonymous Player #N" if not re.search('^Anonymous Player #\d+$', player.nick): - player_nick = PlayerNick() + player_nick = PlayerNick() player_nick.player_id = player.player_id - player_nick.stripped_nick = stripped_nick + player_nick.stripped_nick = player.stripped_nick player_nick.nick = player.nick session.add(player_nick) # We change to the new nick regardless player.nick = new_nick + player.stripped_nick = strip_colors(new_nick) session.add(player) @@ -251,17 +250,19 @@ def get_or_create_player(session=None, hashkey=None, nick=None): session.add(player) session.flush() - # if nick is given to us, use it. If not, use "Anonymous Player" - # with a suffix added for uniqueness. - if nick: - player.nick = nick[:128] - else: - player.nick = "Anonymous Player #{0}".format(player.player_id) + # if nick is given to us, use it. If not, use "Anonymous Player" + # with a suffix added for uniqueness. + if nick: + player.nick = nick[:128] + player.stripped_nick = strip_colors(nick[:128]) + else: + player.nick = "Anonymous Player #{0}".format(player.player_id) + player.stripped_nick = player.nick - hashkey = Hashkey(player_id=player.player_id, hashkey=hashkey) - session.add(hashkey) - log.debug("Created player {0} ({2}) with hashkey {1}".format( - player.player_id, hashkey.hashkey, player.nick.encode('utf-8'))) + hashkey = Hashkey(player_id=player.player_id, hashkey=hashkey) + session.add(hashkey) + log.debug("Created player {0} ({2}) with hashkey {1}".format( + player.player_id, hashkey.hashkey, player.nick.encode('utf-8'))) return player @@ -282,7 +283,7 @@ def create_player_game_stat(session=None, player=None, seq = Sequence('player_game_stats_player_game_stat_id_seq') pgstat_id = session.execute(seq) pgstat = PlayerGameStat(player_game_stat_id=pgstat_id, - create_dt=datetime.datetime.now()) + create_dt=datetime.datetime.utcnow()) # set player id from player record pgstat.player_id = player.player_id @@ -362,7 +363,10 @@ def create_player_weapon_stats(session=None, player=None, matched = re.search("acc-(.*?)-cnt-fired", key) if matched: weapon_cd = matched.group(1) + seq = Sequence('player_weapon_stats_player_weapon_stats_id_seq') + pwstat_id = session.execute(seq) pwstat = PlayerWeaponStat() + pwstat.player_weapon_stats_id = pwstat_id pwstat.player_id = player.player_id pwstat.game_id = game.game_id pwstat.player_game_stat_id = pgstat.player_game_stat_id @@ -389,7 +393,9 @@ def create_player_weapon_stats(session=None, player=None, pwstat.frags = int(round(float( player_events['acc-' + weapon_cd + '-frags']))) + log.debug(pwstat) session.add(pwstat) + log.debug(pwstat) pwstats.append(pwstat) return pwstats @@ -473,33 +479,35 @@ def stats_submit(request): (idfp, status) = verify_request(request) if not idfp: raise pyramid.httpexceptions.HTTPUnauthorized - + (game_meta, players) = parse_body(request) - + if not has_required_metadata(game_meta): log.debug("Required game meta fields missing. "\ "Can't continue.") raise pyramid.exceptions.HTTPUnprocessableEntity - + if not is_supported_gametype(game_meta['G']): raise pyramid.httpexceptions.HTTPOk - if not has_minimum_real_players(players): + if not has_minimum_real_players(request.registry.settings, players): log.debug("The number of real players is below the minimum. " + "Stats will be ignored.") raise pyramid.httpexceptions.HTTPOk - + server = get_or_create_server(session=session, hashkey=idfp, name=game_meta['S']) - + gmap = get_or_create_map(session=session, name=game_meta['M']) - + log.debug(gmap) + 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) - + map_id=gmap.map_id) + log.debug(gmap) + # find or create a record for each player # and add stats for each if they were present at the end # of the game @@ -508,15 +516,15 @@ def stats_submit(request): nick = player_events['n'] else: nick = None - + if 'matches' in player_events and 'scoreboardvalid' \ - in player_events: + in player_events: player = get_or_create_player(session=session, hashkey=player_events['P'], nick=nick) log.debug('Creating stats for %s' % player_events['P']) create_player_stats(session=session, player=player, game=game, player_events=player_events) - + session.commit() log.debug('Success! Stats recorded.') return Response('200 OK')