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;
margin-bottom: 10px;
width:100%;
}
-
+#player-index-table, #server-index-table{
+ width: 600px;
+}
+#map-index-table {
+ width: 300px;
+}
#recent-games {
width: 950px;
}
background-color:#000F4C;
}
+/* column-specific table widths */
+.create-dt{
+ width: 150px;
+}
+
/* Containers */
#filter {
float:left;
"bFilter": false,
"bSort": true,
"bInfo": false,
- "bAutoWidth": false
+ "bAutoWidth": false,
+ "aaSorting": []
});
}
if ($("#recent-games").length) {
"oLanguage": {
"sSearch": "_INPUT_"
},
- "aaSorting": [[ 0, "desc" ]]
+ "aaSorting": []
});
}
if ($("table.scoreboard").length) {
"bFilter": false,
"bSort": true,
"bInfo": false,
- "bAutoWidth": false
+ "bAutoWidth": false,
+ "aaSorting": []
});
}
if ($("table.accuracy").length) {
"bFilter": false,
"bSort": true,
"bInfo": false,
- "bAutoWidth": false
+ "bAutoWidth": false,
+ "aaSorting": []
});
}
if ($(".recent_game_box").length) {
\r
% else:\r
<h2>Map Index</h2>\r
-<table border="1">\r
+<table id="map-index-table" border="1">\r
<tr>\r
- <th>#</th>\r
<th>Name</th>\r
</tr>\r
% for map in maps:\r
<tr>\r
- <td>${map.map_id}</th>\r
<td><a href="${request.route_url("map_info", id=map.map_id)}" title="Go to this map's info page">${map.name}</a></th>\r
</tr>\r
% endfor\r
\r
% else:\r
<h2>Player Index</h2>\r
-<table border="1">\r
+<table id="player-index-table" border="1">\r
<tr>\r
- <th>#</th>\r
<th>Nick</th>\r
- <th>Joined</th>\r
+ <th class="create-dt">Joined</th>\r
</tr>\r
% for player in players:\r
<tr>\r
- <td>${player.player_id}</th>\r
<td><a href="${request.route_url("player_info", id=player.player_id)}" title="Go to this player's info page">${player.nick_html_colors()|n}</a></th>\r
<td>${player.create_dt.strftime('%m/%d/%Y at %H:%M')}</th>\r
</tr>\r
\r
% else:\r
<h2>Server Index</h2>\r
-<table border="1">\r
+<table id="server-index-table" border="1">\r
<tr>\r
- <th>#</th>\r
<th>Name</th>\r
- <th>IP Address</th>\r
+ <th class="create-dt">Added</th>\r
</tr>\r
% for server in servers:\r
<tr>\r
- <td>${server.server_id}</th>\r
<td><a href="${request.route_url("server_info", id=server.server_id)}" title="Go to this server's info page">${server.name}</a></th>\r
+ <td>${server.create_dt.strftime('%m/%d/%Y at %H:%M')}</td>\r
</tr>\r
% endfor\r
</table>\r
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 *
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
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]
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]
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]
import logging\r
from pyramid.response import Response\r
+from sqlalchemy import desc\r
from webhelpers.paginate import Page, PageURL\r
from xonstat.models import *\r
from xonstat.util import page_url\r
\r
try:\r
map_q = DBSession.query(Map).\\r
- order_by(Map.name)\r
+ order_by(Map.map_id.desc())\r
\r
maps = Page(map_q, current_page, url=page_url)\r
\r
try:\r
player_q = DBSession.query(Player).\\r
filter(Player.player_id > 2).\\r
- order_by(Player.player_id)\r
+ order_by(Player.player_id.desc())\r
\r
players = Page(player_q, current_page, url=page_url)\r
\r
import sqlalchemy.sql.expression as expr\r
import time\r
from datetime import datetime, timedelta\r
-from pyramid.config import get_current_registry\r
from pyramid.response import Response\r
from sqlalchemy import desc\r
from webhelpers.paginate import Page, PageURL\r
\r
try:\r
server_q = DBSession.query(Server).\\r
- order_by(Server.name)\r
+ order_by(Server.server_id.desc())\r
\r
servers = Page(server_q, current_page, url=page_url)\r
\r
"""\r
server_id = request.matchdict['id']\r
\r
- # get settings specific to this view\r
- settings = get_current_registry().settings\r
try: \r
leaderboard_lifetime = int(\r
- settings['xonstat.leaderboard_lifetime'])\r
+ request.registry.settings['xonstat.leaderboard_lifetime'])\r
except:\r
leaderboard_lifetime = 30\r
\r
filter(Map.map_id==Game.map_id).\\r
filter(Game.server_id==server.server_id).\\r
filter(Game.create_dt > \r
- (datetime.now() - timedelta(days=leaderboard_lifetime))).\\r
+ (datetime.utcnow() - timedelta(days=leaderboard_lifetime))).\\r
order_by(expr.desc(func.count())).\\r
group_by(Game.map_id).\\r
group_by(Map.name).all()[0:10]\r
filter(Game.server_id == server.server_id).\\r
filter(Player.player_id > 2).\\r
filter(PlayerGameStat.create_dt > \r
- (datetime.now() - timedelta(days=leaderboard_lifetime))).\\r
+ (datetime.utcnow() - timedelta(days=leaderboard_lifetime))).\\r
order_by(expr.desc(func.sum(PlayerGameStat.score))).\\r
group_by(Player.nick).\\r
group_by(Player.player_id).all()[0:10]\r
filter(Game.server_id == server.server_id).\\r
filter(Player.player_id > 2).\\r
filter(PlayerGameStat.create_dt > \r
- (datetime.now() - timedelta(days=leaderboard_lifetime))).\\r
+ (datetime.utcnow() - timedelta(days=leaderboard_lifetime))).\\r
order_by(expr.desc(func.sum(PlayerGameStat.alivetime))).\\r
group_by(Player.nick).\\r
group_by(Player.player_id).all()[0:10]\r
import pyramid.httpexceptions\r
import re\r
import time\r
-from pyramid.config import get_current_registry\r
from pyramid.response import Response\r
from sqlalchemy import Sequence\r
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound\r
return (idfp, status)\r
\r
\r
-def has_minimum_real_players(player_events):\r
+def has_minimum_real_players(settings, player_events):\r
"""\r
Determines if the collection of player events has enough "real" players\r
to store in the database. The minimum setting comes from the config file\r
"""\r
flg_has_min_real_players = True\r
\r
- settings = get_current_registry().settings\r
try: \r
minimum_required_players = int(\r
settings['xonstat.minimum_required_players'])\r
# player_id/stripped_nick not found, create one\r
# but we don't store "Anonymous Player #N"\r
if not re.search('^Anonymous Player #\d+$', player.nick):\r
- player_nick = PlayerNick()\r
+ player_nick = PlayerNick()\r
player_nick.player_id = player.player_id\r
- player_nick.stripped_nick = stripped_nick\r
+ player_nick.stripped_nick = player.stripped_nick\r
player_nick.nick = player.nick\r
session.add(player_nick)\r
\r
# We change to the new nick regardless\r
player.nick = new_nick\r
+ player.stripped_nick = strip_colors(new_nick)\r
session.add(player)\r
\r
\r
session.add(player)\r
session.flush()\r
\r
- # if nick is given to us, use it. If not, use "Anonymous Player"\r
- # with a suffix added for uniqueness.\r
- if nick:\r
- player.nick = nick[:128]\r
- else:\r
- player.nick = "Anonymous Player #{0}".format(player.player_id)\r
+ # if nick is given to us, use it. If not, use "Anonymous Player"\r
+ # with a suffix added for uniqueness.\r
+ if nick:\r
+ player.nick = nick[:128]\r
+ player.stripped_nick = strip_colors(nick[:128])\r
+ else:\r
+ player.nick = "Anonymous Player #{0}".format(player.player_id)\r
+ player.stripped_nick = player.nick\r
\r
- hashkey = Hashkey(player_id=player.player_id, hashkey=hashkey)\r
- session.add(hashkey)\r
- log.debug("Created player {0} ({2}) with hashkey {1}".format(\r
- player.player_id, hashkey.hashkey, player.nick.encode('utf-8')))\r
+ hashkey = Hashkey(player_id=player.player_id, hashkey=hashkey)\r
+ session.add(hashkey)\r
+ log.debug("Created player {0} ({2}) with hashkey {1}".format(\r
+ player.player_id, hashkey.hashkey, player.nick.encode('utf-8')))\r
\r
return player\r
\r
seq = Sequence('player_game_stats_player_game_stat_id_seq')\r
pgstat_id = session.execute(seq)\r
pgstat = PlayerGameStat(player_game_stat_id=pgstat_id, \r
- create_dt=datetime.datetime.now())\r
+ create_dt=datetime.datetime.utcnow())\r
\r
# set player id from player record\r
pgstat.player_id = player.player_id\r
matched = re.search("acc-(.*?)-cnt-fired", key)\r
if matched:\r
weapon_cd = matched.group(1)\r
+ seq = Sequence('player_weapon_stats_player_weapon_stats_id_seq')\r
+ pwstat_id = session.execute(seq)\r
pwstat = PlayerWeaponStat()\r
+ pwstat.player_weapon_stats_id = pwstat_id\r
pwstat.player_id = player.player_id\r
pwstat.game_id = game.game_id\r
pwstat.player_game_stat_id = pgstat.player_game_stat_id\r
pwstat.frags = int(round(float(\r
player_events['acc-' + weapon_cd + '-frags'])))\r
\r
+ log.debug(pwstat)\r
session.add(pwstat)\r
+ log.debug(pwstat)\r
pwstats.append(pwstat)\r
\r
return pwstats\r
(idfp, status) = verify_request(request)\r
if not idfp:\r
raise pyramid.httpexceptions.HTTPUnauthorized\r
-\r
+ \r
(game_meta, players) = parse_body(request) \r
- \r
+ \r
if not has_required_metadata(game_meta):\r
log.debug("Required game meta fields missing. "\\r
"Can't continue.")\r
raise pyramid.exceptions.HTTPUnprocessableEntity\r
- \r
+ \r
if not is_supported_gametype(game_meta['G']):\r
raise pyramid.httpexceptions.HTTPOk\r
\r
- if not has_minimum_real_players(players):\r
+ if not has_minimum_real_players(request.registry.settings, players):\r
log.debug("The number of real players is below the minimum. " + \r
"Stats will be ignored.")\r
raise pyramid.httpexceptions.HTTPOk\r
-\r
+ \r
server = get_or_create_server(session=session, hashkey=idfp, \r
name=game_meta['S'])\r
-\r
+ \r
gmap = get_or_create_map(session=session, name=game_meta['M'])\r
-\r
+ log.debug(gmap)\r
+ \r
game = create_game(session=session, \r
start_dt=datetime.datetime(\r
*time.gmtime(float(game_meta['T']))[:6]), \r
server_id=server.server_id, game_type_cd=game_meta['G'], \r
- map_id=gmap.map_id)\r
- \r
+ map_id=gmap.map_id)\r
+ log.debug(gmap)\r
+ \r
# find or create a record for each player\r
# and add stats for each if they were present at the end\r
# of the game\r
nick = player_events['n']\r
else:\r
nick = None\r
-\r
+ \r
if 'matches' in player_events and 'scoreboardvalid' \\r
- in player_events:\r
+ in player_events:\r
player = get_or_create_player(session=session, \r
hashkey=player_events['P'], nick=nick)\r
log.debug('Creating stats for %s' % player_events['P'])\r
create_player_stats(session=session, player=player, game=game, \r
player_events=player_events)\r
- \r
+ \r
session.commit()\r
log.debug('Success! Stats recorded.')\r
return Response('200 OK')\r