Exemplo n.º 1
0
    def validate_lineup_players_match_existing_entries(self, lineup, entries):
        """
        validate the lineup has the same players as any entries that already exist

        :param lineup: the lineup attempted to be entered
        :param entries: entry objects which 'lineup' must be equivalent to (ie: have the same players)
        :return:
        """
        # print('+---------------------------------------------+')
        # print('lineup name:', str(lineup.name))
        if len(entries) == 0:
            return

        lm = LineupManager(self.user)
        player_srids = lm.get_player_srids(lineup)

        for entry in entries:
            if entry.lineup is None:
                continue
            entry_lineup_player_srids = lm.get_player_srids(entry.lineup)
            if Counter(player_srids) != Counter(entry_lineup_player_srids):
                # debug
                # print('Counter(player_srids) != Counter(entry_lineup_player_srids)')
                # print('lineup       :', str(dict(Counter(player_srids))))
                # print('entry lineup :', str(dict(Counter(entry_lineup_player_srids))))
                err_msg = "Lineup must match the existing lineup '%s' for this Contest." % lineup.name
                raise LineupDoesNotMatchExistingEntryLineup(err_msg)
Exemplo n.º 2
0
    def get_lineup_data(self, user, lineup_id):
        """
        get lineup data we can show to other users, with masked
        out players whos games have not started yet.

        this is the "single team" version of the ContestLineupManager
        method that gets all lineups in a contest,

        ... this gets all the player stats for players in games.

        :param lineup_id:
        :return:
        """
        lm = LineupManager(user)
        return lm.get_lineup_from_id(lineup_id, self.contest)
Exemplo n.º 3
0
    def post(self, request, *args, **kwargs):
        """
        get the Lineup objects
        """
        args = request.data

        # get the contest_id post param - it is required
        contest_id = args.get('contest_id', None)

        # get the lineup_ids or the search_str
        lineup_ids = args.get('lineup_ids', [])
        search_str = args.get('search_str', None)

        # return Response({}, status=status.HTTP_200_OK)
        # return Response({}, status=status.HTTP_401_UNAUTHORIZED)

        if contest_id is None:
            msg = (
                'The POST param "contest_id" is required along with either: "lineup_ids",'
                '"search_str"')
            raise ValidationError(msg)

        lm = LineupManager(self.request.user)

        if lineup_ids:
            #
            # return the lineup usernames for the lineups with the ids, in the particular contest
            # return lm.get_for_contest_by_ids( contest_id, lineup_ids)
            lineups = lm.get_for_contest_by_ids(contest_id, lineup_ids)
            serialized_lineup_data = self.get_serialized_lineups(lineups)
            return Response(serialized_lineup_data, status=status.HTTP_200_OK)

        elif search_str:
            #
            # get the distinct lineups in this contest where the lineup_id matches
            # return lm.get_for_contest_by_search_str(contest_id, search_str)
            lineups = lm.get_for_contest_by_search_str(contest_id, search_str)
            serialized_lineup_data = self.get_serialized_lineups(lineups)
            return Response(serialized_lineup_data, status=status.HTTP_200_OK)
        else:
            lineups = lm.get_for_contest(contest_id)
            serialized_lineup_data = self.get_serialized_lineups(lineups)
            return Response(serialized_lineup_data, status=status.HTTP_200_OK)
