-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathmain.py
133 lines (112 loc) · 5.41 KB
/
main.py
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
import json
import tkinter.messagebox as tm
import traceback
from tkinter import *
from requests import Session
from answer_handler import AnswerHandler
class InvalidLoginDetails(Exception):
pass
class LoginFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.label_username = Label(self, text="Email")
self.label_password = Label(self, text="Password")
self.entry_username = Entry(self)
self.entry_password = Entry(self, show="*")
self.label_username.grid(row=0, sticky=E)
self.label_password.grid(row=1, sticky=E)
self.entry_username.grid(row=0, column=1)
self.entry_password.grid(row=1, column=1)
self.log_btn = Button(self, text="Login", command=self._login_btn_clicked)
self.log_btn.grid(columnspan=2)
self.pack()
def _login_btn_clicked(self):
email = self.entry_username.get()
password = self.entry_password.get()
if '@' not in email:
email += '@kedst.ac.uk'
try:
Interface(email, password)
except InvalidLoginDetails as e:
print(e, file=sys.stderr)
tm.showerror("Login error", "Incorrect Email or Password")
class Interface:
"""
main interface between user and script
"""
def __init__(self, email, password):
self.session = Session()
self.test_login(email, password)
self.handler = AnswerHandler(self.session)
root.destroy() # destroy login menu
self.print_init()
self.print_instructions()
self.main_loop()
def main_loop(self):
"""
main interface loop
will only exit if ctl-c is pressed
"""
print('Press ctrl-c to quit')
while True:
url = input('\nType Question url: ')
handler = AnswerHandler(self.session)
res, err = handler.answer_questions(url)
if res:
print('No more questions for this URL')
else:
print(f'Unexpected exception occurred: {err}', file=sys.stderr)
traceback.print_exc()
def test_login(self, email, password):
login_url = 'https://www.drfrostmaths.com/process-login.php?url='
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
' Chrome/71.0.3578.98 Safari/537.36'}
data = {'login-email': email, 'login-password': password}
self.session.post(login_url, headers=headers, data=data)
try:
"""
verifying user is authenticated by tests if user can load the times tables
"""
res = self.session.get('https://www.drfrostmaths.com/homework/process-starttimestables.php')
json.loads(res.text)
except BaseException:
raise InvalidLoginDetails(f'Email: {email}, Password: {"*" * len(password)}')
@staticmethod
def print_init():
print_string = '---- Dr Frost Answer Tool v3 ----\n' \
'---- Author: AK163631 ----\n' \
'*** Warning: this script has not been properly tested so might unexpectedly break ***\n' \
'Source: https://github.com/AK163631/DFM-Answer-Tool\n' \
'The author does not assume any liability for the use or abuse of this program!\n' \
'This tool is intended to be used to check answers\n' \
'Although it submit most answer types for you\n' \
'Release notes:\n' \
' - Fixed and optimised parser'
print(print_string)
@staticmethod
def print_instructions():
print_string = "\nstep1 - Login to dfm on both the tool and web browser\n" \
"step2 - Navigate to a set of assessment questions on dfm usually set by a teacher\n" \
"Note: you can also use the tool for practice questions aswell\n" \
"step3 - When you start the questions you will be given a URL that look something like this:\n" \
"http://www.drfrostmaths.com/homework/do-question.php?aaid=590397\n" \
"OR like this:\n" \
"http://www.drfrostmaths.com/homework/do-question.php?aaid=590399&qnum=4\n" \
"Note: It does not make a difference if you are in the middle of a set questions or at the " \
"start, the program will answer remaining questions\n" \
"step5 - Copy the URL and paste it into the tool then press enter," \
"step6 - The tool will find the answer all remaining questions\n" \
"Note: If completing practice questions the tool will submit answers indefinitely\n" \
"Note: Rarely the tool may come across an unknown answer type which it is unable to handle." \
"The tool will print this answer to the screen and you will need to input it manually"
choice = input('Do you wish to read the guide on how to use the tool? (y/n): ')
if choice == 'y':
print(print_string)
if __name__ == "__main__":
root = Tk()
root.protocol('WM_DELETE_WINDOW', sys.exit)
root.geometry('300x80')
root.title('DFM Login Screen')
lf = LoginFrame(root)
# wait for login to be retrieved
root.mainloop()