Hide keyboard shortcuts

Hot-keys 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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

"""LICENSE 

Copyright 2019 Hermann Krumrey <hermann@krumreyh.com> 

 

This file is part of footballbot. 

 

footballbot is free software: you can redistribute it and/or modify 

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

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

(at your option) any later version. 

 

footballbot is distributed in the hope that it will be useful, 

but WITHOUT ANY WARRANTY; without even the implied warranty of 

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

GNU General Public License for more details. 

 

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

along with footballbot. If not, see <http://www.gnu.org/licenses/>. 

LICENSE""" 

 

import json 

import requests 

from typing import List, cast, Dict, Any, Optional 

from bokkichat.entities.message.Message import Message 

from bokkichat.entities.message.TextMessage import TextMessage 

from kudubot.Bot import Bot 

from kudubot.db.Address import Address as Address 

from kudubot.parsing.CommandParser import CommandParser 

from footballbot.FootballParser import TableParser 

 

 

class FootballBot(Bot): 

""" 

Class that defines the behaviour of the bot 

""" 

 

leaguemap = { 

"bundesliga": "BL1", 

"germany1": "BL1", 

"germany2": "BL2", 

"germany3": "BL3", 

"premier league": "PL", 

"premierleague": "PL", 

"serie a": "SA", 

"seriea": "SA", 

"primera division": "PD", 

"primeradivision": "PD", 

"england1": "PL", 

"italy1": "SA", 

"spain1": "PD" 

} 

 

def on_msg(self, message: Message, address: Address): 

""" 

Handles received messages 

:param message: The received message 

:param address: The address of the sender 

:return: None 

""" 

parsed = self.parse(message) 

if parsed is None: 

return 

_, command, args = parsed 

reply = cast(TextMessage, message.make_reply()) 

 

if command == "list": 

reply.body = "Available leagues:\n" \ 

"1. Bundesliga (germany1)\n" \ 

"2. Bundesliga (germany2)\n" \ 

"3. Liga (germany3)\n" \ 

"Premier League (england1)\n" \ 

"Primera Division (spain1)\n" \ 

"Serie A (italy1)" 

elif command == "table": 

reply.body = self._get_table(args["league"]) 

elif command == "scorers": 

reply.body = self._get_goalscorers(args["league"]) 

else: 

return 

 

self.connection.send(reply) 

 

@classmethod 

def name(cls) -> str: 

""" 

:return: The name of the bot 

""" 

return "footballbot" 

 

@classmethod 

def parsers(cls) -> List[CommandParser]: 

""" 

Defines the command parsers to be used 

:return: The parsers to use 

""" 

return [TableParser()] 

 

@classmethod 

def extra_config_args(cls) -> List[str]: 

""" 

:return: The list of required settings parameters 

""" 

return ["football_info_api_key"] 

 

def _load_data(self, endpoint: str) -> Optional[Dict[str, Any]]: 

""" 

Load data from an API endpoint 

:param endpoint: The endpoint to call 

:return: The retrieved data, or None if something failed 

""" 

headers = {"X-Auth-Token": self.extras["football_info_api_key"]} 

url = "https://api.football-data.org/v2/{}".format(endpoint) 

resp = requests.get(url, headers=headers) 

 

if resp.status_code != 200: 

return None 

 

return json.loads(resp.text) 

 

def _get_table(self, league: str) -> str: 

""" 

Retrieves the current league table of a league 

:param league: The league for which to fetch the data 

:return: The (formatted) table as a string, or an error message if 

the requested league/year did not exist 

""" 

league = self.leaguemap.get(league.lower(), league) 

endpoint = "competitions/{}/standings".format(league) 

data = self._load_data(endpoint) 

 

if data is None: 

return "Invalid League {}".format(league) 

 

table_msg = "# | Team | Points" 

table = data["standings"][0]["table"] 

for position in table: 

team = position["team"] 

table_msg += "\n{} | {} | {}".format( 

position["position"], team["name"], position["points"] 

) 

 

return table_msg 

 

def _get_goalscorers(self, league: str) -> str: 

""" 

Retrieves a list of goal scorers for a league 

:param league: 

:return: 

""" 

 

league = self.leaguemap.get(league.lower(), league) 

endpoint = "competitions/{}/scorers?limit=25".format(league) 

data = self._load_data(endpoint) 

 

if data is None: 

return "Invalid League {}".format(league) 

 

scorers_msg = "# | Player | Goals" 

for i, scorer in enumerate(data["scorers"]): 

scorer_name = scorer["player"]["name"] 

goals = scorer["numberOfGoals"] 

scorers_msg += "\n{} | {} | {}".format( 

i + 1, 

scorer_name, 

goals 

) 

 

return scorers_msg