Example #1
0
def createNewGame(request):
    response = {}
    reqMethod = getPostOrGetRequest(request)
    print request.GET
    gameName = reqMethod.get("gameName")
    player = reqMethod.get("playerCount")
    try:
        gameObj = Game.objects.filter(name=gameName)
        if gameObj:
            gameObj = gameObj[0]
            gameObj.player = player
            gameObj.save()
            response = generateStatusJson('success',
                                          'Game updated successfully')

        else:
            gameObj = Game(name=gameName,
                           player=player,
                           roles='{}',
                           playerDetails='{}')
            gameObj.save()
            response = generateStatusJson('success',
                                          'Game created successfully')

    except Exception as e:
        response = generateStatusJson(
            'error',
            e.message.encode('ascii', 'ignore').strip())

    return HttpResponse(response, content_type='application/json')
Example #2
0
def update_free_games():
    free_games = []
    for extrator in FREE_GAME_EXTRACTORS:
        free_games += extrator()

    new_free_games = []
    for free_game in free_games:
        if helper.get_object_or_none(Game,
                                     game_id=free_game['id'],
                                     discount=100.0) == None:
            game = Game(
                provider_name=free_game['provider_name'],
                name=free_game['name'],
                source_url=free_game['url'],
                game_id=free_game['id'],
                original_price=0.0,
                discount=free_game['discount'],
            )
            game.save()
            new_free_games.append(game)

    # Delete expired free games
    undeleted_free_game_ids = [free_game['id'] for free_game in free_games]
    Game.objects.filter(discount=100.0).exclude(
        game_id__in=undeleted_free_game_ids).delete()

    if len(new_free_games) > 0:
        notify_new_free_games(new_free_games)
Example #3
0
    def update(self, instance: Game, validated_data: dict):
        categories_slugs_stringify = validated_data.pop('categories', '')
        categories_slugs = get_list_of_categories_from_stringify_list(
            categories_slugs_stringify)

        add_categories_for_game_creation(categories_slugs, instance)
        instance.__dict__.update(**validated_data)
        instance.save()

        return instance
Example #4
0
def initial_comp_setup():
    round_setup()
    for round in range(1, ROUNDS + 1):
        logger.info("Fetching round %s/%s...", round, ROUNDS)
        start = datetime.now()
        r = requests.get(
            "http://api.stats.foxsports.com.au/3.0/api/sports/league/series/1/seasons/116/rounds/"
            + str(round) +
            "/fixturesandresultswithbyes.json?userkey=A00239D3-45F6-4A0A-810C-54A347F144C2"
        )

        if round == 1:
            # Setup teams if they don't already exist
            team_ids = list(Team.objects.values_list('fox_id', flat=True))

            for game in json.loads(r.text):
                team = {}
                team['name'] = game["team_A"]["name"] + ' ' + game["team_A"][
                    "short_name"]
                team['fox_id'] = game["team_A"]["id"]
                if team['fox_id'] not in team_ids:
                    team_ids.append(team['fox_id'])
                    logger.info("Adding team %s to teams", team['name'])
                    new_team = Team(name=team['name'], fox_id=team['fox_id'])
                    new_team.save()

                team = {}
                team['name'] = game["team_B"]["name"] + ' ' + game["team_B"][
                    "short_name"]
                team['fox_id'] = game["team_B"]["id"]
                if team['fox_id'] not in team_ids:
                    team_ids.append(team['fox_id'])
                    logger.info("Adding team %s to teams", team['name'])
                    new_team = Team(name=team['name'], fox_id=team['fox_id'])
                    new_team.save()

        for game in json.loads(r.text):
            fixture_id = game["fixture_id"]
            round_object = Round.objects.get(round=round)
            game_time = parse_datetime(game["match_start_date"])
            home_team = Team.objects.get(fox_id=game["team_A"]["id"])
            away_team = Team.objects.get(fox_id=game["team_B"]["id"])
            stadium = game["venue"]["name"]
            new_game = Game(fixture_id=fixture_id,
                            start_time=game_time,
                            round=round_object,
                            home_team=home_team,
                            away_team=away_team,
                            stadium=stadium)
            new_game.save()
        end = datetime.now()
        elapsed_time = end - start
        if elapsed_time.total_seconds() < 5:
            time.sleep(5 - elapsed_time.total_seconds())
