From f31ab7ea74216a247703cfe7b500ba4875c1f97e Mon Sep 17 00:00:00 2001 From: MXWXZ Date: Tue, 28 May 2019 09:10:01 +0800 Subject: [PATCH] 0.3.1 --- CHANGELOG | 3 +++ README.md | 16 ++++++----- sjtu-automata.user.js | 20 +++++++------- sjtu_automata/__version__.py | 2 +- sjtu_automata/autoelect.py | 43 +++++++++++++++--------------- sjtu_automata/electsys/automata.py | 20 ++++++++++---- version | 2 +- 7 files changed, 61 insertions(+), 45 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3127b64..d25d185 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +v0.3.1 2019-05-28 +1. 课程类型输入方式调整 + v0.3.0 2019-05-27 1. 教务系统改版修复 2. 增加油猴脚本 diff --git a/README.md b/README.md index 911bf37..265ceac 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # sjtu-automata -![Version](https://img.shields.io/badge/Version-0.3.0-blue.svg) ![Language](https://img.shields.io/badge/Language-Python3-red.svg) ![License](https://img.shields.io/badge/License-GPL--3.0-yellow.svg) +![Version](https://img.shields.io/badge/Version-0.3.1-blue.svg) ![Language](https://img.shields.io/badge/Language-Python3-red.svg) ![License](https://img.shields.io/badge/License-GPL--3.0-yellow.svg) **注意!此版本为BETA版,未经过严格测试,可能存在BUG,如有问题请提交[issue](https://github.com/MXWXZ/AutoElect/issues)** @@ -17,7 +17,7 @@ V2协议分析: Windows >> ~~macOS=0(没钱无测试)~~ @@ -32,6 +32,8 @@ Linux > Windows >> ~~macOS=0(没钱无测试)~~ ### [可选]验证码自动识别 Windows可以不装,Linux如无图形界面且无法通过其他方式打开`captcha.jpeg`文件需要安装。 +Arch系安装下面两个包:`tesseract`、`tesseract-data-eng` + Ubuntu 18.04: sudo apt install tesseract-ocr libtesseract-dev @@ -44,12 +46,12 @@ Ubuntu 18.04: - 下面的教程以安装插件之后为准,如果不安装油猴脚本也可以自行查看网页源码提取相关ID 1. 查看课号:想选的课“教学班”第二行的32位字符串即为唯一课号 -2. 查看课程类型:标签页第二行的32位字符串即为课程类型 -3. 使用命令选课,格式为`autoelect [32位课程类型ID] [32位课号ID]`: +2. 查看课程类型:标签页第二行的字符串即为课程类型 +3. 使用命令选课,格式为`autoelect [课程类型ID] [32位课号ID]`: - autoelect ABCDEFGHIJKLMNOPQRSTUVWXYZ123456 BCDEFGHIJKLMNOPQRSTUVWXYZ1234567 CDEFGHIJKLMNOPQRSTUVWXYZ12345678 DEFGHIJKLMNOPQRSTUVWXYZ123456789 + autoelect 01 BCDEFGHIJKLMNOPQRSTUVWXYZ1234567 10 DEFGHIJKLMNOPQRSTUVWXYZ123456789 - 上述命令将会选`ABCDEFGHIJKLMNOPQRSTUVWXYZ123456`课程类型下的`BCDEFGHIJKLMNOPQRSTUVWXYZ1234567`课和`CDEFGHIJKLMNOPQRSTUVWXYZ12345678`课程类型下的`DEFGHIJKLMNOPQRSTUVWXYZ123456789`课,如果需要更多可以在后面继续添加。 + 上述命令将会选`01`课程类型下的`BCDEFGHIJKLMNOPQRSTUVWXYZ1234567`课和`10`课程类型下的`DEFGHIJKLMNOPQRSTUVWXYZ123456789`课,如果需要更多可以在后面继续添加。 注:程序运行过程中输入`s`可以查看选课状态 @@ -76,4 +78,4 @@ Ubuntu 18.04: - `CLASSTYPE`和`CLASSID`成对出现,可以出现多对同步进行,但至少有一对 - `CLASSTYPE`:32位课程类型ID -- `CLASSID`:32位课号ID +- `CLASSID`:课号ID diff --git a/sjtu-automata.user.js b/sjtu-automata.user.js index 7c62570..5c43500 100644 --- a/sjtu-automata.user.js +++ b/sjtu-automata.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name sjtu-automata // @namespace http://tampermonkey.net/ -// @version 1.0 +// @version 1.1 // @description show classid under classname. // @author MXWXZ // @match *://i.sjtu.edu.cn/xsxk/zzxkyzb_cxZzxkYzbIndex.html* @@ -62,18 +62,20 @@ function waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelect waitForKeyElements.controlObj = controlObj; } -function showid(node){ - let id=node.children().children()[0].innerHTML; - node.children('.jxbmc').append('

