Coverage for src/battle_store.py: 0%

116 statements  

« prev     ^ index     » next       coverage.py v7.8.2, created at 2025-06-03 19:06 +0000

1import json 

2import logging 

3 

4import pandas as pd 

5 

6from src.configuration import config, store 

7from src.static.static_values_enum import MatchType, Format 

8from src.utils import store_util, progress_util, spl_util 

9 

10 

11def get_uid_array(team): 

12 uid_array = [team['summoner']['uid']] 

13 for monster in team['monsters']: 

14 uid_array.append(monster['uid']) 

15 return uid_array 

16 

17 

18def add_battle_store_big_my(account, team, battle, match_type): 

19 match_format = get_battle_format(battle['format']) 

20 created_date = battle['created_date'] 

21 mana_cap = battle['mana_cap'] 

22 rulesets = battle['ruleset'] 

23 inactive = battle['inactive'] 

24 battle_id = battle['battle_queue_id_1'] 

25 winner = battle['winner'] 

26 opponent = battle['player_2'] if battle['player_1'] == account else battle['player_1'] 

27 result = "win" if winner == account else "loss" 

28 

29 cards = list(team['monsters']) 

30 cards.append(team['summoner']) 

31 ruleset_split = ['None', 'None', 'None'] 

32 for idx, ruleset in enumerate(rulesets.split('|')): 

33 ruleset_split[idx] = ruleset 

34 

35 for card in cards: 

36 # add new row 

37 card_id = card['card_detail_id'] 

38 card_name = config.card_details_df.loc[card_id]['name'] 

39 df = pd.DataFrame({'card_detail_id': card_id, 

40 'card_name': card_name, 

41 'card_type': config.card_details_df.loc[card_id]['type'], 

42 'rarity': config.card_details_df.loc[card_id]['rarity'], 

43 'color': config.card_details_df.loc[card_id]['color'], 

44 'secondary_color': config.card_details_df.loc[card_id]['secondary_color'], 

45 'xp': card['xp'] if 'xp' in card else None, 

46 'gold': card['gold'], 

47 'level': card['level'], 

48 'edition': card['edition'], 

49 'account': account, 

50 'opponent': opponent, 

51 'created_date': created_date, 

52 'match_type': match_type, 

53 'format': match_format, 

54 'mana_cap': mana_cap, 

55 'ruleset1': ruleset_split[0], 

56 'ruleset2': ruleset_split[1], 

57 'ruleset3': ruleset_split[2], 

58 'inactive': inactive, 

59 'battle_id': battle_id, 

60 'winner': winner, 

61 'result': result, 

62 }, index=[0]) 

63 store.battle_big = pd.concat([store.battle_big, df], ignore_index=True) 

64 

65 

66def log_battle_note(count): 

67 limit = 50 

68 if count == limit: 

69 logging.info(str(limit) + ' or more battles to process consider running this program more often') 

70 logging.info('SPL API limits ' + str(limit) + ' battle history') 

71 else: 

72 logging.info(str(count) + ' battles to process') 

73 

74 

75def add_rating_log(account, battle): 

76 if battle['player_1'] == account: 

77 final_rating = battle['player_1_rating_final'] 

78 else: 

79 final_rating = battle['player_2_rating_final'] 

80 

81 match_format = get_battle_format(battle['format']) 

82 

83 df = pd.DataFrame({'created_date': battle['created_date'], 

84 'account': account, 

85 'rating': final_rating, 

86 'format': match_format, 

87 }, index=[0]) 

88 store.rating = pd.concat([store.rating, df], ignore_index=True) 

89 

90 

91def get_battle_format(battle_format): 

92 # format = null when wild 

93 if battle_format: 

94 return battle_format 

95 else: 

96 return Format.wild.value 

97 

98 

99def add_losing_battle_team(account, team, battle): 

100 match_type = battle['match_type'] 

101 match_format = get_battle_format(battle['format']) 

102 created_date = battle['created_date'] 

103 mana_cap = battle['mana_cap'] 

104 rulesets = battle['ruleset'] 

105 inactive = battle['inactive'] 

106 battle_id = battle['battle_queue_id_1'] 

107 opponent = battle['player_2'] if battle['player_1'] == account else battle['player_1'] 

108 

109 cards = list(team['monsters']) 

110 cards.append(team['summoner']) 

111 ruleset_split = ['None', 'None', 'None'] 

112 for idx, ruleset in enumerate(rulesets.split('|')): 

113 ruleset_split[idx] = ruleset 

114 

115 for card in cards: 

116 # add new row 

117 card_id = card['card_detail_id'] 

