q3stats/q3stats/web_app/blueprints/api_v1/views/sessions.py

147 lines
4.4 KiB
Python

# -*- coding: utf-8 -*-
# Copyright (c) 2017 Tomek Wójcik <tomek@bthlabs.pl>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
"""
q3stats.web_app.blueprints.api_v1.views.sessions
================================================
This module contains the APIv1 sessions views.
"""
from collections import defaultdict
import datetime
from flask import abort, current_app, jsonify
import six
from q3stats.web_app.blueprints.api_v1 import api_v1_blueprint
from q3stats.lib import defs, queries
from q3stats.models import Game
def _get_quad_freaks(games):
"""Returns quad freaks data for *games*."""
intermediate = defaultdict(lambda: defaultdict(int))
for game in games:
for score in game.scores:
if 'Quad' in score.powerups:
intermediate[game.uuid][score.player] +=\
score.powerups['Quad'][0]
result = {}
for game_uuid, players in six.iteritems(intermediate):
sorted_players = sorted(
list(six.iteritems(players)), key=lambda x: x[1], reverse=True
)
result[game_uuid] = sorted_players[0]
return result
@api_v1_blueprint.route('/sessions/')
@api_v1_blueprint.route('/sessions/<day>')
def get_api_v1_sessions(day=None):
"""Returns data for the Sessions view.
If *day* is omitted, the latest session is used."""
date = None
if day is not None:
try:
date = datetime.datetime.strptime(day, defs.DATE_FORMAT).date()
except (TypeError, ValueError):
abort(400)
dates = queries.get_game_dates(current_app.db_session)
if date is None:
date = dates[0]
elif date not in dates:
abort(404)
current_date_idx = dates.index(date)
try:
prev_date = dates[current_date_idx + 1].strftime(defs.DATE_FORMAT)
except IndexError:
prev_date = None
next_date = None
if current_date_idx > 0:
try:
next_date = dates[current_date_idx - 1].strftime(defs.DATE_FORMAT)
except IndexError:
pass
games = current_app.db_session.query(Game).filter_by(date=date).\
order_by(Game.time)
quad_freaks = _get_quad_freaks(games)
result = {
"day": date.strftime(defs.DATE_FORMAT),
"previous_day": prev_date,
"next_day": next_date,
"games": []
}
for game in games:
game_data = {
"uuid": game.uuid,
"map": game.map,
"scores": []
}
game_quad_freaks = quad_freaks.get(game.uuid, [])
for score in game.scores:
weapons = sorted(
score.weapons.keys(), key=lambda x: score.weapons[x]['kills'],
reverse=True
)
try:
favourite_weapon = weapons[0]
except IndexError:
favourite_weapon = None
is_quad_freak = score.player in game_quad_freaks
quad_pickups = 0
if is_quad_freak:
quad_pickups = game_quad_freaks[1]
game_data['scores'].append({
"player": score.player,
"score": score.score,
"kills": score.kills,
"deaths": score.deaths,
"suicides": score.suicides,
"favourite_weapon": favourite_weapon,
"quad_freak": is_quad_freak,
"quad_pickups": quad_pickups
})
result['games'].append(game_data)
return jsonify(result)