This repository has been archived by the owner on Nov 20, 2019. It is now read-only.
/
Fefs.py
346 lines (319 loc) · 12.7 KB
/
Fefs.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
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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
# coding:utf-8
# print('软件初始化中...')
import base64
import configparser
import json
import os
import sys
import time
import webbrowser
from pathlib import Path
import requests
from prettytable import PrettyTable
import __version__
from console_erya import console
from console_erya.config import use_rk_code # , token
from console_erya.printinfo import print_info
from utils.utils import rk_code
info = {
'Version': __version__.__version__,
'Author': __version__.__author__,
'Blog': __version__.__blog__,
}
function = {
'': '请选择一项功能',
'1: ': '刷课',
'2: ': '考试',
'3: ': '设置',
'4: ': '联系作者',
}
class UI:
def __init__(self):
self.terminal_size = os.get_terminal_size()
# 格式化输出信息
def ex_info(self, info):
row = self.terminal_size[0] - 1
print('*' * (self.terminal_size[0]-1), end='\n\n')
for key, value in info.items():
i = str(key) + str(value)
tmp = (row - len(i)) // 2
print(' ' * tmp, end='')
print(i)
print('\n', '*' * (self.terminal_size[0]-1))
def pretty_table(self, head, content):
print('\n\n\n\n\n')
table = PrettyTable(head)
for x in content:
table.add_row(x)
print(table)
print('\n\n\n\n\n')
class Main:
def __init__(self):
self.ui = UI()
self.console = console.Console()
self.auto_login = False
self.account = {}
self.function = {}
self.read_account()
self.register_function(description='刷课', func=self.autolearn)
self.register_function(description='刷课(自动重登)',
func=self.while_true_learn)
self.register_function(description='考试', func=self.exam)
self.register_function(description='设置', func=self.setting)
self.register_function(description='关于', func=self.about)
self.register_function(
description='刷课(需要再次登陆,临时功能)', func=self.relogin)
print(r"""___________ _____ __________ __ _____ __
\_ _____/____ _/ ____\______ \______ \_____ ____ | | _________ ____ _/ ____\_/ |_
| __)_/ __ \\ __\/ ___/ ______ | | _/\__ \ / \ | |/ /\_ __ \ / _ \\ __\ \ __\
| \ \ ___/ | | \___ \ /_____/ | | \ / __ \_| | \| < | | \/( <_> )| | | |
\___ / \___ >|__| /____ > |______ /(____ /|___| /|__|_ \ |__| \____/ |__| |__|
\/ \/ \/ \/ \/ \/ \/ """)
print('\n\n')
# self.ui.ex_info(info)
def save_account(self):
with open('./temp/account.b4', 'wb') as f:
f.write(base64.b64encode(json.dumps(self.account).encode()))
def read_account(self):
try:
with open('./temp/account.b4', 'rb') as f:
self.account = json.loads(base64.b64decode(f.read()).decode())
except:
pass
def register_function(self, **kwargs):
self.function[len(self.function.keys()) +
1] = {'desc': kwargs['description'], 'func': kwargs['func']}
def input_select(self, hint, start, end):
while True:
try:
i = input(hint+'(按q or Ctrl-C退出): ').strip()
if i == 'q':
sys.exit(0)
i = int(i)
except (TypeError, ValueError):
print('输入错误')
continue
if (i >= start) and (i <= end):
return i
print('输入错误')
def input_confirm(self, hint):
while True:
i = input(hint+'(Y/N): ').strip().upper()
if i == 'Y':
return True
elif i == 'N':
return False
def start(self):
# self.check_version()
self.ui.ex_info({k.__str__()+': ': v['desc']
for k, v in self.function.items()})
i = self.input_select('请输入选项数字', 1, len(self.function.keys()))
self.function[i]['func']()
def while_true_learn(self):
if set(['course', 'school', 'sschool', 'num', 'pwd']) - set(self.account.keys()):
print('信息不完整,请重新运行功能: 1')
return False
if not use_rk_code:
print('请运行功能:4,设置若快平台账号和密码')
return False
while True:
try:
self.console = console.Console()
self.console.init()
self.console.search_school(self.account['school'])
self.console.select_school(self.account['sschool'])
code_error = False
pwd_error = False
while True:
if pwd_error:
print('密码错误,请重新运行功能:1')
return False
file_name = self.console.get_login_ver_code(
refresh=code_error, display=not use_rk_code)
code = rk_code(file_name)
print('登陆验证码为:', code)
print('登录中...')
r = self.console.login(
self.account['num'], self.account['pwd'], code)
if r[1]:
print('登 录 成 功 :'+r[0])
break
else:
if '密码错误' == r[0]:
pwd_error = True
elif '验证码错误' == r[0]:
code_error = True
print('登 录 失 败:', r[0])
course = self.console.get_course()
print_info(
['课程', course[self.account['course']], '开始'], 'info', True)
t = self.console.browse_watch(self.account['course'])
if t[0] or (not t[0] and not t[0]):
break
elif not t[0] and t[1]:
continue
except KeyboardInterrupt:
print('结束')
return False
except:
print('错误,重新开始')
self.console.quit()
continue
def autolearn(self):
self.console.init()
self.login()
course = self.console.get_course()
# i = {str(key+1)+':': value for key, value in enumerate(course)}
# i[''] = '请选择观看的课程'
# self.ui.ex_info(i)
self.ui.pretty_table(['编号', '课程'], [[key+1, value]
for key, value in enumerate(course)])
s = self.input_select('请选择', 1, len(course)) - 1
self.account['course'] = s
self.save_account()
self.console.browse_watch(s)
print('开始...')
try:
while True:
time.sleep(10)
except KeyboardInterrupt:
print('KeyboardInterrupt')
exit(0)
def relogin(self):
self.console.init()
self.login()
self.console.driver.switch_to.frame(
self.console.driver.find_elements_by_tag_name('iframe')[0])
self.login()
course = self.console.get_course()
# i = {str(key+1)+':': value for key, value in enumerate(course)}
# i[''] = '请选择观看的课程'
# self.ui.ex_info(i)
self.ui.pretty_table(['编号', '课程'], [[key+1, value]
for key, value in enumerate(course)])
s = self.input_select('请选择', 1, len(course)) - 1
self.account['course'] = s
self.save_account()
self.console.browse_watch(s)
print('开始...')
try:
while True:
time.sleep(10)
except KeyboardInterrupt:
print('KeyboardInterrupt')
exit(0)
def login(self):
if self.account:
if self.input_confirm('是否使用上次的账号({0})登录'.format(self.account['name'])):
self.auto_login = True
if self.auto_login:
school = self.account['school']
else:
school = input('请输入学校: ').strip()
self.account['school'] = school
rschool = self.console.search_school(school)
# i = {str(key+1)+':': value for key, value in enumerate(rschool)}
# i[''] = '请选择学校'
if self.auto_login:
sschool = self.account['sschool']
else:
# self.ui.ex_info(i)
self.ui.pretty_table(['编号', '学校'], [[key+1, value]
for key, value in enumerate(rschool)])
sschool = self.input_select('请选择学校', 1, len(rschool)) - 1
self.account['sschool'] = sschool
if self.console.select_school(sschool):
pass
else:
print_info(['选择学校', '错误', '请重启重试'], 'warning', True)
import sys
sys.exit(0)
pwd_error = False
code_error = False
if self.auto_login:
num = self.account['num']
pwd = self.account['pwd']
else:
num = input('输入学号:').strip()
pwd = input('输入密码:').strip()
self.account['num'] = num
self.account['pwd'] = pwd
while True:
if pwd_error:
pwd = input('输入密码:').strip()
self.account['pwd'] = pwd
file_name = self.console.get_login_ver_code(
refresh=code_error, display=not use_rk_code)
if use_rk_code:
code = rk_code(file_name)
print('登陆验证码为:', code)
else:
code = input('输入验证码:').strip()
print('登录中...')
r = self.console.login(num, pwd, code)
if r[1]:
print('登 录 成 功 :'+r[0])
self.account['name'] = r[0]
break
else:
if '密码错误' == r[0]:
pwd_error = True
elif '验证码错误' == r[0]:
code_error = True
print('登 录 失 败:', r[0])
def exam(self):
t = console.Exam()
while True:
print('请调整到考试页面,关闭其他所有页面')
re = input('是否开始?(Y/N): ').upper()
if re == 'Y':
t.start()
elif re == 'N':
sys.exit(0)
def setting(self):
conf = configparser.ConfigParser()
conf.read(str(Path(os.getcwd()) / 'config.ini'), encoding='utf-8')
wechat_mp = input('查题微信公众号(我的博客有推荐):')
conf.set('User', 'wechat_mp', wechat_mp)
while True:
try:
slp = int(input('章节测验存在未查到答案试题的等待提交时间(分钟)'))
break
except(ValueError, TypeError):
continue
conf.set('User', 'noanswer_sleep', str(slp))
inl = input('默认线路无法播放时切换到:')
conf.set('User', 'internet_line', inl)
token = input('题库token: ')
conf.set('User', 'token', token)
rk_username = input('若快平台账号:')
conf.set('User', 'rk_username', rk_username.strip())
rk_pwd = input('若快平台密码:')
conf.set('User', 'rk_password', rk_pwd.strip())
relogin = self.input_confirm('是否登陆后还需要再重新登陆?(Y/N):')
conf.set('User', 'relogin', relogin.__str__())
with open(str(Path(os.getcwd()) / 'config.ini'), 'w', encoding='utf-8') as f:
conf.write(f)
def about(self):
print('E-mail: bankroftvayne@gmail.com')
print('Blog: https://www.bankroft.cn')
print('Version:', info['Version'])
webbrowser.open('https://www.bankroft.cn')
@staticmethod
def check_version():
try:
res = requests.get(
'https://raw.githubusercontent.com/bankroft/Fefs/master/__version__.py').text.split('\n')
except:
print('无法检测新版本,如果无法观看请手动检查')
return False
new_version = ''
for x in res:
if '__version__' in x:
new_version = x.split('=')[1].strip().strip('\'')
break
if __version__.__version__ != new_version:
print('检测到新版本: ', new_version)
if __name__ == '__main__':
Main().start()
os.system('pause')