Coverage for bundesliga_tippspiel/routes/betting.py: 87%

Shortcuts on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

69 statements  

1"""LICENSE 

2Copyright 2017 Hermann Krumrey <hermann@krumreyh.com> 

3 

4This file is part of bundesliga-tippspiel. 

5 

6bundesliga-tippspiel is free software: you can redistribute it and/or modify 

7it under the terms of the GNU General Public License as published by 

8the Free Software Foundation, either version 3 of the License, or 

9(at your option) any later version. 

10 

11bundesliga-tippspiel is distributed in the hope that it will be useful, 

12but WITHOUT ANY WARRANTY; without even the implied warranty of 

13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

14GNU General Public License for more details. 

15 

16You should have received a copy of the GNU General Public License 

17along with bundesliga-tippspiel. If not, see <http://www.gnu.org/licenses/>. 

18LICENSE""" 

19 

20from typing import List 

21 

22from bundesliga_tippspiel.utils.collections.Leaderboard import Leaderboard 

23from flask import render_template, request, Blueprint, flash, url_for, \ 

24 redirect, abort 

25from flask_login import login_required, current_user 

26from jerrycan.base import db 

27from bundesliga_tippspiel.db import Match, DisplayBotsSettings 

28from bundesliga_tippspiel.utils.matchday import validate_matchday 

29from bundesliga_tippspiel.db.user_generated.Bet import Bet 

30from bundesliga_tippspiel.utils.bets import place_bets as _place_bets 

31 

32 

33def define_blueprint(blueprint_name: str) -> Blueprint: 

34 """ 

35 Defines the blueprint for this route 

36 :param blueprint_name: The name of the blueprint 

37 :return: The blueprint 

38 """ 

39 blueprint = Blueprint(blueprint_name, __name__) 

40 

41 @blueprint.route("/bets", methods=["GET"]) 

42 @login_required 

43 def get_current_bets(): 

44 """ 

45 Displays all matches for the current matchday with entries for betting. 

46 :return: The response 

47 """ 

48 league, season, matchday = validate_matchday(None, None, None) 

49 return get_bets(league, season, matchday) 

50 

51 @blueprint.route("/bets/<string:league>/<int:season>/<int:matchday>", 

52 methods=["GET"]) 

53 @login_required 

54 def get_bets(league: str, season: int, matchday: int): 

55 """ 

56 Displays all matches for a matchday with entries for betting 

57 :param league: The league to display 

58 :param season: The season to display 

59 :param matchday: The matchday to display 

60 :return: The response 

61 """ 

62 validated = validate_matchday(league, season, matchday) 

63 if validated is None: 63 ↛ 64line 63 didn't jump to line 64, because the condition on line 63 was never true

64 return abort(404) 

65 league, season, matchday = validated 

66 

67 matches: List[Match] = Match.query.filter_by( 

68 matchday=matchday, 

69 season=season, 

70 league=league 

71 ).options( 

72 db.joinedload(Match.home_team), 

73 db.joinedload(Match.away_team) 

74 ).all() 

75 if len(matches) == 0: 75 ↛ 76line 75 didn't jump to line 76, because the condition on line 75 was never true

76 flash("Den angegebenen Spieltag gibt es nicht", "danger") 

77 return redirect(url_for("bets.get_bets")) 

78 matches.sort(key=lambda x: x.kickoff) 

79 has_started = matches[0].has_started 

80 all_started = matches[-1].has_started 

81 

82 bets = Bet.query.filter_by( 

83 matchday=matchday, 

84 season=season, 

85 league=league, 

86 user_id=current_user.id 

87 ).all() 

88 

89 matchday_points = 0 

90 for bet in bets: 

91 if bet.points is not None: 91 ↛ 92line 91 didn't jump to line 92, because the condition on line 91 was never true

92 matchday_points += bet.points 

93 

94 bet_match_map = { 

95 (x.home_team_abbreviation, x.away_team_abbreviation): x 

96 for x in bets 

97 } 

98 

99 bet_infos = [] 

100 for match_item in matches: 

101 index = ( 

102 match_item.home_team_abbreviation, 

103 match_item.away_team_abbreviation 

104 ) 

105 bet_infos.append((match_item, bet_match_map.get(index))) 

106 

107 leaderboard = None 

108 if has_started: 108 ↛ 116line 108 didn't jump to line 116, because the condition on line 108 was never false

109 leaderboard = Leaderboard( 

110 league, 

111 season, 

112 matchday, 

113 DisplayBotsSettings.get_state(current_user) 

114 ) 

115 

116 return render_template( 

117 "betting/bets.html", 

118 matchday=matchday, 

119 season=season, 

120 league=league, 

121 bet_infos=bet_infos, 

122 matchday_points=matchday_points, 

123 has_started=has_started, 

124 all_started=all_started, 

125 leaderboard=leaderboard 

126 ) 

127 

128 @blueprint.route("/bets", methods=["POST"]) 

129 @login_required 

130 def place_bets(): 

131 """ 

132 Places bets for a user 

133 Form data should be in the format: 

134 {'league_season_hometeam_awayteam': 'homescore_awayscore'} 

135 :return: The response 

136 """ 

137 bet_data = {} 

138 for identifier, value in request.form.items(): 

139 try: 

140 league, _season, day, home, away, mode = identifier.split("_") 

141 season = int(_season) 

142 matchday = int(day) 

143 score = int(value) 

144 id_tuple = (league, season, matchday, home, away) 

145 if id_tuple not in bet_data: 

146 bet_data[id_tuple] = {} 

147 bet_data[id_tuple][mode] = score 

148 except ValueError: 

149 continue 

150 

151 bets = [] 

152 for (league, season, matchday, home, away), scores in bet_data.items(): 

153 if "home" not in scores or "away" not in scores: 153 ↛ 154line 153 didn't jump to line 154, because the condition on line 153 was never true

154 continue 

155 else: 

156 bets.append(( 

157 league, season, matchday, 

158 home, away, scores["home"], scores["away"] 

159 )) 

160 _place_bets(current_user, bets) 

161 flash("Tipps erfolgreich gesetzt", "success") 

162 return redirect(url_for("betting.get_current_bets")) 

163 

164 return blueprint