Exemplo n.º 4
0
    def get_raw_bytes(self):
        """
        generate the bytes of the payload which contains the
        number of lineups, players per lineup, and each lineup

        note:
            In [21]: struct.calcsize('i')       # 'i' is an integer
            Out[21]: 4

            In [22]: struct.calcsize('h')       # 'h' is a short
            Out[22]: 2

        :return: bytes
        """
        if self.contest.draft_group.start > timezone.now():
            return bytearray()

        bytes = bytearray(self.get_size_in_bytes())
        # print( '# contest entries:', str(self.contest.entries))
        offset, bytes = self.pack_into_h('>i', bytes, 0, self.contest.entries)
        # print( '# players per lineup:', str(self.players_per_lineup))
        offset, bytes = self.pack_into_h('>H', bytes, offset,
                                         self.players_per_lineup)

        for e in self.entries:
            # pack the lineup id
            # print( '    <add lineup> %s' % str(e.lineup.pk), '  : bytes[%s]' % str(len(bytes) ) )
            offset, bytes = self.pack_into_h('>i', bytes, offset, e.lineup.pk)

            # pack in each player in the lineup, in order of course
            lm = LineupManager(e.user)
            for pid in lm.get_player_ids(e.lineup):
                # print( '        pid:', str(pid ))
                # offset, bytes = self.pack_into_h( '>h', bytes, offset, pid )
                # print( 'pid:', str( pid ) )

                offset, bytes = self.pack_into_h('>H', bytes, offset, pid)

        # all the bytes should be packed in there now!
        return bytes
Exemplo n.º 5
0
    def dev_get_all_lineups(self, contest_id):
        """
        for testing purposes, get all the lineups as json.
        """

        settings_module_name = os.environ['DJANGO_SETTINGS_MODULE']
        # 'mysite.settings.local'   should let this method work
        if 'local' not in settings_module_name:
            raise Exception(
                'json from dev_get_all_lineups not allowed unless local settings being used'
            )

        lineups = []

        for e in self.entries:

            lineup_id = e.lineup.pk
            player_ids = []

            # pack in each player in the lineup, in order of course
            lm = LineupManager(e.user)
            for pid in lm.get_player_ids(e.lineup):
                # player_ids.append( self.starter_map[ pid ] ) # masks out no-yet-started players
                player_ids.append(pid)

            lineups.append({
                'lineup_id': lineup_id,
                'player_ids': player_ids,
            })

        data = {
            'endpoint': '/contest/all-lineups/%s?json' % int(contest_id),
            'bytes_for_condensed_response': self.get_size_in_bytes(),
            'total_lineups': self.contest.entries,
            'players_per_lineup': self.players_per_lineup,
            'lineups': lineups,
        }
        return data
Exemplo n.º 6
0
    def create_valid_lineup(self, user):
        players_pos_1 = PlayerChild.objects.filter(
            position=self.world.position1).distinct('team')
        players_pos_2 = PlayerChild.objects.filter(
            position=self.world.position2).order_by('-team').distinct('team')
        self.one = players_pos_1[0]
        self.two = players_pos_2[0]
        self.three = players_pos_1[1]
        self.four = players_pos_2[1]

        team = [self.one, self.two, self.three]
        for player in team:
            c_type = ContentType.objects.get_for_model(player)
            draftgroup_player = Player.objects.get(
                salary_player__player_type=c_type,
                salary_player__player_id=player.pk,
                draft_group=self.world.draftgroup)
            draftgroup_player.salary = 10000
            draftgroup_player.save()

        self.lm = LineupManager(user)
        self.team = [self.one.pk, self.two.pk, self.three.pk]
        self.lineup = self.lm.create_lineup(self.team, self.world.draftgroup)
        return self.lineup
