lse_courses 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 86c640247013f44f18ba17e7abc6fa037e498e44
4
- data.tar.gz: acd3967aac16df1b85f268cb092c34bf8b7bf58a
3
+ metadata.gz: c7c9c9889a37a6207cd6532c6c8dd9063848fcc6
4
+ data.tar.gz: 176a2d786f26fa542c74b811376165016f762e21
5
5
  SHA512:
6
- metadata.gz: 553d717bfbf3cf480786afcd364c41d65d421335933bb7f0697ddfbd908dbff4a0014668b81bc7efee4bbfce77f13d7711ef7e2b565ea4edee898c70cd1de656
7
- data.tar.gz: a906cc99a9718f5545ba6bec3a2fa859b0170c31efc5536de711745c5af84ec2aa22d8c6d547c6b492bb11ee31808b9f724fbb669997685bbd374bef1c7c2dfd
6
+ metadata.gz: b7dd7f44f21af449cd850f376920ac5ae3e003eabb660f90fb6ecd252fb6bc97bb8373218e5f41747e734d1e616afd5597cc0cfed867875e60ce90bcabcfc26e
7
+ data.tar.gz: 2002eff56b061d4953db574ff339f3251b3eb13d37794bd667986ae04731b87ebffe358f1d804b1424dcce871c7853fc1d5b1a244dd9656e6be38e6565199681
data/README.md CHANGED
@@ -9,7 +9,12 @@ something along the line of [YalePlus](http://yaleplus.com/)'s Bluebook+.
9
9
 
10
10
  Add the gem to your Gemfile, then run `bundle install`:
11
11
 
12
- ```
12
+ ```ruby
13
+ # Install from RubyGems
14
+ source "http://rubygems.org"
15
+ gem 'lse_courses', '0.0.3'
16
+
17
+ # Install the latest version via Git
13
18
  gem 'lse_courses', git: 'git@github.com:timrogers/lse_courses.git'
14
19
  ```
15
20
 
@@ -19,10 +24,19 @@ dependent on your setup.
19
24
  You can retrieve an array with every course offered at LSE:
20
25
 
21
26
  ```ruby
27
+ # You can just fetch the most basic information - name, code and type (e.g. undergraduate)
22
28
  courses = LSECourses::Course.all
29
+
30
+ # ...or you can grab everything at once - this will take a long time
31
+ courses = LSECourses::Course.all(preload: true)
32
+
23
33
  courses.each do |course|
24
34
  puts "#{course.code} - #{course.name}"
25
35
 
36
+ # Fetch a more detailed attribute, and we'll grab all of them for you
37
+ # and store them if you didn't preload the data originally
38
+ puts course.department
39
+
26
40
  # LSE records include surveys on courses - stored in #survey on the object
27
41
  puts "#{course.survey.recommended_by}% of students recommend this cause"
28
42
  end
@@ -31,8 +45,11 @@ end
31
45
  ...or you can fetch a specific course by code:
32
46
 
33
47
  ```ruby
34
- course = LSECourses::Course.find_by_code("LSE100")
48
+ course = LSECourses::Course.find("LSE100")
35
49
  puts course.name
50
+
51
+ # All the data is loaded straight up, since there's only one course to fetch
52
+ puts course.department
36
53
  ```
37
54
 
38
55
  Upcoming features that should be added are some kind of search (e.g. for
@@ -1,16 +1,167 @@
1
- require 'active_support/core_ext/object/try'
2
1
  require 'nokogiri'
3
2
 
4
3
  module LSECourses
5
4
  class Course
6
- attr_reader :code, :name, :department, :students, :average_class_size,
7
- :value, :assessments, :teachers, :availability, :prerequisites,
8
- :content, :teaching, :formative_coursework, :reading, :type, :survey
5
+ attr_reader :code, :name, :type
6
+ attr_accessor :url
9
7
 
10
8
  def initialize(opts = {})
11
9
  opts.each { |k, v| instance_variable_set("@#{k}", v) }
12
10
  end
13
11
 
12
+ def fetch_attributes
13
+ page = self.class.fetch_and_parse(url)
14
+ key_facts = page.css('#keyFacts-Content p')
15
+
16
+ @survey = if page.css('#survey-Label').any?
17
+ SurveyResult.new(
18
+ response_rate: page.css('#survey-Label-2 span').text.gsub("Response rate: ", "").gsub("%", "").to_f,
19
+ recommended_by: page.css('#survey-Content-Recommend p')[1].text.gsub("%", "").to_f,
20
+ reading_list: page.css('#survey-Content table tbody td')[1].text.to_f,
21
+ materials: page.css('#survey-Content table tbody td')[3].text.to_f,
22
+ satisfied: page.css('#survey-Content table tbody td')[5].text.to_f,
23
+ lectures: page.css('#survey-Content table tbody td')[7].text.to_f,
24
+ integration: page.css('#survey-Content table tbody td')[9].text.to_f,
25
+ contact: page.css('#survey-Content table tbody td')[11].text.to_f,
26
+ feedback: page.css('#survey-Content table tbody td')[13].text.to_f,
27
+ )
28
+ end
29
+
30
+ @code = page.css('#courseCode').text
31
+ @name = page.css('span#title').text
32
+ @department = key_facts[0].text.gsub("Department: ", "")
33
+ @students = key_facts[1].text.gsub("Total students 2012/13:", "").to_i
34
+ @average_class_size = key_facts[2].text.gsub("Average class size 2012/13: ", "").to_i
35
+ @value = key_facts[3].text.gsub("Value: ", "")
36
+ @assessments = self.class.join_p_tags(page.css('#assessment-Content p'))
37
+ @teachers = self.class.join_p_tags(page.css('#teacherResponsible-Content p'))
38
+ @availability = self.class.join_p_tags(page.css('#availability-Content p'))
39
+ @prerequisites = self.class.join_p_tags(page.css('#preRequisites-Content p'))
40
+ @content = self.class.join_p_tags(page.css('#courseContent-Content p'))
41
+ @teaching = self.class.join_p_tags(page.css('#teaching-Content p'))
42
+ @formative_coursework = self.class.join_p_tags(page.css('#formativeCoursework-Content p'))
43
+ @reading = self.class.join_p_tags(page.css('#indicativeReading-Content p'))
44
+
45
+ self
46
+ end
47
+
48
+ def department
49
+ if @department
50
+ @department
51
+ else
52
+ fetch_attributes
53
+ @department
54
+ end
55
+ end
56
+
57
+ def students
58
+ if @students
59
+ @students
60
+ else
61
+ fetch_attributes
62
+ @students
63
+ end
64
+ end
65
+
66
+ def average_class_size
67
+ if @average_class_size
68
+ @average_class_size
69
+ else
70
+ fetch_attributes
71
+ @average_class_size
72
+ end
73
+ end
74
+
75
+ def value
76
+ if @value
77
+ @value
78
+ else
79
+ fetch_attributes
80
+ @value
81
+ end
82
+ end
83
+
84
+ def assessments
85
+ if @assessments
86
+ @assessments
87
+ else
88
+ fetch_attributes
89
+ @assessments
90
+ end
91
+ end
92
+
93
+ def teachers
94
+ if @teachers
95
+ @teachers
96
+ else
97
+ fetch_attributes
98
+ @teachers
99
+ end
100
+ end
101
+
102
+ def availability
103
+ if @availability
104
+ @availability
105
+ else
106
+ fetch_attributes
107
+ @availability
108
+ end
109
+ end
110
+
111
+ def prerequisites
112
+ if @prerequisites
113
+ @prerequisites
114
+ else
115
+ fetch_attributes
116
+ @prerequisites
117
+ end
118
+ end
119
+
120
+ def content
121
+ if @content
122
+ @content
123
+ else
124
+ fetch_attributes
125
+ @content
126
+ end
127
+ end
128
+
129
+ def teaching
130
+ if @teaching
131
+ @teaching
132
+ else
133
+ fetch_attributes
134
+ @teaching
135
+ end
136
+ end
137
+
138
+ def formative_coursework
139
+ if @formative_coursework
140
+ @formative_coursework
141
+ else
142
+ fetch_attributes
143
+ @formative_coursework
144
+ end
145
+ end
146
+
147
+ def reading
148
+ if @reading
149
+ @reading
150
+ else
151
+ fetch_attributes
152
+ @reading
153
+ end
154
+ end
155
+
156
+ def survey
157
+ if @survey
158
+ @survey
159
+ else
160
+ fetch_attributes
161
+ @survey
162
+ end
163
+ end
164
+
14
165
  def undergraduate?
15
166
  type == "Undergraduate"
16
167
  end
@@ -25,8 +176,7 @@ module LSECourses
25
176
 
26
177
  # Checks if this module is available to General Course students
27
178
  def general_course?
28
- general_course_list = open("http://www.lse.ac.uk/resources/calendar/GeneralCourse/coursesNotAvailableToGeneralCStudents.htm")
29
- !general_course_list.read.include? code
179
+ !self.class.general_course_page.include? code
30
180
  end
31
181
 
32
182
  def survey?
@@ -45,22 +195,31 @@ module LSECourses
45
195
  }
46
196
  end
47
197
 
48
- def self.all
198
+ def self.all(options = {})
199
+ defaults = { preload: false }
200
+ options = defaults.merge(options)
201
+
49
202
  results = []
50
203
 
51
204
  course_lists.each_pair do |type, url|
52
205
  document = fetch_and_parse(url)
53
206
  document.css('table tr td p a').each do |link|
54
- course_url = URI.join(URI.parse(url), URI.parse(link['href'])).to_s
207
+ abstract = link.text.split(" ")
55
208
 
56
- course = fetch_and_parse course_url
57
- key_facts = course.css('#keyFacts-Content p')
58
- code = course.css('#courseCode').text
209
+ course_code = abstract.shift
210
+ name = abstract.join(" ")
211
+ course_url = URI.join(URI.parse(url), URI.parse(link['href'])).to_s
59
212
 
60
- results << course_page_to_object(course, type)
213
+ results << self.new(
214
+ url: course_url,
215
+ name: name,
216
+ code: course_code,
217
+ type: type
218
+ )
61
219
  end
62
220
  end
63
221
 
222
+ results.each(&:fetch_attributes) if options[:preload]
64
223
  results
65
224
  end
66
225
 
@@ -68,15 +227,19 @@ module LSECourses
68
227
  course_lists.each_pair do |type, url|
69
228
  document = fetch_and_parse(url)
70
229
  document.css('table tr td p a').each do |link|
71
- title = link.text
72
- course_code = title.split(" ").first
230
+ abstract = link.text.split(" ")
73
231
 
74
- if code == course_code
75
- course = fetch_and_parse(
76
- URI.join(URI.parse(url), URI.parse(link['href'])).to_s
77
- )
232
+ course_code = abstract.shift
233
+ name = abstract.join(" ")
234
+ course_url = URI.join(URI.parse(url), URI.parse(link['href'])).to_s
78
235
 
79
- return course_page_to_object(course, type)
236
+ if code == course_code
237
+ return self.new(
238
+ url: course_url,
239
+ name: name,
240
+ code: course_code,
241
+ type: type
242
+ ).fetch_attributes
80
243
  end
81
244
  end
82
245
  end
@@ -84,49 +247,18 @@ module LSECourses
84
247
  nil
85
248
  end
86
249
 
87
- def self.course_page_to_object(page, type)
88
- key_facts = page.css('#keyFacts-Content p')
89
-
90
- survey_result = if page.css('#survey-Label').any?
91
- SurveyResult.new(
92
- response_rate: page.css('#survey-Label-2 span').text.gsub("Response rate: ", "").gsub("%", "").to_f,
93
- recommended_by: page.css('#survey-Content-Recommend p')[1].text.gsub("%", "").to_f,
94
- reading_list: page.css('#survey-Content table tbody td')[1].text.to_f,
95
- materials: page.css('#survey-Content table tbody td')[3].text.to_f,
96
- satisfied: page.css('#survey-Content table tbody td')[5].text.to_f,
97
- lectures: page.css('#survey-Content table tbody td')[7].text.to_f,
98
- integration: page.css('#survey-Content table tbody td')[9].text.to_f,
99
- contact: page.css('#survey-Content table tbody td')[11].text.to_f,
100
- feedback: page.css('#survey-Content table tbody td')[13].text.to_f,
101
- )
102
- end
103
-
104
- self.new(
105
- type: type,
106
- code: page.css('#courseCode').text,
107
- name: page.css('span#title').text,
108
- department: key_facts[0].text.gsub("Department: ", ""),
109
- students: key_facts[1].text.gsub("Total students 2012/13:", "").to_i,
110
- average_class_size: key_facts[2].text.gsub("Average class size 2012/13: ", "").to_i,
111
- value: key_facts[3].text.gsub("Value: ", ""),
112
- assessments: join_p_tags(page.css('#assessment-Content p')),
113
- teachers: join_p_tags(page.css('#teacherResponsible-Content p')),
114
- availability: join_p_tags(page.css('#availability-Content p')),
115
- prerequisites: join_p_tags(page.css('#preRequisites-Content p')),
116
- content: join_p_tags(page.css('#courseContent-Content p')),
117
- teaching: join_p_tags(page.css('#teaching-Content p')),
118
- formative_coursework: join_p_tags(page.css('#formativeCoursework-Content p')),
119
- reading: join_p_tags(page.css('#indicativeReading-Content p')),
120
- survey: survey_result
121
- )
122
- end
123
-
124
250
  def self.join_p_tags(elements)
125
251
  elements.map(&:text).join("\n").strip
126
252
  end
127
253
 
254
+ def self.general_course_page
255
+ @general_course_page ||= open("http://www.lse.ac.uk/resources/calendar/GeneralCourse/coursesNotAvailableToGeneralCStudents.htm").read
256
+ end
257
+
128
258
  def self.fetch_and_parse(url)
129
259
  Nokogiri::HTML(open(url, &:read), 'UTF-8')
130
260
  end
261
+
262
+ self.singleton_class.send(:alias_method, :find, :find_by_code)
131
263
  end
132
264
  end
@@ -1,3 +1,3 @@
1
1
  module LSECourses
2
- VERSION = "0.0.2".freeze
2
+ VERSION = "0.0.3".freeze
3
3
  end
@@ -18,5 +18,4 @@ Gem::Specification.new do |spec|
18
18
  spec.require_paths = ["lib"]
19
19
 
20
20
  spec.add_runtime_dependency "nokogiri"
21
- spec.add_runtime_dependency "activesupport"
22
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lse_courses
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Rogers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-21 00:00:00.000000000 Z
11
+ date: 2014-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: activesupport
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '>='
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '>='
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
27
  description: Access to data on courses at the London School of Economics and Political
42
28
  Science (LSE)
43
29
  email: