rowling 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: 459f9ebfd9177eec1e25a4d6d64ca7c87fe6491f
4
+ data.tar.gz: f2e5ca33081dd88320a390dd4fd40be271487584
5
+ SHA512:
6
+ metadata.gz: 6abd827e5307ca49649a09cfde2e12d7ae4ea23161c37830cf53acd3f1bcb3d123c7f55c58faf1c0a4c220453bc412f50fc166c0083653e548b17be374b1991b
7
+ data.tar.gz: a47bd8c08307ce0bb56f21de902070ab28ed6d4b999b0b23032688963d639bdb6d748a1cf92f1dcc1ceee411b5890d6831d15c6c3eb90384852c86da66bd7d19
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /test/cassettes/
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ *.swp
16
+ mkmf.log
17
+ notes.txt
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rowling.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 sonjapeterson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # Rowling
2
+
3
+ A Ruby wrapper for the USA Today Bestsellers API (work in progress!)
4
+
5
+ # Usage
6
+
7
+ Set up a client:
8
+
9
+ ```ruby
10
+ client = Rowling::Client.new(api_key: YOUR_KEY)
11
+ ```
12
+
13
+ Search for books included in bestseller lists:
14
+
15
+ ```ruby
16
+ search_params = { author: "J.K. Rowling",
17
+ title: "Deathly Hallows"
18
+ }
19
+
20
+ books = client.search_books(search_params)
21
+
22
+ ```
23
+
24
+ This returns an array of Book objects:
25
+
26
+ ```ruby
27
+ books.first.title = "Harry Potter and the Deathly Hallows"
28
+ books.first.author = "J.K. Rowling, art by Mary GrandPre"
29
+ books.first.title_api_url = "/Titles/9780545010221"
30
+ ```
31
+
32
+ Books from search only have title, author and api url. For more detailed information, you can find books directly by ISBN:
33
+
34
+ ```ruby
35
+ book = client.find_book_by_isbn("9780545010221")
36
+ ```
37
+ Attributes will include:
38
+
39
+ ```ruby
40
+ title, title_api_url, author, class, description, book_list_appearances, highest_rank, ranks
41
+ ```
42
+
43
+ You can also search for book lists by year, month and date. All parameters are optional and without parameters it will retrive the most recent list.
44
+
45
+ ```ruby
46
+ client.get_booklists(year: 2015, month: 2)
47
+ ```
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new do |test|
5
+ test.libs << 'lib' << 'test'
6
+ test.ruby_opts << "-rubygems"
7
+ test.pattern = 'test/**/*_test.rb'
8
+ test.verbose = true
9
+ end
10
+
data/lib/ext/string.rb ADDED
@@ -0,0 +1,13 @@
1
+ class String
2
+ def camelize
3
+ return self if self !~ /_/ && self =~ /[A-Z]+.*/
4
+ arr = split('_').map do |e|
5
+ if ['api', 'isbn', 'asin'].include? e
6
+ e.upcase
7
+ else
8
+ e.capitalize
9
+ end
10
+ end
11
+ arr.join
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ module Rowling
2
+ class Book
3
+ ATTRIBUTES = [:title, :title_api_url, :author, :class, :description, :book_list_appearances, :highest_rank, :rank_last_week, :isbn, :asin]
4
+
5
+ def initialize(response)
6
+ ATTRIBUTES.each do |key|
7
+ send("#{key}=", response[key.to_s.camelize]) if response[key.to_s.camelize]
8
+ end
9
+ if descrip = response["BriefDescription"]
10
+ self.description = descrip
11
+ end
12
+ if response["Category"]
13
+ self.category_id = response["Category"]["CategoryID"]
14
+ self.category_name = response["Category"]["CategoryName"]
15
+ end
16
+ if response["RankHistories"]
17
+ self.ranks = response["RankHistories"].map do |rank|
18
+ Rowling::Rank.new(rank)
19
+ end
20
+ end
21
+ end
22
+
23
+ attr_accessor *ATTRIBUTES, :category_id, :category_name, :ranks
24
+ end
25
+ end
26
+
@@ -0,0 +1,25 @@
1
+ module Rowling
2
+ class BookList
3
+ def initialize(response)
4
+ self.books = parse_entries(response["BookListEntries"])
5
+ self.date = parse_date(response["BookListDate"])
6
+ self.name = response["Name"]
7
+ self.book_list_api_url = response["BookListDate"]["BookListAPIUrl"]
8
+ end
9
+
10
+ attr_accessor :books, :date, :name, :book_list_api_url
11
+
12
+ def parse_date(date_response)
13
+ date_vals = [date_response["Year"], date_response["Month"], date_response["Date"]]
14
+ date_vals = date_vals.compact.map(&:to_i)
15
+ Date.new(*date_vals)
16
+ end
17
+
18
+ def parse_entries(entries_response)
19
+ books = entries_response.map.with_index do |entry, i|
20
+ [i, book = Rowling::Book.new(entry)]
21
+ end
22
+ books.to_h
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,132 @@
1
+ module Rowling
2
+ class Client
3
+
4
+ attr_accessor *Configuration::CONFIGURATION_KEYS
5
+
6
+ def initialize(args={})
7
+ Configuration::CONFIGURATION_KEYS.each do |key|
8
+ send("#{key}=", args[key])
9
+ end
10
+ end
11
+
12
+ def base_template
13
+ template = Addressable::Template.new("http://api.usatoday.com/open/bestsellers/books{/segments*}{?query*}")
14
+ end
15
+
16
+ def get_classes(args={})
17
+ class_response = make_request({segments: "classes", query: args})
18
+ class_response["Classes"]
19
+ end
20
+
21
+ def get_categories(args={})
22
+ category_response = make_request({segments: "categories", query: args})
23
+ category_response["Categories"]
24
+ end
25
+
26
+ def get_dates(args={})
27
+ date_response = make_request({segments: "dates", query: args})
28
+ date_response["Dates"]
29
+ end
30
+
31
+ def search_books(args={}, raw=false)
32
+ segments = "titles"
33
+ book_response = make_request({segments: segments, query: args})
34
+ if raw
35
+ book_response
36
+ else
37
+ if titles = book_response["Titles"]
38
+ titles.map do |title|
39
+ Rowling::Book.new(title)
40
+ end
41
+ else
42
+ []
43
+ end
44
+ end
45
+ end
46
+
47
+ def find_book_by_isbn(isbn, raw=false)
48
+ segments = ["titles", isbn]
49
+ if raw
50
+ make_request({ segments: segments }, true)
51
+ else
52
+ begin
53
+ book_response = make_request({ segments: segments })
54
+ Rowling::Book.new(book_response["Title"])
55
+ rescue Rowling::Response503Error => e
56
+ return nil
57
+ end
58
+ end
59
+ end
60
+
61
+ def get_booklists(args={}, raw=false)
62
+ date_segments = [:year, :month, :day].map do |segment|
63
+ args.delete(segment)
64
+ end
65
+ segments = ["booklists"].concat(date_segments.compact)
66
+ response = make_request({ segments: segments, args: args})
67
+ if raw
68
+ response
69
+ elsif lists = response["BookLists"]
70
+ lists.map{ |list| BookList.new(list) }
71
+ else
72
+ {}
73
+ end
74
+ end
75
+
76
+ def get_detailed_version(book, raw=false)
77
+ if book.title_api_url
78
+ segments = book.title_api_url
79
+ book_response = make_request({ segments: segments })
80
+ if raw
81
+ book_response
82
+ else
83
+ Rowling::Book.new(book_response["Title"])
84
+ end
85
+ else
86
+ raise Rowling::ResponseError "Can't retrieve details for book without title api url set"
87
+ end
88
+ end
89
+
90
+ def make_request(args={}, raw=false, tries=0)
91
+ if self.api_key
92
+ uri = build_uri(args)
93
+ response = HTTParty.get(uri)
94
+ if raw
95
+ response
96
+ else
97
+ if tries < 2
98
+ begin
99
+ check_errors(response)
100
+ rescue Rowling::Response403Error
101
+ tries += 1
102
+ sleep(2)
103
+ make_request(args, false, tries)
104
+ end
105
+ else
106
+ check_errors(response)
107
+ end
108
+ end
109
+ else
110
+ raise Rowling::NoAPIKeyError
111
+ end
112
+ end
113
+
114
+ def build_uri(args)
115
+ query = { "api_key" => self.api_key }
116
+ query.merge!(args[:query]) if args[:query]
117
+ base_template.expand({segments: args[:segments], query: query}).to_s
118
+ end
119
+
120
+ def check_errors(response)
121
+ if response.code == 503
122
+ raise Rowling::Response503Error
123
+ elsif response.code == 403
124
+ raise Rowling::Response403Error
125
+ elsif response.code != 200
126
+ raise Rowling::ResponseError, "Request Failed. Code #{response.code}."
127
+ else
128
+ response
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,21 @@
1
+ module Rowling
2
+ module Configuration
3
+ DEFAULT_FORMAT = :json
4
+ CONFIGURATION_KEYS = [:api_key, :format]
5
+
6
+ attr_accessor *CONFIGURATION_KEYS
7
+
8
+ def self.extended(base)
9
+ base.reset
10
+ end
11
+
12
+ def reset
13
+ self.api_key = nil
14
+ self.format = :json
15
+ end
16
+
17
+ def configure
18
+ yield self
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ module Rowling
2
+ class Response503Error < StandardError
3
+ def message
4
+ "Service temporarily unavailable."
5
+ end
6
+ end
7
+
8
+ class Response403Error < StandardError
9
+ def message
10
+ "Exceeded quota per second"
11
+ end
12
+ end
13
+
14
+ class NoAPIKeyError < StandardError
15
+ def message
16
+ "You must set a valid API key before making requests"
17
+ end
18
+ end
19
+
20
+ class ResponseError < StandardError; end
21
+
22
+ end
@@ -0,0 +1,16 @@
1
+ module Rowling
2
+ class Rank
3
+
4
+ def initialize(response)
5
+ self.date = Rowling::Rank.parse_rank_date(response["BookListDate"])
6
+ self.rank = response["Rank"]
7
+ self.book_list_api_url = response["BookListDate"]["BookListAPIUrl"]
8
+ end
9
+
10
+ attr_accessor :date, :rank, :book_list_api_url
11
+
12
+ def self.parse_rank_date(date_response)
13
+ Date.new(date_response["Year"].to_i, date_response["Month"].to_i, date_response["Date"].to_i)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ module Rowling
2
+ VERSION = "0.0.2"
3
+ end
data/lib/rowling.rb ADDED
@@ -0,0 +1,16 @@
1
+ require "httparty"
2
+ require "addressable/uri"
3
+ require "addressable/template"
4
+ require "date"
5
+ require "ext/string.rb"
6
+ require "rowling/version.rb"
7
+ require "rowling/configuration.rb"
8
+ require "rowling/book.rb"
9
+ require "rowling/rank.rb"
10
+ require "rowling/exceptions.rb"
11
+ require "rowling/book_list.rb"
12
+ require "rowling/client.rb"
13
+
14
+ module Rowling
15
+ extend Configuration
16
+ end
data/rowling.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rowling/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rowling"
8
+ spec.version = Rowling::VERSION
9
+ spec.authors = ["Sonja Peterson"]
10
+ spec.email = ["sonja.peterson@gmail.com"]
11
+ spec.summary = "Wrapper for USA Today Bestsellers API."
12
+ spec.description = "A simple Ruby wrapper for accessing USA Today bestseller data."
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "minitest-reporters", "~> 1.0.11"
24
+ spec.add_development_dependency "minitest-vcr", "~> 1.3.0"
25
+ spec.add_development_dependency "webmock"
26
+
27
+ spec.add_dependency "httparty", "~> 0.13.3"
28
+ spec.add_dependency "addressable", "~> 2.3.6"
29
+ spec.add_dependency "require_all", "~> 1.3.2"
30
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'rowling'
2
+ require 'minitest/spec'
3
+ require 'minitest/autorun'
4
+ require 'minitest/reporters'
5
+ require 'vcr'
6
+ require 'minitest-vcr'
7
+ require 'webmock'
8
+ require 'pry'
9
+
10
+ reporter_options = { color: true }
11
+ Minitest::Reporters.use! [Minitest::Reporters::DefaultReporter.new(reporter_options)]
12
+
13
+ VCR.configure do |c|
14
+ c.cassette_library_dir = 'test/cassettes'
15
+ c.hook_into :webmock
16
+ end
17
+ MinitestVcr::Spec.configure!
@@ -0,0 +1,5 @@
1
+ require 'helper'
2
+
3
+ describe Rowling::BookList do
4
+ end
5
+
@@ -0,0 +1,37 @@
1
+ require 'helper'
2
+
3
+ describe Rowling::Book do
4
+ before do
5
+ @client = Rowling::Client.new(api_key: ENV["USATODAY_BESTSELLER_KEY"], format: :json)
6
+ end
7
+
8
+ it "should parse the attributes of a book from a request when initializing", :vcr do
9
+ book = @client.find_book_by_isbn("9780758280428")
10
+ book.title.must_equal " Double Fudge Brownie Murder"
11
+ book.author.must_equal "Joanne Fluke"
12
+ book.category_id.must_equal 0
13
+ book.category_name.must_equal "----"
14
+ book.book_list_appearances.must_equal 1
15
+ book.highest_rank.must_equal 39
16
+ end
17
+
18
+ it "should parse rank histories as instances of Rowling::Rank", :vcr do
19
+ book = @client.find_book_by_isbn("9780758280428")
20
+ book.ranks.first.must_be_instance_of Rowling::Rank
21
+ end
22
+
23
+ it "should create a book when only given partial data" do
24
+ response = {
25
+ "Title" => "Embassytown",
26
+ "Author" => "China Mieville",
27
+ "TitleAPIUrl"=> "/Titles/9781451648539"
28
+ }
29
+ book = Rowling::Book.new(response)
30
+ book.title.must_equal "Embassytown"
31
+ book.author.must_equal "China Mieville"
32
+ book.title_api_url.must_equal "/Titles/9781451648539"
33
+ book.category_id.must_equal nil
34
+ end
35
+
36
+ end
37
+
@@ -0,0 +1,92 @@
1
+ require 'helper'
2
+
3
+ describe Rowling::Client do
4
+
5
+ before do
6
+ @client = Rowling::Client.new(api_key: ENV["USATODAY_BESTSELLER_KEY"], format: :json)
7
+ end
8
+
9
+ it "should configure valid configuration keys" do
10
+ @client.api_key.must_equal ENV["USATODAY_BESTSELLER_KEY"]
11
+ @client.format.must_equal :json
12
+ end
13
+
14
+ it "should raise an error if you try to make a request without an API key" do
15
+ @client.api_key = nil
16
+ proc { @client.make_request }.must_raise Rowling::NoAPIKeyError
17
+ end
18
+
19
+ describe "requests", :vcr do
20
+ it "should get classes" do
21
+ classes = @client.get_classes
22
+ classes.must_equal ["---", "Fiction", "NonFiction"]
23
+ end
24
+
25
+ it "should find a book based on a valid ISBN" do
26
+ book = @client.find_book_by_isbn("9780758280428")
27
+ book.must_be_instance_of Rowling::Book
28
+ end
29
+
30
+ it "should return nil if no book is found by ISBN search" do
31
+ book = @client.find_book_by_isbn("9781555976859")
32
+ book.must_be_nil
33
+ end
34
+
35
+ it "should search for books by title" do
36
+ books = @client.search_books(title: "Gone Girl")
37
+ books.first.must_be_instance_of Rowling::Book
38
+ end
39
+
40
+ it "should return an empty array if there are no results for a book" do
41
+ books = @client.search_books(author: "Geoffrey Chaucer")
42
+ books.must_equal []
43
+ end
44
+
45
+ it "should search for books by multiple parameters" do
46
+ books = @client.search_books(author: "Diana Gabaldon", book: "A Leaf on the Wind of All Hallows")
47
+ books.first.must_be_instance_of Rowling::Book
48
+ end
49
+
50
+ it "should get a detailed version of a book found through search" do
51
+ books = @client.search_books(author: "J.K. Rowling")
52
+ detailed_book = @client.get_detailed_version(books.first)
53
+ detailed_book.must_be_instance_of Rowling::Book
54
+ detailed_book.title.must_equal "Fantastic Beasts & Where to Find Them"
55
+ detailed_book.ranks.count.must_equal 24
56
+ detailed_book.category_id.must_equal 140
57
+ detailed_book.category_name.must_equal "Youth"
58
+ end
59
+
60
+ it "should get a booklist" do
61
+ booklists = @client.get_booklists(year: 2015, month: 2)
62
+ booklists.must_be_instance_of Array
63
+ booklists[0].must_be_instance_of Rowling::BookList
64
+ booklists[0].date.must_equal Date.new(2015, 2, 26)
65
+ booklists[0].name.must_equal "Top 150"
66
+ booklists[0].book_list_api_url.must_equal "BookLists/2015/2/26"
67
+ booklists[0].books[0].title.must_equal "The Girl on the Train"
68
+ end
69
+
70
+ describe "when raw is set to true" do
71
+
72
+ describe "when searching by ISBN" do
73
+
74
+ it "should return a raw response" do
75
+ response = @client.find_book_by_isbn("9780758280428", true)
76
+ response.must_be_instance_of Hash
77
+ end
78
+
79
+ it "should not raise an error when a book is not found" do
80
+ response = @client.find_book_by_isbn("9781555976859", true)
81
+ response.must_be_instance_of String
82
+ end
83
+ end
84
+
85
+ it "should return a raw response when searching for a book by parameters" do
86
+ response = @client.search_books({author: "J.K. Rowling"}, true)
87
+ response.must_be_instance_of Hash
88
+ end
89
+
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,23 @@
1
+ require 'helper'
2
+
3
+ describe 'configuration' do
4
+ after do
5
+ Rowling.reset
6
+ end
7
+
8
+ it "should set json as the default format" do
9
+ Rowling.format.must_equal :json
10
+ end
11
+
12
+ it "should set the api key's default value as nil" do
13
+ Rowling.api_key.must_equal nil
14
+ end
15
+
16
+ it "should allow you to set an api key" do
17
+ Rowling.configure do |config|
18
+ config.api_key = "my_secret_key"
19
+ end
20
+ Rowling.api_key.must_equal "my_secret_key"
21
+ end
22
+ end
23
+
@@ -0,0 +1,13 @@
1
+ require 'helper'
2
+
3
+ describe Rowling::Rank do
4
+ it "should convert rank history data to ranks" do
5
+ rank_history = [
6
+ {"BookListDate"=>{"Year"=>"2015", "Month"=>"3", "Date"=>"5", "BookListAPIUrl"=>"BookLists/2015/3/5"}, "Rank"=>39}
7
+ ]
8
+ ranks = rank_history.map{ |rank| Rowling::Rank.new(rank) }
9
+ ranks.first.date.must_equal Date.new(2015, 3, 5)
10
+ ranks.first.rank.must_equal 39
11
+ ranks.first.book_list_api_url.must_equal "BookLists/2015/3/5"
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ describe Rowling do
4
+ it 'should have a version' do
5
+ Rowling::VERSION.wont_be_nil
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rowling
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Sonja Peterson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-15 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.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest-reporters
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.0.11
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.11
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-vcr
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.3.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.3.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: httparty
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.13.3
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.13.3
97
+ - !ruby/object:Gem::Dependency
98
+ name: addressable
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 2.3.6
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 2.3.6
111
+ - !ruby/object:Gem::Dependency
112
+ name: require_all
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 1.3.2
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 1.3.2
125
+ description: A simple Ruby wrapper for accessing USA Today bestseller data.
126
+ email:
127
+ - sonja.peterson@gmail.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - Gemfile
134
+ - LICENSE.txt
135
+ - README.md
136
+ - Rakefile
137
+ - lib/ext/string.rb
138
+ - lib/rowling.rb
139
+ - lib/rowling/book.rb
140
+ - lib/rowling/book_list.rb
141
+ - lib/rowling/client.rb
142
+ - lib/rowling/configuration.rb
143
+ - lib/rowling/exceptions.rb
144
+ - lib/rowling/rank.rb
145
+ - lib/rowling/version.rb
146
+ - rowling.gemspec
147
+ - test/helper.rb
148
+ - test/rowling/book_list_test.rb
149
+ - test/rowling/book_test.rb
150
+ - test/rowling/client_test.rb
151
+ - test/rowling/configuration_test.rb
152
+ - test/rowling/rank_test.rb
153
+ - test/rowling/rowling_test.rb
154
+ homepage: ''
155
+ licenses:
156
+ - MIT
157
+ metadata: {}
158
+ post_install_message:
159
+ rdoc_options: []
160
+ require_paths:
161
+ - lib
162
+ required_ruby_version: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ required_rubygems_version: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - ">="
170
+ - !ruby/object:Gem::Version
171
+ version: '0'
172
+ requirements: []
173
+ rubyforge_project:
174
+ rubygems_version: 2.2.2
175
+ signing_key:
176
+ specification_version: 4
177
+ summary: Wrapper for USA Today Bestsellers API.
178
+ test_files:
179
+ - test/helper.rb
180
+ - test/rowling/book_list_test.rb
181
+ - test/rowling/book_test.rb
182
+ - test/rowling/client_test.rb
183
+ - test/rowling/configuration_test.rb
184
+ - test/rowling/rank_test.rb
185
+ - test/rowling/rowling_test.rb