118 card_name = config.card_details_df.loc[card_id]['name'] 

119 df = pd.DataFrame({'card_detail_id': card_id, 

120 'card_name': card_name, 

121 'card_type': config.card_details_df.loc[card_id]['type'], 

122 'rarity': config.card_details_df.loc[card_id]['rarity'], 

123 'color': config.card_details_df.loc[card_id]['color'], 

124 'secondary_color': config.card_details_df.loc[card_id]['secondary_color'], 

125 'xp': card['xp'] if 'xp' in card else None, 

126 'gold': card['gold'], 

127 'level': card['level'], 

128 'edition': card['edition'], 

129 'account': account, 

130 'created_date': created_date, 

131 'match_type': match_type, 

132 'format': match_format, 

133 'mana_cap': mana_cap, 

134 'ruleset1': ruleset_split[0], 

135 'ruleset2': ruleset_split[1], 

136 'ruleset3': ruleset_split[2], 

137 'inactive': inactive, 

138 'battle_id': battle_id, 

139 'opponent': opponent, 

140 }, index=[0]) 

141 store.losing_big = pd.concat([store.losing_big, df], ignore_index=True) 

142 

143 

144def get_battles_to_process(account): 

145 battle_history = spl_util.get_battle_history_df(account) 

146 if battle_history is not None and \ 

147 not battle_history.empty and \ 

148 not store.last_processed.empty and \ 

149 not store.last_processed.loc[(store.last_processed.account == account)].empty: 

150 # filter out already processed 

151 last_processed_date = \ 

152 store.last_processed.loc[(store.last_processed.account == account)].last_processed.values[0] 

153 battle_history = battle_history.loc[(battle_history['created_date'] > last_processed_date)] 

154 return battle_history 

155 

156 

157def process_battle(account): 

158 battle_history = get_battles_to_process(account) 

159 if battle_history is not None: 

160 log_battle_note(len(battle_history.index)) 

161 if not battle_history.empty: 

162 for index, battle in battle_history.iterrows(): 

163 match_type = battle['match_type'] 

164 

165 battle_details = battle.details 

166 if not is_surrender(battle_details) and not is_training(battle): 

167 winner_name = battle_details['winner'] 

168 

169 if battle_details['team1']['player'] == account: 

170 my_team = battle_details['team1'] 

171 opponent_team = battle_details['team2'] 

172 else: 

173 my_team = battle_details['team2'] 

174 opponent_team = battle_details['team1'] 

175 

176 if 'is_brawl' in battle_details and battle_details['is_brawl']: 

177 match_type = MatchType.BRAWL.value 

178 

179 add_battle_store_big_my(account, 

180 my_team, 

181 battle, match_type) 

182 

183 # If a ranked match also log the rating 

184 if match_type and match_type == MatchType.RANKED.value: 

185 add_rating_log(account, battle) 

186 

187 # If the battle is lost store losing battle 

188 if winner_name != account: 

189 add_losing_battle_team(account, 

190 opponent_team, 

191 battle) 

192 else: 

193 logging.debug("Surrender match skip") 

194 

195 last_processed_date = \ 

196 battle_history.sort_values(by='created_date', ascending=False)['created_date'].iloc[0] 

197 update_last_processed_df(account, last_processed_date) 

198 else: 

199 logging.debug('No battles to process.') 

200 else: 

201 logging.debug('None battles to process.') 

202 

203 

204def update_last_processed_df(account, last_processed_date): 

205 if store.last_processed.empty or store.last_processed.loc[(store.last_processed.account == account)].empty: 

206 # create 

207 new = pd.DataFrame({'account': [account], 

208 'last_processed': [last_processed_date]}, 

209 index=[0]) 

210 store.last_processed = pd.concat([store.last_processed, new], ignore_index=True) 

211 else: 

212 store.last_processed.loc[ 

213 (store.last_processed.account == account), 

214 'last_processed'] = last_processed_date 

215 

216 

217def is_surrender(battle_details): 

218 return 'type' in battle_details and battle_details['type'] == 'Surrender' 

219 

220 

221def is_training(battle): 

222 return (battle['match_type'] == MatchType.CHALLENGE.value 

223 and json.loads(battle['settings'])['is_training'] == 'true') 

224 

225 

226def process_battles(): 

227 progress_util.update_daily_msg("Start processing battles") 

228 for account in store_util.get_account_names(): 

229 if store_util.get_token_dict(account): 

230 progress_util.update_daily_msg("...processing: " + account) 

231 process_battle(account) 

232 else: 

233 logging.info('Skip battle process... not token found. Check config page.')