academic_benchmarks 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c13cf6be09fd07cb0109d047e350f67b5d4cbc26
4
+ data.tar.gz: 64e6b5f20059e2d4a3cb9fa80e2fb646368eb8bd
5
+ SHA512:
6
+ metadata.gz: 3dd28dee3d000f68bedf3b0f096ad3373946fd908bb38ed0eec10d6900d8fc0851243df23eed7dca4354a4b4a698f5542d4eff0ce7158e58b3fb70840becb1d3
7
+ data.tar.gz: b9064ef02deddcef55face091a4212ce4e83a6b4f83189428ad5b9eb75b22d184404a43a17195ee463db3b7353701b98b07fe191dc7f1541ff2037b0cc10be48
@@ -0,0 +1,13 @@
1
+ require 'httparty'
2
+ require 'json'
3
+ require 'base64'
4
+ require 'openssl'
5
+
6
+ begin
7
+ require 'byebug'
8
+ rescue LoadError => e
9
+ end
10
+
11
+ Gem.find_files("academic_benchmarks/**/*.rb").each do |path|
12
+ require path.gsub(/\.rb$/, '')
13
+ end
@@ -0,0 +1,46 @@
1
+ require 'active_support/core_ext/numeric/time'
2
+
3
+ module AcademicBenchmarks
4
+ module Api
5
+ module Auth
6
+ def self.auth_query_params(partner_id:, partner_key:, expires:, user_id: "")
7
+ {
8
+ "partner.id" => partner_id,
9
+ "auth.signature" => signature_for(
10
+ partner_key: partner_key,
11
+ message: self.message(expires: expires, user_id: user_id)),
12
+ "auth.expires" => expires,
13
+ "user.id" => user_id
14
+ }
15
+ end
16
+
17
+ def self.signature_for(partner_key:, message:)
18
+ Base64.encode64(OpenSSL::HMAC.digest(
19
+ OpenSSL::Digest.new('sha256'),
20
+ partner_key,
21
+ message
22
+ )).chomp
23
+ end
24
+
25
+ def self.message(expires:, user_id: '')
26
+ if user_id.empty?
27
+ "#{expires}"
28
+ else
29
+ "#{expires}\n#{user_id}"
30
+ end
31
+ end
32
+
33
+ def self.expire_time_in_10_seconds
34
+ self.expire_time_in(10.seconds)
35
+ end
36
+
37
+ def self.expire_time_in_2_hours
38
+ self.expire_time_in(2.hours)
39
+ end
40
+
41
+ def self.expire_time_in(offset)
42
+ Time.now.to_i + offset
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,43 @@
1
+ module AcademicBenchmarks
2
+ module Api
3
+ module Constants
4
+ def self.base_url
5
+ 'https://api.academicbenchmarks.com/rest/v3'
6
+ end
7
+
8
+ def self.api_version
9
+ '3'
10
+ end
11
+
12
+ def self.partner_id_env_var
13
+ 'ACADEMIC_BENCHMARKS_PARTNER_ID'
14
+ end
15
+
16
+ def self.partner_key_env_var
17
+ 'ACADEMIC_BENCHMARKS_PARTNER_KEY'
18
+ end
19
+
20
+ def self.user_id_env_var
21
+ 'ACADEMIC_BENCHMARKS_USER_ID'
22
+ end
23
+
24
+ def self.standards_search_params
25
+ %w[
26
+ query
27
+ authority
28
+ subject
29
+ grade
30
+ subject_doc
31
+ course
32
+ document
33
+ parent
34
+ deepest
35
+ limit
36
+ offset
37
+ list
38
+ fields
39
+ ]
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,92 @@
1
+ require_relative 'constants'
2
+ require_relative 'standards'
3
+
4
+ module AcademicBenchmarks
5
+ module Api
6
+ class Handle
7
+ include HTTParty
8
+
9
+ attr_accessor :partner_id, :partner_key
10
+
11
+ attr_reader :user_id # user_id writer is defined below
12
+
13
+ base_uri AcademicBenchmarks::Api::Constants.base_url
14
+
15
+ # Allows the user to initialize from environment variables
16
+ def self.init_from_env
17
+ partner_id = partner_id_from_env
18
+ partner_key = partner_key_from_env
19
+
20
+ if !partner_id.present? || !partner_key.present?
21
+ pidstr = !partner_id.present? ?
22
+ AcademicBenchmarks::Api::Constants.partner_id_env_var : ""
23
+ pkystr = !partner_key.present? ?
24
+ AcademicBenchmarks::Api::Constants.partner_key_env_var : ""
25
+ raise StandardError.new(
26
+ "Missing environment variable(s): #{[pidstr, pkystr].join(', ')}"
27
+ )
28
+ end
29
+
30
+ new(
31
+ partner_id: partner_id,
32
+ partner_key: partner_key,
33
+ user_id: user_id_from_env
34
+ )
35
+ end
36
+
37
+ def initialize(partner_id:, partner_key:, user_id: "")
38
+ @partner_id = partner_id
39
+ @partner_key = partner_key
40
+ @user_id = user_id.to_s
41
+ end
42
+
43
+ def user_id=(user_id)
44
+ @user_id = user_id.to_s
45
+ end
46
+
47
+ def related(guid:, fields: [])
48
+ raise StandardError.new("Sorry, not implemented yet!")
49
+ end
50
+
51
+ def standards
52
+ Standards.new(self)
53
+ end
54
+
55
+ def assets
56
+ raise StandardError.new("Sorry, not implemented yet!")
57
+ end
58
+
59
+ def alignments
60
+ raise StandardError.new("Sorry, not implemented yet!")
61
+ end
62
+
63
+ def topics
64
+ raise StandardError.new("Sorry, not implemented yet!")
65
+ end
66
+
67
+ def special
68
+ raise StandardError.new("Sorry, not implemented yet!")
69
+ end
70
+
71
+ private
72
+
73
+ def api_resp_to_array_of_standards(api_resp)
74
+ api_resp.parsed_response["resources"].inject([]) do |retval, resource|
75
+ retval.push(AcademicBenchmarks::Standards::Standard.new(resource["data"]))
76
+ end
77
+ end
78
+
79
+ def self.partner_id_from_env
80
+ ENV[AcademicBenchmarks::Api::Constants.partner_id_env_var]
81
+ end
82
+
83
+ def self.partner_key_from_env
84
+ ENV[AcademicBenchmarks::Api::Constants.partner_key_env_var]
85
+ end
86
+
87
+ def self.user_id_from_env
88
+ ENV[AcademicBenchmarks::Api::Constants.user_id_env_var]
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,128 @@
1
+ require 'active_support/hash_with_indifferent_access'
2
+
3
+ require_relative 'auth'
4
+ require_relative 'constants'
5
+
6
+ module AcademicBenchmarks
7
+ module Api
8
+ class Standards
9
+ DEFAULT_PER_PAGE = 100
10
+
11
+ def initialize(handle)
12
+ @handle = handle
13
+ end
14
+
15
+ def search(opts = {})
16
+ # query: "", authority: "", subject: "", grade: "", subject_doc: "", course: "",
17
+ # document: "", parent: "", deepest: "", limit: -1, offset: -1, list: "", fields: []
18
+ invalid_params = invalid_search_params(opts)
19
+ if invalid_params.empty?
20
+ raw_search(opts).map do |standard|
21
+ AcademicBenchmarks::Standards::Standard.new(standard)
22
+ end
23
+ else
24
+ raise ArgumentError.new(
25
+ "Invalid search params: #{invalid_params.join(', ')}"
26
+ )
27
+ end
28
+ end
29
+
30
+ alias_method :where, :search
31
+
32
+ def guid(guid, fields: [])
33
+ query_params = if fields.empty?
34
+ auth_query_params
35
+ else
36
+ auth_query_params.merge({
37
+ fields: fields.join(",")
38
+ })
39
+ end
40
+ @handle.class.get(
41
+ "/standards/#{guid}",
42
+ query: query_params
43
+ ).parsed_response["resources"].map do |r|
44
+ AcademicBenchmarks::Standards::Standard.new(r["data"])
45
+ end
46
+ end
47
+
48
+ def all
49
+ request_search_pages_and_concat_resources(auth_query_params)
50
+ end
51
+
52
+ def authorities
53
+ raw_search(list: "authority").map{|a| a["data"]["authority"]}.map{|a| AcademicBenchmarks::Standards::Authority.from_hash(a)}
54
+ end
55
+
56
+ private
57
+
58
+ def raw_search(opts = {})
59
+ request_search_pages_and_concat_resources(opts.merge(auth_query_params))
60
+ end
61
+
62
+ def invalid_search_params(opts)
63
+ opts.keys.map(&:to_s) - AcademicBenchmarks::Api::Constants.standards_search_params
64
+ end
65
+
66
+ def auth_query_params
67
+ AcademicBenchmarks::Api::Auth.auth_query_params(
68
+ partner_id: @handle.partner_id,
69
+ partner_key: @handle.partner_key,
70
+ expires: AcademicBenchmarks::Api::Auth.expire_time_in_2_hours,
71
+ user_id: @handle.user_id
72
+ )
73
+ end
74
+
75
+ def request_search_pages_and_concat_resources(query_params)
76
+ query_params.reverse_merge!({limit: DEFAULT_PER_PAGE})
77
+
78
+ if !query_params[:limit] || query_params[:limit] <= 0
79
+ raise ArgumentError.new(
80
+ "limit must be specified as a positive integer"
81
+ )
82
+ end
83
+
84
+ first_page = request_page(
85
+ query_params: query_params,
86
+ limit: query_params[:limit],
87
+ offset: 0
88
+ ).parsed_response
89
+
90
+ resources = first_page["resources"]
91
+ count = first_page["count"]
92
+ offset = query_params[:limit]
93
+
94
+ while offset < count
95
+ page = request_page(
96
+ query_params: query_params,
97
+ limit: query_params[:limit],
98
+ offset: offset
99
+ )
100
+ offset += query_params[:limit]
101
+ resources.push(page.parsed_response["resources"])
102
+ end
103
+
104
+ resources.flatten
105
+ end
106
+
107
+ def request_page(query_params:, limit:, offset:)
108
+ query_params.merge!({
109
+ limit: limit,
110
+ offset: offset,
111
+ })
112
+ resp = @handle.class.get(
113
+ '/standards',
114
+ query: query_params.merge({
115
+ limit: limit,
116
+ offset: offset,
117
+ })
118
+ )
119
+ if resp.code != 200
120
+ raise RuntimeError.new(
121
+ "Received response '#{resp.code}: #{resp.message}' requesting standards from Academic Benchmarks:"
122
+ )
123
+ end
124
+ resp
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,14 @@
1
+
2
+ module InstVarsToHash
3
+ def to_s
4
+ to_h.to_s
5
+ end
6
+
7
+ def to_h
8
+ retval = {}
9
+ instance_variables.each do |iv|
10
+ retval[iv.to_s.gsub('@', '').to_sym] = instance_variable_get(iv)
11
+ end
12
+ retval
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ require_relative '../lib/inst_vars_to_hash'
2
+
3
+ module AcademicBenchmarks
4
+ module Standards
5
+ class Authority
6
+ include InstVarsToHash
7
+
8
+ attr_accessor :code, :guid, :description
9
+
10
+ alias_method :descr, :description
11
+
12
+ def self.from_hash(hash)
13
+ self.new(code: hash["code"], guid: hash["guid"], description: hash["descr"])
14
+ end
15
+
16
+ def initialize(code:, guid:, description:)
17
+ @code = code
18
+ @guid = guid
19
+ @description = description
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ require_relative '../lib/inst_vars_to_hash'
2
+
3
+ module AcademicBenchmarks
4
+ module Standards
5
+ class Course
6
+ include InstVarsToHash
7
+
8
+ attr_accessor :guid, :description
9
+
10
+ alias_method :descr, :description
11
+
12
+ def self.from_hash(hash)
13
+ self.new(description: hash["descr"], guid: hash["guid"])
14
+ end
15
+
16
+ def initialize(guid:, description:)
17
+ @guid = guid
18
+ @description = description
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ require_relative '../lib/inst_vars_to_hash'
2
+
3
+ module AcademicBenchmarks
4
+ module Standards
5
+ class Document
6
+ include InstVarsToHash
7
+
8
+ attr_accessor :title, :guid
9
+
10
+ def self.from_hash(hash)
11
+ self.new(title: hash["title"], guid: hash["guid"])
12
+ end
13
+
14
+ def initialize(title:, guid:)
15
+ @title = title
16
+ @guid = guid
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require_relative '../lib/inst_vars_to_hash'
2
+
3
+ module AcademicBenchmarks
4
+ module Standards
5
+ class Grade
6
+ include InstVarsToHash
7
+
8
+ attr_accessor :high, :low
9
+
10
+ def self.from_hash(hash)
11
+ self.new(high: hash["high"], low: hash["low"])
12
+ end
13
+
14
+ def initialize(high:, low:)
15
+ @high = high
16
+ @low = low
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ require_relative '../lib/inst_vars_to_hash'
2
+
3
+ module AcademicBenchmarks
4
+ module Standards
5
+ class HasRelations
6
+ include InstVarsToHash
7
+
8
+ attr_accessor :origin, :derivative, :related_derivative
9
+
10
+ def self.from_hash(hash)
11
+ self.new(derivative: hash["derivative"], origin: hash["origin"], related_derivative: hash["related_derivative"])
12
+ end
13
+
14
+ def initialize(origin: 0, derivative: 0, related_derivative: 0)
15
+ @origin = origin
16
+ @derivative = derivative
17
+ @related_derivative = related_derivative
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,41 @@
1
+ require_relative '../lib/inst_vars_to_hash'
2
+
3
+ module AcademicBenchmarks
4
+ module Standards
5
+ class Parent
6
+ include InstVarsToHash
7
+
8
+ attr_accessor :guid, :description, :number, :stem, :label, :deepest,
9
+ :seq, :level, :status, :version
10
+
11
+ def self.from_hash(hash)
12
+ self.new(
13
+ guid: hash["guid"],
14
+ description: hash["description"],
15
+ number: hash["number"],
16
+ stem: hash["stem"],
17
+ label: hash["label"],
18
+ deepest: hash["deepest"],
19
+ seq: hash["seq"],
20
+ level: hash["level"],
21
+ status: hash["status"],
22
+ version: hash["version"]
23
+ )
24
+ end
25
+
26
+ def initialize(guid:, description:, number:, stem:, label:, deepest:,
27
+ seq:, level:, status:, version:)
28
+ @guid = guid
29
+ @description = description
30
+ @number = number
31
+ @stem = stem
32
+ @label = label
33
+ @deepest = deepest
34
+ @seq = seq
35
+ @level = level
36
+ @status = status
37
+ @version = version
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,96 @@
1
+ require_relative '../lib/inst_vars_to_hash'
2
+
3
+ module AcademicBenchmarks
4
+ module Standards
5
+ class Standard
6
+ include InstVarsToHash
7
+
8
+ attr_reader :status, :deepest, :children
9
+ attr_accessor :guid, :description, :number, :stem, :label, :level,
10
+ :version, :seq, :adopt_year, :authority, :course,
11
+ :document, :grade, :has_relations, :subject,
12
+ :subject_doc, :parent, :parent_guid
13
+
14
+ alias_method :descr, :description
15
+
16
+ def initialize(data)
17
+ data = data["data"] if data["data"]
18
+ @guid = data["guid"]
19
+ @grade = attr_to_val_or_nil(Grade, data, "grade")
20
+ @label = data["label"]
21
+ @level = data["level"]
22
+ @course = attr_to_val_or_nil(Course, data, "course")
23
+ @number = data["number"]
24
+ @status = data["status"]
25
+ @parent = nil
26
+ @subject = attr_to_val_or_nil(Subject, data, "subject")
27
+ @deepest = data["deepest"]
28
+ @version = data["version"]
29
+ @children = []
30
+ @document = attr_to_val_or_nil(Document, data, "document")
31
+ @authority = attr_to_val_or_nil(Authority, data, "authority")
32
+ @adopt_year = data["adopt_year"]
33
+ @description = data["descr"]
34
+ @subject_doc = attr_to_val_or_nil(SubjectDoc, data, "subject_doc")
35
+ @has_relations = attr_to_val_or_nil(HasRelations, data, "has_relations")
36
+
37
+ # Parent guid extraction can be a little more complicated. Thanks AB!
38
+ if data["parent"] && data["parent"].is_a?(String)
39
+ @parent_guid = data["parent"]
40
+ elsif data["parent"] && data["parent"].is_a?(Hash)
41
+ @parent_guid = data["parent"]["guid"]
42
+ end
43
+ end
44
+
45
+ def active?
46
+ status == "Active"
47
+ end
48
+
49
+ def obsolete?
50
+ status == "Obsolete"
51
+ end
52
+
53
+ def deepest?
54
+ deepest == 'Y'
55
+ end
56
+
57
+ def status=(status)
58
+ unless %w[Active Obsolete].include?(status)
59
+ raise ArgumentError.new(
60
+ "Standard status must be either 'Active' or 'Obsolete'"
61
+ )
62
+ end
63
+ @status = status
64
+ end
65
+
66
+ def deepest=(deepest)
67
+ unless %w[Y N].include?(deepest)
68
+ raise ArgumentError.new("Standard deepest must be either 'Y' or 'N'")
69
+ end
70
+ @deepest = deepest
71
+ end
72
+
73
+ def add_child(child)
74
+ unless child.is_a?(Standard)
75
+ raise ArgumentError.new("Tried to set child that isn't a Standard")
76
+ end
77
+ @children.push(child)
78
+ end
79
+
80
+ def remove_child(child)
81
+ @children.delete(child)
82
+ end
83
+
84
+ def has_children?
85
+ @children.count > 0
86
+ end
87
+
88
+ private
89
+
90
+ def attr_to_val_or_nil(klass, hash, attr)
91
+ return nil unless hash.has_key?(attr)
92
+ klass.from_hash(hash)
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,97 @@
1
+ module AcademicBenchmarks
2
+ module Standards
3
+ class StandardsForest
4
+ attr_reader :trees, :data_hash
5
+
6
+ # The guid to standard hash can optionally be saved to permit speedily
7
+ # adding standards to the tree (since the tree is unordered,
8
+ # this would otherwise be an expensive operation).
9
+ #
10
+ # The initial data hash can also be optionally saved to
11
+ # permit testing and internal consistency checks
12
+
13
+ def initialize(
14
+ data_hash,
15
+ save_guid_to_standard_hash: true,
16
+ save_initial_data_hash: false
17
+ )
18
+ @data_hash = data_hash.dup.freeze if save_initial_data_hash
19
+ @guid_to_standard = {} # a hash of guids to standards
20
+ @trees = []
21
+ process_items(data_hash)
22
+
23
+ # upgrade the hash data to a StandardsTree object
24
+ @trees.map! do |item|
25
+ StandardsTree.new(item, build_item_hash: save_guid_to_standard_hash)
26
+ end
27
+
28
+ unless save_guid_to_standard_hash
29
+ remove_instance_variable('@guid_to_standard')
30
+ end
31
+ end
32
+
33
+ def add_standard(standard)
34
+ if standard.is_a?(Standard)
35
+ raise StandardError.new(
36
+ "adding standards is not currently implemented"
37
+ )
38
+ elsif standard.is_a?(Hash)
39
+ add_standard(Standard.new(standard))
40
+ else
41
+ raise ArgumentError.new(
42
+ "standard must be an 'AcademicBenchmarks::Standards::Standard' " \
43
+ "or a 'Hash' but was a #{standard.class.to_s}"
44
+ )
45
+ end
46
+ end
47
+
48
+ def single_tree?
49
+ @trees.count == 1
50
+ end
51
+
52
+ def empty?
53
+ @trees.empty?
54
+ end
55
+
56
+ private
57
+
58
+ def to_standard(item)
59
+ return item if item.is_a?(Standard)
60
+ Standard.new(item)
61
+ end
62
+
63
+ def process_items(data_hash)
64
+ build_guid_to_standard_hash(data_hash)
65
+ link_parent_and_children
66
+ end
67
+
68
+ def build_guid_to_standard_hash(data_hash)
69
+ data_hash.each do |item|
70
+ item = to_standard(item)
71
+ @guid_to_standard[item.guid] = item
72
+ end
73
+ end
74
+
75
+ def link_parent_and_children
76
+ @guid_to_standard.values.each do |child|
77
+ if child.parent_guid
78
+ present_in_hash_or_raise(child.parent_guid)
79
+ parent = @guid_to_standard[child.parent_guid]
80
+ parent.add_child(child)
81
+ child.parent = parent
82
+ else
83
+ @trees.push(child)
84
+ end
85
+ end
86
+ end
87
+
88
+ def present_in_hash_or_raise(guid)
89
+ unless @guid_to_standard.has_key?(guid)
90
+ raise StandardError.new(
91
+ "item missing from guid_to_standard hash"
92
+ )
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,67 @@
1
+ module AcademicBenchmarks
2
+ module Standards
3
+ class StandardsTree
4
+ attr_reader :root_standard
5
+
6
+ # The item hash can optionally be built to permit the speedy
7
+ # addition of standards to the tree. since the tree is unordered,
8
+ # adding to it can be expensive without this
9
+
10
+ def initialize(root_standard, build_item_hash: true)
11
+ @root_standard = root_standard
12
+ if build_item_hash
13
+ @item_hash = {}
14
+ go_ahead_and_build_item_hash
15
+ end
16
+ end
17
+
18
+ def add_standard(standard)
19
+ if standard.is_a?(Standard)
20
+ parent = @item_hash ? @item_hash[standard.parent_guid] : find_parent(standard)
21
+ unless parent
22
+ raise StandardError.new(
23
+ "Parent of standard not found in tree. Parent guid is " \
24
+ "'#{standard.parent_guid}' and child guid is '#{standard.guid}'"
25
+ )
26
+ end
27
+ parent.add_child(standard)
28
+ standard.parent = parent
29
+ elsif standard.is_a?(Hash)
30
+ add_standard(Standard.new(standard))
31
+ else
32
+ raise ArgumentError.new(
33
+ "standard must be an 'AcademicBenchmarks::Standards::Standard' " \
34
+ "or a 'Hash' but was a #{standard.class.to_s}"
35
+ )
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def go_ahead_and_build_item_hash
42
+ @item_hash[@root_standard.guid] = @root_standard
43
+ add_children_to_item_hash(@root_standard)
44
+ end
45
+
46
+ def add_children_to_item_hash(parent)
47
+ parent.children.each do |child|
48
+ @item_hash[child.guid] = child
49
+ add_children_to_item_hash(child) if child.has_children?
50
+ end
51
+ end
52
+
53
+ def find_parent(standard)
54
+ return @root_standard if @root_standard.guid == standard.parent_guid
55
+ check_children_for_parent(standard.parent_guid, @root_standard)
56
+ end
57
+
58
+ # does a depth-first search
59
+ def check_children_for_parent(parent_guid, standard)
60
+ standard.children.each do |child|
61
+ return child if child.guid == parent_guid
62
+ check_children_for_parent(parent_guid, child) if child.has_children?
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,20 @@
1
+ require_relative '../lib/inst_vars_to_hash'
2
+
3
+ module AcademicBenchmarks
4
+ module Standards
5
+ class Subject
6
+ include InstVarsToHash
7
+
8
+ attr_accessor :code, :broad
9
+
10
+ def self.from_hash(hash)
11
+ self.new(code: hash["code"], broad: hash["broad"], )
12
+ end
13
+
14
+ def initialize(code:, broad:)
15
+ @code = code
16
+ @broad = broad
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ require_relative '../lib/inst_vars_to_hash'
2
+
3
+ module AcademicBenchmarks
4
+ module Standards
5
+ class SubjectDoc
6
+ include InstVarsToHash
7
+
8
+ attr_accessor :guid, :description
9
+
10
+ alias_method :descr, :description
11
+
12
+ def self.from_hash(hash)
13
+ self.new(guid: hash["guid"], description: hash["descr"])
14
+ end
15
+
16
+ def initialize(guid:, description:)
17
+ @guid = guid
18
+ @description = description
19
+ end
20
+ end
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: academic_benchmarks
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Benjamin Porter
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-11-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.13'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: awesome_print
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.6'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.6'
83
+ description: A ruby api for accessing the Academic Benchmarks API. A valid subscription
84
+ with accompanying credentials will be required to access the API
85
+ email: bporter@instructure.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - lib/academic_benchmarks.rb
91
+ - lib/academic_benchmarks/api/auth.rb
92
+ - lib/academic_benchmarks/api/constants.rb
93
+ - lib/academic_benchmarks/api/handle.rb
94
+ - lib/academic_benchmarks/api/standards.rb
95
+ - lib/academic_benchmarks/lib/inst_vars_to_hash.rb
96
+ - lib/academic_benchmarks/standards/authority.rb
97
+ - lib/academic_benchmarks/standards/course.rb
98
+ - lib/academic_benchmarks/standards/document.rb
99
+ - lib/academic_benchmarks/standards/grade.rb
100
+ - lib/academic_benchmarks/standards/has_relations.rb
101
+ - lib/academic_benchmarks/standards/parent.rb
102
+ - lib/academic_benchmarks/standards/standard.rb
103
+ - lib/academic_benchmarks/standards/standards_forest.rb
104
+ - lib/academic_benchmarks/standards/standards_tree.rb
105
+ - lib/academic_benchmarks/standards/subject.rb
106
+ - lib/academic_benchmarks/standards/subject_doc.rb
107
+ homepage: https://github.com/instructure/academic_benchmarks
108
+ licenses:
109
+ - GPL
110
+ metadata: {}
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ requirements: []
126
+ rubyforge_project:
127
+ rubygems_version: 2.2.3
128
+ signing_key:
129
+ specification_version: 4
130
+ summary: A ruby api for accessing the Academic Benchmarks API
131
+ test_files: []
132
+ has_rdoc: