Skip to content

Commit

Permalink
0.3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
MXWXZ committed May 28, 2019
1 parent 6555cf8 commit f31ab7e
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 45 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
v0.3.1 2019-05-28
1. 课程类型输入方式调整

v0.3.0 2019-05-27
1. 教务系统改版修复
2. 增加油猴脚本
Expand Down
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -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)**

Expand All @@ -17,7 +17,7 @@ V2协议分析:<https://github.com/MXWXZ/sjtu-automata/blob/master/Protocol%20
:x: 保证一定可以抢到课

## 系统环境测试程度
最佳支持:Ubuntu 18.04 LTS with Python 3.6.7
最佳支持:Manjaro with python 3.7.3 / Ubuntu 18.04 LTS with Python 3.6.7

Linux > Windows >> ~~macOS=0(没钱无测试)~~

Expand All @@ -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
Expand All @@ -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`可以查看选课状态

Expand All @@ -76,4 +78,4 @@ Ubuntu 18.04:

- `CLASSTYPE``CLASSID`成对出现,可以出现多对同步进行,但至少有一对
- `CLASSTYPE`:32位课程类型ID
- `CLASSID`32位课号ID
- `CLASSID`课号ID
20 changes: 11 additions & 9 deletions sjtu-automata.user.js
Original file line number Diff line number Diff line change
@@ -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*
Expand Down Expand Up @@ -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('<p>'+id+'</p>');
function showid(node) {
let id = node.children().children()[0].innerHTML;
node.children('.jxbmc').append('<p>' + id + '</p>');
}

(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('<p>'+str.substr(str.indexOf("','")+3,32)+' &nbsp;</p>');
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('<p>' + str.substr(str.indexOf("this,'") + 6, pos2 - pos1 - 6) + ' &nbsp;</p>');
});
waitForKeyElements('.body_tr', showid, false);
})();
2 changes: 1 addition & 1 deletion sjtu_automata/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__ = '[email protected]'
__license__ = 'GNU General Public License v3 (GPLv3)'
Expand Down
43 changes: 21 additions & 22 deletions sjtu_automata/autoelect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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):
Expand All @@ -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
Expand All @@ -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():
Expand All @@ -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
Expand Down
20 changes: 15 additions & 5 deletions sjtu_automata/electsys/automata.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.3.0
0.3.1

0 comments on commit f31ab7e

Please sign in to comment.