Example #5
0
def initial_comp_setup():
    round_setup()
    for round in range(1, ROUNDS+1):
        logger.info("Fetching round %s/%s...", round, ROUNDS)
        start = datetime.now()
        r = requests.get("http://api.stats.foxsports.com.au/3.0/api/sports/league/series/1/seasons/114/rounds/"+str(round)+"/fixturesandresultswithbyes.json?userkey=A00239D3-45F6-4A0A-810C-54A347F144C2")

        if round==1:
            teams = []
            for game in json.loads(r.text):
                team = {}
                team['name']=game["team_A"]["name"]+' '+game["team_A"]["short_name"]
                team['fox_id']=game["team_A"]["id"]
                if team not in teams:
                    teams.append(team)
                    logger.info("Adding team %s to teams", team['name'])
                    new_team=Team(name=team['name'], fox_id=team['fox_id'])
                    new_team.save()

                team = {}
                team['name']=game["team_B"]["name"]+' '+game["team_B"]["short_name"]
                team['fox_id']=game["team_B"]["id"]
                if team not in teams:
                    teams.append(team)
                    logger.info("Adding team %s to teams", team['name'])
                    new_team=Team(name=team['name'], fox_id=team['fox_id'])
                    new_team.save()



        for game in json.loads(r.text):
            fixture_id = game["fixture_id"]
            round_object = Round.objects.get(round=round)
            game_time = parse_datetime(game["match_start_date"])
            home_team = Team.objects.get(fox_id=game["team_A"]["id"])
            away_team = Team.objects.get(fox_id=game["team_B"]["id"])
            stadium = game["venue"]["name"]
            new_game = Game(fixture_id=fixture_id,
                            start_time = game_time,
                            round=round_object,
                            home_team=home_team,
                            away_team=away_team,
                            stadium=stadium)
            new_game.save()
        end = datetime.now()
        elapsed_time = end-start
        if elapsed_time.total_seconds()<5:
            time.sleep(5 - elapsed_time.total_seconds())
Example #6
0
def test_update_elo(users):
    """
    Test ELO is recalculated correctly
    The default result is Result(result=Result.WHITE_WINS, termination=Result.NORMAL)
    """

    player, opponent = users

    board_instance, _ = services.create_board_from_pgn(
        "api/pgn_games/fools_mate.pgn", starting_at=4)

    game = Game(
        board=board_instance,
        white_player=player,
        black_player=opponent,
        result=Result(result=Result.BLACK_WINS, termination=Result.NORMAL),
    )

    services.update_elo(game)

    assert player.elo.wins == 0
    assert opponent.elo.wins == 1

    assert player.elo.rating == 1184
    assert opponent.elo.rating == 1216
Example #7
0
 def new(self, request, *args, **kwargs):
     serializer = GameNewSerializer(data=request.data)
     game = None
     player = self.request.user
     if serializer.is_valid(raise_exception=True):
         rows = serializer.validated_data['rows']
         columns = serializer.validated_data['columns']
         mines = serializer.validated_data['mines']
         game = Game()
         game.title = 'Game for user %s' % player.username
         board, player_board = Game.new_boards(rows, columns, mines)
         game.board = board
         game.player_board = player_board
         game.state = Game.STATE_NEW
         game.player = player
         game.save()
     serializer = GameSerializer(game, context={'request': request})
     return Response(serializer.data)
Example #8
0
def game_instance(users):
    player, opponent = users

    return Game(
        board=BOARD_INSTANCE,
        white_player=player,
        black_player=opponent,
        result=Result(result=Result.BLACK_WINS, termination=Result.NORMAL),
    )