Exemplo n.º 7
0
    def payout(self, contests=None, finalize_score=True):
        """
        Takes in an array of contests to payout. If there are not contests passed
        then the payout mechanism will look for all contests who have not been
        paid out yet and pay them out.
        :param contests: an array of :class:`contest.models.Contest` models
        :param finalize_score: always True in production.
            (may be set to False to skip the re-scoring during payouts).
        """

        #
        # validation if the contests are passed as an argument
        if contests is not None:
            #
            # validate that contests is an array
            if not isinstance(contests, list):
                raise mysite.exceptions.IncorrectVariableTypeException(
                    type(self).__name__, 'contests')

            #
            # validate the contest array is an array of contests
            for contest in contests:
                if not isinstance(contest, Contest):
                    raise mysite.exceptions.IncorrectVariableTypeException(
                        type(self).__name__, 'contests')

        #
        # if payout() was called with no arguments,
        # find contests that need to be paid out.
        else:
            #
            # gets all the contests that are completed
            contests = Contest.objects.filter(status=Contest.COMPLETED)

        if finalize_score:
            #
            # get the unique draft group ids within this queryset of contests.
            # update the final scoring for the players in the distinct draft groups.
            draft_group_ids = list(
                set([
                    c.draft_group.pk for c in contests if c.draft_group != None
                ]))
            for draft_group_id in draft_group_ids:
                draft_group_manager = DraftGroupManager()
                try:
                    draft_group_manager.update_final_fantasy_points(
                        draft_group_id)
                except FantasyPointsAlreadyFinalizedException:
                    pass  # its possible the contest we are trying to payout was already finalized

            #
            # update the fantasy_points for each unique Lineup.
            # get the unique lineups from the contests' entries,
            # so we're not doing extra processing...
            lineups = Lineup.objects.filter(
                draft_group__pk__in=draft_group_ids)
            for lineup in lineups:
                lineup_manager = LineupManager(lineup.user)
                lineup_manager.update_fantasy_points(lineup)

        #
        # finally, we can pay out the contests!
        for contest in contests:
            self.__payout_contest(contest)
 def get_player_stats(entry):
     lm = LineupManager(entry.user)
     return lm.get_lineup_from_id(entry.lineup.id, entry.contest)
Exemplo n.º 9
0
    def post(self, request):
        draft_group_id = request.data.get('draft_group')
        players = request.data.get('players', [])
        name = request.data.get('name', '')

        user_lineups = Lineup.objects.filter(user=request.user,
                                             draft_group_id=draft_group_id).values_list('name',
                                                                                        flat=True)
        if name and name in user_lineups:
            raise ValidationError(
                {'detail': 'You already have lineup with this name.'})

        # the draft_group_id has been validated by the serializer
        try:
            draft_group = DraftGroup.objects.get(pk=draft_group_id)
        except DraftGroup.DoesNotExist:
            raise ValidationError({'detail': 'Draft group does not exist.'})

        # use the lineup manager to create the lineup
        try:
            lm = LineupManager(request.user)
        except:
            raise APIException('Invalid user')

        # Attempt to create the lineup.
        try:
            lineup = lm.create_lineup(players, draft_group, name)
            # Keep track of if the user has created a lineup.
            request.user.information.has_created_a_lineup = True
            request.user.information.save()
        # Catch all of the lineupManager exceptions and return validation errors.
        except (
                LineupDoesNotMatchUser,
                NotEnoughTeamsException,
                LineupDoesNotMatchExistingEntryLineup,
                InvalidLineupSizeException,
                InvalidLineupSalaryException,
                LineupInvalidRosterSpotException,
                PlayerDoesNotExistInDraftGroupException,
                DuplicatePlayerException,
                PlayerSwapGameStartedException,
                EditLineupInProgressException,
                LineupUnchangedException,
                CreateLineupExpiredDraftgroupException,
                DraftgroupLineupLimitExceeded,
        ) as e:
            logger.warning("%s | user: %s" % (e, self.request.user))
            raise ValidationError({'detail': e})
        # Catch everything else and log.
        except Exception as e:
            logger.error(e)
            client.captureException()
            raise APIException({'detail': 'Unable to save lineup.'})

        # Log event to user log
        create_user_log(
            request=request,
            user=request.user,
            type=_account_const.CONTEST,
            action=_account_const.LINEUP_CREATED,
            metadata={
                'detail': 'Lineup was created.',
                'lineup_id': lineup.id,
                'players': players,
            }
        )

        # Serialize the lineup and send it back to the client.
        saved_lineup = LineupSerializer(lineup)
        # On successful lineup creation:
        return Response({
            'detail': 'Lineup created.',
            'lineup_id': lineup.id,
            'lineup': saved_lineup.data,
        }, status=status.HTTP_201_CREATED)