rubyuw 0.99.1 → 0.99.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -20,17 +20,21 @@ with. I do not support this.
20
20
 
21
21
  RubyUW functions by emulating a human in an actual browser. It hunts
22
22
  down buttons to click, fields to fill in, etc. It is programmed
23
- using the Ruby Mechanize library to achieve this level of human
24
- simulation.
23
+ using the ruby [mechanize library](http://github.com/tenderlove/mechanize) to achieve
24
+ this level of human simulation.
25
25
 
26
26
  Of course this also means that even minor tweaks to the MyUW layout
27
27
  could potentially "break" the RubyUW library.
28
28
 
29
29
  ## Installing
30
30
 
31
+ The `rubyuw` gem is hosted on [gemcutter](http://gemcutter.org/). If
32
+ your rubygems isn't updated to use gemcutter yet, please visit their
33
+ website to prepare your rubygems installation prior to running the
34
+ following command. (It takes only a minute)
35
+
31
36
  # Install the gem
32
- sudo gem sources -a http://gems.github.com
33
- sudo gem install mitchellh-rubyuw
37
+ sudo gem install rubyuw
34
38
 
35
39
  ## Using RubyUW
36
40
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.99.1
1
+ 0.99.2
data/lib/rubyuw/base.rb CHANGED
@@ -22,8 +22,8 @@ module RubyUW
22
22
  # every feature), will require that this authentication is
23
23
  # completed first.
24
24
  #
25
- # @param [String] UW NetID
26
- # @param [String] Password for the UW NetID
25
+ # @param [String] netid UW NetID
26
+ # @param [String] password Password for the UW NetID
27
27
  # @return [nil]
28
28
  def authenticate(netid, password)
29
29
  # Clear pre-existing session information first
@@ -55,7 +55,7 @@ module RubyUW
55
55
  # Flow item: Go to a specific URL. Calling this method will
56
56
  # attach a task to the current flow to go to a specific URL.
57
57
  #
58
- # @param [String] URL to go to (must respond to #to_s)
58
+ # @param [String] url URL to go to (must respond to #to_s)
59
59
  # @return self
60
60
  def goto(url)
61
61
  current_flow.push([:goto, url])
@@ -67,8 +67,8 @@ module RubyUW
67
67
  # parameters may be given as the second argument to be filled into
68
68
  # the form.
69
69
  #
70
- # @param [String] Name of the form.
71
- # @param [Hash] Parameters to pass through to the form.
70
+ # @param [String] name Name of the form.
71
+ # @param [Hash] parameters Parameters to pass through to the form.
72
72
  # @return self
73
73
  def submit_form(name, parameters={})
74
74
  current_flow.push([:submit_form, name, parameters])
@@ -79,7 +79,7 @@ module RubyUW
79
79
  # a task to verify that the given XPath string matches at least one
80
80
  # element.
81
81
  #
82
- # @param [String] XPath of the element(s) to verify existence of.
82
+ # @param [String] xpath XPath of the element(s) to verify existence of.
83
83
  # @return self
84
84
  def verify(xpath)
85
85
  current_flow.push([:verify, xpath])
@@ -1,6 +1,6 @@
1
1
  module RubyUW
2
2
  # RubyUW::CurriculumEnrollment is used to extract SLN information
3
- # for an entire "curriculum" of courses (whic is how MyUW refers
3
+ # for an entire "curriculum" of courses (which is how MyUW refers
4
4
  # to it). If you have multiple SLNs within the same curriculum
5
5
  # (chemistry, computer science, history, etc.), it is more efficient
6
6
  # to use the CurriculumEnrollment class rather than SLN.
@@ -24,8 +24,8 @@ module RubyUW
24
24
  # directly from the MyUW curriculum information page. Authentication
25
25
  # is required prior to use.
26
26
  #
27
- # @param [String] Curriculum to search for.
28
- # @param [String] The term (quarter) to search in.
27
+ # @param [String] curriculum Curriculum to search for.
28
+ # @param [String] term The term (quarter) to search in.
29
29
  def find(curriculum, term)
30
30
  raise Errors::NotLoggedInError.new unless Base.authenticated?
31
31
 
@@ -21,7 +21,7 @@ module RubyUW
21
21
  # * location
22
22
  # * instructor
23
23
  #
24
- # To get any more details you have to use the {RubyUW::SLN.find}
24
+ # To get any more details you have to use the {RubyUW::SLN} find
25
25
  # method.
26
26
  def get
27
27
  raise Errors::NotLoggedInError.new unless Base.authenticated?
data/lib/rubyuw/sln.rb CHANGED
@@ -16,15 +16,14 @@ module RubyUW
16
16
  # sln_info = RubyUW::SLN.find("12345", "AUT+2009")
17
17
  class SLN
18
18
  attr_reader :sln
19
- attr_reader :data
20
19
 
21
20
  # Initialize a new SLN object. This should never be called on its
22
21
  # own, but instead you should use the find method to setup a
23
22
  # sln.
24
23
  #
25
- # @param [String] SLN number in string format.
26
- # @param [String] Term that the SLN corresponds to.
27
- # @param [Hash] Data of key to value.
24
+ # @param [String] sln SLN number in string format.
25
+ # @param [String] term Term that the SLN corresponds to.
26
+ # @param [Hash] data Data of key to value.
28
27
  def initialize(sln, term, data)
29
28
  @sln = sln
30
29
  @term = term
@@ -34,17 +33,48 @@ module RubyUW
34
33
  # Grab the data of the SLN based on a key. Returns the value of
35
34
  # a field for the SLN, or nil otherwise. Supported fields coming
36
35
  # soon.
37
- def data(key)
36
+ #
37
+ # == Example:
38
+ #
39
+ # # Assuming @sln has an instance of {RubyUW::SLN} already
40
+ # course_name = @sln[:course]
41
+ # capacity = @sln[:room_capacity]
42
+ #
43
+ # == Supported fields in alphabetical order:
44
+ # * *course* - The name of the course
45
+ # * *credits* - The number of credits the course gives
46
+ # * *current_enrollment* - Number of students currently enrolled.
47
+ # * *curriculum* - The curriculum which this course is part of. This field's
48
+ # value can be used to query {RubyUW::CurriculumEnrollment}.
49
+ # * *limit_enrollment* - The maximum (limit) number of students which can be enrolled.
50
+ # * *notes* - Often a multi-paragraph block of text from the "notes" section
51
+ # on the course info page.
52
+ # * *room_capacity* - The capacity of the classroom.
53
+ # * *section* - The section of the course. Ex. "A" or "AB"
54
+ # * *space_available* -
55
+ # Space available at the moment. Note that there is an important difference
56
+ # between this and the difference between "limit_enrollment" and
57
+ # "current_enrollmemnt." This is because sometimes the university closes
58
+ # registration for a day (to open more slots the next day). So even though
59
+ # there may be space, there may be no openings for the day. There are other
60
+ # reasons as well.
61
+ # * *status* - Text pulled directly from "status" box on course info page.
62
+ # * *title* - The name of the course, typically in all caps. Ex. "INTRO TO LOGIC"
63
+ # * *type* - Type of course. Typically "LC" or "QZ" though others exist
64
+ def [](key)
38
65
  @data[key.to_sym]
39
66
  end
40
67
 
68
+ # Aliased for legacy
69
+ alias :data :[]
70
+
41
71
  class <<self
42
72
  # Finds information about a specific SLN. The SLN information
43
73
  # is grabbed from the MyUW time schedule page. Authentication is
44
74
  # required prior to use.
45
75
  #
46
- # @param [#to_s] The SLN, which must respond to #to_s
47
- # @param [String] The term, as represented in the time schedule URL.
76
+ # @param [String, #to_s] sln_number The SLN, which must respond to #to_s
77
+ # @param [String] term The term, as represented in the time schedule URL.
48
78
  # @return [RubyUW::SLN]
49
79
  def find(sln_number, term)
50
80
  raise Errors::NotLoggedInError.new unless Base.authenticated?
@@ -81,13 +111,35 @@ module RubyUW
81
111
  [[:notes], "//table[@border=1 and @cellpadding=3]//tr[count(td)=1]//preceding-sibling::tr[count(th)=1]//following-sibling::tr//td"]
82
112
  ]
83
113
 
114
+ # Extract initial data, straight scraping
84
115
  data = {}
85
- extract_data.each do |keys, xpath|
86
- data.merge!(Base.extract(page, xpath, keys))
87
- end
116
+ extract_data.each { |keys, xpath| data.merge!(Base.extract(page, xpath, keys)) }
117
+
118
+ # Extract other data which must be massaged
119
+ extract_curriculum(data)
88
120
 
89
121
  data
90
122
  end
123
+
124
+ # Extracts the "curriculum" from the SLN information. This curriculum
125
+ # can then be used with {RubyUW::CurriculumEnrollment} to grab multiple
126
+ # classes within the same curriculum simultaneously.
127
+ #
128
+ # The curriculum value used to query the enrollment page appears to
129
+ # follow the pattern that it is the course category, URL encoded.
130
+ #
131
+ # Examples:
132
+ # * CHEM 102 = "CHEM"
133
+ # * C LIT 240 = "C LIT"
134
+ #
135
+ # Note that this is subject to change at any time but this method is
136
+ # well unit tested in both mock and live tests, which should signal
137
+ # any changes quickly.
138
+ def extract_curriculum(data)
139
+ data[:course] =~ /^(.+?)(\d+)$/
140
+ data[:curriculum] = $1.strip
141
+ data
142
+ end
91
143
  end
92
144
  end
93
145
 
data/rubyuw.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rubyuw}
8
- s.version = "0.99.1"
8
+ s.version = "0.99.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Mitchell Hashimoto"]
@@ -11,12 +11,13 @@ class LiveSLNTest < Test::Unit::TestCase
11
11
  :type => "QZ",
