rowling 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 459f9ebfd9177eec1e25a4d6d64ca7c87fe6491f
4
- data.tar.gz: f2e5ca33081dd88320a390dd4fd40be271487584
3
+ metadata.gz: 978cc635d4f1adaab009a1c5ec5a692603fb47b4
4
+ data.tar.gz: 818314298ba15aeca00934a6ac4131cb78a6263a
5
5
  SHA512:
6
- metadata.gz: 6abd827e5307ca49649a09cfde2e12d7ae4ea23161c37830cf53acd3f1bcb3d123c7f55c58faf1c0a4c220453bc412f50fc166c0083653e548b17be374b1991b
7
- data.tar.gz: a47bd8c08307ce0bb56f21de902070ab28ed6d4b999b0b23032688963d639bdb6d748a1cf92f1dcc1ceee411b5890d6831d15c6c3eb90384852c86da66bd7d19
6
+ metadata.gz: bc998add89f1086f2e78b7ba6c056d7223955db21f2d17e7403637fccf896847ec4f39da52c5b314625bfc207f0097cb469ff768ba82f5a75da91b2ee0bed880
7
+ data.tar.gz: 0ed29b3964702a83b8f2d7f48885c39cf1dce8be3c4336fce8378a8a61b9e2a092fc8fb790e6b7dcff9a11575cabffdb1eeb0869a75bc0062901bb9d17126421
data/README.md CHANGED
@@ -1,15 +1,16 @@
1
1
  # Rowling
2
2
 
