lexile 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3b3572b7bf5426c44e0887f4c77425129a96fd3d
4
+ data.tar.gz: e7e3897e33a3c90d8d83bd63e3c5b04b7d11430a
5
+ SHA512:
6
+ metadata.gz: 9d503217391a94ffe678eb940d0037557c32a5f9faf194f018c3f1065009ea61ffb266422f5bafa612894106ec24d968db3798852f3b23ef10b345d3cb7eacf3
7
+ data.tar.gz: b0aea8b1285bf7c94cca0fc3431e32d6e36bc2bac1be29489c9bab0ac833db4aa810550d30c239f6111a1a635553f033fa6d4ea8a3554ea28ae8c96d571b00f5
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea/
data/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ language: ruby
2
+ cache: bundler
3
+
4
+ rvm:
5
+ - 2.1.2
6
+
7
+ script: 'CODECLIMATE_REPO_TOKEN=cd173d6c860a8493b813ea4ed982824b180b0c50604e3a27c3a3c83e94868d71 bundle exec rake'
8
+
9
+ notifications:
10
+ email:
11
+ recipients:
12
+ - mauricio@curriculet.com
13
+ on_failure: change
14
+ on_success: never
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in lexile.gemspec
4
+ gemspec
5
+
6
+ gem 'httparty', '~> 0.10'
7
+ gem 'hashie', '~> 2.0'
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
+ gem "codeclimate-test-reporter", group: :test, require: nil
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+
2
+ The MIT License (MIT)
3
+
4
+ Copyright (c) 2014 Curriculet Inc
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,93 @@
1
+ [![Build Status](https://travis-ci.org/curriculet/lexile.svg?branch=master)](https://travis-ci.org/Curriculet/Lexile)
2
+ [![Code Climate](https://codeclimate.com/github/curriculet/lexile/badges/gpa.svg)](https://codeclimate.com/github/curriculet/lexile)
3
+ [![Test Coverage](https://codeclimate.com/github/curriculet/lexile/badges/coverage.svg)](https://codeclimate.com/github/curriculet/lexile)
4
+ [![GitHub version](https://badge.fury.io/gh/curriculet%2Flexile.svg)](http://badge.fury.io/gh/curriculet%2Flexile)
5
+
6
+ # Lexile®
7
+
8
+ This gem wraps a portion of the Lexile database API. You need to obtain an
9
+ authorized username and password from Lexile to use the API. This gem is not
10
+ meant to be a comprenhensive implementation of the API just a bare bones
11
+ "Find the Lexile for a Specific Book" solution.
12
+
13
+ The gem only covers the endpoints to the `book` resource, the `category` and
14
+ `serial` resources are beyond the scope of this gem . If you need access
15
+ to these resources feel free to submit a PR with code and specs.
16
+
17
+ The gem does not support pagination for result-sets longer than 20 books, while
18
+ the API contains all provisions for pagination, it is beyond the scope of the
19
+ gem to expose those.
20
+
21
+ ## Installation
22
+
23
+ Add this line to your application's Gemfile:
24
+
25
+ gem 'lexile'
26
+
27
+ And then execute:
28
+
29
+ $ bundle install
30
+
31
+ Or install it yourself as:
32
+
33
+ $ gem install lexile
34
+
35
+ ## Usage
36
+
37
+ >> b = Lexile.books.show("315833")
38
+ #<Lexile::Book id= "315833" ISBN="006201272X" ISBN13="9780062012722" ... >
39
+
40
+ >> b.title
41
+ "It Happened to Nancy: By An Anonymous Teenager: A True Story from Her Diary"
42
+
43
+
44
+
45
+ >> b = Lexile.books.find_by_isbn13("9780062012722")
46
+ [#<Lexile::Book ISBN="006201272X" ISBN13="9780062012722" ... >]
47
+
48
+ >> b[0].title
49
+ "It Happened to Nancy: By An Anonymous Teenager: A True Story from Her Diary"
50
+
51
+
52
+
53
+ >> b = Lexile.books.find_by_title("to Nancy")
54
+ [#<Lexile::Book ISBN="0380773155" ISBN13="9780380773152" ... >, #<Lexile::Book ISBN="006201272X" ISBN13="9780062012722" ... >]
55
+
56
+ >> b.length
57
+ 2
58
+
59
+ >> b[0].title
60
+ "It Happened to Nancy: By An Anonymous Teenager: A True Story from Her Diary"
61
+
62
+
63
+ ## Contributing
64
+
65
+ 1. Fork it ( http://github.com/<my-github-username>/lexile/fork )
66
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
67
+ 3. Commit your changes and specs(`git commit -am 'Add some feature'`)
68
+ 4. Push to the branch (`git push origin my-new-feature`)
69
+ 5. Create new Pull Request
70
+
71
+ ## License
72
+
73
+ The MIT License (MIT)
74
+
75
+ Copyright (c) 2014 Curriculet Inc
76
+
77
+ Permission is hereby granted, free of charge, to any person obtaining a copy
78
+ of this software and associated documentation files (the "Software"), to deal
79
+ in the Software without restriction, including without limitation the rights
80
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
81
+ copies of the Software, and to permit persons to whom the Software is
82
+ furnished to do so, subject to the following conditions:
83
+
84
+ The above copyright notice and this permission notice shall be included in
85
+ all copies or substantial portions of the Software.
86
+
87
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
88
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
89
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
90
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
91
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
92
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
93
+ THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ require "rubygems/package_task"
2
+ require "bundler/gem_tasks"
3
+ require 'rspec/core'
4
+ require 'rspec/core/rake_task'
5
+
6
+ gem_spec = eval(File.read("./lexile.gemspec")) rescue nil
7
+ Gem::PackageTask.new(gem_spec) do |pkg|
8
+ pkg.need_zip = false
9
+ pkg.need_tar = false
10
+ end
11
+
12
+ RSpec::Core::RakeTask.new(:spec) do |spec|
13
+ spec.pattern = FileList['spec/**/*_spec.rb']
14
+ end
15
+
16
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
17
+ spec.pattern = 'spec/**/*_spec.rb'
18
+ spec.rcov = true
19
+ end
20
+
21
+ task :default => :spec
22
+
23
+ begin
24
+ require 'yard'
25
+ YARD::Rake::YardocTask.new
26
+ rescue LoadError
27
+ task :yardoc do
28
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
29
+ end
30
+ end
data/lexile.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'lexile/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "lexile"
8
+ spec.version = Lexile::VERSION
9
+
10
+ spec.authors = ["Mauricio Alvarez"]
11
+ spec.email = ["mauricio@curriculet.com"]
12
+ spec.date = "2014-10-25"
13
+ spec.description = "A gem for the Lexile® database API "
14
+ spec.summary = "A gem to find a book's Lexile DB entry by name or ISBN13"
15
+ spec.homepage = "https://github.com/curriculet/lexile"
16
+ spec.license = "MIT"
17
+
18
+ spec.files = `git ls-files -z`.split("\x0")
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_runtime_dependency "httparty", "~> 0.10"
24
+ spec.add_runtime_dependency "hashie", "~> 2.0.0"
25
+ end
@@ -0,0 +1,26 @@
1
+ module Lexile
2
+ module Api
3
+ class Books < Resource
4
+ api_model Lexile::Book
5
+
6
+ def show id
7
+ response = @client.get( "#{ api_model.api_path }/#{id}" )
8
+ api_model.parse(response.body)
9
+ end
10
+
11
+ def find( query_params )
12
+ response = @client.get( "#{ api_model.api_path }", query_params )
13
+ api_model.parse(response.body)
14
+ end
15
+
16
+ def find_by_isbn13 isbn13
17
+ self.find( {"ISBN13" => isbn13 })
18
+ end
19
+
20
+ def find_by_title title
21
+ self.find( {"title__contains" => title } )
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,105 @@
1
+ module Lexile
2
+ module API
3
+ class Client
4
+ include HTTParty
5
+
6
+ # initialize
7
+ #
8
+ # The Lexile Api Client can be configured via Lexile.configure block
9
+ # or via a hash with the appropriate values set
10
+ #
11
+ # endpoint: required. The API endpoing i.e https://api.lexile.com
12
+ # api_version: required. The API version (v1 or V1.1)
13
+ # username: required. Your lexile username
14
+ # password: required. Your lexile password
15
+ # timeout: optional. The HTTP timeout
16
+ # testing: optional. Set it to true to activate debugging output
17
+ #
18
+ # @param configuration [Lexile Hash] A hash or Lexile::Configuration that contains the parameters to
19
+ # be used when issuing HTTP Calls
20
+ def initialize( configuration )
21
+
22
+ if configuration.is_a?(Module) && configuration.to_s == 'Lexile'
23
+ config = configuration
24
+ elsif configuration.is_a?(Hash)
25
+ config = Hashie::Mash.new( configuration )
26
+ config.api_url = [config.endpoint,config.api_version].join('/')
27
+ end
28
+
29
+ #if config.api_key
30
+ #self.class.default_params({ 'api_key' => config.api_key})
31
+ #else
32
+ #raise Lexile::InvalidCredentials.new("Api Key is not present but it is required.")
33
+ #end
34
+
35
+ self.class.base_uri( config.api_url ) if config.api_url
36
+ self.class.default_timeout config.timeout.to_f if config.timeout
37
+ self.class.debug_output if config.testing
38
+ self.class.headers({'User-Agent' => config.user_agent}) if config.user_agent
39
+ end
40
+
41
+ # get
42
+ # send an HTTPS Get request against Edelement's API.
43
+ # Yields the get_options before sending making the request.
44
+ #
45
+ #
46
+ # @param path [String] The path for the api endpoint (with leading slash)
47
+ # @param params [Hash] A hash of query arguments for the request (optional)
48
+ # @param headers [Hash] A hash of header fields (optional).
49
+ #
50
+ #
51
+ # @return [String]. The raw response body (JSON is expected) Raises appropriate exception if it fails
52
+ # @raise Lexile::HTTPError when any HTTP error response is received
53
+ def get( path, params={}, headers={})
54
+ get_options = build_get_options( params, headers)
55
+ yield get_options if block_given?
56
+
57
+ #puts "CALLING API: #{Lexile.api_url}#{path} ===#{get_options}"
58
+ response = self.class.get( path, get_options)
59
+
60
+ case response.code
61
+ when 200..201
62
+ response
63
+ when 400
64
+ raise Lexile::BadRequest.new(response, params)
65
+ when 401
66
+ raise Lexile::AuthenticationFailed.new(response, params)
67
+ when 404
68
+ raise Lexile::NotFound.new(response, params)
69
+ when 500
70
+ raise Lexile::ServerError.new(response, params)
71
+ when 502
72
+ raise Lexile::Unavailable.new(response, params)
73
+ when 503, 504
74
+ raise Lexile::RateLimited.new(response, params)
75
+ else
76
+ raise Lexile::UnknownStatusCode.new(response, params)
77
+ end
78
+ end
79
+
80
+ # build_get_options
81
+ # Build the hash of options for an HTTP get request.
82
+ #
83
+ # @param params [Hash] optional. Any query parameters to add to the request.
84
+ # @param user_headers [Hash] optional. Any query parameters to add to the request.
85
+ #
86
+ # @return [Hash] The properly formated get_options.
87
+ def build_get_options( params={}, user_headers={})
88
+ get_options = {}
89
+ query ={ format: 'json'} #all requests get this query params
90
+
91
+ query.merge!(params)
92
+
93
+ # pass any headers
94
+ headers ={}
95
+ headers.merge!( user_headers )
96
+
97
+ get_options[:query] = query
98
+ get_options[:headers] = headers
99
+ get_options[:basic_auth] = { username: Lexile.options[:username],
100
+ password: Lexile.options[:password]}
101
+ get_options
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,20 @@
1
+ module Lexile
2
+ module Api
3
+ module Endpoints
4
+
5
+
6
+ # books
7
+ #
8
+ # @example
9
+ # Lexile.books.find(title: or isbn: ) returns the details of book
10
+ #
11
+ # @return [Lexile::Api::Books] A properly initialized books api client ready for calls
12
+
13
+
14
+ def books
15
+ @books ||= Lexile::Api::Books.new( client )
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ module Lexile
2
+ module Api
3
+ class Resource
4
+ class << self
5
+ #api_model
6
+ #
7
+ # It tells the parser which Lexile::Model to use when parsing JSON and creating objects
8
+ #
9
+ # @param klass [Lexile::Model] The Lexile::Model class to be used when parsing and objectifying responses.
10
+ def api_model(klass)
11
+ class_eval <<-END
12
+ def api_model
13
+ #{klass}
14
+ end
15
+ END
16
+ end
17
+ end
18
+
19
+ # initialize
20
+ # @param client [Lexile::API::Client] required to issue HTTP calls
21
+ def initialize( client )
22
+ @client = client
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,41 @@
1
+ module Lexile
2
+ class Book < Hashie::Mash
3
+ include Lexile::Model
4
+
5
+ api_path '/book'
6
+
7
+ # Book Resource
8
+ #
9
+ # This is the resource you will likely be using most often. This represents a book.
10
+ #
11
+ # Field Type Filter Description
12
+ # ISBN string ALL International Standard Book Number
13
+ # booktype string ALL Booktype, e.g. Fiction
14
+ # lexile_code string n/a Lexile Code, e.g. GN (graphic novel)
15
+ # series string ALL Book Series, if any
16
+ # lexile_code_spanish string n/a Lexile Code for Spanish Lexile measure if available
17
+ # word_count integer ALL Number of words contained in the book
18
+ # keyword string ALL List of keywords
19
+ # serial integer gt Serial Number this Resource was last modified on
20
+ # id integer n/a ID
21
+ # max_age integer ALL Max age of book
22
+ # call_number string n/a Call Number
23
+ # copyright string n/a Copyright year
24
+ # author string ALL Book Author(s)
25
+ # lexile integer ALL Lexile Measure
26
+ # categories_display string n/a List of categories
27
+ # timestamp datetime gt,gte Date/time the book record was last modified
28
+ # min_age integer ALL Minimum age of book
29
+ # pages integer ALL Number of pages contained in the book
30
+ # categories related ALL List of URIs or individually nested resource data
31
+ # publisher string ALL Book publisher
32
+ # language string ALL Book's written language
33
+ # ISBN13 string ALL 13-digit ISBN
34
+ # lexile_spanish integer n/a Spanish Lexile Measure
35
+ # word_count_spanish integer n/a Number of words in Spanish version of book
36
+ # summary string n/a Summary of the book
37
+ # title string ALL Book Title
38
+ # resource_uri string n/a The resource url for accessing this resource directly
39
+ #
40
+ end
41
+ end
@@ -0,0 +1,73 @@
1
+ module Lexile
2
+ module Configuration
3
+ VALID_CONNECTION_KEYS = [:endpoint, :api_version, :user_agent, :testing, :timeout].freeze
4
+ VALID_OPTIONS_KEYS = [:username,:password].freeze
5
+
6
+ #@!visibility private
7
+ VALID_CONFIG_KEYS = VALID_CONNECTION_KEYS + VALID_OPTIONS_KEYS
8
+
9
+ DEFAULT_ENDPOINT = 'https://fabapi.lexile.com/api/fab'
10
+ DEFAULT_API_VERSION = 'v2'
11
+ DEFAULT_USER_AGENT = 'Lexile API Ruby Gem by Curriculet'.freeze
12
+ DEFAULT_TIMEOUT = nil
13
+ DEFAULT_TESTING = false
14
+ DEFAULT_USERNAME = nil
15
+ DEFAULT_PASSWORD = nil
16
+
17
+ # Build accessor methods for every config options so we can do this, for example:
18
+ attr_accessor *VALID_CONFIG_KEYS
19
+
20
+ # Make sure we have the default values set when we get 'extended'
21
+ def self.extended(base)
22
+ base.reset!
23
+ end
24
+
25
+ # reset!
26
+ # set all options to their defaults and free the client
27
+ def reset!
28
+ self.endpoint = DEFAULT_ENDPOINT
29
+ self.api_version = DEFAULT_API_VERSION
30
+ self.user_agent = DEFAULT_USER_AGENT
31
+ self.timeout = DEFAULT_TIMEOUT
32
+ self.testing = DEFAULT_TESTING
33
+ self.username = DEFAULT_USERNAME
34
+ self.password = DEFAULT_PASSWORD
35
+
36
+ @client = nil
37
+ end
38
+
39
+ #@return [Hash] of all options
40
+ def options
41
+ Hash[ * VALID_CONFIG_KEYS.map { |key| [key, send(key)] }.flatten ]
42
+ end
43
+
44
+ # api_url
45
+ # Interpolate the base url for all calls
46
+ # return [String] the base url for all api calls
47
+ def api_url( path = nil)
48
+ [endpoint,api_version,path].compact.join('/')
49
+ end
50
+
51
+ # Yields itself for use in the configuration block
52
+ # @example
53
+ # Lexile.configure do |c|
54
+ # c.api_key = <MY-API-KEY>
55
+ # c.api_verion = 'v2'
56
+ # c.endpoint = 'https://fabapi.lexile.com/api/fab/'
57
+ # c.timeout = '10' #seconds
58
+ # c.testing = true
59
+ # end
60
+ #
61
+ # @return Lexile::API::Client
62
+ #
63
+ def configure
64
+ yield self
65
+ @client = Lexile::API::Client.new( self )
66
+ end
67
+
68
+ protected
69
+ def client
70
+ @client ||= Lexile::API::Client.new( self )
71
+ end
72
+ end # Configuration
73
+ end
@@ -0,0 +1,27 @@
1
+ module Lexile
2
+ class InvalidCredentials < StandardError; end
3
+ class CannotProcessResponse < StandardError; end
4
+
5
+ class HTTPError < StandardError
6
+ attr_reader :response
7
+ attr_reader :params
8
+
9
+ def initialize(response, params = {})
10
+ @response = response
11
+ @params = params
12
+ super(response)
13
+ end
14
+
15
+ def to_s
16
+ "#{self.class.to_s} : #{response.code} #{response.body}"
17
+ end
18
+ end
19
+
20
+ class NotFound < HTTPError; end
21
+ class Unavailable < HTTPError; end
22
+ class BadRequest < HTTPError; end
23
+ class ServerError < HTTPError; end
24
+ class AuthenticationFailed < HTTPError; end
25
+ class RateLimited < HTTPError; end
26
+ class UnknownStatusCode < HTTPError; end
27
+ end
@@ -0,0 +1,103 @@
1
+ module Lexile
2
+ module Model
3
+ def self.included(base)
4
+ base.send :extend, ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ # api_path
9
+ # This sets the API path so the API collections can use them in an agnostic way
10
+ # @param path [String] the api path for the current model with a leading slash
11
+ # @return [void]
12
+ def api_path(path = nil)
13
+ @_api_path ||= path
14
+ end
15
+
16
+ # Understanding the Response
17
+ # The API will return a JSON response for each query. Lets take a look at a sample response.
18
+ #
19
+ # {"meta":
20
+ # {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 1},
21
+ # "objects":
22
+ # [
23
+ # {
24
+ # "ISBN": "1234567890",
25
+ # "ISBN13": "9781234567890",
26
+ # "author": "Author, Fake",
27
+ # "booktype": "Fiction",
28
+ # "call_number": "",
29
+ # "categories":
30
+ # [{"id": 1, "name": "Action", "resource_uri": "/api/fab/2013-02-04/category/1/"}],
31
+ # "categories_display": "",
32
+ # "copyright": "2013",
33
+ # "id": 1,
34
+ # "keyword": "",
35
+ # "language": "",
36
+ # "lexile": 1000,
37
+ # "lexile_code": "",
38
+ # "lexile_code_spanish": "",
39
+ # "lexile_display": "1000L",
40
+ # "lexile_spanish": null,
41
+ # "max_age": null,
42
+ # "min_age": null,
43
+ # "pages": 5,
44
+ # "publisher":
45
+ # "Fake Publisher",
46
+ # "resource_uri": "/api/fab/2013-02-04/book/1/",
47
+ # "serial": 1,
48
+ # "series": "",
49
+ # "summary": "This is a sample summary",
50
+ # "timestamp": "2013-05-04T17:43:50",
51
+ # "title": "Test Book",
52
+ # "word_count": 400,
53
+ # "word_count_spanish": null
54
+ # }
55
+ # ]
56
+ # }
57
+ #
58
+ # We will mainly cover the meta data in the response in this section. For more details about the book object
59
+ # itself please refer to the resources documentation. Lets take a look at just the meta block.
60
+ #
61
+ # {"meta":{"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 1}
62
+ #
63
+ # In the meta object you will find key pieces of information about your result.
64
+ # limit: By default only 20 objects are sent back in each response. You can increase or decrease this limit by
65
+ # supplying a limit filter on your query.
66
+ #
67
+ # next: The url for you to fetch the next set of results in your query. This url will not be a fully qualified
68
+ # url but instead relative to the base url we discussed earlier. If the value is none there is not another set
69
+ # of results and you have reached the last "page"
70
+ #
71
+ # offset: The number of records you are offsetting this result by. For example if you had a limit of 20 and
72
+ # there were 100 total records. If you had an offset of 60 that would mean you are looking at records 61-80.
73
+ #
74
+ # previous: Same as next but refers to the previous set of results. If this is null there are no previous sets
75
+ # available.
76
+ #
77
+ # total_count: The total number of results in the query. For example if you had a query that generated 100
78
+ # results this number would be 100.
79
+ #
80
+ # A field that is not explained in the resources documentation that should be noted here is resource_uri.
81
+ # You will notice in our sample response there is a resource_uri for the category and the book. This is the
82
+ # url you will use to obtain information about that particular object. Like the next and previous urls, this is
83
+ # not fully qualified and is relative to the base url discussed earlier.
84
+
85
+ # Parses a request.body response into a Lexile::Model objects
86
+ #
87
+ def parse( raw_json )
88
+ parsed_json = String === raw_json ? JSON.parse(raw_json) : json
89
+ if parsed_json.has_key?('objects')
90
+ #this is a multi record and data should contain an array
91
+ unless parsed_json['objects'].is_a? Array
92
+ raise Lexile::CannotProcessResponse.new('[:objects] is present in response but it does not contain an Array')
93
+ end
94
+ return parsed_json['objects'].map {|array_element| new( array_element ) }
95
+ else
96
+ return new( parsed_json )
97
+ end
98
+ end
99
+
100
+ end
101
+
102
+ end
103
+ end
@@ -0,0 +1,3 @@
1
+ module Lexile
2
+ VERSION = "0.0.2"
3
+ end