arb-xmu-course 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 033892d7b5333bf00107dbfec09930a09e51d68d
4
+ data.tar.gz: 6ab649181d6263af37af3248b21084e679b8a28c
5
+ SHA512:
6
+ metadata.gz: bef7169c325840623e5af693600a9b694614dc54791185647a343d08bd761290e2e8f1949e705976821b2389028de7320a7e5ebb091bbe7eca7e73f3302b2ade
7
+ data.tar.gz: 0a02725936ec1a99a09fff4ca0b61704cd1a97309c482a875ffe9075025ff3df7f6ecf6c095665673c34442cf68fa82d5e05eb6091d0db5fc167d906830d8557
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /.idea
11
+ /bin/encrypted_token
data/.rake_tasks~ ADDED
@@ -0,0 +1,6 @@
1
+ build
2
+ clean
3
+ clobber
4
+ install
5
+ install:local
6
+ release[remote]
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'slop', '~> 4.3.0'
4
+ gem 'httpclient', '~> 2.8'
5
+ gem 'nokogiri', '~> 1.6.8'
6
+ gem 'terminal-table', '~> 1.6.0'
7
+
8
+ # Specify your gem's dependencies in arb-xmu-course.gemspec
9
+ gemspec
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # Arb::Xmu::Course
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/arb/xmu/course`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'arb-xmu-course'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install arb-xmu-course
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/arb-xmu-course.
36
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'arb/xmu/course/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "arb-xmu-course"
8
+ spec.version = Arb::Xmu::Course::VERSION
9
+ spec.authors = ["arybin"]
10
+ spec.email = ["arybin@163.com"]
11
+
12
+ spec.summary = %q{XMU Course}
13
+ spec.description = %q{XMU Course}
14
+ spec.homepage = 'https://github.com/arybin-cn/arb-xmu-course'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "bin"
18
+ spec.executables = 'arb-xmu-course'
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.12"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ end
@@ -0,0 +1,236 @@
1
+ #!/usr/bin/env ruby
2
+ require 'slop'
3
+ require 'json'
4
+ require 'httpclient'
5
+ require 'nokogiri'
6
+ require 'terminal-table'
7
+ require 'arb/xmu/course'
8
+
9
+ include Arb::Util
10
+ include Arb::Xmu::Course
11
+
12
+ TOKEN_FILE_NAME = 'encrypted_token'
13
+ TOKEN_SEPARATOR = ':'
14
+
15
+
16
+ def filter_text(raw)
17
+ if Enumerable===raw
18
+ return [].tap do |arr|
19
+ raw.each do |item|
20
+ arr<<filter_text(item)
21
+ end
22
+ end
23
+ end
24
+ black_list =([] << "\r" << "\n" << "\t" << "'")
25
+ black_list.each do |tmp|
26
+ raw.gsub! tmp, ''
27
+ end
28
+ raw
29
+ end
30
+
31
+ def set_up_account
32
+ $stdout.puts '请输入学号:'
33
+ stu_id= $stdin.gets.chomp
34
+ $stdout.puts '请输入密码:'
35
+ passwd= $stdin.gets.chomp
36
+ File.open TOKEN_FILE_NAME, 'w' do |file|
37
+ file.write (SimpleDes.encrypt(stu_id)+TOKEN_SEPARATOR+SimpleDes.encrypt(passwd))
38
+ end
39
+ end
40
+
41
+ def retrieve_check_code(client)
42
+ File.open 'check_code.jpeg', 'wb' do |file|
43
+ file.write(client.get('http://bkxk.xmu.edu.cn/xsxk/getCheckCode').body)
44
+ end
45
+ $stdout.puts '验证码图片已在当前目录生成,请查看后输入:'
46
+ $stdin.gets.chomp
47
+ end
48
+
49
+ def authorize_session(client, username, password)
50
+ checkCode = retrieve_check_code(client)
51
+ client.get 'http://bkxk.xmu.edu.cn/xsxk/login.html', username: username, password: password, checkCode: checkCode
52
+ #握手选课系统
53
+ client.get 'http://bkxk.xmu.edu.cn/xsxk/localInfo.html'
54
+ client.get 'http://bkxk.xmu.edu.cn/xsxk/index.html'
55
+ end
56
+
57
+ #获取选课轮次
58
+ def get_select_round(client, id)
59
+ round_id=nil
60
+ client.get('http://bkxk.xmu.edu.cn/xsxk/index.html').body.scan /addXklcList\((.*?)\)/m do |match|
61
+ tmpArr = filter_text(match[0].split(','))
62
+ if tmpArr[2]==id.to_s
63
+ round_id=tmpArr[1]
64
+ break
65
+ end
66
+ end
67
+ round_id
68
+ end
69
+
70
+ #获取主修选课轮次
71
+ def get_main_select_round(client)
72
+ get_select_round(client, 1)
73
+ end
74
+
75
+ def show_courses_in_table(courses)
76
+ table = Terminal::Table.new do |table|
77
+ table.add_row %w{ID 课程名称 学分 班号 主讲老师 总学时}
78
+ courses.each do |course_entity|
79
+ table.add_separator
80
+ table.add_row course_entity.to_a
81
+ end
82
+ end
83
+ $stdout.puts table
84
+ end
85
+
86
+ def parse_courses(raw_html)
87
+
88
+ course_entities = []
89
+ count=0
90
+ raw_html.scan /top\.createJxbObj\((.*?)\)/m do |match|
91
+ tmpArr = filter_text(match[0].split(','))
92
+ course_entities << CourseEntity.new do |entity|
93
+ entity.index= (count=count+1)
94
+ entity.id= tmpArr[1]
95
+ entity.name= tmpArr[4]
96
+ entity.credit= tmpArr[10]
97
+ entity.teacher= tmpArr[14]
98
+ entity.period= tmpArr[8]
99
+ entity.class_name= tmpArr[5]
100
+ end
101
+ end
102
+ course_entities
103
+ end
104
+
105
+
106
+ def request_select_course(client, course_entity, xxlx, lcid)
107
+ msg = client.get 'http://bkxk.xmu.edu.cn/xsxk/elect.html',
108
+ method: 'handleZxxk',
109
+ jxbid: course_entity.id,
110
+ xxlx: xxlx,
111
+ xklc: lcid
112
+ JSON::parse msg.body
113
+ end
114
+
115
+ def create_attempt_thread(max_interval, client, course_entity, xxlx, lcid)
116
+ Thread.new do
117
+ count=0
118
+ loop do
119
+ count+=1
120
+ interval = 1+rand(max_interval)
121
+ sleep interval
122
+ res = request_select_course(client, course_entity, xxlx, lcid)
123
+ if res[:success]
124
+ $stdout.puts "课程:《#{course_entity.name}》已经成功选课!"
125
+ break
126
+ else
127
+ $stdout.puts "课程:《#{course_entity.name}》第#{count}次尝试选课失败,#{interval}秒后将重试。"
128
+ end
129
+ end
130
+
131
+ end
132
+ end
133
+
134
+
135
+ def select_school_elective(client, username, password)
136
+ authorize_session(client, username, password)
137
+ lcid=get_main_select_round(client)
138
+
139
+ school_courses = parse_courses((client.get 'http://bkxk.xmu.edu.cn/xsxk/yxxx.html').body)
140
+ show_courses_in_table school_courses
141
+
142
+ $stdout.puts
143
+ $stdout.puts '输入要选的课程ID, 以空格分割:'
144
+
145
+ ids = $stdin.gets.chomp.split(' ')
146
+
147
+ $stdout.puts '输入最大重试间隔时间,默认3秒,要求不得低于2秒:'
148
+
149
+ max_interval = $stdin.gets.chomp.to_i
150
+ max_interval = 2 if max_interval<2
151
+
152
+ ids.each do |id|
153
+ create_attempt_thread(max_interval, client, school_courses.find { |course| course.index==id.to_i }, 1, lcid)
154
+ end
155
+
156
+ loop do
157
+ sleep 3
158
+ end
159
+
160
+
161
+ end
162
+
163
+ def select_general_elective
164
+
165
+ end
166
+
167
+ def select_public
168
+
169
+ end
170
+
171
+
172
+ unless (File.exists? TOKEN_FILE_NAME)
173
+ puts '请先设置账户信息(账户信息会先加密然后保存在本地,用于授权选课系统)'
174
+ set_up_account
175
+ exit
176
+ end
177
+
178
+ stu_id, passwd=nil
179
+ client = HTTPClient.new
180
+
181
+ File.open TOKEN_FILE_NAME, 'r' do |file|
182
+ stu_id, passwd=SimpleDes.decrypt(file.read.split(TOKEN_SEPARATOR))
183
+ end
184
+
185
+ opts = Slop.parse do |o|
186
+ o.bool *%w{-h --help}, '显示帮助'
187
+ o.bool *%w{-c --clear}, '清除本地账户信息'
188
+ o.bool *%w{-r --reset}, '重置账户信息'
189
+
190
+ #院选课程 xxlx=4
191
+ o.bool *%w{-s --school}, '院选选课'
192
+ #校选课程 xxlx=3
193
+ o.bool *%w{-g --general}, '校选选课'
194
+ #公共课程 xxlx=5
195
+ o.bool *%w{-p --public}, '公共课选课'
196
+ end
197
+
198
+ case true
199
+ when opts.help?
200
+ puts(opts) && exit
201
+ when opts.clear?
202
+ File.delete(TOKEN_FILE_NAME) && exit
203
+ when opts.reset?
204
+ set_up_account && exit
205
+ when opts.school?
206
+ select_school_elective(client, stu_id, passwd)
207
+ when opts.general?
208
+ # select_general_elective
209
+ when opts.public?
210
+ # select_public
211
+ end
212
+
213
+ # client = HTTPClient.new
214
+
215
+ # #session init
216
+ # client.get 'http://bkxk.xmu.edu.cn/xsxk/login.html'
217
+ #
218
+ # File.open 'checkcode.jpeg','wb' do |file|
219
+ # file.write(client.get('http://bkxk.xmu.edu.cn/xsxk/getCheckCode').body)
220
+ # end
221
+ #
222
+ # puts 'enter your student id'
223
+ # user= gets.chomp
224
+ # puts 'enter your password'
225
+ # passwd=gets.chomp
226
+ # puts 'enter the checkcode'
227
+ # checkcode=gets.chomp
228
+ #
229
+ # client.get 'http://bkxk.xmu.edu.cn/xsxk/login.html',username: user,password: passwd,checkCode: checkcode
230
+ #
231
+ # puts (client.get 'http://bkxk.xmu.edu.cn/xsxk/localInfo.html').body
232
+ #
233
+ # Nokogiri::parse((client.get 'http://bkxk.xmu.edu.cn/xsxk/index.html').body).css('script').each do |x|
234
+ # puts x.text
235
+ # end
236
+ #
Binary file
@@ -0,0 +1,35 @@
1
+ module Arb
2
+ module Xmu
3
+ module Course
4
+ class CourseEntity
5
+ #选课系统课程标识
6
+ attr_accessor :id
7
+ #索引
8
+ attr_accessor :index
9
+ #课程名
10
+ attr_accessor :name
11
+ #学分
12
+ attr_accessor :credit
13
+ #教师名
14
+ attr_accessor :teacher
15
+ #班级
16
+ attr_accessor :class_name
17
+ #总学时
18
+ attr_accessor :period
19
+
20
+ #Entity.new(index: 1,credit: 3, ...)
21
+ def initialize(**hash_args)
22
+ yield self if block_given?
23
+ hash_args.keys.each do |key|
24
+ send "#{key}=", hash_args[key]
25
+ end
26
+ end
27
+
28
+ #for row output
29
+ def to_a
30
+ [index, name, credit, class_name, teacher, period]
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,8 @@
1
+ module Arb
2
+ module Xmu
3
+ module Course
4
+ class CourseSchedule
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,32 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+
4
+ module Arb
5
+ module Util
6
+ class SimpleDes
7
+ ALG = 'DES-EDE3-CBC'
8
+ KEY = (Dir.pwd.split('').select { |char| char=~/\w/ }.join+'bYaRyBin')[0..7]
9
+ DES_KEY = KEY.swapcase
10
+ class << self
11
+ %i{encrypt decrypt}.each do |type|
12
+ define_method type do |input|
13
+ if Enumerable===input
14
+ return [].tap do |arr|
15
+ input.each do |item|
16
+ arr<<(send type, item)
17
+ end
18
+ end
19
+ end
20
+ des = OpenSSL::Cipher::Cipher.new(ALG)
21
+ des.pkcs5_keyivgen(KEY, DES_KEY)
22
+ des.send type
23
+ input=Base64.decode64(input) if :decrypt==type
24
+ res =(des.update(input)<<des.final)
25
+ return Base64.encode64(res).chomp if :encrypt==type
26
+ res
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,7 @@
1
+ module Arb
2
+ module Xmu
3
+ module Course
4
+ VERSION = '1.0.0'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ Gem::Specification.find_by_name('arb-xmu-course').full_require_paths.each do |dir|
2
+ Dir[dir+File::Separator+'**'+File::Separator+'*.rb'].each do |lib_name|
3
+ require lib_name
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: arb-xmu-course
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - arybin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-07-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: XMU Course
42
+ email:
43
+ - arybin@163.com
44
+ executables:
45
+ - arb-xmu-course
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - ".rake_tasks~"
51
+ - Gemfile
52
+ - README.md
53
+ - Rakefile
54
+ - arb-xmu-course.gemspec
55
+ - bin/arb-xmu-course
56
+ - bin/check_code.jpeg
57
+ - lib/arb/xmu/course.rb
58
+ - lib/arb/xmu/course/models/course_entity.rb
59
+ - lib/arb/xmu/course/models/course_schedule.rb
60
+ - lib/arb/xmu/course/util/simple_des.rb
61
+ - lib/arb/xmu/course/version.rb
62
+ homepage: https://github.com/arybin-cn/arb-xmu-course
63
+ licenses: []
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.4.8
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: XMU Course
85
+ test_files: []