wp-api 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: be8b365075e87e981f79e61c1a7e766cd93d078b
4
- data.tar.gz: 4c59262402ba39fa3ab8ce90e6d05b24c3b285b7
3
+ metadata.gz: e47781bfa7510821225aeb90053dab50a11b7579
4
+ data.tar.gz: 74a354808fa1138efa2fcb3ee7a43312c1467ef7
5
5
  SHA512:
6
- metadata.gz: f2658d1c1d13e70bcdcaf28858a8c21c8b980b7a3413df509e99683cb8ab6b9a7274d92005cbd4afffb010341575fc34f67fafee91b1a3c80b3c4057939da8bd
7
- data.tar.gz: c55d99f6ff6c9fd6aa2d5c0c58d203dbbe664f7a681f5baa0d142464caf94b6e90c92b0cd5dd3745f3e56840df753b79deb25ce711847e2ec01359095c7e1778
6
+ metadata.gz: b9d09030d433e7a192488d991ffa4df5bb7805d90817e82fea9e0d7377dae30b432c025c0df98f9ed05569ec34e6daccb8975e5ff0d1e09650370205ee0b1c6c
7
+ data.tar.gz: b653ec85e6228bf9c61fa0a40d61a788e56977f6856128917d4f713f0995000a2463ae2fff1f20588541d4f4a571adc73872f33305bb1a21ac81c7f0f61d6f9b
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.2
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # WP::API
2
2
 
3
+ [![Circle CI](https://circleci.com/gh/colinyoung/wp-api.png?style=badge)](https://circleci.com/gh/colinyoung/wp-api)
4
+
3
5
  Makes it incredibly easy and semantic to access Wordpress blogs that have the new, RESTful WP API plugin installed.
4
6
 
5
7
  ## Installation
@@ -7,6 +9,10 @@ Makes it incredibly easy and semantic to access Wordpress blogs that have the ne
7
9
  gem 'wp-api'
8
10
  bundle
9
11
 
12
+ ## Note
13
+
14
+ This gem requires Ruby 2.0, which is the [oldest currently supported version of Ruby](https://www.ruby-lang.org/en/news/2014/07/01/eol-for-1-8-7-and-1-9-2/).
15
+
10
16
  ## Usage
11
17
 
12
18
  ```ruby
@@ -22,3 +28,4 @@ client.users
22
28
  ## Author
23
29
 
24
30
  @colinyoung
31
+
data/circle.yml ADDED
@@ -0,0 +1,3 @@
1
+ machine:
2
+ ruby:
3
+ version: 2.1.2
data/lib/wp/api/client.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'httparty'
2
- require 'yajl'
3
2
  require 'addressable/uri'
4
3
  require 'wp/api/endpoints'
5
4
 
@@ -20,8 +19,12 @@ module WP::API
20
19
 
21
20
  def get(resource, query = {})
22
21
  path = url_for(resource, query)
23
- body = Client.get(path).body
24
- parse(body)
22
+ response = Client.get(path)
23
+ if response.empty?
24
+ raise WP::API::ResourceNotFoundError
25
+ else
26
+ [ response.parsed_response, response.headers ] # Already parsed.
27
+ end
25
28
  end
26
29
 
27
30
  private
@@ -35,13 +38,13 @@ module WP::API
35
38
 
36
39
  def params(query)
37
40
  uri = Addressable::URI.new
38
- uri.query_values = query
39
- uri.query
40
- end
41
+ filter_hash = {}
42
+ query.each do |key, value|
43
+ filter_hash["filter[#{key}]"] = value
44
+ end
45
+ uri.query_values = filter_hash
41
46
 
42
- def parse(string)
43
- @parser ||= Yajl::Parser.new
44
- @parser.parse(string)
47
+ uri.query
45
48
  end
46
49
  end
47
50
  end
@@ -2,14 +2,18 @@ module WP::API
2
2
  module Endpoints
3
3
 
4
4
  def posts(query = {})
5
- get("posts", query).collect do |hash|
6
- Post.new(hash)
5
+ posts, headers = get("posts", query)
6
+ posts.collect do |hash|
7
+ WP::API::Post.new(hash, headers)
7
8
  end
8
9
  end
9
10
 
10
11
  def post(id, query = {})
11
- hash = get("posts/#{id}", query)
12
- Post.new(hash)
12
+ WP::API::Post.new *get("posts/#{id}", query)
13
+ end
14
+
15
+ def post_named(slug)
16
+ WP::API::Post.new *get("posts", name: slug).first
13
17
  end
14
18
 
15
19
  end
@@ -0,0 +1,3 @@
1
+ module WP::API
2
+ class ResourceNotFoundError < Exception; end
3
+ end
@@ -1,15 +1,18 @@
1
1
  require 'active_support/inflector'
2
+ require 'pry'
2
3
 
3
4
  module WP::API
4
5
  class Resource
5
- attr_reader :attributes
6
+ attr_reader :attributes, :headers
6
7
 
7
- def initialize(attributes)
8
+ def initialize(attributes, headers = {})
9
+ raise ResourceNotFoundError.new(self.class.name) if attributes.nil?
8
10
  @attributes = attributes
11
+ @headers = _downcase_keys(headers).slice("link") if headers
9
12
  end
10
13
 
11
14
  def id
12
- @attributes['ID']
15
+ attributes['ID']
13
16
  end
14
17
 
15
18
  protected
@@ -19,22 +22,22 @@ module WP::API
19
22
  determinant = key[-1]
20
23
  case determinant
21
24
  when '?' # example: post.sticky?
22
- @attributes[key.chomp(determinant)] == true
25
+ attributes[key.chomp(determinant)] == true
23
26
  when '!' # unsupported
24
27
  fail NoMethodError.new(key)
25
28
  when '=' # example: post.title = 'my new title'
26
- @attributes[key.chomp(determinant)] = new_value
29
+ attributes[key.chomp(determinant)] = new_value
27
30
  else
28
31
  # All other values. Hashes are converted to objects
29
32
  # if a resource for them exists (e.g. Authors)
30
- object key, @attributes[key]
33
+ object key, attributes[key]
31
34
  end
32
35
  end
33
36
 
34
37
  private
35
38
 
36
39
  def to_s
37
- @attributes.to_s
40
+ attributes.to_s
38
41
  end
39
42
 
40
43
  def object(key, value)
@@ -46,5 +49,13 @@ module WP::API
46
49
  value
47
50
  end
48
51
  end
52
+
53
+ def _downcase_keys(hash)
54
+ Hash.new.tap do |new_hash|
55
+ hash.each do |k, v|
56
+ new_hash[k.downcase] = v
57
+ end
58
+ end
59
+ end
49
60
  end
50
61
  end
@@ -0,0 +1,7 @@
1
+ module WP::API
2
+ class Category < Resource
3
+ def to_param
4
+ slug
5
+ end
6
+ end
7
+ end
@@ -1,4 +1,35 @@
1
1
  module WP::API
2
2
  class Post < Resource
3
+ def categories
4
+ terms['category'].collect {|cat| WP::API::Category.new(cat) }
5
+ end
6
+
7
+ def prev
8
+ item = link_header_items.find {|rel, url| rel == "prev" }
9
+ item.last if item
10
+ end
11
+
12
+ def next
13
+ item = link_header_items.find {|rel, url| rel == "next" }
14
+ item.last if item
15
+ end
16
+
17
+ def items
18
+ items = link_header_items.select {|rel, url| rel == "item" }
19
+ items.empty? ? [] : items.collect(&:last)
20
+ end
21
+
22
+ private
23
+
24
+ def link_header_items
25
+ @link_header_items ||= headers['link'].split(', ').collect do |header|
26
+ [
27
+ header.match(/rel="([^"]+)"/)[1],
28
+ header.match(/<([^>]+)>/)[1]
29
+ ]
30
+ end
31
+ rescue
32
+ []
33
+ end
3
34
  end
4
35
  end
@@ -1,5 +1,5 @@
1
1
  module WP
2
2
  module API
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  end
data/lib/wp/api.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  require 'wp/api/version'
2
+ require 'wp/api/errors'
2
3
  require 'wp/api/resource'
3
- Dir['lib/wp/api/resources/*.rb'].each {|resource| require resource }
4
+ Dir[File.expand_path(File.dirname(__FILE__) + '/api/resources/*.rb')].each {|resource| require resource }
4
5
  require 'wp/api/client'
5
6
 
6
7
  require 'httparty'
7
- require 'yajl'
8
8
 
9
9
  module WP
10
10
  module API
@@ -17,6 +17,14 @@ describe WP::API do
17
17
  expect(subject).to be_a WP::API::Post
18
18
  end
19
19
 
20
+ it "should have an attributes hash" do
21
+ expect(subject.attributes).to be_a Hash
22
+ end
23
+
24
+ it "should have a headers hash" do
25
+ expect(subject.headers).to be_a Hash
26
+ end
27
+
20
28
  it "should have correct IDs" do
21
29
  expect(subject.id).to eq 1
22
30
  end
@@ -1,5 +1,3 @@
1
- require 'pry'
2
-
3
1
  describe WP::API do
4
2
  context "raw HTTP request" do
5
3
  let(:response) { HTTParty.get('http://wp.example.com/wp-json/posts').body }
@@ -54,6 +52,24 @@ describe WP::API do
54
52
  expect(meta).to be_a Hash
55
53
  end
56
54
  end
55
+
56
+ context "categories" do
57
+ let(:categories) { subject.categories }
58
+
59
+ it "should be converted to a class" do
60
+ expect(categories.first).to be_a WP::API::Category
61
+ end
62
+
63
+ it "should respond to #to_param" do
64
+ expect(categories.first.to_param).to eq "foxes"
65
+ end
66
+ end
67
+
68
+ context "link headers" do
69
+ its(:next) { should == "/wp-json/posts?page=2" }
70
+ its(:prev) { should be_nil }
71
+ its('items.size') { should eq 2 }
72
+ end
57
73
  end
58
74
 
59
75
  end
@@ -165,6 +165,21 @@
165
165
  "self": "http:\/\/wp.example.com\/wp-json\/taxonomies\/post_tag\/terms\/1"
166
166
  }
167
167
  }
168
+ }],
169
+ "category": [{
170
+ "ID": 3,
171
+ "name": "Foxes",
172
+ "slug": "foxes",
173
+ "description": "",
174
+ "parent": null,
175
+ "count": 1,
176
+ "link": "http:\/\/wp.example.com\/category\/foxes\/",
177
+ "meta": {
178
+ "links": {
179
+ "collection": "http:\/\/wp.example.com\/wp-json\/taxonomies\/category\/terms",
180
+ "self": "http:\/\/wp.example.com\/wp-json\/taxonomies\/category\/terms\/3"
181
+ }
182
+ }
168
183
  }]
169
184
  }
170
- }
185
+ }
@@ -165,6 +165,21 @@
165
165
  "self": "http:\/\/wp.example.com\/wp-json\/taxonomies\/post_tag\/terms\/2"
166
166
  }
167
167
  }
168
+ }],
169
+ "category": [{
170
+ "ID": 4,
171
+ "name": "Cars",
172
+ "slug": "cars",
173
+ "description": "",
174
+ "parent": null,
175
+ "count": 1,
176
+ "link": "http:\/\/wp.example.com\/category\/cars\/",
177
+ "meta": {
178
+ "links": {
179
+ "collection": "http:\/\/wp.example.com\/wp-json\/taxonomies\/category\/terms",
180
+ "self": "http:\/\/wp.example.com\/wp-json\/taxonomies\/category\/terms\/4"
181
+ }
182
+ }
168
183
  }]
169
184
  }
170
- }
185
+ }
@@ -0,0 +1 @@
1
+ </wp-json/posts?page=2>; rel="next", <http://wp.twigtale.com/wp-json/posts/1>; rel="item"; title="First post", <http://wp.twigtale.com/wp-json/posts/2>; rel="item"; title="Second post"
@@ -165,6 +165,21 @@
165
165
  "self": "http:\/\/wp.example.com\/wp-json\/taxonomies\/post_tag\/terms\/1"
166
166
  }
167
167
  }
168
+ }],
169
+ "category": [{
170
+ "ID": 3,
171
+ "name": "Foxes",
172
+ "slug": "foxes",
173
+ "description": "",
174
+ "parent": null,
175
+ "count": 1,
176
+ "link": "http:\/\/wp.example.com\/category\/foxes\/",
177
+ "meta": {
178
+ "links": {
179
+ "collection": "http:\/\/wp.example.com\/wp-json\/taxonomies\/category\/terms",
180
+ "self": "http:\/\/wp.example.com\/wp-json\/taxonomies\/category\/terms\/3"
181
+ }
182
+ }
168
183
  }]
169
184
  }
170
185
  },
@@ -335,6 +350,21 @@
335
350
  "self": "http:\/\/wp.example.com\/wp-json\/taxonomies\/post_tag\/terms\/2"
336
351
  }
337
352
  }
353
+ }],
354
+ "category": [{
355
+ "ID": 4,
356
+ "name": "Cars",
357
+ "slug": "cars",
358
+ "description": "",
359
+ "parent": null,
360
+ "count": 1,
361
+ "link": "http:\/\/wp.example.com\/category\/cars\/",
362
+ "meta": {
363
+ "links": {
364
+ "collection": "http:\/\/wp.example.com\/wp-json\/taxonomies\/category\/terms",
365
+ "self": "http:\/\/wp.example.com\/wp-json\/taxonomies\/category\/terms\/4"
366
+ }
367
+ }
338
368
  }]
339
369
  }
340
- }]
370
+ }]
@@ -1,3 +1,5 @@
1
+ require 'yajl'
2
+
1
3
  module JSONHelper
2
4
  def parse_json(file_or_string)
3
5
  Yajl::Parser.new.parse(file_or_string)
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'bundler/setup'
2
+ require 'rspec/its'
2
3
  Bundler.setup
3
4
 
4
5
  $LOAD_PATH << File.dirname(__FILE__) + "/../"
@@ -14,8 +14,8 @@ class MockWordpressServer
14
14
  protected
15
15
 
16
16
  def register_all
17
- FakeWeb.register_uri(:get, "http://#{host}/wp-json/posts", :body => support_file("posts.json"))
18
- FakeWeb.register_uri(:get, "http://#{host}/wp-json/posts/1", :body => support_file("posts/1.json"))
19
- FakeWeb.register_uri(:get, "http://#{host}/wp-json/posts/2", :body => support_file("posts/2.json"))
17
+ FakeWeb.register_uri(:get, "http://#{host}/wp-json/posts", :body => support_file("posts.json"), :content_type => "application/json", :link => support_file("posts.header.txt"))
18
+ FakeWeb.register_uri(:get, "http://#{host}/wp-json/posts/1", :body => support_file("posts/1.json"), :content_type => "application/json")
19
+ FakeWeb.register_uri(:get, "http://#{host}/wp-json/posts/2", :body => support_file("posts/2.json"), :content_type => "application/json")
20
20
  end
21
21
  end
data/wp-api.gemspec CHANGED
@@ -18,14 +18,15 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency 'httparty', '~> 0.13.1'
22
- spec.add_dependency 'yajl-ruby', '~> 1.2.1'
23
- spec.add_dependency 'activesupport'
24
- spec.add_dependency 'addressable'
21
+ spec.add_runtime_dependency 'httparty'
22
+ spec.add_runtime_dependency 'activesupport'
23
+ spec.add_runtime_dependency 'addressable'
25
24
 
26
25
  spec.add_development_dependency "bundler", "~> 1.6"
27
- spec.add_development_dependency "rake"
28
- spec.add_development_dependency "rspec", "~> 3.1.0"
29
- spec.add_development_dependency "fakeweb", "~> 1.3.0"
26
+ spec.add_development_dependency "yajl-ruby", '~> 1.2.1'
27
+ spec.add_development_dependency "rake", '~> 0'
28
+ spec.add_development_dependency "rspec", '>= 2.0'
29
+ spec.add_development_dependency "rspec-its", '>= 1.0.1'
30
+ spec.add_development_dependency "fakeweb", '~> 1.3', '>= 1.3.0'
30
31
  spec.add_development_dependency "pry"
31
32
  end
metadata CHANGED
@@ -1,43 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wp-api
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
  - Colin Young
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-17 00:00:00.000000000 Z
11
+ date: 2014-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: 0.13.1
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: 0.13.1
27
- - !ruby/object:Gem::Dependency
28
- name: yajl-ruby
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
17
+ - - ">="
32
18
  - !ruby/object:Gem::Version
33
- version: 1.2.1
19
+ version: '0'
34
20
  type: :runtime
35
21
  prerelease: false
36
22
  version_requirements: !ruby/object:Gem::Requirement
37
23
  requirements:
38
- - - "~>"
24
+ - - ">="
39
25
  - !ruby/object:Gem::Version
40
- version: 1.2.1
26
+ version: '0'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: activesupport
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -80,39 +66,70 @@ dependencies:
80
66
  - - "~>"
81
67
  - !ruby/object:Gem::Version
82
68
  version: '1.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: yajl-ruby
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.2.1
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.2.1
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: 3.1.0
103
+ version: '2.0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '2.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec-its
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: 1.0.1
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
109
123
  - !ruby/object:Gem::Version
110
- version: 3.1.0
124
+ version: 1.0.1
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: fakeweb
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.3'
132
+ - - ">="
116
133
  - !ruby/object:Gem::Version
117
134
  version: 1.3.0
118
135
  type: :development
@@ -120,6 +137,9 @@ dependencies:
120
137
  version_requirements: !ruby/object:Gem::Requirement
121
138
  requirements:
122
139
  - - "~>"
140
+ - !ruby/object:Gem::Version
141
+ version: '1.3'
142
+ - - ">="
123
143
  - !ruby/object:Gem::Version
124
144
  version: 1.3.0
125
145
  - !ruby/object:Gem::Dependency
@@ -146,19 +166,24 @@ extra_rdoc_files: []
146
166
  files:
147
167
  - ".gitignore"
148
168
  - ".rspec"
169
+ - ".ruby-version"
149
170
  - Gemfile
150
171
  - LICENSE.txt
151
172
  - README.md
152
173
  - Rakefile
174
+ - circle.yml
153
175
  - lib/wp/api.rb
154
176
  - lib/wp/api/client.rb
155
177
  - lib/wp/api/endpoints.rb
178
+ - lib/wp/api/errors.rb
156
179
  - lib/wp/api/resource.rb
157
180
  - lib/wp/api/resources/author.rb
181
+ - lib/wp/api/resources/category.rb
158
182
  - lib/wp/api/resources/post.rb
159
183
  - lib/wp/api/version.rb
160
184
  - spec/endpoints/post_spec.rb
161
185
  - spec/endpoints/posts_spec.rb
186
+ - spec/files/posts.header.txt
162
187
  - spec/files/posts.json
163
188
  - spec/files/posts/1.json
164
189
  - spec/files/posts/2.json
@@ -195,6 +220,7 @@ summary: Easily access Wordpress blogs that have the new, RESTful WP API plugin
195
220
  test_files:
196
221
  - spec/endpoints/post_spec.rb
197
222
  - spec/endpoints/posts_spec.rb
223
+ - spec/files/posts.header.txt
198
224
  - spec/files/posts.json
199
225
  - spec/files/posts/1.json
200
226
  - spec/files/posts/2.json