12
12
  :credits => "",
13
13
  :title => "INTRO TO LOGIC",
14
- :current_enrollment => "25",
14
+ :current_enrollment => "22",
15
15
  :limit_enrollment => "25",
16
16
  :room_capacity => "40",
17
- :space_available => "",
18
- :status => "** Closed **",
19
- :notes => "Quiz Section"
17
+ :space_available => "3",
18
+ :status => "Open",
19
+ :notes => "Quiz Section",
20
+ :curriculum => "PHIL"
20
21
  }
21
22
  }
22
23
  end
@@ -32,6 +32,43 @@ class SLNTest < Test::Unit::TestCase
32
32
  assert_equal v, @sln_obj.data(k.to_s)
33
33
  end
34
34
  end
35
+
36
+ should "be able to access using []" do
37
+ @data.each do |k,v|
38
+ assert_equal v, @sln_obj[k]
39
+ end
40
+ end
41
+ end
42
+
43
+ context "extracting data from SLN page" do
44
+ setup do
45
+ mocked_page = RubyUW::Base.connection.get(path_to_html("sln_status"))
46
+ @data = RubyUW::SLN.extract_data_from_page(mocked_page)
47
+ end
48
+
49
+ context "extracting 'special' data from page" do
50
+ context "curriculum" do
51
+ should "strip any surrounding whitespace and trailing number and return curriculum" do
52
+ result = RubyUW::SLN.extract_curriculum({ :course => @data[:course]})
53
+ assert_equal "PHIL", result[:curriculum]
54
+ end
55
+
56
+ should "extract multiword curriculums" do
57
+ result = RubyUW::SLN.extract_curriculum({ :course => "C LIT 240"})
58
+ assert_equal "C LIT", result[:curriculum]
59
+ end
60
+
61
+ should "modify data in place" do
62
+ data = { :course => "PHIL 120" }
63
+ RubyUW::SLN.extract_curriculum(data)
64
+ assert_equal "PHIL", data[:curriculum]
65
+ end
66
+ end
67
+ end
68
+
69
+ context "extracting typicaly data from page" do
70
+ # TODO
71
+ end
35
72
  end
36
73
 
37
74
  context "finding an SLN" do
@@ -1,4 +1,3 @@
1
- require 'rubygems'
2
1
  $:.unshift(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
3
2
  require 'rubyuw'
4
3
  require 'test/unit'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyuw
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.99.1
4
+ version: 0.99.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mitchell Hashimoto