npr 0.0.0 → 0.1.0
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.
- data/.travis.yml +13 -0
- data/{LICENSE → MIT-LICENSE} +1 -1
- data/README.md +115 -3
- data/Rakefile +6 -0
- data/gemfiles/Gemfile.rb-1.8.7 +6 -0
- data/lib/npr/api/client.rb +87 -0
- data/lib/npr/api/message.rb +38 -0
- data/lib/npr/api/query_builder.rb +222 -0
- data/lib/npr/api/response.rb +32 -0
- data/lib/npr/api.rb +7 -0
- data/lib/npr/concern/attr_typecast.rb +59 -0
- data/lib/npr/concern/relation.rb +103 -0
- data/lib/npr/concern/shallow_attributes.rb +71 -0
- data/lib/npr/concern.rb +9 -0
- data/lib/npr/configuration.rb +120 -0
- data/lib/npr/core_ext/array/wrap.rb +15 -0
- data/lib/npr/entity/audio.rb +28 -0
- data/lib/npr/entity/author.rb +22 -0
- data/lib/npr/entity/base.rb +19 -0
- data/lib/npr/entity/book.rb +21 -0
- data/lib/npr/entity/book_edition.rb +26 -0
- data/lib/npr/entity/byline.rb +18 -0
- data/lib/npr/entity/collection.rb +11 -0
- data/lib/npr/entity/crop.rb +20 -0
- data/lib/npr/entity/enlargement.rb +20 -0
- data/lib/npr/entity/formats.rb +19 -0
- data/lib/npr/entity/image.rb +33 -0
- data/lib/npr/entity/intro_text.rb +21 -0
- data/lib/npr/entity/link.rb +23 -0
- data/lib/npr/entity/list.rb +28 -0
- data/lib/npr/entity/list_text.rb +19 -0
- data/lib/npr/entity/member.rb +23 -0
- data/lib/npr/entity/member_byline.rb +17 -0
- data/lib/npr/entity/member_promo_art.rb +17 -0
- data/lib/npr/entity/mp3.rb +23 -0
- data/lib/npr/entity/organization.rb +18 -0
- data/lib/npr/entity/paragraph.rb +27 -0
- data/lib/npr/entity/permissions.rb +18 -0
- data/lib/npr/entity/program.rb +24 -0
- data/lib/npr/entity/promo_art.rb +17 -0
- data/lib/npr/entity/promo_art_book_edition.rb +18 -0
- data/lib/npr/entity/provider.rb +23 -0
- data/lib/npr/entity/pull_quote.rb +16 -0
- data/lib/npr/entity/related_link.rb +21 -0
- data/lib/npr/entity/show.rb +19 -0
- data/lib/npr/entity/story.rb +179 -0
- data/lib/npr/entity/text.rb +22 -0
- data/lib/npr/entity/title.rb +21 -0
- data/lib/npr/entity/transcript.rb +16 -0
- data/lib/npr/entity.rb +7 -0
- data/lib/npr/errors.rb +17 -0
- data/lib/npr/version.rb +1 -1
- data/lib/npr.rb +64 -3
- data/npr.gemspec +12 -2
- data/spec/fixtures/README.md +30 -0
- data/spec/fixtures/atom/01_story_full_media.atom +36 -0
- data/spec/fixtures/atom/02_story_multiple_images.atom +32 -0
- data/spec/fixtures/atom/03_no_results.atom +10 -0
- data/spec/fixtures/atom/04_invalid_id.atom +344 -0
- data/spec/fixtures/atom/05_no_api_key.atom +9 -0
- data/spec/fixtures/atom/06_story_multiple_ids.atom +59 -0
- data/spec/fixtures/fetch_formats.rb +65 -0
- data/spec/fixtures/html/01_story_full_media.html +54 -0
- data/spec/fixtures/html/02_story_multiple_images.html +55 -0
- data/spec/fixtures/html/03_no_results.html +38 -0
- data/spec/fixtures/html/04_invalid_id.html +82 -0
- data/spec/fixtures/html/05_no_api_key.html +8 -0
- data/spec/fixtures/html/06_story_multiple_ids.html +69 -0
- data/spec/fixtures/js/01_story_full_media.js +1 -0
- data/spec/fixtures/js/02_story_multiple_images.js +1 -0
- data/spec/fixtures/js/03_no_results.js +1 -0
- data/spec/fixtures/js/04_invalid_id.js +1 -0
- data/spec/fixtures/js/05_no_api_key.js +8 -0
- data/spec/fixtures/js/06_story_multiple_ids.js +1 -0
- data/spec/fixtures/json/01_story_full_media.json +1 -0
- data/spec/fixtures/json/02_story_multiple_images.json +1 -0
- data/spec/fixtures/json/03_no_results.json +1 -0
- data/spec/fixtures/json/04_invalid_id.json +1 -0
- data/spec/fixtures/json/05_no_api_key.json +1 -0
- data/spec/fixtures/json/06_story_multiple_ids.json +1 -0
- data/spec/fixtures/json/list.json +1 -0
- data/spec/fixtures/mediarss/01_story_full_media.rss +31 -0
- data/spec/fixtures/mediarss/02_story_multiple_images.rss +40 -0
- data/spec/fixtures/mediarss/03_no_results.rss +17 -0
- data/spec/fixtures/mediarss/04_invalid_id.rss +279 -0
- data/spec/fixtures/mediarss/05_no_api_key.rss +31 -0
- data/spec/fixtures/mediarss/06_story_multiple_ids.rss +65 -0
- data/spec/fixtures/nprml/01_story_full_media.xml +271 -0
- data/spec/fixtures/nprml/02_story_multiple_images.xml +165 -0
- data/spec/fixtures/nprml/03_no_results.xml +14 -0
- data/spec/fixtures/nprml/04_invalid_id.xml +1780 -0
- data/spec/fixtures/nprml/05_no_api_key.xml +9 -0
- data/spec/fixtures/nprml/06_story_multiple_ids.xml +435 -0
- data/spec/fixtures/nprml/list.xml +440 -0
- data/spec/fixtures/podcast/01_story_full_media.rss +30 -0
- data/spec/fixtures/podcast/02_story_multiple_images.rss +32 -0
- data/spec/fixtures/podcast/03_no_results.rss +19 -0
- data/spec/fixtures/podcast/04_invalid_id.rss +186 -0
- data/spec/fixtures/podcast/05_no_api_key.rss +31 -0
- data/spec/fixtures/podcast/06_story_multiple_ids.rss +43 -0
- data/spec/fixtures/rss/01_story_full_media.rss +25 -0
- data/spec/fixtures/rss/02_story_multiple_images.rss +25 -0
- data/spec/fixtures/rss/03_no_results.rss +17 -0
- data/spec/fixtures/rss/04_invalid_id.rss +137 -0
- data/spec/fixtures/rss/05_no_api_key.rss +31 -0
- data/spec/fixtures/rss/06_story_multiple_ids.rss +33 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/support/config_helper.rb +64 -0
- data/spec/support/fake_response.rb +54 -0
- data/spec/support/fixture_helper.rb +23 -0
- data/spec/unit/api/client_spec.rb +42 -0
- data/spec/unit/api/message_spec.rb +68 -0
- data/spec/unit/api/query_builder_spec.rb +195 -0
- data/spec/unit/api/response_spec.rb +45 -0
- data/spec/unit/configuration_spec.rb +63 -0
- data/spec/unit/entity/audio_spec.rb +75 -0
- data/spec/unit/entity/author_spec.rb +30 -0
- data/spec/unit/entity/base_spec.rb +87 -0
- data/spec/unit/entity/book_edition_spec.rb +57 -0
- data/spec/unit/entity/book_spec.rb +31 -0
- data/spec/unit/entity/byline_spec.rb +23 -0
- data/spec/unit/entity/collection_spec.rb +39 -0
- data/spec/unit/entity/crop_spec.rb +25 -0
- data/spec/unit/entity/englargement_spec.rb +21 -0
- data/spec/unit/entity/formats_spec.rb +41 -0
- data/spec/unit/entity/image_spec.rb +82 -0
- data/spec/unit/entity/intro_text_spec.rb +25 -0
- data/spec/unit/entity/link_spec.rb +25 -0
- data/spec/unit/entity/list_spec.rb +22 -0
- data/spec/unit/entity/list_text_spec.rb +31 -0
- data/spec/unit/entity/member_byline_spec.rb +21 -0
- data/spec/unit/entity/member_promo_art_spec.rb +21 -0
- data/spec/unit/entity/member_spec.rb +59 -0
- data/spec/unit/entity/mp3_spec.rb +25 -0
- data/spec/unit/entity/organization_spec.rb +29 -0
- data/spec/unit/entity/paragraph_spec.rb +25 -0
- data/spec/unit/entity/permissions_spec.rb +56 -0
- data/spec/unit/entity/program_spec.rb +27 -0
- data/spec/unit/entity/promo_art_book_edition_spec.rb +21 -0
- data/spec/unit/entity/promo_art_spec.rb +42 -0
- data/spec/unit/entity/pull_quote_spec.rb +29 -0
- data/spec/unit/entity/related_link_spec.rb +55 -0
- data/spec/unit/entity/show_spec.rb +41 -0
- data/spec/unit/entity/story_spec.rb +154 -0
- data/spec/unit/entity/text_spec.rb +54 -0
- data/spec/unit/entity/title_spec.rb +25 -0
- data/spec/unit/entity/transcript_spec.rb +22 -0
- metadata +340 -8
data/.travis.yml
ADDED
data/{LICENSE → MIT-LICENSE}
RENAMED
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
19
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
20
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
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.
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,6 +1,40 @@
|
|
1
|
-
# NPR Ruby Client
|
1
|
+
# NPR API Ruby Client
|
2
|
+
|
3
|
+
[](https://travis-ci.org/bricker88/npr)
|
4
|
+
|
5
|
+
**NOTE** This gem is a WIP
|
6
|
+
|
7
|
+
A simple Ruby client for the
|
8
|
+
[NPR API](http://www.npr.org/api/index).
|
9
|
+
|
10
|
+
|
11
|
+
## Support
|
12
|
+
|
13
|
+
This gem is tested with these versions (but may
|
14
|
+
work with others):
|
15
|
+
|
16
|
+
* Ruby 1.8.7, 1.9.2, 1.9.3, ruby-head
|
17
|
+
* NPR API version 0.94
|
18
|
+
|
19
|
+
|
20
|
+
## Dependencies
|
21
|
+
|
22
|
+
* `faraday >= 0.8.0` (HTTP requests)
|
23
|
+
* `faraday_middleware >= 0.9.0` (response processing)
|
24
|
+
|
25
|
+
**NOTE** If you are running **Ruby < 1.9**, you will have to install
|
26
|
+
the [json gem](http://rubygems.org/gems/json):
|
27
|
+
|
28
|
+
In your Gemfile:
|
29
|
+
|
30
|
+
gem 'json', '~> 1.7.5'
|
31
|
+
|
32
|
+
From the command line:
|
33
|
+
|
34
|
+
$ gem install json
|
35
|
+
|
36
|
+
Ruby 1.9+ comes with JSON support built-in!
|
2
37
|
|
3
|
-
A simple Ruby client for the NPR API
|
4
38
|
|
5
39
|
## Installation
|
6
40
|
|
@@ -16,9 +50,87 @@ Or install it yourself as:
|
|
16
50
|
|
17
51
|
$ gem install npr
|
18
52
|
|
53
|
+
|
19
54
|
## Usage
|
20
55
|
|
21
|
-
|
56
|
+
### API Key
|
57
|
+
|
58
|
+
NPR requires that you have an API key in order to use
|
59
|
+
their API. More information about this (including how
|
60
|
+
to register) can be found at
|
61
|
+
[NPR's API Documentation](http://www.npr.org/api/index).
|
62
|
+
|
63
|
+
### Configuration
|
64
|
+
|
65
|
+
API requests can be configured globally. This is recommended
|
66
|
+
for setting the API Key, but you can also set other parameters
|
67
|
+
which will be passed in with every request (unless overridden):
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
NPR.configure do |config|
|
71
|
+
config.apiKey = "YOUR_API_KEY"
|
72
|
+
config.sort = "date descending"
|
73
|
+
config.requiredAssets = "text"
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
For a Rails application, a good place to put the configuration
|
78
|
+
would be in an initializer, such as `config/initializers/npr_config.rb`.
|
79
|
+
|
80
|
+
### DSL
|
81
|
+
|
82
|
+
The DSL is modeled after Rails' `ActiveRecord::Relation`, so for the
|
83
|
+
most part, if you understand that, then using the NPR gem will come
|
84
|
+
naturally to you!
|
85
|
+
|
86
|
+
To find a story by ID:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
NPR::Story.find(1999) #=> NPR::Story
|
90
|
+
```
|
91
|
+
|
92
|
+
`NPR::Story#find` will either return a Story object if it was found,
|
93
|
+
or an array of Messages from the NPR API.
|
94
|
+
|
95
|
+
Building a query:
|
96
|
+
|
97
|
+
```
|
98
|
+
NPR::Story.where(date: [2.days.ago..Time.now]).order("date ascending").limit(10).offset(50)
|
99
|
+
```
|
100
|
+
|
101
|
+
That's a contrived example but it shows all the methods available.
|
102
|
+
|
103
|
+
You can also query directly on an `NPR::API::Client` object, if you're
|
104
|
+
feeling adventurous:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
client = NPR::API::Client.new(apiKey: NPR.config.apiKey)
|
108
|
+
client.query(sort: "editor assigned", numResults: "12")
|
109
|
+
```
|
110
|
+
|
111
|
+
The params that get passed into the `#query` method map directly to
|
112
|
+
the parameters that NPR's API accepts. See the
|
113
|
+
[NPR API Input Reference](http://www.npr.org/api/inputReference.php)
|
114
|
+
for all of the options.
|
115
|
+
|
116
|
+
|
117
|
+
## TODO
|
118
|
+
|
119
|
+
* More Documentation
|
120
|
+
* Search functionality
|
121
|
+
* Add "select" method to QueryBuilder for the "fields" input
|
122
|
+
* Abstract attributes so they're not tied directly to the API response.
|
123
|
+
Also to make them more Ruby-conventional (i.e. snake_case)
|
124
|
+
* Example: "apiKey" => :api_key
|
125
|
+
* Support for "container" node
|
126
|
+
* Support for "parent" node
|
127
|
+
* Support for "thumbnail" node
|
128
|
+
* Support a way to return raw formats of:
|
129
|
+
* HTML / Javascript (for views)
|
130
|
+
* JSON
|
131
|
+
* ATOM
|
132
|
+
* RSS
|
133
|
+
|
22
134
|
|
23
135
|
## Contributing
|
24
136
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,87 @@
|
|
1
|
+
##
|
2
|
+
# NPR::API::Client
|
3
|
+
#
|
4
|
+
# Basic client for interacting with the NPR API.
|
5
|
+
#
|
6
|
+
# Options passed in when initializing the client will
|
7
|
+
# go out with every API request. You may also pass in
|
8
|
+
# options to +#query+ for a per-request basis.
|
9
|
+
#
|
10
|
+
# You can also set params via +client.params+
|
11
|
+
#
|
12
|
+
# Params should be passed in exactly as they will be sent
|
13
|
+
# to the API. Example: "apiKey", not "api_key"
|
14
|
+
# See the API documentation for what those params are.
|
15
|
+
#
|
16
|
+
module NPR
|
17
|
+
module API
|
18
|
+
class Client
|
19
|
+
attr_accessor :params
|
20
|
+
|
21
|
+
#-----------------
|
22
|
+
# Argument is a hash of params to send to the API.
|
23
|
+
# See <http://www.npr.org/api/inputReference.php> for
|
24
|
+
# API documentation.
|
25
|
+
#
|
26
|
+
# Example:
|
27
|
+
#
|
28
|
+
# NPR::Client.new(apiKey: "YOUR_API_KEY", sort: "date descending")
|
29
|
+
#
|
30
|
+
# Any parameters passed into this method will override the
|
31
|
+
# global configuration.
|
32
|
+
#
|
33
|
+
def initialize(params={})
|
34
|
+
@params = NPR.config.merge(params)
|
35
|
+
@apiKey = @params.delete(:apiKey)
|
36
|
+
end
|
37
|
+
|
38
|
+
#-----------------
|
39
|
+
# Send a query to the NPR API.
|
40
|
+
#
|
41
|
+
# Accepts a hash of options which get passed
|
42
|
+
# directly to the API.
|
43
|
+
#
|
44
|
+
# Any parameters passed directly into this method
|
45
|
+
# will override both the global configuration,
|
46
|
+
# as well as any parameters stored in this object's
|
47
|
+
# @params.
|
48
|
+
#
|
49
|
+
# Example:
|
50
|
+
#
|
51
|
+
# client.query(sort: "date descending", requiredAssets: "image")
|
52
|
+
#
|
53
|
+
# For now, this forced JSON output.
|
54
|
+
# TODO: Support more formats
|
55
|
+
#
|
56
|
+
def query(params={})
|
57
|
+
if @apiKey.nil?
|
58
|
+
raise NPR::NotConfiguredError, "apiKey must be set to perform a query"
|
59
|
+
end
|
60
|
+
|
61
|
+
response = connection.get do |request|
|
62
|
+
request.url NPR::Configuration::API_QUERY_PATH
|
63
|
+
request.params = @params.merge(params)
|
64
|
+
request.params['output'] = "json"
|
65
|
+
request.params['apiKey'] = @apiKey
|
66
|
+
end
|
67
|
+
|
68
|
+
NPR::API::Response.new(response)
|
69
|
+
end
|
70
|
+
|
71
|
+
#-----------------
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
#-----------------
|
76
|
+
|
77
|
+
def connection
|
78
|
+
@connection ||= begin
|
79
|
+
Faraday.new NPR::Configuration::API_ROOT do |conn|
|
80
|
+
conn.response :json, :content_type => /\bjson$/
|
81
|
+
conn.adapter Faraday.default_adapter
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end # Client
|
86
|
+
end # API
|
87
|
+
end # NPR
|
@@ -0,0 +1,38 @@
|
|
1
|
+
##
|
2
|
+
# NPR::API::Message
|
3
|
+
#
|
4
|
+
# If the API returns any messages, use this class
|
5
|
+
# to represent it.
|
6
|
+
#
|
7
|
+
module NPR
|
8
|
+
module API
|
9
|
+
class Message
|
10
|
+
include NPR::Concern::ShallowAttributes
|
11
|
+
|
12
|
+
attr_accessor :id, :level
|
13
|
+
shallow_attribute "text", "timestamp"
|
14
|
+
|
15
|
+
#------------------
|
16
|
+
|
17
|
+
def initialize(json)
|
18
|
+
@_json = json
|
19
|
+
@id = @_json["id"]
|
20
|
+
@level = @_json["level"]
|
21
|
+
|
22
|
+
extract_shallow_attributes(@_json)
|
23
|
+
end
|
24
|
+
|
25
|
+
#------------------
|
26
|
+
|
27
|
+
def error?
|
28
|
+
self.level == "error"
|
29
|
+
end
|
30
|
+
|
31
|
+
#------------------
|
32
|
+
|
33
|
+
def warning?
|
34
|
+
self.level == "warning"
|
35
|
+
end
|
36
|
+
end # Message
|
37
|
+
end # API
|
38
|
+
end # NPR
|
@@ -0,0 +1,222 @@
|
|
1
|
+
##
|
2
|
+
# NPR::API::QueryBuilder
|
3
|
+
#
|
4
|
+
module NPR
|
5
|
+
module API
|
6
|
+
class QueryBuilder
|
7
|
+
CLASS_BUILDER_METHODS = [
|
8
|
+
:where,
|
9
|
+
:order,
|
10
|
+
:limit,
|
11
|
+
:offset
|
12
|
+
]
|
13
|
+
|
14
|
+
attr_reader :_klass, :builder
|
15
|
+
|
16
|
+
#-----------------------
|
17
|
+
|
18
|
+
def initialize(klass)
|
19
|
+
@_klass = klass
|
20
|
+
@builder = {}
|
21
|
+
end
|
22
|
+
|
23
|
+
#-----------------------
|
24
|
+
# Build the params hash.
|
25
|
+
# This is automatically called by #to_a, so it probably
|
26
|
+
# doesn't need to be used manually.
|
27
|
+
def to_params
|
28
|
+
if @_klass == NPR::Entity::Story && @builder[:conditions]
|
29
|
+
conditions = parse_conditions(@builder[:conditions])
|
30
|
+
else
|
31
|
+
conditions = @builder[:conditions]
|
32
|
+
end
|
33
|
+
|
34
|
+
params = conditions || {}
|
35
|
+
params[:sort] = @builder[:order] if @builder[:order]
|
36
|
+
params[:numResults] = @builder[:limit] if @builder[:limit]
|
37
|
+
params[:startNum] = @builder[:offset] if @builder[:offset]
|
38
|
+
params.merge!(@builder[:extra]) if @builder[:extra]
|
39
|
+
|
40
|
+
params
|
41
|
+
end
|
42
|
+
|
43
|
+
#-----------------------
|
44
|
+
# Fire the query and return an Array of stories (or empty [])
|
45
|
+
#
|
46
|
+
# Named +to_a+ to keep in line with ActiveRecord::Relation's
|
47
|
+
# naming convention. It is also aliased as +query+, which
|
48
|
+
# probably makes a little more sense.
|
49
|
+
#
|
50
|
+
# Returns an Array. If the query returned any stories, then
|
51
|
+
# it will be an array of those stories. If no stories were
|
52
|
+
# returned, then it will be an empty array.
|
53
|
+
#
|
54
|
+
# There is no way to access the List or Messages returned
|
55
|
+
# from the response. This method is meant to be a way to
|
56
|
+
# get to the Stories as quickly and easily as possible.
|
57
|
+
# If you want access to the full Response object, use #query.
|
58
|
+
#
|
59
|
+
# Example:
|
60
|
+
#
|
61
|
+
# query = NPR::API::QueryBuilder.new(NPR::Story)
|
62
|
+
# query.where(:id => [100, 150]).to_a
|
63
|
+
# #=> [NPR::Story, NPR::Story]
|
64
|
+
#
|
65
|
+
# # Assuming there is no story with an ID of 1
|
66
|
+
# query.where(:id => 1).to_a
|
67
|
+
# #=> []
|
68
|
+
#
|
69
|
+
# Note that for this method, +NPR.config.apiKey+ must be set.
|
70
|
+
#
|
71
|
+
def to_a
|
72
|
+
response = self.query
|
73
|
+
stories = []
|
74
|
+
|
75
|
+
if list = response.list
|
76
|
+
stories = Array.wrap(response.list.stories)
|
77
|
+
end
|
78
|
+
|
79
|
+
stories
|
80
|
+
end
|
81
|
+
|
82
|
+
#-----------------------
|
83
|
+
# Fire the query and return the full Response object
|
84
|
+
#
|
85
|
+
# Example:
|
86
|
+
#
|
87
|
+
# query = NPR::API::QueryBuilder.new(NPR::Story)
|
88
|
+
# query.where(:id => [100, 150]).query
|
89
|
+
# #=> NPR::API::Response
|
90
|
+
#
|
91
|
+
# See NPR::API::Response for what methods are available
|
92
|
+
# to you.
|
93
|
+
#
|
94
|
+
# Note that for this method, +NPR.config.apiKey+ must be set.
|
95
|
+
def query
|
96
|
+
client.query(self.to_params)
|
97
|
+
end
|
98
|
+
|
99
|
+
#-----------------------
|
100
|
+
# Add in arbitrary parameters.
|
101
|
+
#
|
102
|
+
# These take precedence over anything set via
|
103
|
+
# any of the other builder methods.
|
104
|
+
#
|
105
|
+
# Accepts a hash of key/values that the API
|
106
|
+
# can receive and handle.
|
107
|
+
#
|
108
|
+
# Example:
|
109
|
+
#
|
110
|
+
# query.set(apiKey: "YOUR_API_KEY")
|
111
|
+
#
|
112
|
+
def set(params)
|
113
|
+
@builder[:extra] = (@builder[:extra] || {}).merge(params)
|
114
|
+
self
|
115
|
+
end
|
116
|
+
|
117
|
+
#-----------------------
|
118
|
+
# Merge in the passed-in conditions to what
|
119
|
+
# already exists.
|
120
|
+
#
|
121
|
+
# Accepts a Hash.
|
122
|
+
#
|
123
|
+
# Example:
|
124
|
+
#
|
125
|
+
# query.where(id: 999, requiredAssets: "text")
|
126
|
+
#
|
127
|
+
# Extra convenience:
|
128
|
+
#
|
129
|
+
# * You may pass an array to :id
|
130
|
+
#
|
131
|
+
# query.where(id: [70, 180])
|
132
|
+
#
|
133
|
+
# * You may pass a date range to :date
|
134
|
+
#
|
135
|
+
# last_week = Time.new(2012, 10, 21)
|
136
|
+
# yesterday = Time.new(2012, 10, 25)
|
137
|
+
# query.where(date: (last_week..yesterday))
|
138
|
+
#
|
139
|
+
def where(conditions)
|
140
|
+
@builder[:conditions] = (@builder[:conditions] || {}).merge(conditions)
|
141
|
+
self
|
142
|
+
end
|
143
|
+
|
144
|
+
#-----------------------
|
145
|
+
# Set the order.
|
146
|
+
#
|
147
|
+
# Accepts a String.
|
148
|
+
#
|
149
|
+
# Example:
|
150
|
+
#
|
151
|
+
# query.order("date descending")
|
152
|
+
#
|
153
|
+
def order(order)
|
154
|
+
@builder[:order] = order
|
155
|
+
self
|
156
|
+
end
|
157
|
+
|
158
|
+
#-----------------------
|
159
|
+
# Set the limit.
|
160
|
+
#
|
161
|
+
# Accepts an Integer.
|
162
|
+
#
|
163
|
+
# Example:
|
164
|
+
#
|
165
|
+
# query.limit(10)
|
166
|
+
#
|
167
|
+
# Note that NPR limits the maximum results to 20,
|
168
|
+
# and will return only 20 results if more than the
|
169
|
+
# maximum is requested.
|
170
|
+
def limit(limit)
|
171
|
+
@builder[:limit] = limit
|
172
|
+
self
|
173
|
+
end
|
174
|
+
|
175
|
+
#-----------------------
|
176
|
+
# Offset the number of results
|
177
|
+
# Useful for pagination
|
178
|
+
#
|
179
|
+
# Accepts an Integer.
|
180
|
+
#
|
181
|
+
# Example:
|
182
|
+
#
|
183
|
+
# query.offset(100)
|
184
|
+
#
|
185
|
+
def offset(offset)
|
186
|
+
@builder[:offset] = offset
|
187
|
+
self
|
188
|
+
end
|
189
|
+
|
190
|
+
#-----------------------
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
def client
|
195
|
+
@client ||= NPR::API::Client.new(:apiKey => NPR.config.apiKey)
|
196
|
+
end
|
197
|
+
|
198
|
+
#-----------------------
|
199
|
+
|
200
|
+
def parse_conditions(conditions)
|
201
|
+
parse_conditions!(conditions.dup)
|
202
|
+
end
|
203
|
+
|
204
|
+
#-----------------------
|
205
|
+
|
206
|
+
def parse_conditions!(conditions)
|
207
|
+
|
208
|
+
if conditions[:id].is_a? Array
|
209
|
+
conditions[:id] = conditions[:id].join(",")
|
210
|
+
end
|
211
|
+
|
212
|
+
if conditions[:date].is_a? Range
|
213
|
+
conditions[:startDate] = conditions[:date].first
|
214
|
+
conditions[:endDate] = conditions[:date].last
|
215
|
+
conditions.delete(:date)
|
216
|
+
end
|
217
|
+
|
218
|
+
conditions
|
219
|
+
end
|
220
|
+
end # QueryBuilder
|
221
|
+
end # API
|
222
|
+
end # NPR
|
@@ -0,0 +1,32 @@
|
|
1
|
+
##
|
2
|
+
# NPR::API::Response
|
3
|
+
#
|
4
|
+
# Wrapper around a Faraday response object
|
5
|
+
# Pass in the full response object from Faraday
|
6
|
+
#
|
7
|
+
module NPR
|
8
|
+
module API
|
9
|
+
class Response
|
10
|
+
include NPR::Concern::Relation
|
11
|
+
|
12
|
+
has_many "messages", :key => "message", :class_name => NPR::API::Message
|
13
|
+
attr_reader :raw, :version, :messages, :list
|
14
|
+
|
15
|
+
#--------------------------
|
16
|
+
|
17
|
+
def initialize(response)
|
18
|
+
create_relations(response)
|
19
|
+
@raw = response
|
20
|
+
@version = response.body["version"]
|
21
|
+
|
22
|
+
if response.body["list"]
|
23
|
+
@list = NPR::Entity::List.new(response.body["list"])
|
24
|
+
end
|
25
|
+
|
26
|
+
Array.wrap(response.body["message"]).each do |message|
|
27
|
+
@messages.push NPR::API::Message.new(message)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end # Response
|
31
|
+
end # API
|
32
|
+
end # NPR
|
data/lib/npr/api.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
##
|
4
|
+
# NPR::Concern::AttrTypecast
|
5
|
+
#
|
6
|
+
module NPR
|
7
|
+
#------------------
|
8
|
+
# Attributes that are being typecast to Ruby classes
|
9
|
+
ATTR_TYPES = {
|
10
|
+
"id" => :string_to_i,
|
11
|
+
"partnerId" => :string_to_i,
|
12
|
+
"storyDate" => :string_time_parse,
|
13
|
+
"pubDate" => :string_time_parse,
|
14
|
+
"lastModifiedDate" => :string_time_parse,
|
15
|
+
"showDate" => :string_time_parse,
|
16
|
+
"date" => :string_time_parse,
|
17
|
+
"segNum" => :string_to_i,
|
18
|
+
"num" => :string_to_i,
|
19
|
+
"timestamp" => :string_time_at,
|
20
|
+
"duration" => :string_to_i
|
21
|
+
}
|
22
|
+
|
23
|
+
module Concern
|
24
|
+
module AttrTypecast
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
#------------------
|
29
|
+
# Typecasting methods
|
30
|
+
def string_to_i(value)
|
31
|
+
value.to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
#------------------
|
35
|
+
|
36
|
+
def string_time_parse(value)
|
37
|
+
!value.empty? ? Time.parse(value) : nil
|
38
|
+
end
|
39
|
+
|
40
|
+
#------------------
|
41
|
+
|
42
|
+
def string_time_at(value)
|
43
|
+
Time.at(value.to_f)
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
#------------------
|
48
|
+
#------------------
|
49
|
+
|
50
|
+
def attr_typecast(key, value)
|
51
|
+
if method = NPR::ATTR_TYPES[key]
|
52
|
+
send method, value
|
53
|
+
else
|
54
|
+
value
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end # AttrTypecast
|
58
|
+
end # Concern
|
59
|
+
end # NPR
|