verso 0.0.2 → 0.0.3
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.
- data/.gitignore +2 -0
- data/README.md +10 -22
- data/lib/verso.rb +10 -2
- data/lib/verso/base.rb +50 -0
- data/lib/verso/cluster.rb +55 -25
- data/lib/verso/cluster_list.rb +15 -10
- data/lib/verso/correlation_list.rb +30 -40
- data/lib/verso/course.rb +106 -43
- data/lib/verso/course_list.rb +57 -21
- data/lib/verso/credential.rb +94 -20
- data/lib/verso/credential_list.rb +30 -15
- data/lib/verso/duty_area.rb +23 -10
- data/lib/verso/edition_list.rb +18 -10
- data/lib/verso/emphasis.rb +26 -12
- data/lib/verso/emphasis_list.rb +18 -10
- data/lib/verso/examination_list.rb +28 -12
- data/lib/verso/extra.rb +34 -32
- data/lib/verso/extras_list.rb +28 -12
- data/lib/verso/frontmatter.rb +43 -11
- data/lib/verso/hash.rb +19 -0
- data/lib/verso/http_gettable.rb +31 -0
- data/lib/verso/occupation.rb +36 -14
- data/lib/verso/occupation_data.rb +35 -14
- data/lib/verso/occupation_list.rb +23 -20
- data/lib/verso/pathway.rb +32 -14
- data/lib/verso/program_area.rb +42 -21
- data/lib/verso/program_area_list.rb +15 -11
- data/lib/verso/standard.rb +45 -23
- data/lib/verso/standards_list.rb +41 -30
- data/lib/verso/task.rb +52 -17
- data/lib/verso/task_list.rb +40 -17
- data/lib/verso/version.rb +1 -1
- data/spec/cluster_list_spec.rb +78 -5
- data/spec/cluster_spec.rb +106 -9
- data/spec/correlation_list_spec.rb +108 -50
- data/spec/course_list_spec.rb +112 -23
- data/spec/course_spec.rb +321 -127
- data/spec/credential_list_spec.rb +83 -52
- data/spec/credential_spec.rb +358 -19
- data/spec/duty_area_spec.rb +47 -17
- data/spec/edition_list_spec.rb +90 -4
- data/spec/emphasis_list_spec.rb +75 -11
- data/spec/emphasis_spec.rb +37 -21
- data/spec/examination_list_spec.rb +146 -20
- data/spec/extra_spec.rb +61 -22
- data/spec/extras_list_spec.rb +80 -17
- data/spec/frontmatter_spec.rb +141 -6
- data/spec/hash_spec.rb +49 -0
- data/spec/occupation_data_spec.rb +31 -13
- data/spec/occupation_list_spec.rb +88 -15
- data/spec/occupation_spec.rb +72 -28
- data/spec/pathway_spec.rb +47 -27
- data/spec/program_area_list_spec.rb +78 -4
- data/spec/program_area_spec.rb +70 -22
- data/spec/standard_spec.rb +94 -36
- data/spec/standards_list_spec.rb +130 -36
- data/spec/task_list_spec.rb +160 -51
- data/spec/task_spec.rb +120 -33
- data/verso.gemspec +3 -1
- metadata +41 -17
- data/lib/verso/http_get.rb +0 -9
- data/lib/verso/sol_correlation_list.rb +0 -53
- data/spec/sol_correlation_list_spec.rb +0 -74
data/lib/verso/extra.rb
CHANGED
@@ -1,38 +1,40 @@
|
|
1
1
|
module Verso
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
2
|
+
# Extra resource
|
3
|
+
#
|
4
|
+
# An extra (or related material) associated with a Course framework in
|
5
|
+
# Verso.
|
6
|
+
#
|
7
|
+
# @see http://api.cteresource.org/docs/courses/course/extras/extra
|
8
|
+
#
|
9
|
+
# @!attribute [r] code
|
10
|
+
# @return [String] Course code
|
11
|
+
# @!attribute [r] edition
|
12
|
+
# @return [String] Edition year
|
13
|
+
# @!attribute [r] name
|
14
|
+
# @return [String] Extra name, used as an identifier and not to
|
15
|
+
# be confused with its title, found by {Verso::ExtrasList}
|
16
|
+
# @!attribute [r] description
|
17
|
+
# @return [String] HTML-formatted Extra description
|
18
|
+
# @!attribute [r] title
|
19
|
+
# @return [String] Extra title
|
20
|
+
#
|
21
|
+
# @overload initialize(attrs={})
|
22
|
+
# @note Certain attributes are required for instantiation.
|
23
|
+
# @option attrs [String] :code Course code *Required*
|
24
|
+
# @option attrs [String] :edition Edition year *Required*
|
25
|
+
# @option attrs [String] :name Extra name *Required*
|
26
|
+
class Extra < Verso::Base
|
27
|
+
include HTTPGettable
|
28
|
+
attr_reader :code, :description, :edition, :name, :title
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def path
|
33
|
+
"/courses/#{code},#{edition}/extras/#{name}"
|
25
34
|
end
|
26
35
|
|
27
|
-
def
|
28
|
-
|
29
|
-
@raw_extra.merge!(
|
30
|
-
JSON.parse(
|
31
|
-
http_get("/courses/#{code},#{edition}/extras/#{name}")
|
32
|
-
)["extra"]
|
33
|
-
)
|
34
|
-
end
|
35
|
-
@raw_extra["description"]
|
36
|
+
def fetch
|
37
|
+
super[:extra]
|
36
38
|
end
|
37
39
|
end
|
38
40
|
end
|
data/lib/verso/extras_list.rb
CHANGED
@@ -1,22 +1,38 @@
|
|
1
1
|
module Verso
|
2
|
-
|
3
|
-
|
2
|
+
# Extras List resource
|
3
|
+
#
|
4
|
+
# A collection of {Verso::Extra} associated with a {Course} framework.
|
5
|
+
#
|
6
|
+
# @see http://api.cteresource.org/docs/courses/course/extras
|
7
|
+
#
|
8
|
+
# @example Get extras for 2012 edition of course 6320
|
9
|
+
# extras = Verso::ExtrasList.new(:code => "6320", :edition => "2012")
|
10
|
+
#
|
11
|
+
# @!attribute [r] code
|
12
|
+
# @return [String] Course code
|
13
|
+
# @!attribute [r] edition
|
14
|
+
# @return [String] Edition year
|
15
|
+
#
|
16
|
+
# @overload initialize(attrs={})
|
17
|
+
# @note Certain attributes are required for instantiation.
|
18
|
+
# @option attrs [String] :code Course code *Required*
|
19
|
+
# @option attrs [String] :edition Edition year *Required*
|
20
|
+
class ExtrasList < Verso::Base
|
4
21
|
include Enumerable
|
5
|
-
include
|
22
|
+
include HTTPGettable
|
23
|
+
extend Forwardable
|
24
|
+
attr_reader :code, :edition
|
25
|
+
def_delegators :extras, :[], :each, :empty?, :last, :length
|
6
26
|
|
7
|
-
|
8
|
-
@code, @edition = opts[:code], opts[:edition]
|
9
|
-
end
|
27
|
+
private
|
10
28
|
|
11
29
|
def extras
|
12
|
-
@extras ||=
|
13
|
-
|
14
|
-
)["extras"].
|
15
|
-
collect { |e| Extra.new(e.merge("code" => code, "edition" => edition)) }
|
30
|
+
@extras ||= get_attr(:extras).
|
31
|
+
collect { |e| Extra.new(e.merge(:code => code, :edition => edition)) }
|
16
32
|
end
|
17
33
|
|
18
|
-
def
|
19
|
-
extras
|
34
|
+
def path
|
35
|
+
"/courses/#{code},#{edition}/extras/"
|
20
36
|
end
|
21
37
|
end
|
22
38
|
end
|
data/lib/verso/frontmatter.rb
CHANGED
@@ -1,18 +1,50 @@
|
|
1
1
|
module Verso
|
2
|
-
|
3
|
-
|
2
|
+
# Frontmatter resource
|
3
|
+
#
|
4
|
+
# Frontmatter for {Verso::Course} framework.
|
5
|
+
#
|
6
|
+
# @see http://api.cteresource.org/docs/courses/course/frontmatter
|
7
|
+
#
|
8
|
+
# @!attribute [r] acknowledgments_text
|
9
|
+
# @return [String] HTML-formatted acknowledgments
|
10
|
+
# @!attribute [r] attribution_block
|
11
|
+
# @return [String] HTML-formatted attribution
|
12
|
+
# @!attribute [r] code
|
13
|
+
# @return [String] Course code
|
14
|
+
# @!attribute [r] copyright_year
|
15
|
+
# @return [String] Copyright year
|
16
|
+
# @!attribute [r] developed_by
|
17
|
+
# @return [String] HTML-formatted developed-by text
|
18
|
+
# @!attribute [r] developed_for
|
19
|
+
# @return [String] HTML-formatted developed-for text
|
20
|
+
# @!attribute [r] edition
|
21
|
+
# @return [String] Edition year
|
22
|
+
# @!attribute [r] foreword_text
|
23
|
+
# @return [String] HTML-formatted foreword
|
24
|
+
# @!attribute [r] introduction_text
|
25
|
+
# @return [String] HTML-formatted introduction_text
|
26
|
+
# @!attribute [r] notice_block
|
27
|
+
# @return [String] HTML formatted notice_block
|
28
|
+
#
|
29
|
+
# @overload initialize(attrs={})
|
30
|
+
# @note Any attributes may be set upon instantiation, using Options Hash.
|
31
|
+
# The following are required:
|
32
|
+
# @option attrs [String] :code Course code *Required*
|
33
|
+
# @option attrs [String] :edition Edition year *Required*
|
34
|
+
class Frontmatter < Verso::Base
|
35
|
+
include HTTPGettable
|
36
|
+
attr_reader :acknowledgments_text, :attribution_block, :code,
|
37
|
+
:copyright_year, :developed_by, :developed_for, :edition,
|
38
|
+
:foreword_text, :introduction_text, :notice_block
|
4
39
|
|
5
|
-
|
6
|
-
|
40
|
+
private
|
41
|
+
|
42
|
+
def fetch
|
43
|
+
super[:frontmatter]
|
7
44
|
end
|
8
45
|
|
9
|
-
def
|
10
|
-
|
11
|
-
@raw_frontmatter = JSON.parse(
|
12
|
-
http_get("/courses/#{@raw_frontmatter['code']},#{@raw_frontmatter['edition']}/frontmatter")
|
13
|
-
)["frontmatter"]
|
14
|
-
end
|
15
|
-
@raw_frontmatter[mname.to_s]
|
46
|
+
def path
|
47
|
+
"/courses/#{code},#{edition}/frontmatter"
|
16
48
|
end
|
17
49
|
end
|
18
50
|
end
|
data/lib/verso/hash.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
class Hash
|
2
|
+
def symbolize_nested_keys!
|
3
|
+
keys.each do |key|
|
4
|
+
self[(key.to_sym rescue key) || key] = if self[key].is_a?(Hash)
|
5
|
+
delete(key).symbolize_nested_keys!
|
6
|
+
elsif self[key].is_a?(Array)
|
7
|
+
delete(key).collect do |i|
|
8
|
+
if i.is_a?(Hash)
|
9
|
+
i.symbolize_nested_keys!
|
10
|
+
end
|
11
|
+
i
|
12
|
+
end
|
13
|
+
else
|
14
|
+
delete(key)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
self
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Verso
|
2
|
+
# Mixin for classes derived from {Verso::Base}. Provides the capability to
|
3
|
+
# fetch the JSON resource to update attributes of the class.
|
4
|
+
#
|
5
|
+
# @abstract Implement a path method that gives the relative path of the
|
6
|
+
# corresponding JSON resource.
|
7
|
+
module HTTPGettable
|
8
|
+
protected
|
9
|
+
|
10
|
+
# Get an attribute from the attributes store {#attrs}. Fetch and merge
|
11
|
+
# first if the attribute store doesn't have the key.
|
12
|
+
#
|
13
|
+
# @param [Symbol] attr The attribute key
|
14
|
+
# @return [Object] The attribute
|
15
|
+
def get_attr(attr)
|
16
|
+
attrs.merge!(fetch) unless attrs.has_key?(attr)
|
17
|
+
super attr
|
18
|
+
end
|
19
|
+
|
20
|
+
# HTTP GET the JSON resource
|
21
|
+
# @return [String] JSON resource
|
22
|
+
def http_get
|
23
|
+
Net::HTTP.get('api.cteresource.org', path, 80)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Hash] Resource hash
|
27
|
+
def fetch
|
28
|
+
JSON.parse(http_get).symbolize_nested_keys!
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/verso/occupation.rb
CHANGED
@@ -1,25 +1,47 @@
|
|
1
1
|
module Verso
|
2
|
-
|
3
|
-
|
2
|
+
# Occupation resource
|
3
|
+
#
|
4
|
+
# An occupation is contained by a Pathway
|
5
|
+
#
|
6
|
+
# @see http://api.cteresource.org/docs/occupations/occupation
|
7
|
+
# @see http://www.careertech.org/career-clusters/clusters-occupations.html
|
8
|
+
#
|
9
|
+
# @!attribute [r] description
|
10
|
+
# @return [String] HTML-formatted Occupation description
|
11
|
+
# @!attribute [r] id
|
12
|
+
# @return [Fixnum] Occupation ID
|
13
|
+
# @!attribute [r] preparations
|
14
|
+
# @return [Array] Collection of preparation titles (strings)
|
15
|
+
# @!attribute [r] title
|
16
|
+
# @return [String] Occupation title
|
17
|
+
#
|
18
|
+
# @overload initialize(attrs={})
|
19
|
+
# @note Any attributes may be set upon instantiation, using Options Hash.
|
20
|
+
# The following are required:
|
21
|
+
# @option attrs [Fixnum] :id Occupation ID *Required*
|
22
|
+
class Occupation < Verso::Base
|
23
|
+
include HTTPGettable
|
24
|
+
attr_reader :description, :id, :preparations, :title
|
4
25
|
|
5
|
-
|
6
|
-
|
26
|
+
# @return [Verso::Pathway] Pathway that is the parent of this occupation
|
27
|
+
def pathway
|
28
|
+
@pathway ||= Pathway.new(get_attr(:pathway))
|
7
29
|
end
|
8
30
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@raw_occupation[mname.to_s]
|
31
|
+
# @return [Array] Collection of related {Verso::Course} objects
|
32
|
+
def related_courses
|
33
|
+
@related_courses ||= get_attr(:related_courses).
|
34
|
+
collect { |c| Course.new(c) }
|
14
35
|
end
|
15
36
|
|
16
|
-
|
17
|
-
|
18
|
-
|
37
|
+
private
|
38
|
+
|
39
|
+
def fetch
|
40
|
+
super[:occupation]
|
19
41
|
end
|
20
42
|
|
21
|
-
def
|
22
|
-
|
43
|
+
def path
|
44
|
+
"/occupations/#{id}"
|
23
45
|
end
|
24
46
|
end
|
25
47
|
end
|
@@ -1,30 +1,51 @@
|
|
1
1
|
module Verso
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
# Occupation Data
|
3
|
+
#
|
4
|
+
# A list of occupations grouped by the Cluster/Pathway that contains them.
|
5
|
+
# Occupation Data is not an independent resource. It is a component of
|
6
|
+
# {Verso::OccupationList}, {Verso::Course}, and {Verso::Emphasis}.
|
7
|
+
#
|
8
|
+
# @see http://api.cteresource.org/docs/academics/emphasis
|
9
|
+
# @see http://api.cteresource.org/docs/courses/course
|
10
|
+
# @see http://api.cteresource.org/docs/occupations
|
11
|
+
#
|
12
|
+
# @note Because an OccupationData object is created for you by other
|
13
|
+
# resources you should never need to instantiate one yourself.
|
14
|
+
class OccupationData < Verso::Base
|
15
|
+
# @return [Verso::Cluster] Cluster (grandparent of occupations)
|
7
16
|
def cluster
|
8
|
-
@cluster ||= Cluster.new(
|
17
|
+
@cluster ||= Cluster.new(get_attr(:cluster))
|
9
18
|
end
|
10
19
|
|
11
|
-
|
12
|
-
|
20
|
+
# @return [Array] Collection of {Verso::Occupation} objects
|
21
|
+
def occupations
|
22
|
+
@occupations ||= get_attr(:occupations).collect { |o| Occupation.new(o) }
|
13
23
|
end
|
14
24
|
|
15
|
-
|
16
|
-
|
17
|
-
|
25
|
+
# @return [Verso::Pathway] Pathway (parent of occupations)
|
26
|
+
def pathway
|
27
|
+
@pathway ||= Pathway.new(get_attr(:pathway))
|
18
28
|
end
|
19
29
|
|
30
|
+
# Find OccupationData by cluster, pathway, and occupation slugs
|
31
|
+
#
|
32
|
+
# @example Find an OccupationData for an occupation
|
33
|
+
# od = Verso::OccupationData.find_by_slugs('finance', 'accounting', 'cost-analyst')
|
34
|
+
# od.occupations.count # => 1
|
35
|
+
# od.occupations.first.title # => 'Cost Analyst'
|
36
|
+
#
|
37
|
+
# @param [String] cslug Cluster slug
|
38
|
+
# @param [String] pslug Pathway slug
|
39
|
+
# @param [String] slug Occupation slug
|
40
|
+
# @return [Verso::OccupationData,nil] Containing only one Occupation
|
20
41
|
def self.find_by_slugs(cslug, pslug, slug)
|
21
42
|
cluster = ClusterList.new.find { |c| c.title.parameterize == cslug }
|
22
43
|
pathway = cluster.pathways.find { |p| p.title.parameterize == pslug }
|
23
44
|
occupation = pathway.occupations.find { |o| o.title.parameterize == slug }
|
24
45
|
OccupationData.new(
|
25
|
-
{
|
26
|
-
|
27
|
-
|
46
|
+
{ :cluster => { :title => cluster.title },
|
47
|
+
:pathway => { :title => pathway.title },
|
48
|
+
:occupations => [{ :title => occupation.title }] }
|
28
49
|
)
|
29
50
|
end
|
30
51
|
end
|
@@ -1,32 +1,35 @@
|
|
1
1
|
module Verso
|
2
|
-
|
2
|
+
# Occupation list resource
|
3
|
+
#
|
4
|
+
# Search {Verso::Occupation} objects using free text. Result is a collection
|
5
|
+
# of {Verso::OccupationData} objects containing relevant {Verso::Occupation}
|
6
|
+
# objects.
|
7
|
+
#
|
8
|
+
# @see http://api.cteresource.org/docs/occupations
|
9
|
+
#
|
10
|
+
# @example Search by free text
|
11
|
+
# ods = Verso::OccupationList.new(:text => "golf") # => golf-related ODs
|
12
|
+
#
|
13
|
+
# @overload initialize(attrs={})
|
14
|
+
# @option attrs [String] :text Free text
|
15
|
+
class OccupationList < Verso::Base
|
3
16
|
include Enumerable
|
4
|
-
include
|
17
|
+
include HTTPGettable
|
18
|
+
extend Forwardable
|
19
|
+
def_delegators :occupations, :[], :each, :empty?, :last, :length
|
5
20
|
|
6
|
-
|
7
|
-
@q_uri = Addressable::URI.new(
|
8
|
-
:path => '/occupations',
|
9
|
-
:query_values => raw_query
|
10
|
-
)
|
11
|
-
end
|
21
|
+
private
|
12
22
|
|
13
23
|
def occupations
|
14
|
-
|
15
|
-
|
24
|
+
return [] if attrs[:text].to_s.empty?
|
25
|
+
@occupations ||= get_attr(:occupation_data).
|
16
26
|
collect { |o| OccupationData.new(o) }.
|
17
27
|
sort_by { |o| [o.cluster.title, o.pathway.title] }
|
18
28
|
end
|
19
29
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
def last
|
25
|
-
occupations[-1]
|
26
|
-
end
|
27
|
-
|
28
|
-
def empty?
|
29
|
-
occupations.empty?
|
30
|
+
def path
|
31
|
+
@path ||= Addressable::URI.new(:path => '/occupations',
|
32
|
+
:query_values => attrs).request_uri
|
30
33
|
end
|
31
34
|
end
|
32
35
|
end
|
data/lib/verso/pathway.rb
CHANGED
@@ -1,25 +1,43 @@
|
|
1
1
|
module Verso
|
2
|
-
|
3
|
-
|
2
|
+
# Pathway Resource
|
3
|
+
#
|
4
|
+
# @see http://api.cteresource.org/docs/pathways/pathway
|
5
|
+
# @see http://www.careertech.org/career-clusters/clusters-occupations.html
|
6
|
+
#
|
7
|
+
# @!attribute [r] description
|
8
|
+
# @return [String] HTML-formatted Pathway description
|
9
|
+
# @!attribute [r] id
|
10
|
+
# @return [Fixnum] Pathway id
|
11
|
+
# @!attribute [r] title
|
12
|
+
# @return [String] Pathway title
|
13
|
+
#
|
14
|
+
# @overload initialize(attrs={})
|
15
|
+
# @note Any attributes may be set upon instantiation, using Options Hash.
|
16
|
+
# The following are required:
|
17
|
+
# @option attrs [Fixnum] :id Pathway id *Required*
|
18
|
+
class Pathway < Verso::Base
|
19
|
+
include HTTPGettable
|
20
|
+
attr_reader :description, :id, :title
|
4
21
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def method_missing(mname)
|
10
|
-
if @raw_pathway[mname.to_s].nil?
|
11
|
-
@raw_pathway = JSON.parse(http_get("/pathways/#{id}"))["pathway"]
|
12
|
-
end
|
13
|
-
@raw_pathway[mname.to_s]
|
22
|
+
# @return [Verso::Cluster] Parent Cluster
|
23
|
+
def cluster
|
24
|
+
@cluster ||= Cluster.new(get_attr(:cluster))
|
14
25
|
end
|
15
26
|
|
27
|
+
# @return [Array] Children {Verso::Occupation} objects
|
16
28
|
def occupations
|
17
|
-
@occupations ||=
|
29
|
+
@occupations ||= get_attr(:occupations).
|
18
30
|
collect { |o| Occupation.new(o) }
|
19
31
|
end
|
20
32
|
|
21
|
-
|
22
|
-
|
33
|
+
private
|
34
|
+
|
35
|
+
def fetch
|
36
|
+
super[:pathway]
|
37
|
+
end
|
38
|
+
|
39
|
+
def path
|
40
|
+
"/pathways/#{id}"
|
23
41
|
end
|
24
42
|
end
|
25
43
|
end
|