'+id+'

'); +function showid(node) { + let id = node.children().children()[0].innerHTML; + node.children('.jxbmc').append('

' + id + '

'); } -(function() { +(function () { 'use strict'; - let node=$('.nav.nav-tabs.sl_nav_tabs li'); - node.each(function(){ - let str=$(this).children('a')[0].getAttribute("onclick"); - $(this).append('

'+str.substr(str.indexOf("','")+3,32)+'  

'); + let node = $('.nav.nav-tabs.sl_nav_tabs li'); + node.each(function () { + let str = $(this).children('a')[0].getAttribute("onclick"); + let pos1 = str.indexOf("this,'"); + let pos2 = str.indexOf("','"); + $(this).append('

' + str.substr(str.indexOf("this,'") + 6, pos2 - pos1 - 6) + '  

'); }); waitForKeyElements('.body_tr', showid, false); })(); \ No newline at end of file diff --git a/sjtu_automata/__version__.py b/sjtu_automata/__version__.py index 413d4a9..2009de9 100644 --- a/sjtu_automata/__version__.py +++ b/sjtu_automata/__version__.py @@ -2,7 +2,7 @@ __description__ = 'Auto elect script for SJTUer.' __url__ = 'https://github.com/MXWXZ/sjtu-automata' __update_url__ = 'https://raw.githubusercontent.com/MXWXZ/sjtu-automata/master/version' -__version__ = '0.3.0' +__version__ = '0.3.1' __author__ = 'MXWXZ' __author_email__ = 'me@imwxz.com' __license__ = 'GNU General Public License v3 (GPLv3)' diff --git a/sjtu_automata/autoelect.py b/sjtu_automata/autoelect.py index e24b73a..cde63ba 100644 --- a/sjtu_automata/autoelect.py +++ b/sjtu_automata/autoelect.py @@ -7,11 +7,13 @@ import threading sys.path.append('../') + +from sjtu_automata import check_update, echoerror, echoinfo, echowarning +from sjtu_automata.__version__ import __author__, __url__, __version__ +from sjtu_automata.credential import login from sjtu_automata.electsys.automata import ( get_studentid, get_params, elect_class) -from sjtu_automata.credential import login -from sjtu_automata.__version__ import __author__, __url__, __version__ -from sjtu_automata import check_update, echoerror, echoinfo, echowarning + class UserInterface(object): def __init__(self): @@ -60,10 +62,10 @@ def login(self, ocr, delay): echoinfo('Login successful!') return True - def __elect_thread(self, tid, xkkzid, classid, delay): + def __elect_thread(self, tid, classtype, classid, delay): while self.status[tid] == 2 or self.status[tid] == 4 or self.status[tid] == -1: ret = elect_class(self.session, self.studentid, - self.params, xkkzid, classid) + self.params, classtype, classid) with self.tl[tid]: if self.status[tid] != 0 and self.status[tid] != 1 and self.status[tid] != 3: self.status[tid] = ret @@ -72,10 +74,10 @@ def __elect_thread(self, tid, xkkzid, classid, delay): break sleep(delay) - def add_elect(self, number, xkkzid, classid, delay): + def add_elect(self, number, classtype, classid, delay): for i in range(number): self.tp.append(threading.Thread( - target=self.__elect_thread, args=(self.id, xkkzid, classid, delay,))) + target=self.__elect_thread, args=(self.id, classtype, classid, delay,))) self.tl.append(threading.Lock()) self.tclass.append(classid) self.status.append(-1) @@ -90,22 +92,22 @@ def start_elect(self): def __parse_status(self, tid, status): with self.glock: if status == -1: - secho('['+self.tclass[tid]+'] ', fg='red', nl=False) + secho('[' + self.tclass[tid] + '] ', fg='red', nl=False) echo('Not started!') elif status == 0: - secho('['+self.tclass[tid]+'] ', fg='green', nl=False) + secho('[' + self.tclass[tid] + '] ', fg='green', nl=False) echo('Finished!') elif status == 1: - secho('['+self.tclass[tid]+'] ', fg='red', nl=False) + secho('[' + self.tclass[tid] + '] ', fg='red', nl=False) echo('Time conflict! Stopped.') elif status == 2: - secho('['+self.tclass[tid]+'] ', fg='yellow', nl=False) + secho('[' + self.tclass[tid] + '] ', fg='yellow', nl=False) echo('Class is full! Retrying...') elif status == 3: - secho('['+self.tclass[tid]+'] ', fg='red', nl=False) + secho('[' + self.tclass[tid] + '] ', fg='red', nl=False) echo('Param error! Stopped.') elif status == 4: - secho('['+self.tclass[tid]+'] ', fg='yellow', nl=False) + secho('[' + self.tclass[tid] + '] ', fg='yellow', nl=False) echo('Unknown error! Retrying...') def fetch_status(self): @@ -130,8 +132,8 @@ def print_version(ctx, param, value): # override click version print if not value or ctx.resilient_parsing: return - echo('AutoElect by '+__author__) - echo('Version: '+__version__) + echo('AutoElect by ' + __author__) + echo('Version: ' + __version__) ctx.exit() # TODO: Add more command @@ -153,9 +155,9 @@ def print_version(ctx, param, value): @click.argument('classtypeid', required=True, nargs=-1) def cli(no_update, ocr, print_cookie, delay, check_delay, number, classtypeid): version = __version__ - echo('AutoElect by '+__author__) - echo('Version: '+version) - echo('Github: '+__url__+'\n') + echo('AutoElect by ' + __author__) + echo('Version: ' + version) + echo('Github: ' + __url__ + '\n') # TODO: remove in 1.0.0 if not no_update and check_update(): @@ -174,10 +176,7 @@ def cli(no_update, ocr, print_cookie, delay, check_delay, number, classtypeid): if print_cookie: ui.print_cookie() for i in range(0, len(classtypeid), 2): - if len(classtypeid[i]) != 32: - echowarning('Class type ' + classtypeid[i] + ' invalid! Ignore.') - continue - ui.add_elect(number, classtypeid[i], classtypeid[i+1], delay) + ui.add_elect(number, classtypeid[i], classtypeid[i + 1], delay) ui.start_elect() cmd = threading.Thread(target=ui.get_input) cmd.daemon = True diff --git a/sjtu_automata/electsys/automata.py b/sjtu_automata/electsys/automata.py index 75ef940..fdf2b0d 100644 --- a/sjtu_automata/electsys/automata.py +++ b/sjtu_automata/electsys/automata.py @@ -1,5 +1,6 @@ from time import sleep +import re import requests from requests.exceptions import RequestException from tenacity import retry, retry_if_exception_type, wait_fixed @@ -62,18 +63,25 @@ def get_params(session, studentid): Returns: dict: + xkkz_id: dict, [cnt]:[id] njdm_id: str, njdm_id zyh_id: str, zyh_id """ params = {'gnmkdm': 'N253512', 'layout': 'default', 'su': studentid} req = _request( session, 'GET', 'http://i.sjtu.edu.cn/xsxk/zzxkyzb_cxZzxkYzbIndex.html', params=params) + xkkz_id = {} + xkkz = re.findall( + r'\'(.*?)\',\'(.*?)\'\)" role="tab" data-toggle="tab">', req) + for i in xkkz: + xkkz_id[i[0]] = i[1] + njdm_id = re_search(r'id="njdm_id" value="(.*?)"/>', req) zyh_id = re_search(r'id="zyh_id" value="(.*?)"/>', req) - return {'njdm_id': njdm_id, 'zyh_id': zyh_id} + return {'xkkz_id': xkkz_id, 'njdm_id': njdm_id, 'zyh_id': zyh_id} -def elect_class(session, studentid, params, xkkzid, classid): +def elect_class(session, studentid, params, classtype, classid): """Elect class. Directly elect class. @@ -83,14 +91,16 @@ def elect_class(session, studentid, params, xkkzid, classid): session: requests session, login session. studentid: str, student id. params: dict, get_params returned - xkkzid: str, 32 length id + classtype: str, class type classid: str, class id Returns: - int, -1 for param error, 0 for success, 1 for time conflict, 2 for full, 3 for param error, 4 for other. + int, 0 for success, 1 for time conflict, 2 for full, 3 for param error, 4 for other. """ + if classtype not in params['xkkz_id']: + return 3 post_params = {'gnmkdm': 'N253512', 'su': studentid} - data = {'jxb_ids': classid, 'xkkz_id': xkkzid, + data = {'jxb_ids': classid, 'xkkz_id': params['xkkz_id'][classtype], 'njdm_id': params['njdm_id'], 'zyh_id': params['zyh_id']} req = _request( diff --git a/version b/version index 9325c3c..a2268e2 100644 --- a/version +++ b/version @@ -1 +1 @@ -0.3.0 \ No newline at end of file +0.3.1 \ No newline at end of file