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)
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)
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)
class BuildWorldMixin(object): """ this class is intended to be inherited by test classes that require fundamental things required for submitting lineups (ie: contests) """ DEFAULT_USER_PASSWORD = '******' def build_world(self): self.world = BuildWorldForTesting() self.world.build_world() def get_or_create_player(self): # player, created = PlayerChild.objects.get_or_create() # TODO pass 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 def create_user(self, username): """ creates a user and gives them $10,000 :param username: :return: """ user = User.objects.create(username=username) user.set_password(self.DEFAULT_USER_PASSWORD) user.save() Information.objects.create(user=user) ct = CashTransaction(user) ct.deposit(10000.00) return user
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
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
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
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)
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)