ghost_rb 0.2.0 → 0.2.5
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 +5 -5
- data/.rubocop.yml +2 -0
- data/.travis.yml +21 -19
- data/README.md +49 -7
- data/lib/ghost_rb.rb +2 -1
- data/lib/ghost_rb/client.rb +8 -4
- data/lib/ghost_rb/controllers/base_controller.rb +9 -4
- data/lib/ghost_rb/controllers/posts_controller.rb +1 -5
- data/lib/ghost_rb/controllers/tags_controller.rb +0 -4
- data/lib/ghost_rb/resources/base_resource.rb +5 -1
- data/lib/ghost_rb/resources/post.rb +6 -6
- data/lib/ghost_rb/support/hash_with_indifferent_access.rb +116 -0
- data/lib/ghost_rb/{resources → support}/hydratable.rb +4 -1
- data/lib/ghost_rb/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: ae7d0ffa5e71dc5aa33aaacfafc9067c4e6b8bcaf9c4f21767f04236dbf98bfb
|
|
4
|
+
data.tar.gz: d754a62a53e84d262eabb9afbb07ef07f604d149a31c69caa1926f1f462f8d5c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9f9582960b53730e4642d931a98e36a67b7644a628d7fd09d6b9753607ae80662426bce46d872e3ed841b6d02131f8aa87864451a5f7233519fc0e59b7c7bb0c
|
|
7
|
+
data.tar.gz: ae539d9c1e6923bf8c78a57359b20f951f1b9fe637f30042e2ebdca2840a5703287440999ff7a71ae0caefa9eda9ecb9d40f881111d37c4873b4fa12a8929a2b
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
|
@@ -1,36 +1,38 @@
|
|
|
1
1
|
sudo: false
|
|
2
2
|
language: ruby
|
|
3
3
|
rvm:
|
|
4
|
-
|
|
4
|
+
- 2.4.0
|
|
5
5
|
env:
|
|
6
6
|
global:
|
|
7
7
|
- CC_TEST_REPORTER_ID=a56fc1316eb9869f9ef69353912ad37abd138ff4a594b6290c9830718ae5cd81
|
|
8
8
|
before_install: gem install bundler -v 1.14.4
|
|
9
9
|
before_script:
|
|
10
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64
|
|
10
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64
|
|
11
|
+
> ./cc-test-reporter
|
|
11
12
|
- chmod +x ./cc-test-reporter
|
|
12
|
-
- ./cc-test-reporter before-build
|
|
13
|
+
- "./cc-test-reporter before-build"
|
|
13
14
|
script:
|
|
14
15
|
- bundle exec rspec
|
|
15
16
|
after_script:
|
|
16
|
-
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
|
17
|
+
- "./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT"
|
|
17
18
|
before_deploy:
|
|
18
19
|
- cat ./README.md >> ./docs/index.md
|
|
19
20
|
deploy:
|
|
20
|
-
- provider: pages
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
- provider: pages
|
|
22
|
+
skip_cleanup: true
|
|
23
|
+
github_token: "$GITHUB_TOKEN"
|
|
24
|
+
local_dir: "./docs"
|
|
25
|
+
target_branch: gh-pages
|
|
26
|
+
on:
|
|
27
|
+
branch:
|
|
27
28
|
- develop
|
|
28
29
|
- master
|
|
29
|
-
- provider: rubygems
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
- provider: rubygems
|
|
31
|
+
api_key:
|
|
32
|
+
secure: NG9gd7Ff8Cs8LJhIjuWtbQSBRFGBBgfJ0/IKkbiMKQi3ezNKKHz1ha2jMvR6pFj8YYCkvnsO7Lj+VHCJU0SbRziPSeYxjBdDSKvOJ0K5Ui0vdFJzIZHgWJdD/C/ns60A1FnweR3cVAYBfCpquJpTKRMWmc6f1+ZRy/XzkwDOBdK9/TChzhjEO8xSHVq74EcMIwM9CO3rAnwgdzXszD5obwZ9/gIY64uivg0snxcvc5REPBEfpmn6GQ40mmIFj0tm/bF3BgE7B2h2cWEsPiUsNfl+UZy/LApJeuV8bpfL68QRcx0zGHYpMr3ZmWrZONL2dIiRN7YHXZVPCi2Fr5z5HdTrvy/WnLx3AwjJ0/j3uTHQUqRd9aqilXSqY6i68E0gaSQcrFUQts6k2AYtJzB/h+VudKxHpIcqt6zKH3O3FOcAtV15yDvQVv+krLrMPRAJ6S8idSpEkOjiNiKGjV0XpQ30B3Wchpzqr/c4ryAyb/FTPQSWLYdOd0koUeGEDBcQ9nZ0tSN58RSDyFSlk2ChZRqySQTpod2b1XzQ1NRR/hYo23C/tZB1xf1Z3MoT7cM4/T6LIsCISM5ZqJpVgY3s5E1crQxxjX1Jvy9gh28U+MABwHeZkmEDZyqC47quVn4+ArKOeuVSnJjuvgBaP7MIGZghgAT3ijIpDIbixDF31vc=
|
|
33
|
+
gem: ghost_rb
|
|
34
|
+
on:
|
|
35
|
+
tags: true
|
|
36
|
+
repo: renehernandez/ghost_rb
|
|
37
|
+
branch: master
|
|
38
|
+
|
data/README.md
CHANGED
|
@@ -25,29 +25,71 @@ Or install it yourself as:
|
|
|
25
25
|
To create a new client:
|
|
26
26
|
|
|
27
27
|
```ruby
|
|
28
|
-
client = GhostRb::Client.new('URL', 'CLIENT_ID'
|
|
28
|
+
client = GhostRb::Client.new('URL', 'CLIENT_ID', 'CLIENT_SECRET')
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
**Note:** If parameters are not specified for resources retrieval, the default values, as specified by [Ghost API](https://api.ghost.org/), are used.
|
|
32
|
+
|
|
31
33
|
#### Posts
|
|
32
34
|
|
|
33
|
-
To
|
|
35
|
+
To access posts from the blog, first create a controller:
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
ctrl = GhostRb::Controllers::PostsController.new(client) # using previous defined client var
|
|
39
|
+
```
|
|
34
40
|
|
|
41
|
+
A handier way to get the controller is:
|
|
35
42
|
```ruby
|
|
36
|
-
|
|
43
|
+
ctrl = client.posts
|
|
37
44
|
```
|
|
38
45
|
|
|
39
|
-
|
|
46
|
+
##### Single post by id
|
|
47
|
+
|
|
48
|
+
```ruby
|
|
49
|
+
post = client.posts.find_by(id: 'lhafdkaalkdfha')
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
##### Single post by slug
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
post = client.posts.find_by(slug: 'welcome-to-ghost')
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
##### Get all post by setting the limit
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
posts = client.posts.limit('all').all
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
##### Using where
|
|
65
|
+
|
|
66
|
+
```ruby
|
|
67
|
+
ctrl = client.posts
|
|
68
|
+
posts = posts.where(include: 'tags, author', limit: 5).all
|
|
69
|
+
```
|
|
40
70
|
|
|
41
71
|
#### Tags
|
|
42
72
|
|
|
43
|
-
|
|
73
|
+
Similarly for tags, you can create directly the controller or call it from the client instance.
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
```ruby
|
|
77
|
+
ctrl = GhostRb::Controllers::TagsController.new(client)
|
|
78
|
+
# or
|
|
79
|
+
ctrl = client.tags
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
##### All tags
|
|
44
83
|
|
|
45
84
|
```ruby
|
|
46
|
-
|
|
85
|
+
tags = client.tags.limit('all').all
|
|
47
86
|
```
|
|
48
87
|
|
|
49
|
-
|
|
88
|
+
## Documentation
|
|
89
|
+
|
|
90
|
+
The documentation lives at the [github pages](https://renehernandez.github.io/ghost_rb/). For the nitty gritty details of the implementation go to [http://www.rubydoc.info/gems/ghost_rb](http://www.rubydoc.info/gems/ghost_rb).
|
|
50
91
|
|
|
92
|
+
You can also go check [this post](https://bitsofknowledge.net/2017/10/02/ghost_rb-a-ghost-rest-api-client/) where I have provided an analysis of the implementation.
|
|
51
93
|
|
|
52
94
|
## Development
|
|
53
95
|
|
data/lib/ghost_rb.rb
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
require 'ghost_rb/version'
|
|
4
4
|
require 'ghost_rb/client'
|
|
5
5
|
require 'ghost_rb/errors'
|
|
6
|
-
require 'ghost_rb/
|
|
6
|
+
require 'ghost_rb/support/hydratable'
|
|
7
|
+
require 'ghost_rb/support/hash_with_indifferent_access'
|
|
7
8
|
require 'ghost_rb/resources/base_resource'
|
|
8
9
|
require 'ghost_rb/resources/post'
|
|
9
10
|
require 'ghost_rb/resources/user'
|
data/lib/ghost_rb/client.rb
CHANGED
|
@@ -10,14 +10,15 @@ module GhostRb
|
|
|
10
10
|
class Client
|
|
11
11
|
attr_reader :base_url, :client_id, :client_secret, :default_query
|
|
12
12
|
|
|
13
|
-
REQUEST_OK = 200
|
|
14
|
-
|
|
15
13
|
def initialize(base_url, client_id, client_secret)
|
|
16
14
|
@base_url = URI.join(base_url, 'ghost/', 'api/', 'v0.1/')
|
|
17
15
|
@client_id = client_id
|
|
18
16
|
@client_secret = client_secret
|
|
19
17
|
@http = HTTPClient.new(base_url: @base_url)
|
|
20
|
-
@default_query =
|
|
18
|
+
@default_query = Support::HashWithIndifferentAccess.new(
|
|
19
|
+
client_id: @client_id,
|
|
20
|
+
client_secret: @client_secret
|
|
21
|
+
)
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
def posts
|
|
@@ -30,7 +31,10 @@ module GhostRb
|
|
|
30
31
|
|
|
31
32
|
def get(endpoint, query)
|
|
32
33
|
response = @http.get(endpoint, query, {}, follow_redirect: true)
|
|
33
|
-
content =
|
|
34
|
+
content = Support::HashWithIndifferentAccess.new(
|
|
35
|
+
JSON.parse(response.body)
|
|
36
|
+
)
|
|
37
|
+
|
|
34
38
|
[response.status_code, content]
|
|
35
39
|
end
|
|
36
40
|
end
|
|
@@ -13,7 +13,11 @@ module GhostRb
|
|
|
13
13
|
|
|
14
14
|
def initialize(client)
|
|
15
15
|
@client = client
|
|
16
|
-
@params =
|
|
16
|
+
@params = Support::HashWithIndifferentAccess.new
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def all
|
|
20
|
+
fetch_list.map { |r| @resource_klass.generate(r) }
|
|
17
21
|
end
|
|
18
22
|
|
|
19
23
|
def limit(limit)
|
|
@@ -50,7 +54,8 @@ module GhostRb
|
|
|
50
54
|
@params.delete(key)
|
|
51
55
|
end
|
|
52
56
|
|
|
53
|
-
fetch_single(kvp)
|
|
57
|
+
content = fetch_single(kvp)
|
|
58
|
+
resource_klass.generate(content)
|
|
54
59
|
end
|
|
55
60
|
|
|
56
61
|
private
|
|
@@ -64,7 +69,7 @@ module GhostRb
|
|
|
64
69
|
raise_fetch_single_error(kvp, status, content['errors'])
|
|
65
70
|
end
|
|
66
71
|
|
|
67
|
-
|
|
72
|
+
content
|
|
68
73
|
end
|
|
69
74
|
|
|
70
75
|
def fetch_list
|
|
@@ -73,7 +78,7 @@ module GhostRb
|
|
|
73
78
|
|
|
74
79
|
raise_fetch_list_error(status, content['errors']) if error?(status)
|
|
75
80
|
|
|
76
|
-
content
|
|
81
|
+
content[@endpoint]
|
|
77
82
|
end
|
|
78
83
|
|
|
79
84
|
def error?(status)
|
|
@@ -13,10 +13,6 @@ module GhostRb
|
|
|
13
13
|
@resource_klass = Resources::Post
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def all
|
|
17
|
-
fetch_list['posts'].map { |r| @resource_klass.generate(r) }
|
|
18
|
-
end
|
|
19
|
-
|
|
20
16
|
def formats(formats)
|
|
21
17
|
where(formats: formats)
|
|
22
18
|
end
|
|
@@ -25,7 +21,7 @@ module GhostRb
|
|
|
25
21
|
|
|
26
22
|
def raise_fetch_single_error(kvp, status, errors)
|
|
27
23
|
key = kvp.key?(:id) ? :id : :slug
|
|
28
|
-
message = "Unable to fetch
|
|
24
|
+
message = "Unable to fetch post with #{key} = #{kvp[key]}"
|
|
29
25
|
raise Errors::RequestError.new(message,
|
|
30
26
|
status,
|
|
31
27
|
errors)
|
|
@@ -7,13 +7,17 @@ module GhostRb
|
|
|
7
7
|
# @author Rene Hernandez
|
|
8
8
|
# @since 0.1
|
|
9
9
|
class BaseResource
|
|
10
|
-
include Hydratable
|
|
10
|
+
include Support::Hydratable
|
|
11
11
|
|
|
12
12
|
def self.generate(hash)
|
|
13
13
|
res_instance = new
|
|
14
14
|
res_instance.hydrate(hash)
|
|
15
15
|
res_instance
|
|
16
16
|
end
|
|
17
|
+
|
|
18
|
+
def self.hash_value?(data, key)
|
|
19
|
+
data.key?(key) && data[key].is_a?(Hash)
|
|
20
|
+
end
|
|
17
21
|
end
|
|
18
22
|
end
|
|
19
23
|
end
|
|
@@ -6,17 +6,17 @@ module GhostRb
|
|
|
6
6
|
# @since 0.1
|
|
7
7
|
class Post < BaseResource
|
|
8
8
|
attr_accessor :id, :title, :slug, :html, :page,
|
|
9
|
-
:status, :published_at, :created_at, :
|
|
10
|
-
:visibility, :featured, :plaintext, :
|
|
9
|
+
:status, :published_at, :created_at, :author,
|
|
10
|
+
:visibility, :featured, :plaintext, :tags
|
|
11
11
|
|
|
12
12
|
alias page? page
|
|
13
13
|
|
|
14
14
|
alias featured? featured
|
|
15
15
|
|
|
16
|
-
def self.generate(
|
|
17
|
-
inst = super(
|
|
18
|
-
inst.author = User.generate(
|
|
19
|
-
inst.tags =
|
|
16
|
+
def self.generate(data)
|
|
17
|
+
inst = super(data)
|
|
18
|
+
inst.author = User.generate(data[:author]) if hash_value?(data, :author)
|
|
19
|
+
inst.tags = data[:tags].map { |t| Tag.generate(t) } if data.key?(:tags)
|
|
20
20
|
|
|
21
21
|
inst
|
|
22
22
|
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GhostRb
|
|
4
|
+
module Support
|
|
5
|
+
# rubocop:disable Metrics/LineLength
|
|
6
|
+
# Provides indifferent access for symbol and string keys.
|
|
7
|
+
# Both :bar and "bar" are considered to be the same key.
|
|
8
|
+
# This is implementation is heavily based on the
|
|
9
|
+
# [ActiveSupport implementation]{http://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html}
|
|
10
|
+
# @author Rene Hernandez
|
|
11
|
+
# @since 0.3
|
|
12
|
+
# rubocop:enable Metrics/LineLength
|
|
13
|
+
class HashWithIndifferentAccess < Hash
|
|
14
|
+
def initialize(data = {})
|
|
15
|
+
if data.respond_to?(:to_hash)
|
|
16
|
+
super()
|
|
17
|
+
update(data)
|
|
18
|
+
|
|
19
|
+
hash = data.to_hash
|
|
20
|
+
self.default = hash.default if hash.default
|
|
21
|
+
self.default_proc = hash.default_proc if hash.default_proc
|
|
22
|
+
else
|
|
23
|
+
super(data)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def [](key)
|
|
28
|
+
super(convert_key(key))
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
alias regular_writer []= unless method_defined?(:regular_writer)
|
|
32
|
+
|
|
33
|
+
def []=(key, value)
|
|
34
|
+
regular_writer(convert_key(key), convert_value(value))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def dup
|
|
38
|
+
self.class.new(self).tap do |new_hash|
|
|
39
|
+
add_defaults(new_hash)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def default(*args)
|
|
44
|
+
super(*args.map { |arg| convert_key(arg) })
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def delete(key)
|
|
48
|
+
super(convert_key(key))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def fetch(key, *extras)
|
|
52
|
+
super(convert_key(key), *extras)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def key?(key)
|
|
56
|
+
super(convert_key(key))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
alias has_key? key?
|
|
60
|
+
|
|
61
|
+
alias include? key?
|
|
62
|
+
|
|
63
|
+
def update(other_hash)
|
|
64
|
+
if other_hash.is_a? HashWithIndifferentAccess
|
|
65
|
+
super(other_hash)
|
|
66
|
+
else
|
|
67
|
+
other_hash.to_hash.each_pair do |key, value|
|
|
68
|
+
if block_given? && key?(key)
|
|
69
|
+
value = yield(convert_key(key), self[key], value)
|
|
70
|
+
end
|
|
71
|
+
regular_writer(convert_key(key), convert_value(value))
|
|
72
|
+
end
|
|
73
|
+
self
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
alias merge! update
|
|
78
|
+
|
|
79
|
+
def merge(hash, &block)
|
|
80
|
+
dup.update(hash, &block)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def to_hash
|
|
84
|
+
new_hash = {}
|
|
85
|
+
add_defaults(new_hash)
|
|
86
|
+
|
|
87
|
+
each do |key, value|
|
|
88
|
+
new_hash[key] = convert_value(value)
|
|
89
|
+
end
|
|
90
|
+
new_hash
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
private
|
|
94
|
+
|
|
95
|
+
def convert_key(key)
|
|
96
|
+
key.is_a?(Symbol) ? key.to_s : key
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def convert_value(value)
|
|
100
|
+
return self.class.new(value) if value.is_a? Hash
|
|
101
|
+
|
|
102
|
+
return value.map { |e| convert_value(e) } if value.is_a?(Array)
|
|
103
|
+
|
|
104
|
+
value
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def add_defaults(target) # :doc:
|
|
108
|
+
if default_proc
|
|
109
|
+
target.default_proc = default_proc.dup
|
|
110
|
+
else
|
|
111
|
+
target.default = default
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
data/lib/ghost_rb/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ghost_rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rene Hernandez
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-
|
|
11
|
+
date: 2017-11-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: httpclient
|
|
@@ -147,10 +147,11 @@ files:
|
|
|
147
147
|
- lib/ghost_rb/controllers/tags_controller.rb
|
|
148
148
|
- lib/ghost_rb/errors.rb
|
|
149
149
|
- lib/ghost_rb/resources/base_resource.rb
|
|
150
|
-
- lib/ghost_rb/resources/hydratable.rb
|
|
151
150
|
- lib/ghost_rb/resources/post.rb
|
|
152
151
|
- lib/ghost_rb/resources/tag.rb
|
|
153
152
|
- lib/ghost_rb/resources/user.rb
|
|
153
|
+
- lib/ghost_rb/support/hash_with_indifferent_access.rb
|
|
154
|
+
- lib/ghost_rb/support/hydratable.rb
|
|
154
155
|
- lib/ghost_rb/version.rb
|
|
155
156
|
homepage: https://github.com/renehernandez/ghost_rb
|
|
156
157
|
licenses:
|
|
@@ -172,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
172
173
|
version: '0'
|
|
173
174
|
requirements: []
|
|
174
175
|
rubyforge_project:
|
|
175
|
-
rubygems_version: 2.
|
|
176
|
+
rubygems_version: 2.7.1
|
|
176
177
|
signing_key:
|
|
177
178
|
specification_version: 4
|
|
178
179
|
summary: GhostRb is a REST API client to interact with a given Ghost blog
|