kahoot-cli 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
kahoot_cli/__init__.py ADDED
@@ -0,0 +1,11 @@
1
+ # Hey! Thanks for downloading my package. It means a lot to me. Also, this is the first real project I've ever made and published, so you might find some bugs. If you do, post an issue on GitHub, and I'll gladly take a look!
2
+ from .kahoot_cli import *
3
+ from selenium import webdriver
4
+ from selenium.webdriver.chrome.options import Options
5
+ from selenium.webdriver.common.by import By
6
+ import time
7
+ # Used by CLI
8
+ from termcolor import colored
9
+ import os
10
+ from readchar import readkey, key
11
+ import random
kahoot_cli/__main__.py ADDED
@@ -0,0 +1,413 @@
1
+ from kahoot_cli import *
2
+ if __name__ == "__main__":
3
+ def printSelectedAnswer(options: list, option_no: int = 0, question_type: str = "Quiz", picked_options: list = []):
4
+ if question_type == "Quiz":
5
+ if option_no == 0:
6
+ print(colored(f"> {options[0]}", "red", None, ["bold"]))
7
+ print(colored(f" {options[1]}", "blue", None, ["bold"]))
8
+ if len(options) >= 3:
9
+ print(colored(f" {options[2]}", "yellow", None, ["bold"]))
10
+ if len(options) >= 4:
11
+ print(colored(f" {options[3]}", "green", None, ["bold"]))
12
+ elif option_no == 1:
13
+ print(colored(f" {options[0]}", "red", None, ["bold"]))
14
+ print(colored(f"> {options[1]}", "blue", None, ["bold"]))
15
+ if len(options) >= 3:
16
+ print(colored(f" {options[2]}", "yellow", None, ["bold"]))
17
+ if len(options) >= 4:
18
+ print(colored(f" {options[3]}", "green", None, ["bold"]))
19
+ if option_no == 2:
20
+ print(colored(f" {options[0]}", "red", None, ["bold"]))
21
+ print(colored(f" {options[1]}", "blue", None, ["bold"]))
22
+ if len(options) >= 3:
23
+ print(colored(f"> {options[2]}", "yellow", None, ["bold"]))
24
+ if len(options) >= 4:
25
+ print(colored(f" {options[3]}", "green", None, ["bold"]))
26
+ elif option_no == 3:
27
+ print(colored(f" {options[0]}", "red", None, ["bold"]))
28
+ print(colored(f" {options[1]}", "blue", None, ["bold"]))
29
+ if len(options) >= 3:
30
+ print(colored(f" {options[2]}", "yellow", None, ["bold"]))
31
+ if len(options) >= 4:
32
+ print(colored(f"> {options[3]}", "green", None, ["bold"]))
33
+ elif question_type == "TorF":
34
+ if option_no == 0:
35
+ print(colored(f"> {options[0]}", "blue", None, ["bold"])) # Yes, red is blue and blue is red. I know that.
36
+ print(colored(f" {options[1]}", "red", None, ["bold"]))
37
+ elif option_no == 1:
38
+ print(colored(f" {options[0]}", "blue", None, ["bold"]))
39
+ print(colored(f"> {options[1]}", "red", None, ["bold"]))
40
+ elif question_type == "Multi":
41
+ if option_no == 0:
42
+ print(colored(f"> {options[0]}", "red", None, ["bold"]))
43
+ elif option_no != 0:
44
+ if 0 in picked_options:
45
+ print(colored(">", "white", None, ["bold"]) ,colored(f"{options[0]}", "red", None, ["bold"]))
46
+ else:
47
+ print(colored(f" {options[0]}", "red", None, ["bold"]))
48
+ if option_no == 1:
49
+ print(colored(f"> {options[1]}", "blue", None, ["bold"]))
50
+ elif option_no != 1:
51
+ if 1 in picked_options:
52
+ print(colored(">", "white", None, ["bold"]), colored(f"{options[1]}", "blue", None, ["bold"]))
53
+ else:
54
+ print(colored(f" {options[1]}", "blue", None, ["bold"]))
55
+ if option_no == 2 and len(options) >= 3:
56
+ print(colored(f"> {options[2]}", "yellow", None, ["bold"]))
57
+ elif option_no != 2 and len(options) >= 3:
58
+ if 2 in picked_options:
59
+ print(colored(">", "white", None, ["bold"]), colored(f"{options[2]}", "yellow", None, ["bold"]))
60
+ else:
61
+ print(colored(f" {options[2]}", "yellow", None, ["bold"]))
62
+ if option_no == 3 and len(options) >= 4:
63
+ print(colored(f"> {options[3]}", "green", None, ["bold"]))
64
+ elif option_no != 3 and len(options) >= 4:
65
+ if 3 in picked_options:
66
+ print(colored(">", "white", None, ["bold"]), colored(f"{options[3]}", "green", None, ["bold"]))
67
+ else:
68
+ print(colored(f" {options[3]}", "green", None, ["bold"]))
69
+ if option_no == amountOptions:
70
+ if picked_options == []:
71
+ print(colored(f"> SUBMIT", "dark_grey", None, ["bold"]))
72
+ else:
73
+ print(colored(f"> SUBMIT", "white", None, ["bold"]))
74
+ elif option_no != amountOptions:
75
+ if picked_options == []:
76
+ print(colored(f" SUBMIT", "dark_grey", None, ["bold"]))
77
+ else:
78
+ print(colored(f" SUBMIT", "white", None, ["bold"]))
79
+ correctMessages = ["Way to go, superstar!", "Amazing!", "Trust me, your oponents are jealous.", "One step closer to victory!", "Keep the flame lit!"]
80
+ wrongMessages = ["Don't worry, you'll get them next time!", "Never back down never what?", "Nice try!"]
81
+
82
+
83
+ print(colored("""
84
+ ██╗░░██╗░█████╗░██╗░░██╗░█████╗░░█████╗░████████╗░░░░░░░█████╗░██╗░░░░░██╗
85
+ ██║░██╔╝██╔══██╗██║░░██║██╔══██╗██╔══██╗╚══██╔══╝░░░░░░██╔══██╗██║░░░░░██║
86
+ █████═╝░███████║███████║██║░░██║██║░░██║░░░██║░░░█████╗██║░░╚═╝██║░░░░░██║
87
+ ██╔═██╗░██╔══██║██╔══██║██║░░██║██║░░██║░░░██║░░░╚════╝██║░░██╗██║░░░░░██║
88
+ ██║░╚██╗██║░░██║██║░░██║╚█████╔╝╚█████╔╝░░░██║░░░░░░░░░╚█████╔╝███████╗██║
89
+ ╚═╝░░╚═╝╚═╝░░╚═╝╚═╝░░╚═╝░╚════╝░░╚════╝░░░░╚═╝░░░░░░░░░░╚════╝░╚══════╝╚═╝""", (100, 53, 173)))
90
+
91
+ print("Welcome to Kahoot_CLI! Made by @Aquaticsanti\n")
92
+
93
+ client = KahootClient()
94
+ pin = ""
95
+
96
+ while True:
97
+ try:
98
+ if pin == "":
99
+ pin = input("Input the game pin: ")
100
+ if "https://kahoot.it" in pin: # For development purposes, this also takes copied links (I do not want to copy the pin manually)
101
+ pass
102
+ else:
103
+ pin = pin.replace(" ", "")
104
+ pin = int(pin)
105
+ except ValueError:
106
+ pin = input("That doesn't look like a number... Please input the game pin: ")
107
+ if "https://kahoot.it" in pin: # For development purposes, this also takes copied links (I do not want to copy the pin manually)
108
+ pass
109
+ else:
110
+ pin = int(pin)
111
+ else:
112
+ break
113
+
114
+ while True:
115
+ try:
116
+ joinedGame = client.JoinGame(pin)
117
+ except InvalidPinError:
118
+ try:
119
+ pin = input("Uh oh, the pin is invalid. Input the game pin (no spaces): ")
120
+ if "https://kahoot.it/" in pin:
121
+ pass
122
+ else:
123
+ pin = int(pin)
124
+ except ValueError:
125
+ pin = input("That doesn't look like a number... Please input the game pin (no spaces): ")
126
+ if "https://kahoot.it/" in pin:
127
+ pass
128
+ else:
129
+ pin = int(pin)
130
+ joinedGame = client.JoinGame(pin)
131
+ else:
132
+ break
133
+
134
+ if joinedGame == "ok":
135
+ validNickname = False
136
+ nickname = input("What's your name? (Don't use your real name): ")
137
+ while validNickname != True:
138
+ if nickname == "":
139
+ nickname = input("Uh oh, looks like your nickname is blank. Please choose a valid nickname (Don't use your real name): ")
140
+ elif len(nickname) > 15:
141
+ nickname = input("Uh oh, looks like your nickname is too long. Please choose a nickname with less than 15 characters (Don't use your real name): ")
142
+ else:
143
+ try:
144
+ nicknameSet = client.SetNickname(nickname)
145
+ except InvalidNameError:
146
+ nickname = input("Uh oh, looks like your nickname was taken. Please choose another nickname (Don't use your real name): ")
147
+ else:
148
+ break
149
+
150
+ elif joinedGame == "namerator":
151
+ print("This game uses a random name generator!")
152
+ print("Press", colored("enter", None, None, ["italic"]), "to re-roll, and", colored("space", None, None, ["italic"]), "to select!")
153
+ spins = 3
154
+ while True:
155
+ keypress = readkey()
156
+ if keypress == key.ENTER:
157
+ if spins > 0:
158
+ spins -= 1
159
+ print("Rolling...", end="\r")
160
+ nickname = client.Namerator(roll = True)
161
+ print("Your nickname is...", colored(nickname, None, None, ["bold"]))
162
+ print(colored(f"{spins} spins left", "dark_grey"))
163
+ else:
164
+ print("Uh oh, looks like there's no spins left! Please press", colored("space", None, None, ["italic"]), "to select.")
165
+ elif keypress == key.SPACE:
166
+ try:
167
+ nickname = client.Namerator(keep=True)
168
+ except NameratorError:
169
+ print("Please roll once!")
170
+ else:
171
+ break
172
+
173
+
174
+ while True:
175
+ CurrentState = client.ClientState()
176
+ if CurrentState == "Lobby":
177
+ try:
178
+ if nicknameSet != "": # Check if random name generator wasn't used
179
+ pass
180
+ except NameError:
181
+ print("You're in! See your name on the screen?")
182
+ else:
183
+ if nicknameSet not in ["ok", "twoauth"]:
184
+ nickname = nicknameSet
185
+ print(f"Your name has been changed to {nickname}")
186
+ else:
187
+ print("You're in! See your name on the screen?")
188
+ print(colored("Note: Reactions and avatars are not supported yet.", "dark_grey"))
189
+ break
190
+ elif CurrentState == "Quiz":
191
+ break
192
+ elif CurrentState == "TwoAuth":
193
+ try:
194
+ if AuthValid == True:
195
+ pass # This is supposed to check if the combo exists, AKA if it's the first time inputting the code
196
+ except NameError:
197
+ print("Looks like this game uses 2FA! Please input the combination shown on screen.")
198
+ print(colored("r", "red"), "for", colored("red", "red"), end=", ")
199
+ print(colored("b", "blue"), "for", colored("blue", "blue"), end=", ")
200
+ print(colored("y", "yellow"), "for", colored("yellow", "yellow"), end=", ")
201
+ print("and", colored("g", "green"), "for", colored("green", "green"))
202
+ else:
203
+ print("Please input the combination shown on screen.")
204
+ combo = input()
205
+ while True:
206
+ if len(combo) != 4:
207
+ combo = input("That combo is invalid, please try again: ")
208
+ else:
209
+ combo2 = []
210
+ for char in combo:
211
+ if char not in ["r", "b", "y", "g", "R", "B", "Y", "G"]:
212
+ combo = input("That combo is invalid, please try again: ")
213
+ break
214
+ else:
215
+ combo2.append(char.lower())
216
+ if len(combo) == 4: # Not the best solution, but I guess it works?
217
+ break
218
+ AuthValid = client.TwoAuth(combo2)
219
+ time.sleep(0.5)
220
+ if AuthValid == False:
221
+ print("Uh oh, that combo was invalid.")
222
+ else:
223
+ pass
224
+ if CurrentState == "Out":
225
+ print("Uh oh, looks like you've been kicked out. Exiting...")
226
+ os._exit(1) # Source - https://stackoverflow.com/a/49950466
227
+ if CurrentState == "Quiz" or CurrentState == "Start":
228
+ break
229
+
230
+ while True:
231
+ CurrentState = client.ClientState()
232
+ if CurrentState == "Start":
233
+ print("Get ready!")
234
+ question_no = 1
235
+ break
236
+ elif CurrentState == "Quiz":
237
+ break
238
+
239
+
240
+ while True: # This encapsulates the whole game logic.
241
+ CurrentState = client.ClientState()
242
+ while CurrentState != "Quiz":
243
+ CurrentState = client.ClientState()
244
+
245
+ cls() # Source - https://stackoverflow.com/a/684344, Clears entire CLI
246
+
247
+ question = client.GetQuestion()
248
+ total_points = client.GetPoints()
249
+ optionList = question[3:]
250
+ print(colored(f"{client.nickname} - {total_points} points", "dark_grey"))
251
+ if question[0] == "Quiz" or question[0] == "TorF":
252
+ if question[1] != "":
253
+ print(f"Question {question[2]} - {question[1]}")
254
+ else:
255
+ print(f"Question {question[2]}")
256
+ elif question[0] == "Multi":
257
+ if question[1] == "":
258
+ print(f"Question {question[2]}", colored(" (MULTIPLE CHOICE!)", None, None, ["bold"]))
259
+ else:
260
+ print(f"Question {question[2]} - {question[1]}", colored(" (MULTIPLE CHOICE!)", None, None, ["bold"]))
261
+
262
+ amountOptions = len(question) - 3
263
+
264
+ if question[0] == "Multi":
265
+ amountOptions += 1 # To account for the submit button
266
+ picked_ans = []
267
+
268
+ selected_ans = 0
269
+
270
+ printSelectedAnswer(optionList, selected_ans, question[0])
271
+ while True:
272
+ CurrentState = client.ClientState(fast=True)
273
+ if CurrentState == "Res":
274
+ break
275
+ keypress = readkey()
276
+ if keypress == key.RIGHT or keypress == key.LEFT:
277
+ continue
278
+ print(f"\033[{amountOptions+1}A") # Moves cursor up x lines, Source - https://stackoverflow.com/a/72667369
279
+ if keypress == key.UP:
280
+ CurrentState = client.ClientState(fast=True)
281
+ if CurrentState == "Res":
282
+ break
283
+ selected_ans -= 1
284
+ if selected_ans < 0:
285
+ selected_ans = amountOptions
286
+ if question[0] != "Multi":
287
+ printSelectedAnswer(optionList, selected_ans, question[0])
288
+ else:
289
+ printSelectedAnswer(optionList, selected_ans, question[0], picked_ans)
290
+ if keypress == key.DOWN:
291
+ CurrentState = client.ClientState(fast=True)
292
+ if CurrentState == "Res":
293
+ break
294
+ selected_ans += 1
295
+ if selected_ans > amountOptions:
296
+ selected_ans = 0
297
+ if question[0] != "Multi":
298
+ printSelectedAnswer(optionList, selected_ans, question[0])
299
+ else:
300
+ printSelectedAnswer(optionList, selected_ans, question[0], picked_ans)
301
+ if keypress == key.ENTER:
302
+ CurrentState = client.ClientState(fast=True)
303
+ if CurrentState == "Res":
304
+ break
305
+ if question[0] == "Quiz" or question[0] == "TorF":
306
+ printSelectedAnswer(optionList, selected_ans, question[0])
307
+ client.AnswerQuestion(selected_ans)
308
+ break
309
+ elif question[0] == "Multi":
310
+ printSelectedAnswer(optionList, selected_ans, question[0], picked_ans)
311
+ if selected_ans == 0:
312
+ if 0 not in picked_ans:
313
+ picked_ans.append(0)
314
+ elif 0 in picked_ans:
315
+ picked_ans.remove(0)
316
+ elif selected_ans == 1:
317
+ if 1 not in picked_ans:
318
+ picked_ans.append(1)
319
+ elif 1 in picked_ans:
320
+ picked_ans.remove(1)
321
+ elif selected_ans == 2:
322
+ if 2 not in picked_ans:
323
+ picked_ans.append(2)
324
+ elif 2 in picked_ans:
325
+ picked_ans.remove(2)
326
+ elif selected_ans == 3:
327
+ if 3 not in picked_ans:
328
+ picked_ans.append(3)
329
+ elif 3 in picked_ans:
330
+ picked_ans.remove(3)
331
+ elif selected_ans == amountOptions:
332
+ if picked_ans == []:
333
+ continue
334
+ else:
335
+ client.AnswerQuestion(picked_ans)
336
+ break
337
+
338
+ while CurrentState != "Res":
339
+ CurrentState = client.ClientState(True)
340
+ result = client.GetResult()
341
+ if type(result) == str:
342
+ if result == "NoTime":
343
+ print(colored("You ran out of time...", "red", None, ["bold"]))
344
+ print(wrongMessages[random.randrange(len(wrongMessages))])
345
+ elif result == "Lose":
346
+ print(colored("Wrong...", "red", None, ["bold"]))
347
+ print(wrongMessages[random.randrange(len(wrongMessages))])
348
+ else:
349
+ if result[0] == "Win":
350
+ print(colored(f"Correct! {result[1]} points", "green", None, ["bold"]))
351
+ print(correctMessages[random.randrange(len(correctMessages))])
352
+ else:
353
+ print(colored("Partially Correct", "light_blue", None, ["bold"]), f"- {result[0]} right answers, for {result[1]} points")
354
+
355
+ leaderboard_pos = client.GetLeaderboardPos()
356
+ leaderboard_pos_int = str(leaderboard_pos[0])
357
+ leaderboard_pos_int += "th"
358
+ if leaderboard_pos[0] != "Podium":
359
+ print(f"You're in {leaderboard_pos_int} place,", leaderboard_pos[1])
360
+ else:
361
+ print("You're in the podium!")
362
+
363
+ while True: # Check if game has finished, or if there's another question
364
+ CurrentState = client.ClientState(fast=True)
365
+ if CurrentState == "Quiz":
366
+ finished = False
367
+ break
368
+ elif CurrentState == "End":
369
+ finished = True
370
+ cls()
371
+ break
372
+ else:
373
+ pass
374
+
375
+ if finished == False:
376
+ pass
377
+ elif finished == True:
378
+ break
379
+
380
+ ranking = client.GetFinalRanking()
381
+
382
+ if ranking not in [0, 1, 2, 3]:
383
+ ranking = str(ranking)
384
+ leaderboard_pos_int += "th"
385
+ while True:
386
+ try:
387
+ total_points = client.GetPoints()
388
+ except:
389
+ pass
390
+ else:
391
+ break
392
+ print(f"You got {ranking} place, with a total of {total_points} points!!")
393
+ else:
394
+ print("Drumroll please...")
395
+ while True:
396
+ # TODO: Checkea q todo funcione, aca estaba fallando.
397
+ ranking = client.GetFinalRanking()
398
+ if ranking == 3:
399
+ total_points = client.GetPoints()
400
+ podiumPlace = 3
401
+ print("You got", colored("3rd place,", (205, 127, 50)), f"with a total of {total_points} points!")
402
+ break
403
+ elif ranking == 2:
404
+ total_points = client.GetPoints()
405
+ print("You got", colored("2nd place,", (192, 192, 192)), f"with a total of {total_points} points!")
406
+ break
407
+ elif ranking == 1:
408
+ total_points = client.GetPoints()
409
+ print("You got", colored("1st place,", (255, 215, 0)), f"with a total of {total_points} points!")
410
+ break
411
+ else:
412
+ pass
413
+