5
5
"""
6
6
7
7
__author__ = "yanyongyu"
8
- __version__ = "1.5.1 "
8
+ __version__ = "1.5.2 "
9
9
10
10
import asyncio
11
11
import logging
14
14
import webbrowser
15
15
16
16
import requests
17
+ from lxml import etree
17
18
from tkinter import *
18
19
from tkinter .ttk import *
19
20
from tkinter .messagebox import showinfo , askyesno
@@ -65,6 +66,72 @@ class App():
65
66
bd[_0x320a[18]][_0x320a[20]] = _0x320a[21];
66
67
}
67
68
a()
69
+ """
70
+ ZHS_JS = """
71
+ function speedUp_muted_bq() {
72
+
73
+ $(".speedTab15")[0].click();
74
+ setTimeout(function() {
75
+ document.getElementById("vjs_mediaplayer_html5_api").muted = true;
76
+ }, 1000);
77
+ $(".line1bq")[0].click();
78
+ }
79
+
80
+
81
+ function autoChooseTest() {
82
+ //check if the test window is open
83
+ if (!document.getElementById("tmDialog_iframe")) {
84
+ return;
85
+ } else {
86
+ //choose right answer
87
+ var myradio = document.getElementById("tmDialog_iframe").contentWindow.document.getElementsByClassName("answerOption");
88
+ for (var i = 0; i < myradio.length; i++) {
89
+ if (myradio[i].getElementsByTagName("input")[0].getAttribute("_correctanswer") == "1")
90
+ myradio[i].getElementsByTagName("input")[0].click();
91
+ //double click checked;
92
+ if (myradio[i].getElementsByTagName("input")[0].getAttribute("checked") == "checked")
93
+ myradio[i].getElementsByTagName("input")[0].click();
94
+ }
95
+ }
96
+
97
+
98
+ //close the window of answer
99
+ for (var i = 0; i < $(".popbtn_cancel span").length; i++) {
100
+ if ($(".popbtn_cancel span")[i].innerHTML == "关闭" || $(".popbtn_cancel span")[i].innerHTML == "Close") {
101
+ $(".popbtn_cancel span")[i].click();
102
+ //console.log($(".popbtn_cancel span")[i].innerHTML);
103
+ }
104
+ }
105
+
106
+ }
107
+
108
+ function nextVideo() {
109
+ var video = document.getElementById("vjs_mediaplayer_html5_api");
110
+ //testTest if it has accelerated
111
+ if (video.playbackRate != 1.5) {
112
+ setTimeout(function() {
113
+ speedUp_muted_bq();
114
+ }, 1500);
115
+ }
116
+ if ((video.currentTime / video.duration) >= 1) {
117
+ console.log("Finish");
118
+ $(".tm_next_lesson")[0].click();
119
+ setTimeout(function() {
120
+ speedUp_muted_bq();
121
+ }, 1500);
122
+ }
123
+ //If a chapter is finish, test if next video is as same to the current video
124
+ }
125
+
126
+ speedUp_muted_bq();
127
+ if (myInterval) {
128
+ clearInterval(myInterval);
129
+ }
130
+ var myInterval = setInterval(function() {
131
+ autoChooseTest();
132
+ console.log(new Date().getSeconds());
133
+ nextVideo();
134
+ }, 5000);
68
135
"""
69
136
70
137
def __init__ (self ):
@@ -95,7 +162,7 @@ def show(self):
95
162
"显示主窗口"
96
163
self .root = Tk ()
97
164
self .root .title (
98
- "超星查题助手v %s -designed by ShowTime-Joker" % __version__ )
165
+ "查题助手v %s -designed by ShowTime-Joker" % __version__ )
99
166
# 窗口居中坐标
100
167
sw = self .root .winfo_screenwidth ()
101
168
sh = self .root .winfo_screenheight ()
@@ -131,6 +198,10 @@ def show(self):
131
198
label = "超星" ,
132
199
command = lambda : webbrowser .open (App .PLUGIN_CX_URL )
133
200
)
201
+ plugin_menu .add_cascade (
202
+ label = "智慧树脚本" ,
203
+ command = lambda : self .zhs_js ()
204
+ )
134
205
plugin_menu .add_cascade (
135
206
label = "解除右键锁定" ,
136
207
command = lambda : self .unfreeze_js ()
@@ -141,10 +212,15 @@ def show(self):
141
212
option_menu = Menu (menu , tearoff = 0 )
142
213
self .isTop = IntVar ()
143
214
self .isTop .set (0 )
215
+ self .isBreak = IntVar ()
216
+ self .isBreak .set (0 )
144
217
option_menu .add_checkbutton (
145
218
label = "窗口置顶" , variable = self .isTop ,
146
219
command = lambda : self .root_top_show ()
147
220
)
221
+ option_menu .add_checkbutton (
222
+ label = "中断式查询" , variable = self .isBreak
223
+ )
148
224
menu .add_cascade (label = "选项" , menu = option_menu )
149
225
150
226
# 帮助菜单
@@ -197,13 +273,17 @@ def _configure_frame(event):
197
273
size = (frame_in .winfo_reqwidth (), frame_in .winfo_reqheight ())
198
274
canvas .config (scrollregion = "0 0 %s %s" % size )
199
275
if frame_in .winfo_reqwidth () != canvas .winfo_width ():
200
- # 更新画布大小以适配内部框架
276
+ # 更新画布宽度以适配内部框架
201
277
canvas .config (width = frame_in .winfo_reqwidth ())
278
+
202
279
if len (self .text ) <= 3 :
203
280
self .root .geometry ('%dx%d' % (600 , 35 + 70 * len (self .text )))
204
281
canvas .config (height = frame_in .winfo_reqheight ())
205
- canvas .bind_all ('<MouseWheel>' , _unscroll_canvas )
206
- elif frame_in .winfo_reqheight () < canvas .winfo_height ():
282
+ elif len (self .text ) > 3 :
283
+ self .root .geometry ('%dx%d' % (600 , 35 + 70 * 3 ))
284
+ canvas .config (height = 210 )
285
+
286
+ if frame_in .winfo_reqheight () < canvas .winfo_height ():
207
287
canvas .bind_all ('<MouseWheel>' , _unscroll_canvas )
208
288
else :
209
289
canvas .bind_all ('<MouseWheel>' , _scroll_canvas )
@@ -240,16 +320,43 @@ def _create_entry():
240
320
command = _create_entry )
241
321
add_button .grid (row = 1 , column = 1 , padx = 2 , pady = 2 )
242
322
self .text .append (text )
323
+ return text
243
324
244
325
_create_entry ()
245
326
327
+ # 超星一键粘贴
328
+ def _cx_paste ():
329
+ question = self .scan_cx ()
330
+ if not question :
331
+ showinfo (
332
+ title = "查题助手" ,
333
+ message = "未能检索到题目!\n 目前支持html源码粘贴以及【题目类型】特征识别" )
334
+ return
335
+ for each in question :
336
+ text = _create_entry ()
337
+ text .insert (1.0 , each )
338
+
339
+ def _zhs_paste ():
340
+ question = self .scan_zhs ()
341
+ if not question :
342
+ showinfo (
343
+ title = "查题助手" ,
344
+ message = "未能检索到题目!\n 目前支持html源码粘贴以及【题目类型】特征识别" )
345
+ return
346
+ for each in question :
347
+ text = _create_entry ()
348
+ text .insert (1.0 , each )
349
+
350
+
246
351
# 查询按钮框
247
352
frame3 = Frame (self .root , style = 'White.TFrame' )
248
353
frame3 .pack (side = BOTTOM , fill = X )
249
354
button1 = Button (frame3 , text = "查询" , command = self .start_search )
250
355
button1 .pack (side = LEFT , expand = True )
251
- # button2 = Button(frame3, text="一键粘贴", command=self.scan_clipboard)
252
- # button2.pack(side=RIGHT, expand=False)
356
+ button2 = Button (frame3 , text = "超星粘贴" , command = _cx_paste )
357
+ button2 .pack (side = RIGHT , expand = False )
358
+ button3 = Button (frame3 , text = "智慧树粘贴" , command = _zhs_paste )
359
+ button3 .pack (side = RIGHT , expand = False )
253
360
254
361
self .root .update ()
255
362
self .root .mainloop ()
@@ -264,19 +371,43 @@ def root_top_show(self):
264
371
def usage (self ):
265
372
"显示使用说明窗口"
266
373
top = Toplevel (self .root )
267
- top .geometry ('350x150 ' )
374
+ top .geometry ('350x250 ' )
268
375
top .resizable (False , False )
269
376
top .wm_attributes ('-topmost' , 1 )
270
377
frame = Frame (top )
271
378
frame .pack (fill = BOTH )
272
379
273
380
Label (frame , text = "复制题目到输入框,一个输入框只能输入一题!" ).pack ()
274
381
Label (frame , text = "如需多题查询点击 + 号增加输入框。" ).pack ()
382
+ Label (frame , text = "或直接选择一键粘贴(特征检测【】或html源码)" ).pack ()
383
+ Label (frame , text = "点击查询或使用鼠标中键开始查询" ).pack ()
384
+ Label (frame , text = "非中断式查询会查询所有api但更慢" ).pack ()
275
385
Label (frame , text = "本软件自动检测更新" ).pack ()
276
386
Label (frame , text = "目前题库包含超星尔雅、知到智慧树。" ).pack ()
277
387
Label (frame , text = "如遇到问题请点击帮助-反馈问题" ).pack ()
278
388
Label (frame , text = "或点击加入我们加群反馈" ).pack ()
279
389
390
+ def zhs_js (self ):
391
+ top = Toplevel (self .root )
392
+ top .geometry ('350x180' )
393
+ top .resizable (False , False )
394
+ top .wm_attributes ('-topmost' , 1 )
395
+ frame = Frame (top )
396
+ frame .pack (fill = BOTH )
397
+
398
+ # 复制到剪切板
399
+ def _copy ():
400
+ self .root .clipboard_clear ()
401
+ self .root .clipboard_append (App .UNFREEZE_JS )
402
+
403
+ Label (frame , text = "点击复制按钮,到浏览器页面" ).pack ()
404
+ Label (frame , text = "按F12或者Ctrl+Shift+i打开开发者工具" ).pack ()
405
+ Label (frame , text = "切换到Console栏粘贴并回车" ).pack ()
406
+ Label (frame , text = "提示成功即解除成功!部分浏览器可能不支持" ).pack ()
407
+ Label (frame , text = "原项目地址:https://github.com/tignioj/" ).pack ()
408
+ Label (frame , text = "test_login/tree/master/zhs/" ).pack ()
409
+ Button (frame , text = "点我复制" , command = _copy ).pack ()
410
+
280
411
def unfreeze_js (self ):
281
412
"显示解除右键限制说明"
282
413
top = Toplevel (self .root )
@@ -297,8 +428,37 @@ def _copy():
297
428
Label (frame , text = "提示成功即解除成功!部分浏览器可能不支持" ).pack ()
298
429
Button (frame , text = "点我复制" , command = _copy ).pack ()
299
430
300
- def scan_clipboard (self ):
301
- print (self .root .clipboard_get ().split ('\n ' ))
431
+ def scan_cx (self ):
432
+ clipboard_text = self .root .clipboard_get ().strip ()
433
+
434
+ selector = etree .HTML (clipboard_text )
435
+ cx_html = selector .xpath ('//div[@class="clearfix"]' )
436
+ html = list (map (lambda x : x .xpath ("string(.)" ).strip (), cx_html ))
437
+
438
+ cx_text = clipboard_text .split ("\n " )
439
+
440
+ question = html or cx_text
441
+
442
+ raw_question = [each [each .index ("】" ) + 1 :]
443
+ for each in question if each .find ("】" ) != - 1 ]
444
+ return raw_question
445
+
446
+ def scan_zhs (self ):
447
+ clipboard_text = self .root .clipboard_get ().strip ()
448
+
449
+ selector = etree .HTML (clipboard_text )
450
+ zhs_html = selector .xpath ('//div[@class="subject_describe"]' )
451
+ html = list (map (lambda x : x .xpath ("string(.)" ).strip (), zhs_html ))
452
+
453
+ zhs_text = clipboard_text .split ("\n " )
454
+
455
+ question = html or zhs_text
456
+
457
+ raw_question = [question [i + 1 ]
458
+ for i in range (len (question ) - 1 )
459
+ if question [i ].find ("】" ) != - 1
460
+ if question [i ].find (r")" ) != - 1 ]
461
+ return raw_question
302
462
303
463
def start_search (self ):
304
464
"开始搜索,显示答案窗口"
@@ -382,7 +542,8 @@ async def search(self, frame_list):
382
542
for answer in result :
383
543
label ['text' ] = label ['text' ] + answer ['topic' ] + '\n '
384
544
label ['text' ] = label ['text' ] + '答案:' + answer ['correct' ] + '\n '
385
- break
545
+ if self .isBreak .get ():
546
+ break
386
547
387
548
# 关闭event loop
388
549
loop = asyncio .get_event_loop ()
@@ -462,15 +623,15 @@ async def scan_release(self, silence):
462
623
res .raise_for_status ()
463
624
except requests .exceptions .RequestException as e :
464
625
logging .info ("Request Exception appeared: %s" % e )
465
- showinfo (title = "超星查题助手 " ,
626
+ showinfo (title = "查题助手 " ,
466
627
message = "检查更新失败了!" )
467
628
else :
468
629
info = res .json ()
469
630
latest = info ['tag_name' ].strip ("v" ).split ('.' )
470
631
now = __version__ .split ('.' )
471
632
if latest == now :
472
633
if not silence :
473
- showinfo (title = "超星查题助手 " ,
634
+ showinfo (title = "查题助手 " ,
474
635
message = "已是最新版本!无需更新。" )
475
636
return
476
637
if len (latest ) < len (now ):
@@ -479,7 +640,7 @@ async def scan_release(self, silence):
479
640
now .append ('0' )
480
641
for i in range (len (now )):
481
642
if latest [i ] > now [i ]:
482
- if askyesno (title = "超星查题助手 " ,
643
+ if askyesno (title = "查题助手 " ,
483
644
message = "发现新版本%s!是否前去更新?"
484
645
% info ['tag_name' ]):
485
646
webbrowser .open (info ['html_url' ])
0 commit comments