lexile 0.0.5 → 0.0.6
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.
- checksums.yaml +4 -4
- data/Gemfile +0 -11
- data/README.md +41 -17
- data/bin/console +20 -0
- data/lexile.gemspec +8 -0
- data/lib/lexile.rb +3 -0
- data/lib/lexile/api/books.rb +5 -4
- data/lib/lexile/api/client.rb +5 -4
- data/lib/lexile/api/page.rb +74 -0
- data/lib/lexile/api/page_list.rb +44 -0
- data/lib/lexile/api/result_list.rb +31 -0
- data/lib/lexile/book.rb +1 -1
- data/lib/lexile/configuration.rb +9 -5
- data/lib/lexile/model.rb +1 -2
- data/lib/lexile/version.rb +1 -1
- data/spec/lexile/api/books_spec.rb +16 -16
- data/spec/lexile/configuration_spec.rb +2 -2
- data/spec/lexile/model_spec.rb +3 -3
- data/spec/spec_helper.rb +5 -9
- data/spec/vcr_tapes/books.yml +543 -172
- data/spec/vcr_tapes/errors.yml +25 -339
- metadata +98 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6fb1bf0a8ef1cde0481ba7c7f71b612705ee2ba1
|
4
|
+
data.tar.gz: 14b12295e34c5dbfc326e98fb403c3bdce1e979e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14f9461ddfb86c80d6568ed4e044d5315772b7bb58e79782b6617fe4739db8846dec8aadbb886c8890698a78b96959bba6a54eac82ac6a05e0759948766c6d36
|
7
|
+
data.tar.gz: 0718ec372bf2e13c02c2e74f624ec258b9bea2de351d4d154a500bf52144cee10fb256bb97b8707e50e68f08b177c988b9882300b610eb5814b07f2ba50609f2
|
data/Gemfile
CHANGED
@@ -3,15 +3,4 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in lexile.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
gem 'httparty', '~> 0.10'
|
7
|
-
gem 'hashie'
|
8
|
-
|
9
|
-
group :development, :test do
|
10
|
-
gem 'rspec', '~> 2'
|
11
|
-
gem 'webmock'
|
12
|
-
gem 'vcr', '~> 2.8'
|
13
|
-
gem 'jeweler'
|
14
|
-
gem 'factory_girl'
|
15
|
-
end
|
16
|
-
|
17
6
|
gem "codeclimate-test-reporter", group: :test, require: nil
|
data/README.md
CHANGED
@@ -8,15 +8,18 @@
|
|
8
8
|
This gem wraps a portion of the Lexile database API. You need to obtain an
|
9
9
|
authorized username and password from Lexile to use the API. This gem is not
|
10
10
|
meant to be a comprenhensive implementation of the API just a bare bones
|
11
|
-
"Find the Lexile for a Specific Book" solution.
|
11
|
+
"Find the Lexile for a Specific Book or Update your Lexile DB" solution.
|
12
12
|
|
13
|
-
The gem only covers the
|
13
|
+
The gem only covers the endpoint to the `book` resource, the `category` and
|
14
14
|
`serial` resources are beyond the scope of this gem . If you need access
|
15
15
|
to these resources feel free to submit a PR with code and specs.
|
16
16
|
|
17
|
-
The gem
|
18
|
-
the
|
19
|
-
|
17
|
+
The gem now supports pagination for long result-sets using the `next` and `previous` links
|
18
|
+
of the `meta` element of the response. Pagination is implemented as an Enumerable and it is
|
19
|
+
transparent when you traverse the enumerable with each, select, map, etc.... ( `count` will
|
20
|
+
paginate the whole collection, a more efficient implementation using the `total_count` from
|
21
|
+
the `meta` is left as practice for the reader)
|
22
|
+
|
20
23
|
|
21
24
|
## Installation
|
22
25
|
|
@@ -39,7 +42,8 @@ Or install it yourself as:
|
|
39
42
|
end
|
40
43
|
|
41
44
|
## Usage
|
42
|
-
|
45
|
+
```
|
46
|
+
# FIND BY LEXILE ID
|
43
47
|
>> b = Lexile.books.show("315833")
|
44
48
|
#<Lexile::Book id= "315833" ISBN="006201272X" ISBN13="9780062012722" ... >
|
45
49
|
|
@@ -47,24 +51,44 @@ Or install it yourself as:
|
|
47
51
|
"It Happened to Nancy: By An Anonymous Teenager: A True Story from Her Diary"
|
48
52
|
|
49
53
|
|
50
|
-
|
51
|
-
>> b = Lexile.books.find_by_isbn13("9780062012722")
|
54
|
+
# FIND BY ISBN13
|
55
|
+
>> b = Lexile.books.find_by_isbn13("9780062012722").first
|
52
56
|
[#<Lexile::Book ISBN="006201272X" ISBN13="9780062012722" ... >]
|
53
57
|
|
54
58
|
>> b[0].title
|
55
59
|
"It Happened to Nancy: By An Anonymous Teenager: A True Story from Her Diary"
|
56
60
|
|
57
61
|
|
58
|
-
|
59
|
-
>>
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
# FIND BY TITLE
|
63
|
+
>> books = Lexile.books.find_by_title("to Nancy")
|
64
|
+
books.count
|
65
|
+
>> 2
|
66
|
+
|
67
|
+
books.each do |b|
|
68
|
+
puts b.ISBN13
|
69
|
+
end
|
70
|
+
>> 9780380773152
|
71
|
+
>> 9780062012722
|
72
|
+
|
73
|
+
>> books.first.title
|
66
74
|
"It Happened to Nancy: By An Anonymous Teenager: A True Story from Her Diary"
|
67
75
|
|
76
|
+
# GET LATEST UPDATES TO DB ( supports paging )
|
77
|
+
books = Lexile.books.find( timestamp__gte: '2015-08-04', limit:100 )
|
78
|
+
# will load pages of 100 elements at a time until there are no further pages
|
79
|
+
books.each do |b|
|
80
|
+
....
|
81
|
+
end
|
82
|
+
|
83
|
+
books.first
|
84
|
+
>>[#<Lexile::Book ISBN="006201272X" ISBN13="9780062012722" ... >]
|
85
|
+
|
86
|
+
books.fist(20).last
|
87
|
+
>>[#<Lexile::Book ISBN="00620XXX" ISBN13="9780063013733" ... >]
|
88
|
+
|
89
|
+
books.count
|
90
|
+
>>107 #will paginate through the whole collection
|
91
|
+
```
|
68
92
|
|
69
93
|
## Contributing
|
70
94
|
|
@@ -78,7 +102,7 @@ Or install it yourself as:
|
|
78
102
|
|
79
103
|
The MIT License (MIT)
|
80
104
|
|
81
|
-
Copyright (c)
|
105
|
+
Copyright (c) 2015 Curriculet Inc
|
82
106
|
|
83
107
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
84
108
|
of this software and associated documentation files (the "Software"), to deal
|
data/bin/console
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "lexile"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
Lexile.configure do |config|
|
14
|
+
config.username = ENV['LEXILE_USERNAME']
|
15
|
+
config.password = ENV['LEXILE_PASSWORD']
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
require "irb"
|
20
|
+
IRB.start
|
data/lexile.gemspec
CHANGED
@@ -22,4 +22,12 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.add_runtime_dependency "httparty", "~> 0.10"
|
24
24
|
spec.add_runtime_dependency "hashie"
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", ">= 1.3.0","< 2.0"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
spec.add_development_dependency "rspec", "~> 2"
|
29
|
+
spec.add_development_dependency "webmock"
|
30
|
+
spec.add_development_dependency "vcr", "~> 2.8"
|
31
|
+
spec.add_development_dependency "jeweler"
|
32
|
+
|
25
33
|
end
|
data/lib/lexile.rb
CHANGED
@@ -15,6 +15,9 @@ require 'lexile/book'
|
|
15
15
|
require 'lexile/api/resource'
|
16
16
|
require 'lexile/api/books'
|
17
17
|
require 'lexile/api/endpoints'
|
18
|
+
require 'lexile/api/page'
|
19
|
+
require 'lexile/api/page_list'
|
20
|
+
require 'lexile/api/result_list'
|
18
21
|
|
19
22
|
module Lexile
|
20
23
|
extend Configuration
|
data/lib/lexile/api/books.rb
CHANGED
@@ -4,13 +4,14 @@ module Lexile
|
|
4
4
|
api_model Lexile::Book
|
5
5
|
|
6
6
|
def show id
|
7
|
-
|
8
|
-
api_model.parse(
|
7
|
+
response_json = @client.get( "#{Lexile.api_version}/#{ api_model.api_path }/#{id}" )
|
8
|
+
api_model.parse( response_json )
|
9
9
|
end
|
10
10
|
|
11
11
|
def find( query_params )
|
12
|
-
|
13
|
-
|
12
|
+
Lexile::Api::PageList.new( @client, api_model, query_params ).to_results_list
|
13
|
+
#response_json = @client.get( "#{ api_model.api_path }", query_params )
|
14
|
+
#api_model.parse( response_json )
|
14
15
|
end
|
15
16
|
|
16
17
|
def find_by_isbn13 isbn13
|
data/lib/lexile/api/client.rb
CHANGED
@@ -52,12 +52,13 @@ module Lexile
|
|
52
52
|
|
53
53
|
yield get_args if block_given?
|
54
54
|
|
55
|
-
|
55
|
+
puts "CALLING API: #{Lexile.api_url}#{path} ===#{get_args}"
|
56
56
|
response = self.class.get( path, get_args)
|
57
57
|
|
58
58
|
case response.code
|
59
59
|
when 200..201
|
60
60
|
response
|
61
|
+
JSON.parse( response.body )
|
61
62
|
when 400
|
62
63
|
raise Lexile::BadRequest.new(response, params)
|
63
64
|
when 401
|
@@ -84,12 +85,12 @@ module Lexile
|
|
84
85
|
# @return [Hash] The properly formated get_options.
|
85
86
|
def build_get_args( params={}, user_headers={})
|
86
87
|
get_args = {}
|
87
|
-
query ={
|
88
|
+
query ={} #all requests get these query params
|
88
89
|
|
89
90
|
query.merge!(params)
|
90
91
|
|
91
|
-
|
92
|
-
headers ={}
|
92
|
+
|
93
|
+
headers ={ 'Accept' => 'application/json'} #all requests get these headers
|
93
94
|
headers.merge!( user_headers )
|
94
95
|
|
95
96
|
get_args[:query] = query
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Lexile
|
2
|
+
module Api
|
3
|
+
# Represents a page of data
|
4
|
+
class Page
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
# Request a page of data and store the results in this instance
|
8
|
+
# @api private
|
9
|
+
# @return [Lexile::Api::Page]
|
10
|
+
# @example
|
11
|
+
# page = Page.new '/v2.1/book'
|
12
|
+
def initialize(client, api_model, uri, query_params = {})
|
13
|
+
@client = client
|
14
|
+
@api_model = api_model
|
15
|
+
@uri = uri
|
16
|
+
@query_params = query_params
|
17
|
+
|
18
|
+
response_json = @client.get( uri, @query_params )
|
19
|
+
@all = api_model.parse(response_json)
|
20
|
+
|
21
|
+
raise Lexile::CannotProcessResponse.new('[:meta] is not present in response') unless response_json.has_key?('meta')
|
22
|
+
|
23
|
+
@limit = response_json['meta']['limit']
|
24
|
+
@next = response_json['meta']['next']
|
25
|
+
#puts "NEXT URI IS ==>#{@next}<=="
|
26
|
+
@offset = response_json['meta']['offset']
|
27
|
+
@previous = response_json['meta']['previous']
|
28
|
+
@total_count = response_json['meta']['total_count']
|
29
|
+
end
|
30
|
+
|
31
|
+
# Gets next page if one is present, nil otherwise
|
32
|
+
# @api private
|
33
|
+
# @return [Lexile::Api::Page, nil] Next page, or nil if last
|
34
|
+
# @example
|
35
|
+
# next_page = page.next
|
36
|
+
# unless next_page.nil?
|
37
|
+
# next_page.each do |elem| puts elem; end
|
38
|
+
def next
|
39
|
+
return nil if @next.nil?
|
40
|
+
Page.new( @client, @api_model, @next, {} )
|
41
|
+
end
|
42
|
+
|
43
|
+
# Iterate over all elements in the page
|
44
|
+
# @api private
|
45
|
+
# @return [Array] List of all elements
|
46
|
+
# @example
|
47
|
+
# page.each { |elem| puts elem }
|
48
|
+
def each(&blk)
|
49
|
+
@all.each(&blk)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Get all elements in page
|
53
|
+
# @api private
|
54
|
+
# @return [Array] List of all elements
|
55
|
+
# @example
|
56
|
+
# all_elems = page.all
|
57
|
+
attr_reader :all
|
58
|
+
|
59
|
+
# Retrieve the last element or n elements in the resource
|
60
|
+
# @api public
|
61
|
+
# @param num [nil, Integer] If nil, last elem; else, num elems to fetch
|
62
|
+
# @return [Lexile::Model, Lexile::Api::Page] elem, or
|
63
|
+
# elems found. If list, sorted in ascending order of ids.
|
64
|
+
# @example
|
65
|
+
# books = Lexile.books.first(20)
|
66
|
+
# last_elem = books.last
|
67
|
+
# last_elems = books.last 5
|
68
|
+
def last(num = nil)
|
69
|
+
return @all.last num if num
|
70
|
+
@all.last
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Lexile
|
2
|
+
module Api
|
3
|
+
# Handles paginated requests.
|
4
|
+
class PageList
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
# Create a new PageList, without making any requests immediately
|
8
|
+
# @api private
|
9
|
+
# @return [PageList]
|
10
|
+
def initialize(client, api_model, query_params = {})
|
11
|
+
@client = client
|
12
|
+
@api_model = api_model
|
13
|
+
@uri = "#{Lexile.api_version}/#{api_model.api_path}"
|
14
|
+
@query_params = query_params
|
15
|
+
end
|
16
|
+
|
17
|
+
# Iterate through each page, making requests as you iterate
|
18
|
+
# @api private
|
19
|
+
# @return [nil]
|
20
|
+
# @example
|
21
|
+
# pagelist.each do |page|
|
22
|
+
# page.each do |elem|
|
23
|
+
# puts elem
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
def each
|
27
|
+
page = Page.new( @client, @api_model, @uri, @query_params )
|
28
|
+
until page.nil?
|
29
|
+
yield page
|
30
|
+
page = page.next
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Convert PageList into a ResultsList for easier iteration
|
35
|
+
# @api private
|
36
|
+
# @return [Lexile::Api::ResultsList]
|
37
|
+
# @example
|
38
|
+
# pagelist.to_results_list.each { |elem| puts elem }
|
39
|
+
def to_results_list
|
40
|
+
Lexile::Api::ResultsList.new( self )
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Lexile
|
2
|
+
module Api
|
3
|
+
# Represents a list of results for a paged request.
|
4
|
+
class ResultsList
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
# Create a results list from a PageList
|
8
|
+
# @api private
|
9
|
+
# @return [ResultsList]
|
10
|
+
def initialize( page_list )
|
11
|
+
@pages = page_list
|
12
|
+
end
|
13
|
+
|
14
|
+
# Iterate over results list
|
15
|
+
# @api public
|
16
|
+
# @return [nil]
|
17
|
+
# @example
|
18
|
+
# results = Lexile::Book.find # returns a ResultsList
|
19
|
+
# results.each do |book|
|
20
|
+
# puts district.title
|
21
|
+
# end
|
22
|
+
def each
|
23
|
+
@pages.each do |page|
|
24
|
+
page.each do |elem|
|
25
|
+
yield elem
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/lexile/book.rb
CHANGED
data/lib/lexile/configuration.rb
CHANGED
@@ -6,8 +6,8 @@ module Lexile
|
|
6
6
|
#@!visibility private
|
7
7
|
VALID_CONFIG_KEYS = VALID_CONNECTION_KEYS + VALID_OPTIONS_KEYS
|
8
8
|
|
9
|
-
DEFAULT_ENDPOINT = 'https://fabapi.lexile.com
|
10
|
-
DEFAULT_API_VERSION = 'v2'
|
9
|
+
DEFAULT_ENDPOINT = 'https://fabapi.lexile.com'
|
10
|
+
DEFAULT_API_VERSION = '/api/fab/v2.1'
|
11
11
|
DEFAULT_USER_AGENT = 'Lexile API Ruby Gem by Curriculet'.freeze
|
12
12
|
DEFAULT_TIMEOUT = nil
|
13
13
|
DEFAULT_TESTING = false
|
@@ -45,15 +45,19 @@ module Lexile
|
|
45
45
|
# Interpolate the base url for all calls
|
46
46
|
# return [String] the base url for all api calls
|
47
47
|
def api_url( path = nil)
|
48
|
-
[endpoint,
|
48
|
+
[endpoint,path].compact.join('/')
|
49
|
+
end
|
50
|
+
|
51
|
+
def config
|
52
|
+
self
|
49
53
|
end
|
50
54
|
|
51
55
|
# Yields itself for use in the configuration block
|
52
56
|
# @example
|
53
57
|
# Lexile.configure do |c|
|
54
58
|
# c.api_key = <MY-API-KEY>
|
55
|
-
# c.api_verion = 'v2'
|
56
|
-
# c.endpoint = 'https://fabapi.lexile.com
|
59
|
+
# c.api_verion = '/api/fab/v2'
|
60
|
+
# c.endpoint = 'https://fabapi.lexile.com'
|
57
61
|
# c.timeout = '10' #seconds
|
58
62
|
# c.testing = true
|
59
63
|
# end
|
data/lib/lexile/model.rb
CHANGED
@@ -84,8 +84,7 @@ module Lexile
|
|
84
84
|
|
85
85
|
# Parses a request.body response into a Lexile::Model objects
|
86
86
|
#
|
87
|
-
def parse(
|
88
|
-
parsed_json = String === raw_json ? JSON.parse(raw_json) : json
|
87
|
+
def parse( parsed_json )
|
89
88
|
if parsed_json.has_key?('objects')
|
90
89
|
#this is a multi record and data should contain an array
|
91
90
|
unless parsed_json['objects'].is_a? Array
|
data/lib/lexile/version.rb
CHANGED
@@ -40,12 +40,12 @@ describe Lexile::Api::Books, :vcr => { :cassette_name => "books" } do
|
|
40
40
|
expect(books).to_not be_nil
|
41
41
|
end
|
42
42
|
|
43
|
-
it 'should be array' do
|
44
|
-
expect(books).to be_an_instance_of( Array )
|
43
|
+
it 'first(10) should be array' do
|
44
|
+
expect(books.first(10)).to be_an_instance_of( Array )
|
45
45
|
end
|
46
46
|
|
47
|
-
it '
|
48
|
-
expect(books.
|
47
|
+
it 'count should be > 0' do
|
48
|
+
expect(books.count).to_not be_zero
|
49
49
|
end
|
50
50
|
|
51
51
|
it 'should be array of Lexile::Book' do
|
@@ -55,19 +55,19 @@ describe Lexile::Api::Books, :vcr => { :cassette_name => "books" } do
|
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'should have id key' do
|
58
|
-
expect(books
|
58
|
+
expect(books.first).to respond_to(:id)
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'should have lexile key' do
|
62
|
-
expect(books
|
62
|
+
expect(books.first).to respond_to(:lexile)
|
63
63
|
end
|
64
64
|
|
65
65
|
it 'should have lexile_display key' do
|
66
|
-
expect(books[0]).to respond_to(:lexile_display)
|
66
|
+
expect(books.first(5)[0]).to respond_to(:lexile_display)
|
67
67
|
end
|
68
68
|
|
69
69
|
it 'should have pages key' do
|
70
|
-
expect(books
|
70
|
+
expect(books.first).to respond_to(:pages)
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
@@ -78,12 +78,12 @@ describe Lexile::Api::Books, :vcr => { :cassette_name => "books" } do
|
|
78
78
|
expect(books).to_not be_nil
|
79
79
|
end
|
80
80
|
|
81
|
-
it 'should
|
82
|
-
expect(books).to be_an_instance_of( Array )
|
81
|
+
it 'first(10) should return array' do
|
82
|
+
expect(books.first(10) ).to be_an_instance_of( Array )
|
83
83
|
end
|
84
84
|
|
85
|
-
it '
|
86
|
-
expect(books.
|
85
|
+
it 'count should be > 0' do
|
86
|
+
expect(books.count).to_not be_zero
|
87
87
|
end
|
88
88
|
|
89
89
|
it 'should be array of Lexile::Book' do
|
@@ -93,19 +93,19 @@ describe Lexile::Api::Books, :vcr => { :cassette_name => "books" } do
|
|
93
93
|
end
|
94
94
|
|
95
95
|
it 'should have id key' do
|
96
|
-
expect(books
|
96
|
+
expect(books.first).to respond_to(:id)
|
97
97
|
end
|
98
98
|
|
99
99
|
it 'should have lexile key' do
|
100
|
-
expect(books
|
100
|
+
expect(books.first).to respond_to(:lexile)
|
101
101
|
end
|
102
102
|
|
103
103
|
it 'should have lexile_display key' do
|
104
|
-
expect(books
|
104
|
+
expect(books.first).to respond_to(:lexile_display)
|
105
105
|
end
|
106
106
|
|
107
107
|
it 'should have pages key' do
|
108
|
-
expect(books
|
108
|
+
expect(books.first).to respond_to(:pages)
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|