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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2950b93ddb836d175974d4c592411f479fffd479
4
- data.tar.gz: 5f770516776da3f381c15649bd749c62b7e6549b
2
+ SHA256:
3
+ metadata.gz: ae7d0ffa5e71dc5aa33aaacfafc9067c4e6b8bcaf9c4f21767f04236dbf98bfb
4
+ data.tar.gz: d754a62a53e84d262eabb9afbb07ef07f604d149a31c69caa1926f1f462f8d5c
5
5
  SHA512:
6
- metadata.gz: 95d4b0c061dd1de4630de52d099fed5787a43b9b974515474966f44ee5fb6162723f24f6d5e9a112b37f855b2c7f2dbecc9d2d3bc187e0aa9f30081aa2d00b09
7
- data.tar.gz: 4f674f52a9eb2584c0030fc3949fa2e63ce396e6753d21a96b5d9042d51183fc043da6ab163db56ec8ee838c848948b565b73be698ededade7a503887844aed2
6
+ metadata.gz: 9f9582960b53730e4642d931a98e36a67b7644a628d7fd09d6b9753607ae80662426bce46d872e3ed841b6d02131f8aa87864451a5f7233519fc0e59b7c7bb0c
7
+ data.tar.gz: ae539d9c1e6923bf8c78a57359b20f951f1b9fe637f30042e2ebdca2840a5703287440999ff7a71ae0caefa9eda9ecb9d40f881111d37c4873b4fa12a8929a2b
@@ -12,6 +12,8 @@ Metrics/AbcSize:
12
12
  Max: 20
13
13
  Metrics/CyclomaticComplexity:
14
14
  Max: 10
15
+ Metrics/PerceivedComplexity:
16
+ Max: 10
15
17
  Metrics/BlockLength:
16
18
  Exclude:
17
19
  - spec/**/*
@@ -1,36 +1,38 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.4.0
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 > ./cc-test-reporter
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
- skip_cleanup: true
22
- github_token: "$GITHUB_TOKEN"
23
- local_dir: "./docs"
24
- target_branch: gh-pages
25
- on:
26
- branch:
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
- api_key:
31
- secure: aZt6t60GH8ISKGw+AY/Pik1rgvYWJW0uc6Co35OlOBTNs3YitHbk5sMTq2wP0bs6qvJyPJDedAXU5F1ZEEuWz6m2wScD+Ld1hscwadNA7xcdQX6VWsJqR4biq4MkR5fLmQnTa+cDcG476J9+vL7qHJPNuiN+3jm2ODhvFlmtwtx/nXv1KgoYgpUVKBENuaVkL/7zGiFTs0nc4R32U7HGfzOGg7uXKK2JYsW5PN3KpeYVM3Df8qemVIhT6InBZvGovN1PfQ4oFV25VPLCLrQPY+qCJt54LvJQAhZVPYQaBowm1Pgg6tPA3dIHAaHI3iPKi1hOFQLoSci70OmQb7My38gWU0ARkq02eiR0uZrhkcYOuVqVU4quOGuEpagqDuWnXIz7LfnZAzfqers//TKFl/o2sLvOEfCSMZFiby6f9vk87SLyRCcsYtxYQfRBTanCgB2AlOKalSZ+WzQ4F8LvZJZbgxEoN9ul1MxHP1SeSwDlBHpXutxrX+EOfP8b/Bvi0nu8Xq2Y7HbPtfiVOXOM9aiUqWJDVaf+S5zhWd72IS54JUcCgIjeB8ryK9k1vSnfvm1VMOo7illN4MxfNNYMQk5zSeyhOLzTIQvFgALrJDGk4JtZjire0BFWUkrtEqoiD1ZuMIKWVLZbIBBMskl+bkf+VvwiubX6LibVAC4itlk=
32
- gem: ghost_rb
33
- on:
34
- tags: true
35
- repo: renehernandez/ghost_rb
36
- branch: master
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'], 'CLIENT_SECRET')
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 get a list with all the blog posts, simply write:
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
- status, posts = client.get_posts
43
+ ctrl = client.posts
37
44
  ```
38
45
 
39
- You can change the *limit* (defaults to all) of posts to return for the query and whether to include *author* and *tags* information.
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
- To get a list with all the tags, write instead:
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
- status, tags = client.get_tags
85
+ tags = client.tags.limit('all').all
47
86
  ```
48
87
 
49
- You can change the *limit* (defaults to all) of tags to return for the query and whether to include *count.posts* information.
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
 
@@ -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/resources/hydratable'
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'
@@ -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 = { client_id: @client_id, client_secret: @client_secret }
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 = JSON.parse(response.body)
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
- resource_klass.generate(content)
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 tag with #{key} = #{kvp[key]}"
24
+ message = "Unable to fetch post with #{key} = #{kvp[key]}"
29
25
  raise Errors::RequestError.new(message,
30
26
  status,
31
27
  errors)
@@ -13,10 +13,6 @@ module GhostRb
13
13
  @resource_klass = Resources::Tag
14
14
  end
15
15
 
16
- def all
17
- fetch_list['tags'].map { |r| @resource_klass.generate(r) }
18
- end
19
-
20
16
  private
21
17
 
22
18
  def raise_fetch_single_error(kvp, status, 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, :author_id,
10
- :visibility, :featured, :plaintext, :author, :tags
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(hash)
17
- inst = super(hash)
18
- inst.author = User.generate(hash[:author]) if hash.key?(:author)
19
- inst.tags = hash[:tags].map { |t| Tag.generate(t) } if hash.key?(: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
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GhostRb
4
- module Resources
4
+ # Provides utility classes and modules extensions for GhostRb
5
+ # @author Rene Hernandez
6
+ # @since 0.3
7
+ module Support
5
8
  # @author Rene Hernandez
6
9
  # @since 0.1
7
10
  module Hydratable
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GhostRb
4
- VERSION = '0.2.0'
4
+ VERSION = '0.2.5'
5
5
  end
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.0
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-10-08 00:00:00.000000000 Z
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.6.13
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