Example #9
0
async def test_receive(game_communicator):
    connected, _ = await game_communicator.connect()

    Game.objects.get = mock.MagicMock(return_value=Game(uuid=GAME_UUID))

    await game_communicator.send_to(json.dumps({"update": "foo"}))
    received_message = await game_communicator.receive_json_from()

    assert received_message["uuid"] == GAME_UUID

    await game_communicator.disconnect()
Example #10
0
def createNewGame(request):
    response={}
    reqMethod = getPostOrGetRequest(request)
    print request.GET
    gameName = reqMethod.get("gameName")
    player = reqMethod.get("playerCount")
    try:
        gameObj = Game.objects.filter(name=gameName)
        if gameObj:
            gameObj = gameObj[0]
            gameObj.player = player
            gameObj.save()
            response = generateStatusJson('success', 'Game updated successfully')

        else:
            gameObj = Game(name=gameName, player=player ,roles='{}',playerDetails='{}')
            gameObj.save()
            response = generateStatusJson('success', 'Game created successfully')

    except  Exception as e:
        response = generateStatusJson('error', e.message.encode('ascii', 'ignore').strip())

    return HttpResponse(response,content_type='application/json')
Example #11
0
def game_create(request):
    if request.method == "POST":
        # Generate a random, 6-digit number
        gameID = 0
        while gameID < 100000 or gameID > 999999:
            gameID = math.floor(random.random() * 10**6)

        # Create the game model
        game = Game(gameID=gameID)
        game.save()

        # Create the player model
        playerID = request.POST.get("playerID", "")
        playerName = request.POST.get("playerName", "")
        player = Player(game=game,
                        cookie=playerID,
                        name=playerName,
                        holdings=1500)
        player.save()

        return JsonResponse({"status": "success", "data": {"gameID": gameID}})
    else:
        return JsonResponse({"status": "error", "data": None})
Example #12
0
def client():
    config_dict = {
        "SQLALCHEMY_DATABASE_URI": "sqlite:///" + SQLITE_FILE_PATH,
        "DEBUG": True,
        "SQLALCHEMY_TRACK_MODIFICATIONS": False,
        "GIANTBOMB_KEY": "",
    }
    app = create_app(config_dict)
    app.app_context().push()

    # wait for sqlite file to be created
    time.sleep(2)
    from api.models import db, Game, Ranking

    db.drop_all()
    db.create_all()
    for i in range(len(game_ids)):
        game = {}
        game["id"] = game_ids[i]
        game["name"] = game_names[i]
        game["system"] = game_systems[i]
        game["gender"] = game_genders[i]
        game["current"] = True
        g = Game(game)
        db.session.add(g)
    db.session.commit()

    for i in range(len(ranking_ids)):
        ranking = {}
        ranking["id"] = ranking_ids[i]
        ranking["age"] = ranking_ages[i]
        ranking["symptom"] = ranking_symptoms[i]
        ranking["game_id"] = ranking_game_ids[i]
        ranking["rank"] = ranking_ranks[i]
        r = Ranking(ranking)
        db.session.add(r)
    db.session.commit()
    # for test client api reference
    # http://flask.pocoo.org/docs/1.0/api/#test-client
    client = app.test_client()
    yield client

    # remove the file
    os.remove(SQLITE_FILE_PATH)
Example #13
0
def recreate_db():
    """
    Recreates a local database. You probably should not use this on
    production.
    """
    db.drop_all()
    db.create_all()
    for i in range(len(game_ids)):
        game = {}
        game["id"] = game_ids[i]
        game["name"] = game_names[i]
        game["system"] = game_systems[i]
        game["gender"] = game_genders[i]
        game["description"] = game_descriptions[i]
        game["image"] = game_images[i]
        game["thumbnail"] = game_thumbnails[i]
        game["current"] = True
        g = Game(game)
        db.session.add(g)
    db.session.commit()