3
- A Ruby wrapper for the USA Today Bestsellers API (work in progress!)
3
+ A Ruby wrapper for the [USA Today Bestsellers API](http://developer.usatoday.com/docs/read/bestselling_books).
4
4
 
5
5
  # Usage
6
6
 
7
- Set up a client:
7
+ First, you'll need an API key, which you can get [here](http://developer.usatoday.com/member/register). Then, you can set up a client:
8
8
 
9
9
  ```ruby
10
10
  client = Rowling::Client.new(api_key: YOUR_KEY)
11
11
  ```
12
12
 
13
+ ##Books
13
14
  Search for books included in bestseller lists:
14
15
 
15
16
  ```ruby
@@ -18,9 +19,11 @@ search_params = { author: "J.K. Rowling",
18
19
  }
19
20
 
20
21
  books = client.search_books(search_params)
21
-
22
22
  ```
23
23
 
24
+ You can view the search parameters [here]( http://developer.usatoday.com/docs/read/bestselling_books#parameters).
25
+
26
+
24
27
  This returns an array of Book objects:
25
28
 
26
29
  ```ruby
@@ -40,8 +43,41 @@ Attributes will include:
40
43
  title, title_api_url, author, class, description, book_list_appearances, highest_rank, ranks
41
44
  ```
42
45
 
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.
46
+ ##Booklists
47
+ You can search for book lists by year, month and date. All parameters are optional and without parameters it will retrive the most recent list.
44
48
 
45
49
  ```ruby
46
50
  client.get_booklists(year: 2015, month: 2)
47
51
  ```
52
+
53
+ ##Other Requests
54
+
55
+ ```ruby
56
+ # returns available book classes (fiction vs. nonfiction)
57
+ client.get_classes
58
+
59
+ # returns available book categories
60
+ client.get_categories
61
+
62
+ # returns dates that bestseller lists were published on (can be filtered by using
63
+ # parameters of month and year, without parameters returns all dates since Oct. 1993)
64
+ client.get_dates(year: 2015, month: 3)
65
+ ```
66
+
67
+ ##Options
68
+
69
+ If you don't want the responses parsed for you, set up your client with "raw" set to true. The default is false.
70
+
71
+ ```ruby
72
+ client = Rowling::Client.new(api_key: YOUR_API_KEY, raw: true)
73
+ ```
74
+
75
+ If you would like the client to pause and retry requests when you hit a rate limit, set up your client with "retries" set to the number of times you would like it to retry requests. The default is 0.
76
+
77
+ ```ruby
78
+ client = Rowling::Client.new(api_key: YOUR_API_KEY, retries: 2)
79
+ ```
80
+
81
+ ###Why is it called Rowling?
82
+ She holds the record for longest #1 USA Today Bestselling Book, with Harry Potter and Sorcerer's Stone topping the list for 31 weeks in 1999. So that's pretty cool.
83
+
data/lib/rowling.rb CHANGED
@@ -4,13 +4,8 @@ require "addressable/template"
4
4
  require "date"
5
5
  require "ext/string.rb"
6
6
  require "rowling/version.rb"
7
- require "rowling/configuration.rb"
8
7
  require "rowling/book.rb"
9
8
  require "rowling/rank.rb"
10
9
  require "rowling/exceptions.rb"
11
10
  require "rowling/book_list.rb"
12
11
  require "rowling/client.rb"
13
-
14
- module Rowling
15
- extend Configuration
16
- end
@@ -1,12 +1,20 @@
1
1
  module Rowling
2
2
  class Client
3
3
 
4
- attr_accessor *Configuration::CONFIGURATION_KEYS
4
+ CONFIGURATION_KEYS = [:api_key, :raw, :retries]
5
5
 
6
6
  def initialize(args={})
7
- Configuration::CONFIGURATION_KEYS.each do |key|
7
+ CONFIGURATION_KEYS.each do |key|
8
8
  send("#{key}=", args[key])
9
9
  end
10
+ set_defaults
11
+ end
12
+
13
+ attr_accessor *CONFIGURATION_KEYS
14
+
15
+ def set_defaults
16
+ @raw ||= false
17
+ @retries ||= 0
10
18
  end
11
19
 
12
20
  def base_template
@@ -28,10 +36,10 @@ module Rowling
28
36
  date_response["Dates"]
29
37
  end
30
38
 
31
- def search_books(args={}, raw=false)
39
+ def search_books(args={})
32
40
  segments = "titles"
33
41
  book_response = make_request({segments: segments, query: args})
34
- if raw
42
+ if self.raw
35
43
  book_response
36
44
  else
37
45
  if titles = book_response["Titles"]
@@ -44,27 +52,27 @@ module Rowling
44
52
  end
45
53
  end
46
54
 
47
- def find_book_by_isbn(isbn, raw=false)
55
+ def find_book_by_isbn(isbn)
48
56
  segments = ["titles", isbn]
49
- if raw
50
- make_request({ segments: segments }, true)
57
+ if self.raw
58
+ make_request({ segments: segments })
51
59
  else
52
60
  begin
53
61
  book_response = make_request({ segments: segments })
54
62
  Rowling::Book.new(book_response["Title"])
55
- rescue Rowling::Response503Error => e
63
+ rescue Rowling::Response503Error, Rowling::Response400Error => e
56
64
  return nil
57
65
  end
58
66
  end
59
67
  end
60
68
 
61
- def get_booklists(args={}, raw=false)
69
+ def get_booklists(args={})
62
70
  date_segments = [:year, :month, :day].map do |segment|
63
71
  args.delete(segment)
64
72
  end
65
73
  segments = ["booklists"].concat(date_segments.compact)
66
74
  response = make_request({ segments: segments, args: args})
67
- if raw
75
+ if self.raw
68
76
  response
69
77
  elsif lists = response["BookLists"]
70
78
  lists.map{ |list| BookList.new(list) }
@@ -73,11 +81,11 @@ module Rowling
73
81
  end
74
82
  end
75
83
 
76
- def get_detailed_version(book, raw=false)
84
+ def get_detailed_version(book)
77
85
  if book.title_api_url
78
86
  segments = book.title_api_url
79
87
  book_response = make_request({ segments: segments })
80
- if raw
88
+ if self.raw
81
89
  book_response
82
90
  else
83
91
  Rowling::Book.new(book_response["Title"])
@@ -87,20 +95,20 @@ module Rowling
87
95
  end
88
96
  end
89
97
 
90
- def make_request(args={}, raw=false, tries=0)
98
+ def make_request(args={}, tries=0)
91
99
  if self.api_key
92
100
  uri = build_uri(args)
93
101
  response = HTTParty.get(uri)
94
- if raw
102
+ if self.raw
95
103
  response
96
104
  else
97
- if tries < 2
105
+ if tries < self.retries
98
106
  begin
99
107
  check_errors(response)
100
108
  rescue Rowling::Response403Error
101
109
  tries += 1
102
- sleep(2)
103
- make_request(args, false, tries)
110
+ sleep(1)
111
+ make_request(args, tries)
104
112
  end
105
113
  else
106
114
  check_errors(response)
@@ -120,6 +128,8 @@ module Rowling
120
128
  def check_errors(response)
121
129
  if response.code == 503
122
130
  raise Rowling::Response503Error
131
+ elsif response.code == 400
132
+ raise Rowling::Response400Error
123
133
  elsif response.code == 403
124
134
  raise Rowling::Response403Error
125
135
  elsif response.code != 200
@@ -5,9 +5,15 @@ module Rowling
5
5
  end
6
6
  end
7
7
 
8
+ class Response400Error < StandardError
9
+ def message
10
+ "Bad request (data not found)."
11
+ end
12
+ end
13
+
8
14
  class Response403Error < StandardError
9
15
  def message
10
- "Exceeded quota per second"
16
+ "Exceeded quota per second/api rate limit"
11
17
  end
12
18
  end
13
19
 
@@ -1,3 +1,3 @@
1
1
  module Rowling
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -3,12 +3,16 @@ require 'helper'
3
3
  describe Rowling::Client do
4
4
 
5
5
  before do
6
- @client = Rowling::Client.new(api_key: ENV["USATODAY_BESTSELLER_KEY"], format: :json)
6
+ @client = Rowling::Client.new(api_key: ENV["USATODAY_BESTSELLER_KEY"])
7
7
  end
8
8
 
9
- it "should configure valid configuration keys" do
9
+ it "should configure an api key" do
10
10
  @client.api_key.must_equal ENV["USATODAY_BESTSELLER_KEY"]
11
- @client.format.must_equal :json
11
+ end
12
+
13
+ it "should configure default values for other attributes" do
14
+ @client.retries.must_equal 0
15
+ @client.raw.must_equal false
12
16
  end
13
17
 
14
18
  it "should raise an error if you try to make a request without an API key" do
@@ -17,6 +21,19 @@ describe Rowling::Client do
17
21
  end
18
22
 
19
23
  describe "requests", :vcr do
24
+ before do
25
+ @client.retries = 2
26
+ end
27
+ # this is a shitty test but the VCR request it created works for now,
28
+ # will need to come up with a better one at some point
29
+ it "should pause and retry when throttled" do
30
+ retry_client = Rowling::Client.new(api_key: ENV["USATODAY_BESTSELLER_KEY"])
31
+ 3.times do
32
+ book = @client.find_book_by_isbn("9780758280428")
33
+ book.must_be_instance_of Rowling::Book
34
+ end
35
+ end
36
+
20
37
  it "should get classes" do
21
38
  classes = @client.get_classes
22
39
  classes.must_equal ["---", "Fiction", "NonFiction"]
@@ -68,22 +85,25 @@ describe Rowling::Client do
68
85
  end
69
86
 
70
87
  describe "when raw is set to true" do
88
+ before do
89
+ @client.raw = true
90
+ end
71
91
 
72
92
  describe "when searching by ISBN" do
73
93
 
74
94
  it "should return a raw response" do
75
- response = @client.find_book_by_isbn("9780758280428", true)
95
+ response = @client.find_book_by_isbn("9780758280428")
76
96
  response.must_be_instance_of Hash
77
97
  end
78
98
 
79
99
  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
100
+ response = @client.find_book_by_isbn("9781555976859")
101
+ response.must_be_instance_of Hash
82
102
  end
83
103
  end
84
104
 
85
105
  it "should return a raw response when searching for a book by parameters" do
86
- response = @client.search_books({author: "J.K. Rowling"}, true)
106
+ response = @client.search_books({author: "J.K. Rowling"})
87
107
  response.must_be_instance_of Hash
88
108
  end
89
109
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rowling
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sonja Peterson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-15 00:00:00.000000000 Z
11
+ date: 2015-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -139,7 +139,6 @@ files:
139
139
  - lib/rowling/book.rb
140
140
  - lib/rowling/book_list.rb
141
141
  - lib/rowling/client.rb
142
- - lib/rowling/configuration.rb
143
142
  - lib/rowling/exceptions.rb
144
143
  - lib/rowling/rank.rb
145
144
  - lib/rowling/version.rb
@@ -148,7 +147,6 @@ files:
148
147
  - test/rowling/book_list_test.rb
149
148
  - test/rowling/book_test.rb
150
149
  - test/rowling/client_test.rb
151
- - test/rowling/configuration_test.rb
152
150
  - test/rowling/rank_test.rb
153
151
  - test/rowling/rowling_test.rb
154
152
  homepage: ''
@@ -180,6 +178,5 @@ test_files:
180
178
  - test/rowling/book_list_test.rb
181
179
  - test/rowling/book_test.rb
182
180
  - test/rowling/client_test.rb
183
- - test/rowling/configuration_test.rb
184
181
  - test/rowling/rank_test.rb
185
182
  - test/rowling/rowling_test.rb
@@ -1,21 +0,0 @@
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
@@ -1,23 +0,0 @@
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
-