arb-xmu-course 2.0.1 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/bin/arb-xmu-course +109 -96
- data/lib/arb/xmu/course/models/course_entity.rb +1 -1
- data/lib/arb/xmu/course/version.rb +1 -1
- metadata +1 -2
- data/bin/check_code.jpeg +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6eda3309e782a73522b07b1da16a94f540e8db3
|
4
|
+
data.tar.gz: 5f838bf91a12911f9bb51767d58fd7203d7b2b14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b4b660bf377c3f5a9750866277bfe40c8f307045ce392871413068ef9b01ce54ec9dbde216c716a11de4c43ac87ec392d4a1b6b57c686adf5eccb191dd278c3
|
7
|
+
data.tar.gz: 2b486e12a2e89959153df2f8c7a85f315f16934d606f6ba688d23b58c3361a98f8522c56308e9f3f0a6880ba7c7cf84ccc316ebca0c8689ec282468e7d105d62
|
data/.gitignore
CHANGED
data/bin/arb-xmu-course
CHANGED
@@ -13,20 +13,61 @@ TOKEN_FILE_NAME = 'encrypted_token'
|
|
13
13
|
TOKEN_SEPARATOR = ':'
|
14
14
|
CLIENT = HTTPClient.new
|
15
15
|
|
16
|
+
opts = Slop.parse do |o|
|
17
|
+
o.bool *%w{-h --help}, '显示帮助'
|
18
|
+
o.bool *%w{-c --clear}, '清除本地账户信息'
|
19
|
+
o.bool *%w{-r --reset}, '重置账户信息'
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
#院选课程 xxlx=4
|
22
|
+
o.bool *%w{-s --school}, '院选选课模式'
|
23
|
+
#校选课程 xxlx=3
|
24
|
+
o.bool *%w{-g --general}, '校选选课模式'
|
25
|
+
#公共课程 xxlx=5
|
26
|
+
o.bool *%w{-p --public}, '公共课选课模式'
|
27
|
+
|
28
|
+
o.bool *%w{-v --version}, '显示当前版本'
|
29
|
+
end
|
30
|
+
|
31
|
+
case true
|
32
|
+
when opts.version?
|
33
|
+
puts Arb::Xmu::Course::VERSION
|
34
|
+
when opts.help?
|
35
|
+
puts(opts) && exit
|
36
|
+
when opts.clear?
|
37
|
+
File.delete(TOKEN_FILE_NAME) && exit
|
38
|
+
when opts.reset?
|
39
|
+
set_up_account
|
40
|
+
when opts.school?
|
41
|
+
select_school_elective(CLIENT)
|
42
|
+
when opts.general?
|
43
|
+
select_general_elective(CLIENT)
|
44
|
+
when opts.public?
|
45
|
+
select_public(CLIENT)
|
46
|
+
else
|
47
|
+
puts(opts) && exit
|
48
|
+
end
|
49
|
+
|
50
|
+
def select_school_elective(client)
|
51
|
+
select_course_common client, 'http://bkxk.xmu.edu.cn/xsxk/yxxx.html?pagination=5000', 4
|
52
|
+
end
|
53
|
+
|
54
|
+
def select_general_elective(client)
|
55
|
+
select_course_common client, 'http://bkxk.xmu.edu.cn/xsxk/qxxxx.html?pagination=5000', 3
|
56
|
+
end
|
57
|
+
|
58
|
+
def select_public(client)
|
59
|
+
select_course_common client, 'http://bkxk.xmu.edu.cn/xsxk/ggk.html?pagination=5000', 5
|
60
|
+
end
|
61
|
+
|
62
|
+
def select_course_common(client, url, xxlx)
|
63
|
+
prepare_select_course(client)
|
64
|
+
courses = parse_courses((client.get url).body)
|
65
|
+
show_courses_in_table courses
|
66
|
+
try_to_select_courses(client, courses, xxlx, get_main_select_round(client))
|
67
|
+
$stdout.puts '已经开始选课,输入字符q退出。'
|
68
|
+
loop do
|
69
|
+
exit if 'q'==$stdin.gets.chomp
|
28
70
|
end
|
29
|
-
raw
|
30
71
|
end
|
31
72
|
|
32
73
|
def set_up_account
|
@@ -37,6 +78,8 @@ def set_up_account
|
|
37
78
|
File.open TOKEN_FILE_NAME, 'w' do |file|
|
38
79
|
file.write (SimpleDes.encrypt(stu_id)+TOKEN_SEPARATOR+SimpleDes.encrypt(passwd))
|
39
80
|
end
|
81
|
+
$stdout.puts '账号信息已经加密并保存在当前目录,请妥善保管。'
|
82
|
+
exit
|
40
83
|
end
|
41
84
|
|
42
85
|
def retrieve_check_code(client)
|
@@ -48,8 +91,7 @@ def retrieve_check_code(client)
|
|
48
91
|
end
|
49
92
|
|
50
93
|
def authorize_session(client, username, password)
|
51
|
-
checkCode
|
52
|
-
client.get 'http://bkxk.xmu.edu.cn/xsxk/login.html', username: username, password: password, checkCode: checkCode
|
94
|
+
client.get 'http://bkxk.xmu.edu.cn/xsxk/login.html', username: username, password: password, checkCode: retrieve_check_code(client)
|
53
95
|
#握手选课系统
|
54
96
|
client.get 'http://bkxk.xmu.edu.cn/xsxk/localInfo.html'
|
55
97
|
client.get 'http://bkxk.xmu.edu.cn/xsxk/index.html'
|
@@ -59,9 +101,9 @@ end
|
|
59
101
|
def get_select_round(client, id)
|
60
102
|
round_id=nil
|
61
103
|
client.get('http://bkxk.xmu.edu.cn/xsxk/index.html').body.scan /addXklcList\((.*?)\)/m do |match|
|
62
|
-
|
63
|
-
if
|
64
|
-
round_id=
|
104
|
+
tmp_arr = filter_text(match[0].split(','))
|
105
|
+
if tmp_arr[2]==id.to_s
|
106
|
+
round_id=tmp_arr[1]
|
65
107
|
break
|
66
108
|
end
|
67
109
|
end
|
@@ -85,32 +127,21 @@ def show_courses_in_table(courses)
|
|
85
127
|
end
|
86
128
|
|
87
129
|
def parse_courses(raw_html)
|
88
|
-
|
89
|
-
course_entities = []
|
130
|
+
courses = []
|
90
131
|
count=0
|
91
|
-
raw_html.scan /top\.createJxbObj\((.*?)\)/m do |match|
|
92
|
-
|
93
|
-
|
132
|
+
transform_bracket(raw_html).scan /top\.createJxbObj\((.*?)\)/m do |match|
|
133
|
+
tmp_arr = filter_text(match[0].split(','))
|
134
|
+
courses << CourseEntity.new do |entity|
|
94
135
|
entity.index= (count=count+1)
|
95
|
-
entity.id=
|
96
|
-
entity.name=
|
97
|
-
entity.credit=
|
98
|
-
entity.teacher=
|
99
|
-
entity.period=
|
100
|
-
entity.class_name=
|
136
|
+
entity.id= tmp_arr[1]
|
137
|
+
entity.name= tmp_arr[4]
|
138
|
+
entity.credit= tmp_arr[10]
|
139
|
+
entity.teacher= tmp_arr[14]
|
140
|
+
entity.period= tmp_arr[8]
|
141
|
+
entity.class_name= tmp_arr[5]
|
101
142
|
end
|
102
143
|
end
|
103
|
-
|
104
|
-
end
|
105
|
-
|
106
|
-
|
107
|
-
def request_select_course(client, course_entity, xxlx, lcid)
|
108
|
-
msg = client.get 'http://bkxk.xmu.edu.cn/xsxk/elect.html',
|
109
|
-
method: 'handleZxxk',
|
110
|
-
jxbid: course_entity.id,
|
111
|
-
xxlx: xxlx,
|
112
|
-
xklc: lcid
|
113
|
-
JSON::parse msg.body
|
144
|
+
courses.select { |course| course.id.size>0 }
|
114
145
|
end
|
115
146
|
|
116
147
|
def create_attempt_thread(max_interval, client, course, xxlx, lcid, &block)
|
@@ -122,16 +153,25 @@ def create_attempt_thread(max_interval, client, course, xxlx, lcid, &block)
|
|
122
153
|
sleep interval
|
123
154
|
res = request_select_course(client, course, xxlx, lcid)
|
124
155
|
if res['success']
|
125
|
-
$stdout.puts '', "
|
156
|
+
$stdout.puts '', "《#{course.name}》(#{course.class_name}班)已经成功选课!", ''
|
126
157
|
break
|
127
158
|
else
|
128
|
-
$stdout.puts '', "
|
159
|
+
$stdout.puts '', "《#{course.name}》(#{course.class_name}班)第#{count}次尝试选课失败,#{interval}秒后将重试。(#{filter_text(res['message'])})", ''
|
129
160
|
end
|
130
161
|
end
|
131
162
|
exit if block.binding.local_variable_get(:opened_thread_count)-1==0
|
132
163
|
end
|
133
164
|
end
|
134
165
|
|
166
|
+
def request_select_course(client, course_entity, xxlx, lcid)
|
167
|
+
msg = client.get 'http://bkxk.xmu.edu.cn/xsxk/elect.html',
|
168
|
+
method: 'handleZxxk',
|
169
|
+
jxbid: course_entity.id,
|
170
|
+
xxlx: xxlx,
|
171
|
+
xklc: lcid
|
172
|
+
JSON::parse msg.body
|
173
|
+
end
|
174
|
+
|
135
175
|
def prepare_select_course(client)
|
136
176
|
ensure_local_account
|
137
177
|
username, password = get_account_info
|
@@ -167,68 +207,41 @@ def get_account_info
|
|
167
207
|
[stu_id, passwd]
|
168
208
|
rescue
|
169
209
|
puts '账号信息受损,请重新设置:'
|
170
|
-
set_up_account
|
171
|
-
end
|
172
|
-
|
173
|
-
def select_course_common(client, url, xxlx)
|
174
|
-
prepare_select_course(client)
|
175
|
-
courses = parse_courses((client.get url).body)
|
176
|
-
show_courses_in_table courses
|
177
|
-
try_to_select_courses(client, courses, xxlx, get_main_select_round(client))
|
178
|
-
loop do
|
179
|
-
sleep 3
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
def select_school_elective(client)
|
184
|
-
select_course_common client, 'http://bkxk.xmu.edu.cn/xsxk/yxxx.html?pagination=5000', 4
|
185
|
-
end
|
186
|
-
|
187
|
-
def select_general_elective(client)
|
188
|
-
select_course_common client, 'http://bkxk.xmu.edu.cn/xsxk/qxxxx.html?pagination=5000', 3
|
189
|
-
end
|
190
|
-
|
191
|
-
def select_public(client)
|
192
|
-
select_course_common client, 'http://bkxk.xmu.edu.cn/xsxk/ggk.html?pagination=5000', 5
|
210
|
+
set_up_account
|
193
211
|
end
|
194
212
|
|
195
213
|
def ensure_local_account
|
196
|
-
unless
|
214
|
+
unless File.exists? TOKEN_FILE_NAME
|
197
215
|
puts '请先设置账号信息(账号信息会先加密然后保存在本地,用于授权选课系统)'
|
198
216
|
set_up_account && exit
|
199
217
|
end
|
200
218
|
end
|
201
219
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
220
|
+
#转换圆括号
|
221
|
+
def transform_bracket(raw)
|
222
|
+
if Enumerable===raw
|
223
|
+
return [].tap do |arr|
|
224
|
+
raw.each do |item|
|
225
|
+
arr<<transform_bracket(item)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
raw.gsub! /\((.*)\)/ do |match|
|
230
|
+
"(#{match[1..-2]})"
|
231
|
+
end
|
232
|
+
raw
|
215
233
|
end
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
select_general_elective(CLIENT)
|
230
|
-
when opts.public?
|
231
|
-
select_public(CLIENT)
|
232
|
-
else
|
233
|
-
puts(opts) && exit
|
234
|
+
def filter_text(raw)
|
235
|
+
if Enumerable===raw
|
236
|
+
return [].tap do |arr|
|
237
|
+
raw.each do |item|
|
238
|
+
arr<<filter_text(item)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
black_list =([] << "\r" << "\n" << "\t" << "'" << '<br>')
|
243
|
+
black_list.each do |tmp|
|
244
|
+
raw.gsub! tmp, ''
|
245
|
+
end
|
246
|
+
raw
|
234
247
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arb-xmu-course
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- arybin
|
@@ -95,7 +95,6 @@ files:
|
|
95
95
|
- Rakefile
|
96
96
|
- arb-xmu-course.gemspec
|
97
97
|
- bin/arb-xmu-course
|
98
|
-
- bin/check_code.jpeg
|
99
98
|
- lib/arb/xmu/course.rb
|
100
99
|
- lib/arb/xmu/course/models/course_entity.rb
|
101
100
|
- lib/arb/xmu/course/models/course_schedule.rb
|
data/bin/check_code.jpeg
DELETED
Binary file
|