sfcsfs 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ .*.swp
2
+ .*.swo
3
+ *~
4
+ Gemfile.lock
5
+ pkg/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sfcsfs.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 ymrl
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,52 @@
1
+ # SFCSFS
2
+
3
+ SFCSFS is a SFC-SFS Scraping Library. SFC-SFS is an internal website for Keio Univ. Shounan Fujisawa Campus.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'sfcsfs'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install sfcsfs
18
+
19
+ ## Usage
20
+
21
+ config = Pit.get("sfcsfs", :require => {
22
+ :account => "your CNS account",
23
+ :password => "your CNS password"
24
+ })
25
+
26
+ # Login to SFC-SFS
27
+ agent = SFCSFS.login(config[:account],config[:password])
28
+
29
+ # Get all classes of this semester and shows
30
+ # It takes several minutes...
31
+ list = agent.all_classes_of_this_semester
32
+
33
+ # Show name of these
34
+ list.each do |e|
35
+ puts e.title
36
+ end
37
+
38
+ # Get your current weekly schedule
39
+ list = agent.my_schedule
40
+
41
+ # Show name of these
42
+ list.each do |e|
43
+ puts e.title
44
+ end
45
+
46
+ ## Contributing
47
+
48
+ 1. Fork it
49
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
50
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
51
+ 4. Push to the branch (`git push origin my-new-feature`)
52
+ 5. Create new Pull Request
@@ -0,0 +1,10 @@
1
+ #coding:utf-8
2
+ require 'rake'
3
+ $:.unshift File.join(File.dirname(__FILE__),'lib')
4
+
5
+ require 'rspec/core'
6
+ require 'rspec/core/rake_task'
7
+ require "bundler/gem_tasks"
8
+
9
+ task :default => :spec
10
+ Dir['tasks/**/*.rake'].each { |t| load t}
@@ -0,0 +1,16 @@
1
+ #coding:utf-8
2
+ $:.unshift(File.dirname(__FILE__)) unless
3
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
4
+
5
+ directory = File.expand_path(File.dirname(__FILE__))
6
+
7
+ require directory+'/sfcsfs/lecture.rb'
8
+ require directory+'/sfcsfs/homework.rb'
9
+ require directory+'/sfcsfs/util.rb'
10
+ require directory+'/sfcsfs/agent.rb'
11
+ require directory+'/sfcsfs/agent/navigations.rb'
12
+
13
+
14
+ module SFCSFS
15
+ VERSION = '0.1.0'
16
+ end
@@ -0,0 +1,88 @@
1
+ #coding:utf-8
2
+ require 'nokogiri'
3
+ require 'uri'
4
+ require 'net/https'
5
+ require 'addressable/uri'
6
+
7
+ module SFCSFS
8
+ REDIRECT_LIMIT = 5
9
+
10
+ class Agent
11
+
12
+ def inspect
13
+ "#{self.class} #{@id}"
14
+ end
15
+
16
+ def request uri,method=:get,data={}
17
+ ret = nil
18
+ count = 0
19
+ while count < REDIRECT_LIMIT and !ret or Net::HTTPRedirection === ret
20
+ uri = (URI::Generic === uri ? uri : URI.parse(uri))
21
+ req = nil
22
+ uri += '/' if uri.path == ''
23
+ path = uri.path
24
+ path += "?#{uri.query}" if uri.query && uri.query.length > 0
25
+ if method.to_sym == :post
26
+ req = Net::HTTP::Post.new(path)
27
+ else
28
+ req = Net::HTTP::Get.new(path)
29
+ end
30
+ req.set_form_data(data) if data.length > 0
31
+ http = Net::HTTP.new(uri.host,uri.port)
32
+ http.use_ssl = true if uri.scheme == 'https'
33
+ http.start{|http| ret = http.request(req)}
34
+ @uri = uri
35
+ uri = ret['location'] if ret['location']
36
+ count += 0
37
+ end
38
+ if count >= REDIRECT_LIMIT
39
+ raise TooManyRedirectionsException
40
+ end
41
+ return ret
42
+ end
43
+
44
+ def request_parse uri,method=:get,data={}
45
+ uri = (URI::Generic === uri ? uri : URI.parse(uri))
46
+ r = request(uri,method,data)
47
+ @doc = Nokogiri.HTML(SFCSFS.convert_encoding(r.body),nil,'UTF-8')
48
+ if meta = @doc.search('meta[http-equiv=refresh]').first
49
+ match = meta.attr('content').match(/url=(.*)$/)
50
+ if match
51
+ request_parse(@uri+match[1])
52
+ end
53
+ end
54
+ return @doc
55
+ end
56
+
57
+ def initialize
58
+ @uri = nil
59
+ @doc = nil
60
+ @id = nil
61
+ @base_uri = nil
62
+ @type = nil
63
+ return self
64
+ end
65
+
66
+ def Agent.login(account,passwd,options={})
67
+ a = Agent.new
68
+ doc = a.request_parse('https://gc.sfc.keio.ac.jp/sfc-sfs/')
69
+ action = doc.search('form').attr('action')
70
+ a.request_parse(action,:post,:u_login => account, :u_pass => passwd)
71
+ query_values = Addressable::URI.parse(a.uri).query_values
72
+ a.id = query_values['id']
73
+ a.type = query_values['type']
74
+
75
+ if options[:vu9]
76
+ a.base_uri = URI.parse('https://vu9.sfc.keio.ac.jp/')
77
+ else
78
+ a.base_uri = a.uri + '/'
79
+ end
80
+
81
+ return a
82
+ end
83
+ attr_accessor :login,:query_values,:base_uri,
84
+ :doc,:id,:uri,:type
85
+ end
86
+ class TooManyRedirectionsException < Exception
87
+ end
88
+ end
@@ -0,0 +1,97 @@
1
+ #coding:UTF-8
2
+ class SFCSFS::Agent
3
+ def plan_of_this_semester
4
+ get_plans_page_of_this_semester
5
+ plan_list_from_plans_page
6
+ end
7
+
8
+ def plan_of_next_semester
9
+ get_plans_page_of_next_semester
10
+ plan_list_from_plans_page
11
+ end
12
+
13
+ def all_classes_of_this_semester
14
+ get_plans_page_of_this_semester
15
+ all_classes_from_plans_page
16
+ end
17
+
18
+ def all_classes_of_next_semester
19
+ get_plans_page_of_next_semester
20
+ all_classes_from_plans_page
21
+ end
22
+
23
+ def get_plans_page_of_this_semester
24
+ outer_uri = @base_uri +
25
+ "/sfc-sfs/portal_s/s02.cgi?id=#{@id}&type=#{@type}&mode=1&lang=ja"
26
+ request_parse(outer_uri)
27
+ inner_uri = outer_uri + @doc.search('iframe').attr('src').to_s
28
+ request_parse(inner_uri)
29
+ end
30
+
31
+ def get_plans_page_of_next_semester
32
+ outer_uri = @base_uri +
33
+ "/sfc-sfs/portal_s/s02.cgi?id=#{@id}&type=#{@type}&mode=2&lang=ja"
34
+ request_parse(outer_uri)
35
+ inner_uri = outer_uri + @doc.search('iframe').attr('src').to_s
36
+ request_parse(inner_uri)
37
+ end
38
+
39
+ def all_classes_from_plans_page
40
+ list = []
41
+ uri = @uri
42
+ @doc.search('a[href]').to_a.delete_if{|e| !e.attr('href').match(/class_list\.cgi/)}.each do |e|
43
+ request_parse uri+e.attr('href')
44
+ @doc.search('a[href]').to_a.delete_if{|e| !e.attr('href').match(/plan_list\.cgi/)}.each do |e|
45
+ str = e.parent.text
46
+ title = nil
47
+ instructor = nil
48
+ #if match = str.match(/:\d+\(.+?\) …\s?(.+?)\s?\((.+?)\)…/)
49
+ if match = str.match(/:\d+\(.+?\) … (.+?)\s?\(([^\(\)]+?)\)…/u)
50
+ title = match[1]
51
+ instructor = match[2]
52
+ end
53
+ q = Addressable::URI.parse(e.attr('href')).query_values
54
+ ks = q['ks']
55
+ yc = q['yc']
56
+ reg = q['reg']
57
+ term = q['term']
58
+ list.push SFCSFS::Lecture.new(self,title,instructor,:ks=>ks,:yc=>yc,:reg=>reg,:term=>term)
59
+ end
60
+ end
61
+ return list
62
+ end
63
+
64
+ def plan_list_from_plans_page
65
+ @doc.search('a').to_a.delete_if{|e| !e.attributes['href'].match(/syll_view.cgi/)}.map do |e|
66
+ href = e.attributes['href']
67
+ q = Addressable::URI.parse(href).query_values
68
+ ks = q['ks']
69
+ yc = q['yc']
70
+ title = e.children.first.to_s
71
+ SFCSFS::Lecture.new(self,title,nil,:ks=>ks,:yc=>yc)
72
+ end
73
+ end
74
+
75
+ def my_schedule
76
+ outer_uri = @base_uri +
77
+ "/sfc-sfs/portal_s/s01.cgi?id=#{@id}&type=#{@type}&mode=1&lang=ja"
78
+ request_parse outer_uri
79
+ inner_uri = @uri + @doc.search('iframe').attr('src').to_s
80
+ request_parse inner_uri
81
+
82
+ @doc.search('table a[href]').to_a.delete_if{|e|
83
+ !e.attr('href').match(/sfs_class/)
84
+ }.map do |e|
85
+ href = e.attr("href")
86
+ q = Addressable::URI.parse(href).query_values
87
+ option ={}
88
+ option[:ks] = q['ks']
89
+ option[:yc] = q['yc']
90
+ option[:mode] = href.match(/faculty/) ? 'faculty' : 'student'
91
+ title = e.children.first.to_s
92
+ title.gsub!(/\[([^\]]*)\]$/u){option[:place]=$1;""}
93
+ instructor = e.next.next.to_s.gsub(/[()\s ]/u,'')
94
+ SFCSFS::Lecture.new(self,title,instructor,option)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,12 @@
1
+ #coding:utf-8
2
+
3
+ module SFCSFS
4
+ class Homework
5
+ def initialize(title,url)
6
+ @title = title.to_s
7
+ @url = url.to_s
8
+ end
9
+ attr_accessor :title,:url
10
+ end
11
+ end
12
+
@@ -0,0 +1,125 @@
1
+ #coding:utf-8
2
+ module SFCSFS
3
+ class Lecture
4
+ def initialize(agent,title,instructor,config={})
5
+ @agent = agent
6
+ @title = title
7
+ @instructor = instructor
8
+ @instructors = config[:instructors] || []
9
+ @mode = config[:mode]
10
+ @yc = config[:yc]
11
+ @ks = config[:ks]
12
+ @reg = config[:reg]
13
+ @term = config[:term]
14
+ @homeworks = config[:homeworks] || []
15
+ @periods = config[:periods] || []
16
+ @applicants = config[:applicants]
17
+ @limit = config[:limit]
18
+ @place = config[:place]
19
+ end
20
+ def inspect
21
+ "#{self.class} \"#{@title}\" \"#{@instructor}\" #{@yc} #{@ks}"
22
+ end
23
+ def class_top_path
24
+ unless @yc && @ks && @agent.id
25
+ raise NotEnoughParamsException
26
+ end
27
+ mode = 'student'
28
+ file = 's_class_top.cgi'
29
+ if(self.mode == 'faculty')
30
+ mode = 'faculty'
31
+ file = 'f_class_top.cgi'
32
+ end
33
+ return "/sfc-sfs/sfs_class/#{mode}/#{file}?lang=ja&ks=#{@ks}&yc=#{@yc}&id=#{@agent.id}"
34
+ end
35
+ def stay_input_path
36
+ unless @yc && @ks && @agent.id
37
+ raise NotEnoughParamsException
38
+ end
39
+ "/sfc-sfs/sfs_class/stay/stay_input.cgi?yc=#{@yc}&ks=#{@ks}&enc_id=#{@agent.id}"
40
+ end
41
+ def student_selection_path
42
+ unless @yc && @agent.id
43
+ raise NotEnoughParamsException
44
+ end
45
+ "/sfc-sfs/sfs_class/student/view_student_select.cgi?enc_id=#{@agent.id}&yc=#{@yc}&lang=ja"
46
+ end
47
+
48
+ def get_detail
49
+ uri = @agent.base_uri + class_top_path
50
+ doc = @agent.request_parse(uri)
51
+ @title = doc.search('h3.one').first.children.first.to_s.gsub(/[\s ]/,'')
52
+ @instructors += doc.search('h3.one > a[href]').to_a.delete_if{|e| !e.attr('href').match(/profile\.cgi/)}.map{|e|e.children.first.to_s}
53
+ @instructors.uniq!
54
+ term = doc.search('h3.one .ja').text.match(/時限:(\d{4})年([春秋])学期(.*)$/)
55
+ if term
56
+ @term = "#{term[1]}#{term[2] == '春' ? 's' : 'f'}"
57
+ @periods += term[3].gsub(/\s/,'').split(/,/)
58
+ @periods.uniq!
59
+ end
60
+ page = doc.to_s
61
+ #a.doc.search('a').to_a.delete_if{|e|!e.attributes['href'].match(%r{/report/report\.cgi\?})}.each do |e|
62
+ # # TODO : Homeworks Func
63
+ #end
64
+ if m = page.match(/履修希望者数:(\d+)/)
65
+ @applicants = m[1].to_i
66
+ end
67
+ if m = page.match(/受入学生数(予定):約 (\d+) 人/)
68
+ @limit = m[1].to_i
69
+ end
70
+ return self
71
+ end
72
+
73
+ def student_selection_list
74
+ uri = @agent.base_uri + student_selection_path
75
+ doc = @agent.request_parse(uri)
76
+ return doc.search('tr[bgcolor="#efefef"] td').map{|e| e.children.first.to_s}.delete_if{|e| !e.match(/^\d{8}/)}
77
+ end
78
+
79
+ def get_stay_input_page
80
+ uri = @agent.base_uri + stay_input_path
81
+ @agent.request_parse(uri)
82
+ end
83
+ def submit_stay_form data
84
+ param = {}
85
+ uri = @agent.base_uri + '/sfc-sfs/sfs_class/stay/stay_input.cgi'
86
+ unless @yc && @ks && @aget.id
87
+ raise NotEnoughParamsException
88
+ end
89
+ param[:stay_phone] = data[:stay_phone]
90
+ param[:stay_p_phone] = data[:stay_p_phone]
91
+ param[:stay_time] = data[:stay_time]
92
+ param[:selectRoom] = data[:selectRoom]
93
+ param[:selectFloor] = data[:selectFloor]
94
+ param[:stay_room_other] = data[:stay_room_other]
95
+ param[:stay_reason] = data[:stay_reason]
96
+ param[:mode] = 'submit'
97
+ param[:yc] = @yc
98
+ param[:ks] = @ks
99
+ param[:enc_id] = @agent.id
100
+ request uri,:post,data
101
+ end
102
+ def add_to_plan
103
+ unless @reg && @yc && @ks && @agent.id && @term
104
+ raise NotEnoughParamsException
105
+ end
106
+ uri = @agent.base_uri + "/sfc-sfs/sfs_class/student/plan_list.cgi?reg=#{@reg}&yc=#{@yc}&mode=add&ks=#{@ks}&id=#{@agent.id}&term=#{@term}&lang=ja"
107
+ @agent.request(uri)
108
+ end
109
+
110
+ def delete_from_plan
111
+ unless @yc && @ks && @agent.id && @term
112
+ raise NotEnoughParamsException
113
+ end
114
+ uri = @agent.base_uri + "/sfc-sfs/sfs_class/student/plan_list.cgi?reg=#{@reg}&yc=#{@yc}&mode=del&ks=#{@ks}&id=#{@agent.id}&term=#{@term}&lang=ja"
115
+ @agent.request(uri)
116
+ end
117
+
118
+ attr_accessor :title,:instructor,:mode,:yc,:ks,:homeworks,
119
+ :add_list_url,:periods,:applicants,:limit,
120
+ :reg,:term, :place
121
+ end
122
+
123
+ class NotEnoughParamsException < Exception
124
+ end
125
+ end
@@ -0,0 +1,15 @@
1
+ module SFCSFS
2
+ def SFCSFS.login(account,passwd)
3
+ return Agent.login(account,passwd)
4
+ end
5
+
6
+ def SFCSFS.convert_encoding str
7
+ if RUBY_VERSION >= "1.9"
8
+ return str.force_encoding(Encoding::EUC_JP).encode(Encoding::UTF_8,:invalid=>:replace,:undef=>:replace)
9
+ else
10
+ require 'kconv'
11
+ return Kconv.kconv(str,Kconv::UTF8,Kconv::EUC)
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r ./#{File.dirname(__FILE__) + '/../lib/sfcsfs'}"
9
+ libs << " -r ./#{File.dirname(__FILE__) + '/console_helper'}"
10
+ puts "Loading SFCSFS"
11
+ puts "SFCSFS::Agent.login(CONFIG[:account],CONFIG[:password])"
12
+ exec "#{irb} #{libs} --simple-prompt"
@@ -0,0 +1,4 @@
1
+ require 'pit'
2
+ CONFIG = Pit.get("sfcsfs", :require => {
3
+ :account => "your CNS account",
4
+ :password => "your CNS password" })
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/sfcsfs', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["ymrl"]
6
+ gem.email = ["ymrl@ymrl.net"]
7
+ gem.description = %q{SFC-SFS Scraping Library}
8
+ gem.summary = %q{SFC-SFS Scraping Library}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "sfcsfs"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = SFCSFS::VERSION
17
+ gem.add_dependency('nokogiri','~> 1.5.5')
18
+ gem.add_dependency('addressable','~> 2.2.8')
19
+ gem.add_development_dependency('rspec', '~> 2.10.0')
20
+ gem.add_development_dependency('rake')
21
+ gem.add_development_dependency('pit')
22
+ end
@@ -0,0 +1,84 @@
1
+ #coding:utf-8
2
+
3
+ require File.dirname(__FILE__) + '/spec_helper.rb'
4
+ require File.dirname(__FILE__) + '/../lib/sfcsfs.rb'
5
+
6
+ describe 'Agent' do
7
+ before do
8
+ config = Pit.get("sfcsfs", :require => {
9
+ :account => "your CNS account",
10
+ :password => "your CNS password"
11
+ })
12
+ @agent = SFCSFS.login(config[:account],config[:password])
13
+ end
14
+ it 'URLがs01.cgiにいる' do
15
+ @agent.uri.to_s.match(%r!^https://vu.\.sfc\.keio\.ac\.jp/sfc-sfs/portal_s/s01\.cgi.*!).should be_true
16
+ end
17
+
18
+ it 'idがセットされている' do
19
+ @agent.id.should be_true
20
+ end
21
+
22
+ #it '次学期プランページへのアクセス' do
23
+ # @agent.get_plans_page_of_next_semester
24
+ #end
25
+
26
+ #context '次学期プランの履修' do
27
+ # it '科目一覧の取得' do
28
+ # list = @agent.get_class_list_of_next_semester
29
+ # list.each do |e|
30
+ # e.should be_instance_of(SFCSFS::Lecture)
31
+ # e.add_list_url.should be_true
32
+ # end
33
+ # end
34
+ #end
35
+ #it '今学期プランページへのアクセス' do
36
+ # @agent.get_plans_page_of_this_semester
37
+ #end
38
+
39
+ #context '今学期プランの履修' do
40
+ # it '科目一覧の取得' do
41
+ # list = @agent.get_class_list_of_this_semester
42
+ # list.each do |e|
43
+ # e.should be_instance_of(SFCSFS::Lecture)
44
+ # e.add_list_url.should be_true
45
+ # end
46
+ # end
47
+ #end
48
+
49
+
50
+ context 'my時間割にアクセスする' do
51
+ before do
52
+ @lectures = @agent.my_schedule
53
+ end
54
+ it 'Lectureが生成されている' do
55
+ @lectures.each do |e|
56
+ e.should be_instance_of(SFCSFS::Lecture)
57
+ e.instructor.should have_at_least(1).items
58
+ e.yc.should be_true
59
+ e.ks.should be_true
60
+ e.mode.should be_true
61
+ e.homeworks.should be_instance_of(Array)
62
+ end
63
+ end
64
+ #it 'Lectureから残留届けページヘ行ける' do
65
+ # @lectures.each {|e| e.get_stay_input_page(@agent)}
66
+ #end
67
+ it 'Lecture#instructorが括弧とか\sとか含まない' do
68
+ @lectures.each { |e| (e.instructor.match(/[()()\s]/)).should be_false }
69
+ end
70
+ #it 'Lectureそれぞれに詳細情報を取得できる' do
71
+ # @lectures.each do |e| e.get_detail()
72
+ # e.homeworks.each do |h|
73
+ # h.should be_instance_of(SFCSFS::Homework)
74
+ # h.title.should have_at_least(1).items
75
+ # h.title.match(/^「/).should be_false
76
+ # h.title.match(/」$/).should be_false
77
+ # h.url.match(%r{.*\.sfc\.keio\.ac\.jp/sfc-sfs/sfs_class/report/report.cgi\?}).should be_true
78
+ # end
79
+ # end
80
+ #end
81
+ end
82
+ end
83
+
84
+
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,8 @@
1
+ #coding:utf-8
2
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__)))
4
+
5
+ Dir[File.join(File.dirname(__FILE__), "..", "lib", "models", "**/*.rb")].each do |f|
6
+ require f
7
+ end
8
+ require 'pit'
@@ -0,0 +1,49 @@
1
+ require './' + File.dirname(__FILE__) + '/../lib/sfcsfs.rb'
2
+ require 'pit'
3
+ desc "Add All Lectures of Next Semester"
4
+
5
+ task :addnext do
6
+ config = Pit.get("sfcsfs", :require => {
7
+ :account => "your CNS account",
8
+ :password => "your CNS password"
9
+ })
10
+ agent = SFCSFS.login(config[:account],config[:password])
11
+ list = agent.all_classes_of_next_semester
12
+ list.each do |lecture|
13
+ puts "#{lecture.title} (#{lecture.instructor})"
14
+ retry_count = 0
15
+ begin
16
+ lecture.add_to_plan
17
+ rescue
18
+ sleep 60
19
+ retry_count += 1
20
+ if retry_count < 10
21
+ retry
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ desc "Add All Lectures of this Semester"
28
+ task :addall do
29
+ config = Pit.get("sfcsfs", :require => {
30
+ :account => "your CNS account",
31
+ :password => "your CNS password"
32
+ })
33
+ agent = SFCSFS.login(config[:account],config[:password])
34
+ list = agent.all_classes_of_this_semester
35
+ list.each do |lecture|
36
+ puts "#{lecture.title} (#{lecture.instructor})"
37
+ retry_count = 0
38
+ begin
39
+ lecture.add_to_plan
40
+ rescue
41
+ sleep 60
42
+ retry_count += 1
43
+ if retry_count < 10
44
+ retry
45
+ end
46
+ end
47
+ end
48
+ end
49
+
@@ -0,0 +1,20 @@
1
+ begin
2
+ require 'rspec'
3
+ rescue LoadError
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ require 'rspec'
6
+ end
7
+ begin
8
+ require 'rspec/core/rake_task'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ RSpec::Core::RakeTask.new do |t|
18
+ t.rspec_opts = ['--options', "spec/spec.opts"]
19
+ t.pattern = 'spec/**/*_spec.rb'
20
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sfcsfs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - ymrl
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
16
+ requirement: &87235160 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.5.5
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *87235160
25
+ - !ruby/object:Gem::Dependency
26
+ name: addressable
27
+ requirement: &87234920 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 2.2.8
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *87234920
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &87234690 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 2.10.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *87234690
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: &87234500 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *87234500
58
+ - !ruby/object:Gem::Dependency
59
+ name: pit
60
+ requirement: &87234270 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *87234270
69
+ description: SFC-SFS Scraping Library
70
+ email:
71
+ - ymrl@ymrl.net
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - LICENSE
79
+ - README.md
80
+ - Rakefile
81
+ - lib/sfcsfs.rb
82
+ - lib/sfcsfs/agent.rb
83
+ - lib/sfcsfs/agent/navigations.rb
84
+ - lib/sfcsfs/homework.rb
85
+ - lib/sfcsfs/lecture.rb
86
+ - lib/sfcsfs/util.rb
87
+ - script/console
88
+ - script/console_helper.rb
89
+ - script/destroy
90
+ - script/generate
91
+ - sfcsfs.gemspec
92
+ - spec/sfcsfs_agent_spec.rb
93
+ - spec/spec.opts
94
+ - spec/spec_helper.rb
95
+ - tasks/add.rake
96
+ - tasks/rspec.rake
97
+ homepage: ''
98
+ licenses: []
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ! '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ! '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubyforge_project:
117
+ rubygems_version: 1.8.11
118
+ signing_key:
119
+ specification_version: 3
120
+ summary: SFC-SFS Scraping Library
121
+ test_files:
122
+ - spec/sfcsfs_agent_spec.rb
123
+ - spec/spec.opts
124
+ - spec/spec_helper.rb