Example #14
0
def add_categories_for_game_creation(categories_slugs: list, game: Game):
    game.categories.set(Category.objects.filter(slug__in=categories_slugs))
    game.save()

    return game
Example #15
0
def new_game(request):
    game = Game()
    game.save()
    return Response(status=status.HTTP_200_OK, data={"game_link": game.id})
Example #16
0
def get_recent_matches(summoner_id, region):
    """
    Retrieves game data for last 10 games played by a summoner, given a summoner ID and region.

    This potentially executes several queries:
    -first, we get match history.
        -game stats
        -IDs of participants
    -then we make a list of summoner IDs that we don't have in the DB
        -this gets broken up into MAX_IDS chunks and each chunk is a queried as a single call for basic summoner data

    Since match history returns the last 10 games, and each game can have 9 other players
    (assuming non-hexakill mode) - that's 90 potentially unknown summoner IDs + 1 for the summoner in question,
    giving us 91 summoner IDs that we need to query.

    91 / 40 = 2.275 rounded up is 3 queries at most for summoner ID data.

    3 + 1 (for the initial match history call) = 4 calls at most.
    """

    #print 'get_recent_matches()', summoner_id, region

    recent = riot_api.get_recent_games(summoner_id, region)

    # First make a set of the associated summoner IDs (a set cannot have duplicate entries).
    unique_players = set()
    for g in recent['games']:
        if 'fellowPlayers' in g:
            for p in g['fellowPlayers']:
                unique_players.add(p['summonerId'])

    # Now we take note of any summoner IDs we already have cached (so we can remove them).
    to_remove = set()
    for p in unique_players:
        try:
            Summoner.objects.filter(region=region).get(summoner_id=p)
            to_remove.add(p)
        except ObjectDoesNotExist:
            pass

    # Remove the already cached summoner IDs from the working set.
    for p in to_remove:
        unique_players.remove(p)

    player_list = list(
        unique_players
    )  # make a list of the set, so we can call chunks() on it

    # Don't forget, we have to check for the summoner ID whose history we're examining as well!
    try:
        Summoner.objects.filter(region=region).get(summoner_id=summoner_id)
    except ObjectDoesNotExist:  # if it isn't cached, and it isn't in the list yet, add it
        if summoner_id not in player_list:
            player_list.append(summoner_id)

    query_list = list(
        chunks(player_list, MAX_IDS)
    )  # query_list now holds a list of lists of at most MAX_ID elements

    # Now ask the API for info on summoners, at most MAX_ID at a time.
    #print 'Now asking for participants...'
    summoner_dto = []
    for i in query_list:
        summoner_dto.append(riot_api.get_summoners(ids=i, region=region))

    #print 'Done getting participants!'

    # TODO: This part is sometimes getting duplicate summoners! (fixed?)
    # Now put those summoner DTOs in the cache.
    for chunk in summoner_dto:
        for player in chunk:
            # for v in chunk[player]:
            #     print v, len(v)
            #print u'ADDING summoner {}'.format(chunk[player]['name'])
            summoner = Summoner(summoner_id=chunk[player]['id'],
                                name=chunk[player]['name'],
                                std_name=chunk[player]['name'].replace(
                                    ' ', '').lower(),
                                profile_icon_id=chunk[player]['profileIconId'],
                                revision_date=chunk[player]['revisionDate'],
                                summoner_level=chunk[player]['summonerLevel'],
                                region=region)

            # Sometimes requests will go out synchronously for the same summoner.
            # This means the cache is not hit and a double query for a single summoner occurs.
            # Duplicate summoners are prevented via the unique_together constraint on summoner_id and region,
            # which will throw IntegrityError and prevent the dupe from being made.
            try:
                #print summoner.name, len(summoner.name)
                summoner.save()
            except IntegrityError:
                pass

    # Requires summoners (as well as all related field values) to be cached before-hand (summoner caching done above).
    for match in recent['games']:
        # first fill in the simple stuff
        game = Game(
            summoner_id=Summoner.objects.filter(region=region).get(
                summoner_id=summoner_id),
            champion_id=Champion.objects.get(champion_id=match['championId']),
            create_date=match['createDate'],
            game_id=match['gameId'],
            game_mode=match['gameMode'],
            game_type=match['gameType'],
            invalid=match['invalid'],
            ip_earned=match['ipEarned'],
            level=match['level'],
            map_id=match['mapId'],
            spell_1=SummonerSpell.objects.get(spell_id=match['spell1']),
            spell_2=SummonerSpell.objects.get(spell_id=match['spell2']),
            sub_type=match['subType'],
            team_id=match['teamId'],
            region=region,
            champion_key=Champion.objects.get(
                champion_id=match['championId']).key)

        stats = RawStat()

        # Here we add stats that were returned (only stats that aren't None or 0 will be returned by API)
        for i in match['stats']:
            setattr(stats, inflection.underscore(i), match['stats'][i])

        stats.save()

        # associate the RawStat object with this game
        game.stats = stats

        game_saved = False

        # Ensures no dupes of Game (or any related objects).
        try:
            game.save()
            game_saved = True
        except IntegrityError:
            pass

        # if game saved, we're good and just need to add the participating players
        if game_saved:
            # associate each Player object with this game
            if 'fellowPlayers' in match:
                for p in match['fellowPlayers']:
                    player = Player(
                        champion=Champion.objects.get(
                            champion_id=p['championId']),
                        summoner=Summoner.objects.filter(region=region).get(
                            summoner_id=p['summonerId']),
                        team_id=p['teamId'],
                        participant_of=game)
                    player.save()
        else:  # if it didn't save, we can get rid of the stats object too.
            stats.delete()
