-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
223 lines (149 loc) · 5.98 KB
/
main.py
File metadata and controls
223 lines (149 loc) · 5.98 KB
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
import requests
import xml.etree.ElementTree as ET
from InquirerPy import inquirer
from InquirerPy.base.control import Choice
from InquirerPy.validator import NumberValidator
base_url = "https://api.geekdo.com/xmlapi"
def main():
action = inquirer.select(
message="What do you want to do:",
choices=[
Choice(value="collection", name="Get my collection"),
Choice(value="by_id", name="Find a game by ID" ),
Choice(value="by_name", name="Find a game by name"),
Choice(value=None, name="Exit"),
],
default="collection",
).execute()
if action:
if ("collection" == action):
username = inquirer.text(message="What's your BGG username?").execute()
get_collection(username)
if ("by_id" == action):
id = inquirer.text(message="What's the ID?", validate=NumberValidator()).execute()
get_boardgame_by_id(id, True)
if ("by_name" == action):
name = inquirer.text(message="What's the name of the game?").execute()
search_boardgame(name)
def get_collection(username = ""):
if ("" == username ):
return
collection = []
wishlist = []
collection_route = f"{base_url}/collection/{username}"
print(f"Looking for this user's BGG collection: {username}\n")
root = get_xml_root(collection_route)
if ("" == root):
return
for item in root.iter('item'):
status = item.find('status')
owned = status.get('own')
wishlisted = status.get('wishlist')
name = item.find('name').text
if ( "1" == owned ):
collection.append(name)
if ( "1" == wishlisted ):
wishlist.append(name)
if ( 0 < len(collection) ):
print(f"I found these games in your collection:\n")
for gaem in collection:
print(f"{gaem}\r")
else:
print("I found no games in your collection.")
if ( 0 < len(wishlist) ):
print(f"\nI also found these games on your wishlist:\n")
for gaem in wishlist:
print(f"{gaem}\r")
def get_boardgame_by_id(id = 0, command=False):
if (0==id):
return
boardgame_route = f"{base_url}/boardgame/{id}"
if ( command ):
print(f"Looking for a game with this ID: {id}\n")
root = get_xml_root(boardgame_route)
name = root.find('boardgame/name[@primary="true"]').text
designer_node = root.find('boardgame/boardgamedesigner')
if ( designer_node is not None ):
designer = designer_node.text
published = root.find('boardgame/yearpublished').text
min_players = root.find('boardgame/minplayers').text
max_players = root.find('boardgame/maxplayers').text
player_poll = root.find('boardgame/poll[@name="suggested_numplayers"]')
best_playercount = parse_suggest_player_polls(player_poll)
player_string = f"It plays between {min_players} and {max_players} players"
if command:
print(f"I have found this game: {name}.\n")
else:
print(f"I have found a game with that name!\n")
if designer_node is not None:
print(f"It was designed by {designer} and published in {published}.\n")
else:
print(f"I've no idea who designed it, but it was published in {published}.\n")
if ( 0 != best_playercount ):
player_string += f", but polls suggest that it's best with {best_playercount} players."
else:
player_string += "."
print(player_string)
def search_boardgame(query = ""):
if (""==query):
return
search_route = f"{base_url}/search?search={query}"
print(f"Looking for a game with this query: \"{query}\"\n")
root = get_xml_root(search_route)
results = root.findall('boardgame')
result_count = len(results)
if ( 0 == result_count ):
retry = inquirer.confirm(message="I've found nothing. Want to try again?", default=True).execute()
if retry:
new_query = inquirer.text(message="Okay, great. What's the name of the game?", default=query).execute()
search_boardgame(new_query)
else:
return
if (1 < result_count):
found_games = []
game_id = 0
for game in root.iter('boardgame'):
name = game.find('name')
if (None != name):
found_games.append(name.text)
if name.text == query:
game_id = game.get("objectid")
if query in found_games and 0 != game_id:
get_boardgame_by_id( game_id )
else:
retry = inquirer.confirm(message=f"I've found {result_count} results, but none match your search query exactly. Would you like to refine your search?", default=True).execute()
if retry:
new_query = inquirer.text(message="Okay, great. What game are you looking for?", default=query).execute()
search_boardgame(new_query)
else:
print(f"No problem, here are the games I did find:\n")
for gaem in found_games:
print(f"{gaem}\r")
return
if (1 == result_count):
game_id = root.find('boardgame').get("objectid")
get_boardgame_by_id( game_id )
def get_xml_root(route = ""):
if ("" == route):
return
req = requests.get(route)
root = ET.fromstring(req.content)
return root
def parse_suggest_player_polls(poll = ""):
if ( "" == poll ):
return 0
best_playercount = 0
most_votes = 0
for result in poll.iter('results'):
poll_player_count = result.get('numplayers')
for result_count in result.iter('result'):
vote_name = result_count.get("value")
if ( "Best" != vote_name ):
continue
vote_count = int(result_count.get('numvotes'))
if vote_count > most_votes:
most_votes = vote_count
best_playercount = poll_player_count
return best_playercount
if __name__ == "__main__":
main()