school_loop 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +91 -0
- data/LICENSE +19 -0
- data/README.md +106 -0
- data/Rakefile +6 -0
- data/lib/school_loop.rb +25 -0
- data/lib/school_loop/client.rb +39 -0
- data/lib/school_loop/configuration.rb +54 -0
- data/lib/school_loop/connection.rb +28 -0
- data/lib/school_loop/error.rb +16 -0
- data/lib/school_loop/error/bad_request.rb +12 -0
- data/lib/school_loop/error/service_error.rb +22 -0
- data/lib/school_loop/error/unauthorized.rb +12 -0
- data/lib/school_loop/resources.rb +8 -0
- data/lib/school_loop/resources/progress_reports.rb +15 -0
- data/lib/school_loop/resources/roster.rb +18 -0
- data/lib/school_loop/response.rb +20 -0
- data/lib/school_loop/response/raise_error.rb +21 -0
- data/lib/school_loop/response/xmlize.rb +28 -0
- data/lib/school_loop/version.rb +3 -0
- data/school_loop.gemspec +27 -0
- data/spec/fixtures/progress_report_submission.xml +33 -0
- data/spec/fixtures/roster_response.xml +50 -0
- data/spec/helper.rb +28 -0
- data/spec/school_loop/client_spec.rb +84 -0
- data/spec/school_loop/configuration_spec.rb +41 -0
- data/spec/school_loop/resources/progress_reports_spec.rb +39 -0
- data/spec/school_loop/resources/roster_spec.rb +41 -0
- data/spec/school_loop/response/xmlize_spec.rb +0 -0
- data/spec/school_loop_spec.rb +64 -0
- metadata +143 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 07ac5da7b48f65a5d323294763459397ec01ebe6
|
4
|
+
data.tar.gz: c019c80fbdc560ac6810f163d251e8a6e6d76dc0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b41f0caca0c1850d4ccc4415265d91fd6084e1cf51873fb8a5205991fdb31ceced125b83a75780333fcab1534314715a5accf87f96d3de781edf8afa7b55ab56
|
7
|
+
data.tar.gz: b6d0ed1e89c2aa21318afc7dc45c9a55f2bf9f9201ae296ed01c5f6edcad02f5f8d08649e2e83954307a0457925c3cf228a961a7b911d7851970c3c46d978153
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.0
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
school_loop (0.0.1)
|
5
|
+
faraday (~> 0.9)
|
6
|
+
faraday_middleware (~> 0.9)
|
7
|
+
nokogiri (>= 1.5.2)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://www.rubygems.org/
|
11
|
+
specs:
|
12
|
+
addressable (2.3.8)
|
13
|
+
coderay (1.1.0)
|
14
|
+
coveralls (0.8.2)
|
15
|
+
json (~> 1.8)
|
16
|
+
rest-client (>= 1.6.8, < 2)
|
17
|
+
simplecov (~> 0.10.0)
|
18
|
+
term-ansicolor (~> 1.3)
|
19
|
+
thor (~> 0.19.1)
|
20
|
+
crack (0.4.2)
|
21
|
+
safe_yaml (~> 1.0.0)
|
22
|
+
diff-lcs (1.2.5)
|
23
|
+
docile (1.1.5)
|
24
|
+
domain_name (0.5.24)
|
25
|
+
unf (>= 0.0.5, < 1.0.0)
|
26
|
+
faraday (0.9.1)
|
27
|
+
multipart-post (>= 1.2, < 3)
|
28
|
+
faraday_middleware (0.10.0)
|
29
|
+
faraday (>= 0.7.4, < 0.10)
|
30
|
+
http-cookie (1.0.2)
|
31
|
+
domain_name (~> 0.5)
|
32
|
+
json (1.8.3)
|
33
|
+
method_source (0.8.2)
|
34
|
+
mime-types (1.25.1)
|
35
|
+
mini_portile (0.6.2)
|
36
|
+
multipart-post (2.0.0)
|
37
|
+
netrc (0.10.3)
|
38
|
+
nokogiri (1.6.6.2)
|
39
|
+
mini_portile (~> 0.6.0)
|
40
|
+
pry (0.10.1)
|
41
|
+
coderay (~> 1.1.0)
|
42
|
+
method_source (~> 0.8.1)
|
43
|
+
slop (~> 3.4)
|
44
|
+
rake (10.4.2)
|
45
|
+
rest-client (1.8.0)
|
46
|
+
http-cookie (>= 1.0.2, < 2.0)
|
47
|
+
mime-types (>= 1.16, < 3.0)
|
48
|
+
netrc (~> 0.7)
|
49
|
+
rspec (3.3.0)
|
50
|
+
rspec-core (~> 3.3.0)
|
51
|
+
rspec-expectations (~> 3.3.0)
|
52
|
+
rspec-mocks (~> 3.3.0)
|
53
|
+
rspec-core (3.3.2)
|
54
|
+
rspec-support (~> 3.3.0)
|
55
|
+
rspec-expectations (3.3.1)
|
56
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
57
|
+
rspec-support (~> 3.3.0)
|
58
|
+
rspec-mocks (3.3.2)
|
59
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
60
|
+
rspec-support (~> 3.3.0)
|
61
|
+
rspec-support (3.3.0)
|
62
|
+
safe_yaml (1.0.4)
|
63
|
+
simplecov (0.10.0)
|
64
|
+
docile (~> 1.1.0)
|
65
|
+
json (~> 1.8)
|
66
|
+
simplecov-html (~> 0.10.0)
|
67
|
+
simplecov-html (0.10.0)
|
68
|
+
slop (3.6.0)
|
69
|
+
term-ansicolor (1.3.2)
|
70
|
+
tins (~> 1.0)
|
71
|
+
thor (0.19.1)
|
72
|
+
tins (1.5.4)
|
73
|
+
unf (0.1.4)
|
74
|
+
unf_ext
|
75
|
+
unf_ext (0.0.7.1)
|
76
|
+
webmock (1.21.0)
|
77
|
+
addressable (>= 2.3.6)
|
78
|
+
crack (>= 0.3.2)
|
79
|
+
|
80
|
+
PLATFORMS
|
81
|
+
ruby
|
82
|
+
|
83
|
+
DEPENDENCIES
|
84
|
+
bundler (~> 1.0)
|
85
|
+
coveralls
|
86
|
+
pry
|
87
|
+
rake
|
88
|
+
rspec (~> 3.3)
|
89
|
+
school_loop!
|
90
|
+
simplecov
|
91
|
+
webmock (>= 1.9)
|
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2015 Mitch Dempsey
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# School Loop API
|
2
|
+
|
3
|
+
|
4
|
+
[![Build Status](https://travis-ci.org/webdestroya/school_loop.svg)](https://travis-ci.org/webdestroya/school_loop)
|
5
|
+
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Install the gem by issuing
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem install school_loop
|
13
|
+
```
|
14
|
+
|
15
|
+
or put it in your Gemfile and run `bundle install`
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
gem "school_loop"
|
19
|
+
```
|
20
|
+
|
21
|
+
## Configuration
|
22
|
+
|
23
|
+
These global settings will be used unless specifically overridden by an instance below.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
SchoolLoop.configure do |config|
|
27
|
+
config.subdomain = 'demoschool'
|
28
|
+
config.username = 'apiuser'
|
29
|
+
config.password = 'some_api_password'
|
30
|
+
config.adapter = :net_http
|
31
|
+
end
|
32
|
+
```
|
33
|
+
|
34
|
+
## Usage
|
35
|
+
|
36
|
+
Create a new client using the global defaults:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
school_loop = SchoolLoop.new
|
40
|
+
```
|
41
|
+
|
42
|
+
Create a new client instance and override global defaults
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
school_loop = SchoolLoop.new subdomain: 'demoschool', username: 'apiuser', password: 'some_api_password'
|
46
|
+
```
|
47
|
+
|
48
|
+
Alternatively, you can configure the School Loop settings by passing a block:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
school_loop = SchoolLoop.new do |config|
|
52
|
+
config.subdomain = 'demoschool'
|
53
|
+
config.username = 'apiuser'
|
54
|
+
config.password = 'some_api_password'
|
55
|
+
config.adapter = :net_http
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
|
60
|
+
Currently, only three methods are implemented:
|
61
|
+
|
62
|
+
#### Get Entire School Roster
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
roster = school_loop.get_roster
|
66
|
+
# returns a Nokogiri::XML::Document
|
67
|
+
```
|
68
|
+
|
69
|
+
#### Get Teacher Roster
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
teacher_id = "12345"
|
73
|
+
roster = school_loop.get_roster(teacher_id)
|
74
|
+
# returns a Nokogiri::XML::Document (with a single 'teacher' node)
|
75
|
+
```
|
76
|
+
|
77
|
+
Example roster data is available on [School Loop's Documentation](http://www.schoolloop.com/about-us/partners/progress-report-api/progress-report-api-schema/#ProgressReportSchema-IVSampleSchoolLoopRosterDownload)
|
78
|
+
|
79
|
+
#### Posting Progress Reports
|
80
|
+
|
81
|
+
For a detailed schema for Progress reports, you can look at [School Loop's Progress Report API Schema](http://www.schoolloop.com/about-us/partners/progress-report-api/progress-report-api-schema/)
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
prog_report_xml = <<-EOF
|
85
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
86
|
+
<root>
|
87
|
+
<sections>
|
88
|
+
<section ID="1234">
|
89
|
+
<progressReports>
|
90
|
+
<progressReport markName="Current Grades" ... grade="A">
|
91
|
+
...
|
92
|
+
</progressReport>
|
93
|
+
</progressReports>
|
94
|
+
</section>
|
95
|
+
</sections>
|
96
|
+
</root>
|
97
|
+
EOF
|
98
|
+
|
99
|
+
school_loop.publish_progress_report(prog_report_xml)
|
100
|
+
```
|
101
|
+
|
102
|
+
## License
|
103
|
+
[MIT](http://opensource.org/licenses/MIT)
|
104
|
+
|
105
|
+
## Special Thanks
|
106
|
+
This gem is heavily based on the [bitbucket_rest_api](https://github.com/vongrippen/bitbucket) gem by Mike Cochran.
|
data/Rakefile
ADDED
data/lib/school_loop.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'school_loop/version'
|
2
|
+
require 'school_loop/configuration'
|
3
|
+
require 'school_loop/connection'
|
4
|
+
require 'school_loop/client'
|
5
|
+
|
6
|
+
module SchoolLoop
|
7
|
+
extend Configuration
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def new(options = {}, &block)
|
11
|
+
SchoolLoop::Client.new(options, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(method, *args, &block)
|
15
|
+
return super unless new.respond_to?(method)
|
16
|
+
new.send(method, *args, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def respond_to?(method, include_private = false)
|
20
|
+
new.respond_to?(method, include_private) || super(method, include_private)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'school_loop/configuration'
|
2
|
+
require 'school_loop/connection'
|
3
|
+
require 'school_loop/resources'
|
4
|
+
|
5
|
+
module SchoolLoop
|
6
|
+
class Client
|
7
|
+
include Connection
|
8
|
+
|
9
|
+
include Resources::ProgressReports
|
10
|
+
include Resources::Roster
|
11
|
+
|
12
|
+
attr_reader *Configuration::VALID_OPTIONS_KEYS
|
13
|
+
|
14
|
+
# Callback to update global configuration options
|
15
|
+
class_eval do
|
16
|
+
Configuration::VALID_OPTIONS_KEYS.each do |key|
|
17
|
+
define_method "#{key}=" do |arg|
|
18
|
+
self.instance_variable_set("@#{key}", arg)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Creates new API
|
24
|
+
def initialize(options={}, &block)
|
25
|
+
super()
|
26
|
+
setup options
|
27
|
+
|
28
|
+
self.instance_eval(&block) if block_given?
|
29
|
+
end
|
30
|
+
|
31
|
+
def setup(options={})
|
32
|
+
options = SchoolLoop.options.merge(options)
|
33
|
+
Configuration::VALID_OPTIONS_KEYS.each do |key|
|
34
|
+
send("#{key}=", options[key])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module SchoolLoop
|
2
|
+
module Configuration
|
3
|
+
VALID_OPTIONS_KEYS = [
|
4
|
+
:username,
|
5
|
+
:password,
|
6
|
+
:subdomain,
|
7
|
+
|
8
|
+
:secure,
|
9
|
+
|
10
|
+
:adapter,
|
11
|
+
:user_agent,
|
12
|
+
:connection_options,
|
13
|
+
:debug,
|
14
|
+
].freeze
|
15
|
+
|
16
|
+
DEFAULT_ADAPTER = :net_http
|
17
|
+
|
18
|
+
DEFAULT_USERNAME = nil
|
19
|
+
DEFAULT_PASSWORD = nil
|
20
|
+
DEFAULT_SUBDOMAIN = nil
|
21
|
+
|
22
|
+
DEFAULT_USER_AGENT = "School Loop Ruby API v#{SchoolLoop::VERSION}".freeze
|
23
|
+
|
24
|
+
DEFAULT_CONNECTION_OPTIONS = {}
|
25
|
+
|
26
|
+
attr_accessor *VALID_OPTIONS_KEYS
|
27
|
+
|
28
|
+
def configure
|
29
|
+
yield self
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.extended(base)
|
33
|
+
base.set_defaults
|
34
|
+
end
|
35
|
+
|
36
|
+
def options
|
37
|
+
options = { }
|
38
|
+
VALID_OPTIONS_KEYS.each { |k| options[k] = send(k) }
|
39
|
+
options
|
40
|
+
end
|
41
|
+
|
42
|
+
def set_defaults
|
43
|
+
self.adapter = DEFAULT_ADAPTER
|
44
|
+
self.user_agent = DEFAULT_USER_AGENT
|
45
|
+
self.connection_options = DEFAULT_CONNECTION_OPTIONS
|
46
|
+
self.username = DEFAULT_USERNAME
|
47
|
+
self.subdomain = DEFAULT_SUBDOMAIN
|
48
|
+
self.password = DEFAULT_PASSWORD
|
49
|
+
self.secure = true
|
50
|
+
self.debug = false
|
51
|
+
self
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
3
|
+
require 'school_loop/response'
|
4
|
+
require 'school_loop/response/raise_error'
|
5
|
+
require 'school_loop/response/xmlize'
|
6
|
+
|
7
|
+
module SchoolLoop
|
8
|
+
module Connection
|
9
|
+
extend self
|
10
|
+
|
11
|
+
|
12
|
+
def connection
|
13
|
+
@connection ||= Faraday.new({url: "#{secure ? 'https' : 'http'}://#{subdomain}.schoolloop.com"}.merge(connection_options)) do |faraday|
|
14
|
+
faraday.request :basic_auth, username, password
|
15
|
+
faraday.headers[:user_agent] = user_agent
|
16
|
+
|
17
|
+
if debug
|
18
|
+
faraday.response :logger
|
19
|
+
end
|
20
|
+
|
21
|
+
faraday.use SchoolLoop::Response::Xmlize, :content_type => /\bxml$/
|
22
|
+
faraday.use SchoolLoop::Response::RaiseError
|
23
|
+
faraday.adapter adapter
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module SchoolLoop
|
2
|
+
module Error
|
3
|
+
class SchoolLoopError < StandardError
|
4
|
+
attr_reader :response_message, :response_headers
|
5
|
+
|
6
|
+
def initialize(message)
|
7
|
+
super message
|
8
|
+
@response_message = message
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
require "school_loop/error/service_error"
|
15
|
+
require "school_loop/error/bad_request"
|
16
|
+
require "school_loop/error/unauthorized"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module SchoolLoop #:nodoc
|
4
|
+
# Raised when SchoolLoop returns any of the HTTP status codes
|
5
|
+
module Error
|
6
|
+
class ServiceError < SchoolLoopError
|
7
|
+
attr_accessor :http_headers, :http_status, :http_method, :url
|
8
|
+
|
9
|
+
def initialize(env)
|
10
|
+
super(generate_message(env))
|
11
|
+
@http_headers = env[:response_headers]
|
12
|
+
@http_status = env[:status]
|
13
|
+
@http_method = env[:method].to_s.upcase
|
14
|
+
@url = env[:url].to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate_message(env)
|
18
|
+
"#{env[:body]}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end # Error
|
22
|
+
end # SchoolLoop
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module SchoolLoop
|
2
|
+
module Resources
|
3
|
+
module ProgressReports
|
4
|
+
|
5
|
+
def publish_progress_report(xml_body)
|
6
|
+
connection.post do |req|
|
7
|
+
req.url "/api/progressReports"
|
8
|
+
req.headers['Content-Type'] = "application/xml"
|
9
|
+
req.body = xml_body
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SchoolLoop
|
2
|
+
module Resources
|
3
|
+
module Roster
|
4
|
+
|
5
|
+
# Get the roster for all teachers, or limit to a specific teacher
|
6
|
+
def get_roster(teacher_id = nil)
|
7
|
+
connection.get do |req|
|
8
|
+
req.url "/api/roster"
|
9
|
+
|
10
|
+
if teacher_id
|
11
|
+
req.params['teacher_id'] = teacher_id
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
require 'faraday'
|
3
|
+
|
4
|
+
module SchoolLoop
|
5
|
+
class Response < Faraday::Response::Middleware
|
6
|
+
CONTENT_TYPE = 'Content-Type'.freeze
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_accessor :parser
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.define_parser(&block)
|
13
|
+
@parser = block
|
14
|
+
end
|
15
|
+
|
16
|
+
def response_type(env)
|
17
|
+
env[:response_headers][CONTENT_TYPE].to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
require 'school_loop/error'
|
5
|
+
|
6
|
+
module SchoolLoop
|
7
|
+
class Response::RaiseError < Faraday::Response::Middleware
|
8
|
+
|
9
|
+
def on_complete(env)
|
10
|
+
case env[:status].to_i
|
11
|
+
when 400
|
12
|
+
raise SchoolLoop::Error::BadRequest.new(env)
|
13
|
+
when 401
|
14
|
+
raise SchoolLoop::Error::Unauthorized.new(env)
|
15
|
+
when 400...600
|
16
|
+
raise SchoolLoop::Error::ServiceError.new(env)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end # Response::RaiseError
|
21
|
+
end # SchoolLoop
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
require 'faraday_middleware'
|
5
|
+
require 'faraday_middleware/response_middleware'
|
6
|
+
|
7
|
+
module SchoolLoop
|
8
|
+
class Response::Xmlize < ::FaradayMiddleware::ResponseMiddleware
|
9
|
+
dependency 'nokogiri'
|
10
|
+
|
11
|
+
define_parser do |body|
|
12
|
+
::Nokogiri::XML body
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse(body)
|
16
|
+
case body
|
17
|
+
when ''
|
18
|
+
nil
|
19
|
+
when 'true'
|
20
|
+
true
|
21
|
+
when 'false'
|
22
|
+
false
|
23
|
+
else
|
24
|
+
self.class.parser.call body
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end # Response::Xmlize
|
28
|
+
end # SchoolLoop
|
data/school_loop.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require 'school_loop/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "school_loop"
|
7
|
+
spec.version = SchoolLoop::VERSION
|
8
|
+
spec.platform = Gem::Platform::RUBY
|
9
|
+
spec.authors = ['Mitch Dempsey']
|
10
|
+
spec.email = ['mitch@mitchdempsey.com']
|
11
|
+
spec.licenses = ['MIT']
|
12
|
+
spec.homepage = "https://github.com/webdestroya/school_loop"
|
13
|
+
spec.summary = "Client for School Loop API (OpenLoop)"
|
14
|
+
spec.description = "Client for School Loop API (OpenLoop)"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split("\n")
|
17
|
+
spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.0'
|
22
|
+
|
23
|
+
spec.add_dependency 'faraday', '~> 0.9'
|
24
|
+
spec.add_dependency 'faraday_middleware', '~> 0.9'
|
25
|
+
#spec.add_dependency 'ox', '~> 2.2.1'
|
26
|
+
spec.add_dependency 'nokogiri', '>= 1.5.2'
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<root>
|
3
|
+
<sections>
|
4
|
+
<section ID="1234">
|
5
|
+
<progressReports>
|
6
|
+
<progressReport markName="Current Grades" date="2007-08-12T22:24:15Z" score="0.95" grade="A" hasScore="true" useWeighting="false" gradebookDate="">
|
7
|
+
<gradeDefinitions>
|
8
|
+
<keyValue key="INC" value="INCOMPLETE (not handed in)"/>
|
9
|
+
</gradeDefinitions>
|
10
|
+
<categories>
|
11
|
+
<category hasScore="true" name="Assignment" weight="-1.000" score="0.000"/>
|
12
|
+
</categories>
|
13
|
+
<course period="3" systemID="100000881299" name="English"/>
|
14
|
+
<gradingScale>
|
15
|
+
<cutoffs>
|
16
|
+
<cutoff Start="90" Name="A"/>
|
17
|
+
<cutoff Start="0" Name="F"/>
|
18
|
+
</cutoffs>
|
19
|
+
</gradingScale>
|
20
|
+
<grades>
|
21
|
+
<grade score="10" excused="false" comment="" grade="B">
|
22
|
+
<assignment categoryName="Assignment" maxPoints="10" dueDate="2007-05-18T00:00:00Z" title="WWI"/>
|
23
|
+
</grade>
|
24
|
+
<grade score="10" excused="false" comment="" grade="B">
|
25
|
+
<assignment categoryName="Assignment" maxPoints="10" dueDate="2007-05-18T00:00:00Z" title="Thing 2"/>
|
26
|
+
</grade>
|
27
|
+
</grades>
|
28
|
+
<student name="Cleaver, Kevin" schoolID="7123456"/>
|
29
|
+
</progressReport>
|
30
|
+
</progressReports>
|
31
|
+
</section>
|
32
|
+
</sections>
|
33
|
+
</root>
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
|
3
|
+
<root>
|
4
|
+
<roster source="schoolloop.com">
|
5
|
+
<teachers>
|
6
|
+
<teacher systemID="1111180131503" localID="111111" name="Reynolds, Mr. Malcom">
|
7
|
+
<courses>
|
8
|
+
<course systemID="1111107012313" name="Math">
|
9
|
+
<periods>
|
10
|
+
<period systemID="1111133312598" number="1">
|
11
|
+
<assignments/>
|
12
|
+
<students>
|
13
|
+
<student permID="1000265" systemID="1111170083336" gradeLevel="12" firstName="Ryan" middleName="Chris" lastName="Test" displayID="1000265" localID="1234" sectionID="1234" sectionSystemID="1111133311259"/>
|
14
|
+
<student permID="1000186" systemID="1111170083213" gradeLevel="11" firstName="Manuel" middleName="" lastName="Test" displayID="1000186" localID="5677" sectionID="1234" sectionSystemID="1111133311259"/>
|
15
|
+
<student permID="1000673" systemID="1111170083137" gradeLevel="11" firstName="Justin" middleName="" lastName="Test" displayID="1000673" localID="8900" sectionID="1234" sectionSystemID="1111133311259"/>
|
16
|
+
<student permID="1000878" systemID="1111170082883" gradeLevel="11" firstName="Dave" middleName="" lastName="Test" displayID="1000878" localID="1235" sectionID="1234" sectionSystemID="1111133311259"/>
|
17
|
+
<student permID="1000985" systemID="1111107494444" gradeLevel="12" firstName="Colby" middleName="Jeffrey" lastName="Test" displayID="1000985" localID="1236" sectionID="1234" sectionSystemID="1111133311259"/>
|
18
|
+
</students>
|
19
|
+
</period>
|
20
|
+
</periods>
|
21
|
+
</course>
|
22
|
+
<course systemID="1111107012069" name="English 3">
|
23
|
+
<periods>
|
24
|
+
<period systemID="1111133312700" number="5">
|
25
|
+
<assignments>
|
26
|
+
<assignment dueDate="2015-08-27T00:00:00Z" maxPoints="10.0" systemID="1111143710574" categoryName="Assignment" title="Parent Signature" categoryID="1111146128059"/>
|
27
|
+
<assignment dueDate="2015-09-10T00:00:00Z" maxPoints="42.0" systemID="1111124172130" categoryName="Assignment" title="Unit 1 Literary Terms Worksheet and Test" categoryID="1111146128059"/>
|
28
|
+
<assignment dueDate="2015-10-02T00:00:00Z" maxPoints="100.0" systemID="1111124171925" categoryName="Assignment" title="Participation/Professionalism" categoryID="1111146128059"/>
|
29
|
+
</assignments>
|
30
|
+
<students>
|
31
|
+
<student permID="1000338" systemID="1111170083144" gradeLevel="11" firstName="Henny" middleName="" lastName="Test" displayID="1000338" localID="123" sectionID="1000" sectionSystemID="1111133311919"/>
|
32
|
+
<student permID="1000997" systemID="1111170083020" gradeLevel="11" firstName="Sean" middleName="" lastName="Test" displayID="1000997" localID="456" sectionID="1000" sectionSystemID="1111133311919"/>
|
33
|
+
<student permID="1000673" systemID="1111170083137" gradeLevel="11" firstName="Justin" middleName="" lastName="Test" displayID="1000673" localID="789" sectionID="1000" sectionSystemID="1111133311919"/>
|
34
|
+
<student permID="1000828" systemID="1111143756226" gradeLevel="11" firstName="Fred" middleName="Adele" lastName="Test" displayID="1000828" localID="8456" sectionID="1000" sectionSystemID="1111133311919"/>
|
35
|
+
<student permID="1000977" systemID="1111170082757" gradeLevel="11" firstName="Peter" middleName="Jay" lastName="Test" displayID="1000977" localID="9456" sectionID="1000" sectionSystemID="1111133311919"/>
|
36
|
+
<student permID="1000183" systemID="1111170083015" gradeLevel="11" firstName="Kyle" middleName="Kend" lastName="Test" displayID="1000183" localID="7456" sectionID="1000" sectionSystemID="1111133311919"/>
|
37
|
+
</students>
|
38
|
+
</period>
|
39
|
+
</periods>
|
40
|
+
</course>
|
41
|
+
</courses>
|
42
|
+
<categories>
|
43
|
+
<category systemID="1111146879613" name="Classwork - Homework"/>
|
44
|
+
<category systemID="1111146128059" name="Assignment"/>
|
45
|
+
<category systemID="1111175461981" name="Quiz / Test"/>
|
46
|
+
</categories>
|
47
|
+
</teacher>
|
48
|
+
</teachers>
|
49
|
+
</roster>
|
50
|
+
</root>
|
data/spec/helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
if RUBY_ENGINE == 'ruby'
|
2
|
+
require 'simplecov'
|
3
|
+
require 'coveralls'
|
4
|
+
|
5
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
6
|
+
SimpleCov::Formatter::HTMLFormatter,
|
7
|
+
Coveralls::SimpleCov::Formatter
|
8
|
+
]
|
9
|
+
SimpleCov.start
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'school_loop'
|
13
|
+
require 'rspec'
|
14
|
+
require 'webmock/rspec'
|
15
|
+
|
16
|
+
WebMock.disable_net_connect!(:allow => 'coveralls.io')
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.raise_errors_for_deprecations!
|
20
|
+
end
|
21
|
+
|
22
|
+
def fixture_path
|
23
|
+
File.expand_path("../fixtures", __FILE__)
|
24
|
+
end
|
25
|
+
|
26
|
+
def fixture(file)
|
27
|
+
File.new(fixture_path + '/' + file)
|
28
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe SchoolLoop::Client do
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
describe "error handling" do
|
9
|
+
|
10
|
+
let(:unauth_client) do
|
11
|
+
SchoolLoop.new do |config|
|
12
|
+
config.subdomain = 'subdomain'
|
13
|
+
config.username = 'username'
|
14
|
+
config.password = 'password'
|
15
|
+
config.adapter = :net_http
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# bad user, good password
|
20
|
+
# 401 ERROR: Authorization failed: user or role not privileged.
|
21
|
+
|
22
|
+
# bad user, bad password
|
23
|
+
# 401 ERROR: Authorization failed: password incorrect.
|
24
|
+
|
25
|
+
# api not enabled
|
26
|
+
# 400 Error: OpenLoop is not enabled for subdomain.schoolloop.com. Contact School Loop.
|
27
|
+
|
28
|
+
|
29
|
+
context "401 Unauthorized" do
|
30
|
+
before(:each) do
|
31
|
+
stub_request(:any, /.*schoolloop\.com\/.*/)
|
32
|
+
.to_return(status: 401, body: "ERROR: Authorization failed: password incorrect.")
|
33
|
+
end
|
34
|
+
it "raises an exception" do
|
35
|
+
expect { unauth_client.get_roster }.to raise_error(SchoolLoop::Error::Unauthorized)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "400 Bad Request" do
|
40
|
+
before(:each) do
|
41
|
+
stub_request(:any, /.*schoolloop\.com\/.*/)
|
42
|
+
.to_return(status: 400, body: "some error message")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "raises an exception" do
|
46
|
+
expect { unauth_client.get_roster }.to raise_error(SchoolLoop::Error::BadRequest, "some error message")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "404" do
|
51
|
+
before(:each) do
|
52
|
+
stub_request(:any, /.*schoolloop\.com\/.*/)
|
53
|
+
.to_return(status: 404, body: "not found")
|
54
|
+
end
|
55
|
+
|
56
|
+
it "raises an exception" do
|
57
|
+
expect { unauth_client.get_roster }.to raise_error(SchoolLoop::Error::ServiceError, "not found")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "503" do
|
62
|
+
before(:each) do
|
63
|
+
stub_request(:any, /.*schoolloop\.com\/.*/)
|
64
|
+
.to_return(status: 503, body: "backend failure")
|
65
|
+
end
|
66
|
+
|
67
|
+
it "raises an exception" do
|
68
|
+
expect { unauth_client.get_roster }.to raise_error(SchoolLoop::Error::ServiceError, "backend failure")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "timeout" do
|
73
|
+
before(:each) do
|
74
|
+
stub_request(:any, /.*schoolloop\.com\/.*/).to_timeout
|
75
|
+
end
|
76
|
+
|
77
|
+
it "raises an exception" do
|
78
|
+
expect { unauth_client.get_roster }.to raise_error(Faraday::TimeoutError)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe SchoolLoop::Configuration do
|
4
|
+
|
5
|
+
describe ".configure" do
|
6
|
+
|
7
|
+
it "sets global configuration settings" do
|
8
|
+
SchoolLoop.configure do |config|
|
9
|
+
config.username = "test2"
|
10
|
+
config.password = "setting2"
|
11
|
+
end
|
12
|
+
|
13
|
+
expect(SchoolLoop.options[:username]).to eq "test2"
|
14
|
+
expect(SchoolLoop.options[:password]).to eq "setting2"
|
15
|
+
|
16
|
+
client = SchoolLoop.new
|
17
|
+
|
18
|
+
expect(client.username).to eq "test2"
|
19
|
+
expect(client.password).to eq "setting2"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "allows the user to specify extra config options" do
|
23
|
+
SchoolLoop.configure do |config|
|
24
|
+
config.connection_options = {ssl: {verify: false}, request: {timeout: 1234}}
|
25
|
+
end
|
26
|
+
|
27
|
+
client = SchoolLoop.new
|
28
|
+
expect(client.connection.options.timeout).to eq 1234
|
29
|
+
end
|
30
|
+
|
31
|
+
describe ":secure" do
|
32
|
+
it { expect(SchoolLoop.new(secure: false, subdomain: "test").connection.url_prefix.scheme).to eq "http" }
|
33
|
+
|
34
|
+
it { expect(SchoolLoop.new(secure: true, subdomain: "test").connection.url_prefix.scheme).to eq "https" }
|
35
|
+
it { expect(SchoolLoop.new(subdomain: "test").connection.url_prefix.scheme).to eq "https" }
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe SchoolLoop::Resources::ProgressReports do
|
4
|
+
|
5
|
+
let(:client) do
|
6
|
+
SchoolLoop.new do |config|
|
7
|
+
config.subdomain = 'subdomain'
|
8
|
+
config.username = 'username'
|
9
|
+
config.password = 'password'
|
10
|
+
config.adapter = :net_http
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#publish_progress_report" do
|
15
|
+
|
16
|
+
it "publishes a progress report" do
|
17
|
+
stub_request(:post, "https://username:password@subdomain.schoolloop.com/api/progressReports")
|
18
|
+
.to_return(status: 200, body: "SUCCESS\n")
|
19
|
+
|
20
|
+
response = client.publish_progress_report("<xml/>")
|
21
|
+
expect(a_request(:post, /.*subdomain\.schoolloop\.com\/api\/progressReports/)).to have_been_made.once
|
22
|
+
|
23
|
+
expect(response.status).to eq 200
|
24
|
+
expect(response.body).to eq "SUCCESS\n"
|
25
|
+
end
|
26
|
+
|
27
|
+
context "errors" do
|
28
|
+
before(:each) do
|
29
|
+
stub_request(:any, /.*schoolloop\.com\/.*/)
|
30
|
+
.to_return(status: 400, body: "Error: failed to parse XML reports. No reports found. Check XML syntax.")
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
it { expect { client.publish_progress_report("<xml/>") }.to raise_error(SchoolLoop::Error::BadRequest) }
|
35
|
+
it { expect { client.publish_progress_report("<xml/>") }.to raise_error("Error: failed to parse XML reports. No reports found. Check XML syntax.") }
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe SchoolLoop::Resources::Roster do
|
4
|
+
|
5
|
+
let(:client) do
|
6
|
+
SchoolLoop.new do |config|
|
7
|
+
config.subdomain = 'subdomain'
|
8
|
+
config.username = 'username'
|
9
|
+
config.password = 'password'
|
10
|
+
config.adapter = :net_http
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#get_roster" do
|
15
|
+
|
16
|
+
before do
|
17
|
+
stub_request(:get, /.*schoolloop\.com\/api\/roster.*/)
|
18
|
+
.to_return(status: 200, body: fixture("roster_response.xml").read,
|
19
|
+
headers: {'Content-Type' => 'text/xml'}
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "for entire school" do
|
24
|
+
response = client.get_roster
|
25
|
+
expect(a_request(:get, /.*subdomain\.schoolloop\.com\/api\/roster/)).to have_been_made.once
|
26
|
+
|
27
|
+
expect(response.status).to eq 200
|
28
|
+
expect(response.body).to be_a Nokogiri::XML::Document
|
29
|
+
expect(response.body.xpath("//root/roster/teachers/teacher")[0].attr("name")).to eq "Reynolds, Mr. Malcom"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "for a specific teacher" do
|
33
|
+
response = client.get_roster("12345")
|
34
|
+
expect(a_request(:get, /.*subdomain\.schoolloop\.com\/api\/roster/).with(query: {teacher_id: "12345"})).to have_been_made.once
|
35
|
+
|
36
|
+
expect(response.status).to eq 200
|
37
|
+
expect(response.body).to be_a Nokogiri::XML::Document
|
38
|
+
expect(response.body.xpath("//root/roster/teachers/teacher")[0].attr("name")).to eq "Reynolds, Mr. Malcom"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
File without changes
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe SchoolLoop do
|
4
|
+
|
5
|
+
describe ".new" do
|
6
|
+
|
7
|
+
it "allows an instance to override the global configuration" do
|
8
|
+
SchoolLoop.configure do |config|
|
9
|
+
config.username = "test2"
|
10
|
+
config.password = "setting2"
|
11
|
+
end
|
12
|
+
|
13
|
+
client = SchoolLoop.new
|
14
|
+
|
15
|
+
expect(client.username).to eq "test2"
|
16
|
+
expect(client.password).to eq "setting2"
|
17
|
+
|
18
|
+
client2 = SchoolLoop.new(username: "test3", password: "setting3")
|
19
|
+
expect(client2.username).to eq "test3"
|
20
|
+
expect(client2.password).to eq "setting3"
|
21
|
+
|
22
|
+
expect(client.username).to eq "test2"
|
23
|
+
expect(client.password).to eq "setting2"
|
24
|
+
|
25
|
+
client3 = SchoolLoop.new(username: "test4")
|
26
|
+
expect(client3.username).to eq "test4"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "does not modify the global configuration" do
|
30
|
+
SchoolLoop.configure do |config|
|
31
|
+
config.username = "testg"
|
32
|
+
config.password = "passg"
|
33
|
+
end
|
34
|
+
|
35
|
+
client = SchoolLoop.new(username: "gtest", password: "gpass")
|
36
|
+
|
37
|
+
expect(client.username).to eq "gtest"
|
38
|
+
expect(client.password).to eq "gpass"
|
39
|
+
|
40
|
+
expect(SchoolLoop.options[:username]).to eq "testg"
|
41
|
+
expect(SchoolLoop.options[:password]).to eq "passg"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
describe ".method_missing" do
|
47
|
+
let(:client_dbl) { double(SchoolLoop::Client) }
|
48
|
+
|
49
|
+
before do
|
50
|
+
allow(SchoolLoop).to receive(:new).and_return(client_dbl)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "creates an instance and calls the method" do
|
54
|
+
expect(client_dbl).to receive(:get_roster).with("1234").and_return(true)
|
55
|
+
expect(SchoolLoop.get_roster("1234")).to be_truthy
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe ".respond_to?" do
|
60
|
+
it { expect(SchoolLoop).to respond_to(:get_roster) }
|
61
|
+
it { expect(SchoolLoop).to respond_to(:publish_progress_report) }
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
metadata
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: school_loop
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mitch Dempsey
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-09-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.9'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: faraday_middleware
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.9'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.9'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: nokogiri
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.5.2
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.5.2
|
69
|
+
description: Client for School Loop API (OpenLoop)
|
70
|
+
email:
|
71
|
+
- mitch@mitchdempsey.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- ".ruby-version"
|
79
|
+
- ".travis.yml"
|
80
|
+
- Gemfile
|
81
|
+
- Gemfile.lock
|
82
|
+
- LICENSE
|
83
|
+
- README.md
|
84
|
+
- Rakefile
|
85
|
+
- lib/school_loop.rb
|
86
|
+
- lib/school_loop/client.rb
|
87
|
+
- lib/school_loop/configuration.rb
|
88
|
+
- lib/school_loop/connection.rb
|
89
|
+
- lib/school_loop/error.rb
|
90
|
+
- lib/school_loop/error/bad_request.rb
|
91
|
+
- lib/school_loop/error/service_error.rb
|
92
|
+
- lib/school_loop/error/unauthorized.rb
|
93
|
+
- lib/school_loop/resources.rb
|
94
|
+
- lib/school_loop/resources/progress_reports.rb
|
95
|
+
- lib/school_loop/resources/roster.rb
|
96
|
+
- lib/school_loop/response.rb
|
97
|
+
- lib/school_loop/response/raise_error.rb
|
98
|
+
- lib/school_loop/response/xmlize.rb
|
99
|
+
- lib/school_loop/version.rb
|
100
|
+
- school_loop.gemspec
|
101
|
+
- spec/fixtures/progress_report_submission.xml
|
102
|
+
- spec/fixtures/roster_response.xml
|
103
|
+
- spec/helper.rb
|
104
|
+
- spec/school_loop/client_spec.rb
|
105
|
+
- spec/school_loop/configuration_spec.rb
|
106
|
+
- spec/school_loop/resources/progress_reports_spec.rb
|
107
|
+
- spec/school_loop/resources/roster_spec.rb
|
108
|
+
- spec/school_loop/response/xmlize_spec.rb
|
109
|
+
- spec/school_loop_spec.rb
|
110
|
+
homepage: https://github.com/webdestroya/school_loop
|
111
|
+
licenses:
|
112
|
+
- MIT
|
113
|
+
metadata: {}
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubyforge_project:
|
130
|
+
rubygems_version: 2.4.5
|
131
|
+
signing_key:
|
132
|
+
specification_version: 4
|
133
|
+
summary: Client for School Loop API (OpenLoop)
|
134
|
+
test_files:
|
135
|
+
- spec/fixtures/progress_report_submission.xml
|
136
|
+
- spec/fixtures/roster_response.xml
|
137
|
+
- spec/helper.rb
|
138
|
+
- spec/school_loop/client_spec.rb
|
139
|
+
- spec/school_loop/configuration_spec.rb
|
140
|
+
- spec/school_loop/resources/progress_reports_spec.rb
|
141
|
+
- spec/school_loop/resources/roster_spec.rb
|
142
|
+
- spec/school_loop/response/xmlize_spec.rb
|
143
|
+
- spec/school_loop_spec.rb
|