Example #17
0
    if host:
        p = Profile.objects.get(nickname=host[:-1])
        try:
            e = Event.objects.get(host=p, date=date)
        except:
            print("No event")
            e = Event(league=league, host=p, date=date, status='F')
            e.save()
        g = None
        try:
            g = Game.objects.get(event=e, number=int(game))
        except:
            print("No game")
            try:
                g = Game(event=e, number=int(game), stake=stake)
                g.save()
            except:
                pass
        if g:
            j = 0
            for player in df.columns[7:-3]:
                placing = df[df.columns[7 + j]][i]
                j = j + 1
                if placing in [0, 1, 2, 3]:
                    print(player, placing)
                    p = Profile.objects.get(nickname=player)
                    try:
                        pg = GamePlayer.objects.get(game=g, player=p)
                    except:
                        pg = GamePlayer(game=g, player=p)
Example #18
0
 def test_create_game(self):
     data = {"id": 11, "name": "test"}
     game = Game.from_json(data)
     self.assertEqual(data["id"], game.id)
     self.assertEqual(data["name"], game.name)
Example #19
0
 def setUp(self) -> None:
     Game.objects.bulk_create(
         [Game(**game_data) for game_data in TestData.TEST_GAMES_DATA])
     self.user = User.objects.create_user(
         username=TestData.TEST_USERNAME,
         password=TestData.TEST_USER_PASSWORD)
Example #20
0
def post_games_async(file_id):
    tmpfile = None
    try:
        tmpfile = db.session.query(TmpFile).filter(
            TmpFile.id == file_id).first()
        book = xlrd.open_workbook(file_contents=tmpfile.file)
        # Entering the games into database
        id = 0
        # dictionary to store ids of current games and tags of old games
        game_info_dict = {}
        for sheet in book.sheets():
            # Each sheet has the system name at the top
            system = str(sheet.cell(0, 1).value).strip()
            game_info_dict[system] = {}
            count = 0
            current_row = 0
            # Exit out of the while loop when it has iterated through all categories on the page
            # SYMPTOM_NUMBER = 6
            while count != 2 * SYMPTOM_NUMBER:
                # Iterate through white space to where the ranking begins, at ranking = 1
                while sheet.cell(current_row, 0).value != 1:
                    current_row += 1
                initial_row = current_row
                # Iterates through the two age categories that are side by side in the spread sheet
                # AGE_NUMBER = 2
                for age_index in range(AGE_NUMBER):
                    name = str(
                        sheet.cell(current_row,
                                   2 * age_index + 1).value).strip()
                    # Iterates through the rankings of a specific symptom and category until the end
                    while name != "":
                        # Checks if the game has already been found
                        if name.lower() not in game_info_dict[system]:
                            game = {}
                            game["system"] = system
                            game["name"] = name
                            game["gender"] = str(
                                sheet.cell(current_row,
                                           2 * age_index + 2).value).strip()
                            game["id"] = id
                            # API extra information stuff
                            extra_data = get_giantbomb_data(name)
                            game["thumbnail"] = extra_data["thumbnail"]
                            game["image"] = extra_data["image"]
                            game["description"] = extra_data["description"]
                            game["current"] = True
                            g = Game(game)
                            db.session.add(g)
                            game_info_dict[system][name.lower()] = {"id": id}
                            id = id + 1
                        current_row += 1
                        # Breaks out of the loop if we have reached the end of the sheet
                        if current_row == sheet.nrows:
                            break
                        name = str(
                            sheet.cell(current_row,
                                       2 * age_index + 1).value).strip()
                    # If the sheet only has one age category
                    if sheet.ncols < FULL_COLUMN_NUMBER:
                        count += 2
                        break
                    # If we are on the first age category, reset row to beginning row of the age category
                    if age_index == 0:
                        current_row = initial_row
                    count += 1
        # query returns previous state
        old_games = db.session.query(Game).all()
        for old_game in old_games:
            # if game has not been found in new spreadsheet
            if old_game.name.lower() not in game_info_dict[old_game.system]:
                old_game_dict = old_game.to_dict()
                old_game_dict["id"] = id
                old_game_dict["current"] = False
                id = id + 1
                # define tags for ranking purposes
                game_info_dict[old_game.system][old_game.name.lower()] = {
                    "ages": [
                        age[0] for age in db.session.query(
                            Ranking.age).distinct(Ranking.age).filter(
                                Ranking.game_id == old_game.id).all()
                    ],
                    "symptoms": [
                        symptom[0] for symptom in db.session.query(
                            Ranking.symptom).distinct(Ranking.symptom).filter(
                                Ranking.game_id == old_game.id).all()
                    ],
                }
                g = Game(old_game_dict)
                db.session.add(g)
        # delete before flushing
        db.session.query(Ranking).delete()
        db.session.query(Game).delete()
        # flushing pushes changes to database but does not persist them
        db.session.flush()
        # Entering the rankings into the database
        id = 0
        for sheet in book.sheets():
            system = sheet.cell(0, 1).value
            start_row = 0
            for symptom_index in range(SYMPTOM_NUMBER):
                start_row = start_row + 1
                while sheet.cell(start_row, 0).value != "Rank":
                    start_row = start_row + 1
                for age_index in range(AGE_NUMBER):
                    if (1 + 2 * age_index < sheet.ncols and len(
                            sheet.cell(start_row, 1 + 2 * age_index).value) !=
                            0):
                        system_symptom_age = sheet.cell(
                            start_row, 1 + 2 * age_index).value
                        if (system_symptom_age ==
                                "Oculus Rift (Short Term) - 13 and Above"):
                            symptom = "Bored (Short Term)"
                            age = "13 and Older"
                        else:
                            descriptors = system_symptom_age.split("-")
                            symptom = descriptors[1].strip()
                            if symptom == "Pain Management":
                                symptom = "Pain"
                            elif symptom == "Calming":
                                symptom = "Anxiety/Hyperactivity"
                            elif symptom == "Cheering":
                                symptom = "Sadness"
                            elif symptom == "Fuzzy":
                                symptom = "Cognitive Impairment"
                            age = descriptors[2].strip()
                            if age == "13 and Above":
                                age = "13 and Older"
                        for game_index in range(NUMBER_RANKINGS):
                            rank = int(
                                sheet.cell(start_row + 1 + game_index,
                                           0).value)
                            name = str(
                                sheet.cell(start_row + 1 + game_index,
                                           1 + 2 * age_index).value).strip()
                            if len(name) != 0:
                                # fetch id from dict
                                game_id = game_info_dict[system][
                                    name.lower()]["id"]
                                ranking = {}
                                ranking["id"] = id
                                ranking["age"] = age
                                ranking["symptom"] = symptom
                                ranking["game_id"] = game_id
                                ranking["rank"] = rank
                                r = Ranking(ranking)
                                db.session.add(r)
                                id = id + 1
        # iterate through all games defined as "old" (not current)
        old_games = db.session.query(Game).filter(Game.current == False).all()
        for old_game in old_games:
            old_game_dict = old_game.to_dict()
            # create rankings behind all other for all age/symptom combinations
            for age in game_info_dict[old_game.system][
                    old_game.name.lower()]["ages"]:
                for symptom in game_info_dict[old_game.system][
                        old_game.name.lower()]["symptoms"]:
                    ranking = {}
                    ranking["id"] = id
                    ranking["age"] = age
                    ranking["symptom"] = symptom
                    ranking["game_id"] = old_game_dict["id"]
                    ranking["rank"] = 26
                    r = Ranking(ranking)
                    db.session.add(r)
                    id = id + 1
        db.session.query(Update).delete()
        update = {}
        update["time"] = datetime.now(
            pytz.timezone("UTC")).strftime("%I:%M:%S %p, %m/%d/%Y")
        update["valid"] = True
        u = Update(update)
        db.session.add(u)
        db.session.commit()
        print("Success")
        db.session.delete(tmpfile)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        db.session.query(Update).filter(Update.valid == False).delete()
        update = {}
        update["time"] = datetime.now(
            pytz.timezone("UTC")).strftime("%I:%M:%S %p, %m/%d/%Y")
        update["valid"] = False
        u = Update(update)
        db.session.add(u)
        db.session.commit()
        print(e)
        print(tmpfile.id)
        db.session.delete(tmpfile)
        db.session.commit()
