<commit_before>from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
import re
import json
from models import *
from django.utils.html import strip_tags

# API methods expect an HTTP header in the form:
# Authorization: Token <PASSWORD>
# where "abc123" is the secret token of an API key in the database

def api_token_required(view_func):
    def _wrapped_view_func(request, *args, **kwargs):
        if not 'HTTP_AUTHORIZATION' in request.META:
            return HttpResponse('Unauthorized', status=401)
        match = re.match('\s*Token\s*(\w+)\s*', request.META['HTTP_AUTHORIZATION'])
        if match is None or len(ApiKey.objects.filter(secret_token=match.group(1))) == 0:
            return HttpResponse('Unauthorized', status=401)
        return view_func(request, *args, **kwargs)
    return _wrapped_view_func

@api_token_required
def find_pairing(request):
    try:
        league_tag = request.GET.get('league', None)
        season_tag = request.GET.get('season', None)
        player = request.GET.get('player', None)
        white = request.GET.get('white', None)
        black = request.GET.get('black', None)
    except ValueError:
        return HttpResponse('Bad request', status=400)

    rounds = _get_active_rounds(league_tag, season_tag)
    if len(rounds) == 0:
        return JsonResponse({'updated': 0, 'error': 'no_data'})

    pairings = []
    for r in rounds:
        print r, pairings
        pairings += list(_get_pairings(r, player, white, black))

    if len(pairings) == 0:
        # Try alternate colors
        for r in rounds:
            pairings += list(_get_pairings(r, player, black, white))

    return JsonResponse({'pairings': [_export_pairing(p) for p in pairings]})

def _export_pairing(p):
    if hasattr(p, 'teamplayerpairing'):
        return {
            'league': p.team_pairing.round.season.league.tag,
            'season': p.team_pairing.round.season.tag,
            'round': p.team_pairing.round.number,
            'white_team': p.white_team().name,
            'white_team_number': p.white_team().number,
            'black_team': p.black_team().name,
            'black_team_number': p.black_team().number,
            'white': p.white.lichess_username,
            'white_rating': p.white.rating,
            'black': p.black.lichess_username,
            'black_rating': p.black.rating,
            'game_link': p.game_link,
            'result': p.result,
            'datetime': p.scheduled_time,
        }
    else:
        return {
            'league': p.round.season.league.tag,
            'season': p.round.season.tag,
            'round': p.round.number,
            'white': p.white.lichess_username,
            'white_rating': p.white.rating,
            'black': p.black.lichess_username,
            'black_rating': p.black.rating,
            'game_link': p.game_link,
            'result': p.result,
            'datetime': p.scheduled_time,
        }

@csrf_exempt
@api_token_required
def update_pairing(request):
    try:
        league_tag = request.POST.get('league', None)
        season_tag = request.POST.get('season', None)
        white = request.POST.get('white', None)
        black = request.POST.get('black', None)
        game_link = request.POST.get('game_link', None)
        result = request.POST.get('result', None)
    except ValueError:
        return HttpResponse('Bad request', status=400)

    rounds = _get_active_rounds(league_tag, season_tag)
    if len(rounds) == 0:
        return JsonResponse({'updated': 0, 'error': 'no_data'})

    pairings = []
    for r in rounds:
        pairings += _get_pairings(r, None, white, black)

    if len(pairings) == 0:
        return JsonResponse({'updated': 0, 'error': 'not_found'})
    if len(pairings) > 1:
        return JsonResponse({'updated': 0, 'error': 'ambiguous'})

    pairing = pairings[0]

    if game_link is not None:
        pairing.game_link = game_link
    if result is not None:
        pairing.result = result
    pairing.save()

    return JsonResponse({'updated': 1})

def _get_active_rounds(league_tag, season_tag):
    rounds = Round.objects.filter(publish_pairings=True, is_completed=False).order_by('-season__start_date', '-season__id', '-number')
    if league_tag is not None:
        rounds = rounds.filter(season__league__tag=league_tag)
    if season_tag is not None:
        rounds = rounds.filter(season__tag=season_tag)
    return rounds

def _get_pairings(round_, player=None, white=None, black=None):
    pairings = _filter_pairings(TeamPlayerPairing.objects.filter(team_pairing__round=round_).nocache(), player, white, black)
    pairings += _filter_pairings(LonePlayerPairing.objects.filter(round=round_).nocache(), player, white, black)
    return pairings

def _filter_pairings(pairings, player=None, white=None, black=None):
    if player is not None:
        white_pairings = pairings.filter(white__lichess_username__iexact=player)
        black_pairings = pairings.filter(black__lichess_username__iexact=player)
        pairings = white_pairings | black_pairings
    if white is not None:
        pairings = pairings.filter(white__lichess_username__iexact=white)
    if black is not None:
        pairings = pairings.filter(black__lichess_username__iexact=black)
    return list(pairings)

@api_token_required
def get_roster(request):
    try:
        league_tag = request.GET.get('league', None)
        season_tag = request.GET.get('season', None)
        if season_tag is not None:
            season_tag = int(season_tag)
    except ValueError:
        return HttpResponse('Bad request', status=400)

    try:
        seasons = Season.objects.order_by('-start_date', '-id')
        if league_tag is not None:
            seasons = seasons.filter(league__tag=league_tag)
        if season_tag is not None:
            seasons = seasons.filter(pk=season_tag)
        else:
            seasons = seasons.filter(is_active=True)

        season = seasons[0]
    except IndexError:
        return JsonResponse({'season_tag': None, 'players': None, 'teams': None, 'error': 'no_data'})

    season_players = season.seasonplayer_set.all()
    teams = season.team_set.order_by('number').all()

    return JsonResponse({
        'season_tag': season.tag,
        'players': [{
            'username': season_player.player.lichess_username,
            'rating': season_player.player.rating
        } for season_player in season_players],
        'teams': [{
            'name': team.name,
            'number': team.number,
            'players': [{
                'board_number': team_member.board_number,
                'username': team_member.player.lichess_username,
                'is_captain': team_member.is_captain
            } for team_member in team.teammember_set.order_by('board_number')]
        } for team in teams],
        'alternates': [{<commit_msg>Fix for get_rosters API method<commit_after>from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
import re
import json
from models import *
from django.utils.html import strip_tags

# API methods expect an HTTP header in the form:
# Authorization: Token <PASSWORD>
# where "abc123" is the secret token of an API key in the database

def api_token_required(view_func):
    def _wrapped_view_func(request, *args, **kwargs):
        if not 'HTTP_AUTHORIZATION' in request.META:
            return HttpResponse('Unauthorized', status=401)
        match = re.match('\s*Token\s*(\w+)\s*', request.META['HTTP_AUTHORIZATION'])
        if match is None or len(ApiKey.objects.filter(secret_token=match.group(1))) == 0:
            return HttpResponse('Unauthorized', status=401)
        return view_func(request, *args, **kwargs)
    return _wrapped_view_func

@api_token_required
def find_pairing(request):
    try:
        league_tag = request.GET.get('league', None)
        season_tag = request.GET.get('season', None)
        player = request.GET.get('player', None)
        white = request.GET.get('white', None)
        black = request.GET.get('black', None)
    except ValueError:
        return HttpResponse('Bad request', status=400)

    rounds = _get_active_rounds(league_tag, season_tag)
    if len(rounds) == 0:
        return JsonResponse({'updated': 0, 'error': 'no_data'})

    pairings = []
    for r in rounds:
        print r, pairings
        pairings += list(_get_pairings(r, player, white, black))

    if len(pairings) == 0:
        # Try alternate colors
        for r in rounds:
            pairings += list(_get_pairings(r, player, black, white))

    return JsonResponse({'pairings': [_export_pairing(p) for p in pairings]})

def _export_pairing(p):
    if hasattr(p, 'teamplayerpairing'):
        return {
            'league': p.team_pairing.round.season.league.tag,
            'season': p.team_pairing.round.season.tag,
            'round': p.team_pairing.round.number,
            'white_team': p.white_team().name,
            'white_team_number': p.white_team().number,
            'black_team': p.black_team().name,
            'black_team_number': p.black_team().number,
            'white': p.white.lichess_username,
            'white_rating': p.white.rating,
            'black': p.black.lichess_username,
            'black_rating': p.black.rating,
            'game_link': p.game_link,
            'result': p.result,
            'datetime': p.scheduled_time,
        }
    else:
        return {
            'league': p.round.season.league.tag,
            'season': p.round.season.tag,
            'round': p.round.number,
            'white': p.white.lichess_username,
            'white_rating': p.white.rating,
            'black': p.black.lichess_username,
            'black_rating': p.black.rating,
            'game_link': p.game_link,
            'result': p.result,
            'datetime': p.scheduled_time,
        }

@csrf_exempt
@api_token_required
def update_pairing(request):
    try:
        league_tag = request.POST.get('league', None)
        season_tag = request.POST.get('season', None)
        white = request.POST.get('white', None)
        black = request.POST.get('black', None)
        game_link = request.POST.get('game_link', None)
        result = request.POST.get('result', None)
    except ValueError:
        return HttpResponse('Bad request', status=400)

    rounds = _get_active_rounds(league_tag, season_tag)
    if len(rounds) == 0:
        return JsonResponse({'updated': 0, 'error': 'no_data'})

    pairings = []
    for r in rounds:
        pairings += _get_pairings(r, None, white, black)

    if len(pairings) == 0:
        return JsonResponse({'updated': 0, 'error': 'not_found'})
    if len(pairings) > 1:
        return JsonResponse({'updated': 0, 'error': 'ambiguous'})

    pairing = pairings[0]

    if game_link is not None:
        pairing.game_link = game_link
    if result is not None:
        pairing.result = result
    pairing.save()

    return JsonResponse({'updated': 1})

def _get_active_rounds(league_tag, season_tag):
    rounds = Round.objects.filter(publish_pairings=True, is_completed=False).order_by('-season__start_date', '-season__id', '-number')
    if league_tag is not None:
        rounds = rounds.filter(season__league__tag=league_tag)
    if season_tag is not None:
        rounds = rounds.filter(season__tag=season_tag)
    return rounds

def _get_pairings(round_, player=None, white=None, black=None):
    pairings = _filter_pairings(TeamPlayerPairing.objects.filter(team_pairing__round=round_).nocache(), player, white, black)
    pairings += _filter_pairings(LonePlayerPairing.objects.filter(round=round_).nocache(), player, white, black)
    return pairings

def _filter_pairings(pairings, player=None, white=None, black=None):
    if player is not None:
        white_pairings = pairings.filter(white__lichess_username__iexact=player)
        black_pairings = pairings.filter(black__lichess_username__iexact=player)
        pairings = white_pairings | black_pairings
    if white is not None:
        pairings = pairings.filter(white__lichess_username__iexact=white)
    if black is not None:
        pairings = pairings.filter(black__lichess_username__iexact=black)
    return list(pairings)

@api_token_required
def get_roster(request):
    try:
        league_tag = request.GET.get('league', None)
        season_tag = request.GET.get('season', None)
    except ValueError:
        return HttpResponse('Bad request', status=400)

    try:
        seasons = Season.objects.order_by('-start_date', '-id')
        if league_tag is not None:
            seasons = seasons.filter(league__tag=league_tag)
        if season_tag is not None:
            seasons = seasons.filter(tag=season_tag)
        else:
            seasons = seasons.filter(is_active=True)

        season = seasons[0]
    except IndexError:
        return JsonResponse({'season_tag': None, 'players': None, 'teams': None, 'error': 'no_data'})

    season_players = season.seasonplayer_set.all()
    teams = season.team_set.order_by('number').all()

    return JsonResponse({
        'league': season.league.tag,
        'season': season.tag,
        'players': [{
            'username': season_player.player.lichess_username,
            'rating': season_player.player.rating
        } for season_player in season_players],
        'teams': [{
            'name': team.name,
            'number': team.number,
            'players': [{
                'board_number': team_member.board_number,
                'username': team_member.player.lichess_username,
                'is_captain': team_member.is_captain
            } for team_member in team.teammember_set.order_by('board_number')]
        } for team in teams],
        'alternates': [{
{'fraction_non_alphanumeric': 0.11811652035115722, 'fraction_numerical': 0.004643401291445984, 'mean_word_length': 2.857822558074447, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1748276', 'n_tokens_mistral': 4305, 'n_tokens_neox': 4214, 'n_words': 919}