Example #21
0
def get_recent_matches(summoner_id, region):
    """
    Retrieves game data for last 10 games played by a summoner, given a summoner ID and region.

    This potentially executes several queries:
    -first, we get match history.
        -game stats
        -IDs of participants
    -then we make a list of summoner IDs that we don't have in the DB
        -this gets broken up into MAX_IDS chunks and each chunk is a queried as a single call for basic summoner data

    Since match history returns the last 10 games, and each game can have 9 other players
    (assuming non-hexakill mode) - that's 90 potentially unknown summoner IDs + 1 for the summoner in question,
    giving us 91 summoner IDs that we need to query.

    91 / 40 = 2.275 rounded up is 3 queries at most for summoner ID data.

    3 + 1 (for the initial match history call) = 4 calls at most.
    """

    #print 'get_recent_matches()', summoner_id, region

    recent = riot_api.get_recent_games(summoner_id, region)

    # First make a set of the associated summoner IDs (a set cannot have duplicate entries).
    unique_players = set()
    for g in recent['games']:
        if 'fellowPlayers' in g:
            for p in g['fellowPlayers']:
                unique_players.add(p['summonerId'])

    # Now we take note of any summoner IDs we already have cached (so we can remove them).
    to_remove = set()
    for p in unique_players:
        try:
            Summoner.objects.filter(region=region).get(summoner_id=p)
            to_remove.add(p)
        except ObjectDoesNotExist:
            pass

    # Remove the already cached summoner IDs from the working set.
    for p in to_remove:
        unique_players.remove(p)

    player_list = list(unique_players)  # make a list of the set, so we can call chunks() on it

    # Don't forget, we have to check for the summoner ID whose history we're examining as well!
    try:
        Summoner.objects.filter(region=region).get(summoner_id=summoner_id)
    except ObjectDoesNotExist:  # if it isn't cached, and it isn't in the list yet, add it
        if summoner_id not in player_list:
            player_list.append(summoner_id)

    query_list = list(chunks(player_list, MAX_IDS))  # query_list now holds a list of lists of at most MAX_ID elements

    # Now ask the API for info on summoners, at most MAX_ID at a time.
    #print 'Now asking for participants...'
    summoner_dto = []
    for i in query_list:
        summoner_dto.append(riot_api.get_summoners(ids=i, region=region))

    #print 'Done getting participants!'

    # TODO: This part is sometimes getting duplicate summoners! (fixed?)
    # Now put those summoner DTOs in the cache.
    for chunk in summoner_dto:
        for player in chunk:
            # for v in chunk[player]:
            #     print v, len(v)
            #print u'ADDING summoner {}'.format(chunk[player]['name'])
            summoner = Summoner(summoner_id=chunk[player]['id'],
                                name=chunk[player]['name'],
                                std_name=chunk[player]['name'].replace(' ', '').lower(),
                                profile_icon_id=chunk[player]['profileIconId'],
                                revision_date=chunk[player]['revisionDate'],
                                summoner_level=chunk[player]['summonerLevel'],
                                region=region)

            # Sometimes requests will go out synchronously for the same summoner.
            # This means the cache is not hit and a double query for a single summoner occurs.
            # Duplicate summoners are prevented via the unique_together constraint on summoner_id and region,
            # which will throw IntegrityError and prevent the dupe from being made.
            try:
                #print summoner.name, len(summoner.name)
                summoner.save()
            except IntegrityError:
                pass

    # Requires summoners (as well as all related field values) to be cached before-hand (summoner caching done above).
    for match in recent['games']:
        # first fill in the simple stuff
        game = Game(summoner_id=Summoner.objects.filter(region=region).get(summoner_id=summoner_id),
                    champion_id=Champion.objects.get(champion_id=match['championId']),
                    create_date=match['createDate'],
                    game_id=match['gameId'],
                    game_mode=match['gameMode'],
                    game_type=match['gameType'],
                    invalid=match['invalid'],
                    ip_earned=match['ipEarned'],
                    level=match['level'],
                    map_id=match['mapId'],
                    spell_1=SummonerSpell.objects.get(spell_id=match['spell1']),
                    spell_2=SummonerSpell.objects.get(spell_id=match['spell2']),
                    sub_type=match['subType'],
                    team_id=match['teamId'],
                    region=region,
                    champion_key=Champion.objects.get(champion_id=match['championId']).key)

        stats = RawStat()

        # Here we add stats that were returned (only stats that aren't None or 0 will be returned by API)
        for i in match['stats']:
            setattr(stats, inflection.underscore(i), match['stats'][i])

        stats.save()

        # associate the RawStat object with this game
        game.stats = stats

        game_saved = False

        # Ensures no dupes of Game (or any related objects).
        try:
            game.save()
            game_saved = True
        except IntegrityError:
            pass

        # if game saved, we're good and just need to add the participating players
        if game_saved:
            # associate each Player object with this game
            if 'fellowPlayers' in match:
                for p in match['fellowPlayers']:
                    player = Player(champion=Champion.objects.get(champion_id=p['championId']),
                                    summoner=Summoner.objects.filter(region=region).get(summoner_id=p['summonerId']),
                                    team_id=p['teamId'],
                                    participant_of=game)
                    player.save()
        else:  # if it didn't save, we can get rid of the stats object too.
            stats.delete()