ghost_rb 0.2.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/docs/index.md ADDED
@@ -0,0 +1,3 @@
1
+ ---
2
+ layout: default
3
+ ---
data/ghost_rb.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ghost_rb/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ghost_rb"
8
+ spec.version = GhostRb::VERSION
9
+ spec.authors = ["Rene Hernandez"]
10
+ spec.email = ["renehr9102@gmail.com"]
11
+
12
+ spec.summary = %q{GhostRb is a REST API client to interact with a given Ghost blog}
13
+ spec.homepage = "https://github.com/renehernandez/ghost_rb"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features|doc)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_dependency "httpclient", "~> 2.8"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.14"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ spec.add_development_dependency "rspec", "~> 3.0"
28
+ spec.add_development_dependency "yard", "~> 0.9"
29
+ spec.add_development_dependency "rubocop", "~> 0.49"
30
+ spec.add_development_dependency "simplecov", "~> 0.15"
31
+ end
data/lib/ghost_rb.rb ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ghost_rb/version'
4
+ require 'ghost_rb/client'
5
+ require 'ghost_rb/errors'
6
+ require 'ghost_rb/resources/hydratable'
7
+ require 'ghost_rb/resources/base_resource'
8
+ require 'ghost_rb/resources/post'
9
+ require 'ghost_rb/resources/user'
10
+ require 'ghost_rb/resources/tag'
11
+ require 'ghost_rb/controllers/base_controller'
12
+ require 'ghost_rb/controllers/posts_controller'
13
+ require 'ghost_rb/controllers/tags_controller'
14
+
15
+ # @author Rene Hernandez
16
+ # @since 0.1
17
+ module GhostRb
18
+ # Your code goes here...
19
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'httpclient'
4
+ require 'uri'
5
+ require 'json'
6
+
7
+ module GhostRb
8
+ # @author Rene Hernandez
9
+ # @since 0.1
10
+ class Client
11
+ attr_reader :base_url, :client_id, :client_secret, :default_query
12
+
13
+ REQUEST_OK = 200
14
+
15
+ def initialize(base_url, client_id, client_secret)
16
+ @base_url = URI.join(base_url, 'ghost/', 'api/', 'v0.1/')
17
+ @client_id = client_id
18
+ @client_secret = client_secret
19
+ @http = HTTPClient.new(base_url: @base_url)
20
+ @default_query = { client_id: @client_id, client_secret: @client_secret }
21
+ end
22
+
23
+ def posts
24
+ Controllers::PostsController.new(self)
25
+ end
26
+
27
+ def tags
28
+ Controllers::TagsController.new(self)
29
+ end
30
+
31
+ def get(endpoint, query)
32
+ response = @http.get(endpoint, query, {}, follow_redirect: true)
33
+ content = JSON.parse(response.body)
34
+ [response.status_code, content]
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+
5
+ module GhostRb
6
+ # @author Rene Hernandez
7
+ # @since 0.2
8
+ module Controllers
9
+ # @author Rene Hernandez
10
+ # @since 0.2
11
+ class BaseController
12
+ attr_reader :client, :params
13
+
14
+ def initialize(client)
15
+ @client = client
16
+ @params = {}
17
+ end
18
+
19
+ def limit(limit)
20
+ where(limit: limit)
21
+ end
22
+
23
+ def page(page)
24
+ where(page: page)
25
+ end
26
+
27
+ def order(order_str)
28
+ where(order: order_str)
29
+ end
30
+
31
+ def fields(fields_str)
32
+ where(fields: fields_str)
33
+ end
34
+
35
+ def filter(filter_query)
36
+ where(filter: filter_query)
37
+ end
38
+
39
+ def include(resources_str)
40
+ where(include: resources_str)
41
+ end
42
+
43
+ def where(hash)
44
+ @params.merge!(hash)
45
+ self
46
+ end
47
+
48
+ def find_by(kvp)
49
+ @params.keys.reject { |k| k == :include }.each do |key|
50
+ @params.delete(key)
51
+ end
52
+
53
+ fetch_single(kvp)
54
+ end
55
+
56
+ private
57
+
58
+ def fetch_single(kvp)
59
+ endpoint = format_endpoint(kvp)
60
+ query = client.default_query.merge(@params)
61
+ status, content = client.get(endpoint, query)
62
+
63
+ if error?(status)
64
+ raise_fetch_single_error(kvp, status, content['errors'])
65
+ end
66
+
67
+ resource_klass.generate(content)
68
+ end
69
+
70
+ def fetch_list
71
+ query = client.default_query.merge(@params)
72
+ status, content = client.get(endpoint, query)
73
+
74
+ raise_fetch_list_error(status, content['errors']) if error?(status)
75
+
76
+ content
77
+ end
78
+
79
+ def error?(status)
80
+ status >= 400
81
+ end
82
+
83
+ def format_endpoint(kvp)
84
+ return [endpoint, kvp[:id]].join('/') if kvp.key?(:id)
85
+ return [endpoint, 'slug', kvp[:slug]].join('/') if kvp.key?(:slug)
86
+
87
+ raise Errors::InvalidEndpointError,
88
+ "Invalid endpoint for #{endpoint}. Should be either :id or :slug"
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GhostRb
4
+ module Controllers
5
+ # @author Rene Hernandez
6
+ # @since 0.2
7
+ class PostsController < BaseController
8
+ attr_reader :endpoint, :resource_klass
9
+
10
+ def initialize(client)
11
+ super
12
+ @endpoint = 'posts'
13
+ @resource_klass = Resources::Post
14
+ end
15
+
16
+ def all
17
+ fetch_list['posts'].map { |r| @resource_klass.generate(r) }
18
+ end
19
+
20
+ def formats(formats)
21
+ where(formats: formats)
22
+ end
23
+
24
+ private
25
+
26
+ def raise_fetch_single_error(kvp, status, errors)
27
+ key = kvp.key?(:id) ? :id : :slug
28
+ message = "Unable to fetch tag with #{key} = #{kvp[key]}"
29
+ raise Errors::RequestError.new(message,
30
+ status,
31
+ errors)
32
+ end
33
+
34
+ def raise_fetch_list_error(status, errors)
35
+ raise Errors::RequestError.new('Unable to fetch posts',
36
+ status,
37
+ errors)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GhostRb
4
+ module Controllers
5
+ # @author Rene Hernandez
6
+ # @since 0.2
7
+ class TagsController < BaseController
8
+ attr_reader :endpoint, :resource_klass
9
+
10
+ def initialize(client)
11
+ super
12
+ @endpoint = 'tags'
13
+ @resource_klass = Resources::Tag
14
+ end
15
+
16
+ def all
17
+ fetch_list['tags'].map { |r| @resource_klass.generate(r) }
18
+ end
19
+
20
+ private
21
+
22
+ def raise_fetch_single_error(kvp, status, errors)
23
+ key = kvp.key?(:id) ? :id : :slug
24
+ message = "Unable to fetch tag with #{key} = #{kvp[key]}"
25
+ raise Errors::RequestError.new(message,
26
+ status,
27
+ errors)
28
+ end
29
+
30
+ def raise_fetch_list_error(status, errors)
31
+ raise Errors::RequestError.new('Unable to fetch tags',
32
+ status,
33
+ errors)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GhostRb
4
+ # @author Rene Hernandez
5
+ # @since 0.2
6
+ module Errors
7
+ # @author Rene Hernandez
8
+ # @since 0.2
9
+ class RequestError < StandardError
10
+ attr_reader :status, :errors
11
+
12
+ def initialize(message, status, errors)
13
+ super(message)
14
+ @status = status
15
+ @errors = errors
16
+ end
17
+ end
18
+
19
+ # @author Rene Hernandez
20
+ # @since 0.2
21
+ InvalidEndpointError = Class.new(StandardError)
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GhostRb
4
+ # @author Rene Hernandez
5
+ # @since 0.1
6
+ module Resources
7
+ # @author Rene Hernandez
8
+ # @since 0.1
9
+ class BaseResource
10
+ include Hydratable
11
+
12
+ def self.generate(hash)
13
+ res_instance = new
14
+ res_instance.hydrate(hash)
15
+ res_instance
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GhostRb
4
+ module Resources
5
+ # @author Rene Hernandez
6
+ # @since 0.1
7
+ module Hydratable
8
+ def hydrate(hash)
9
+ hash.each do |k, v|
10
+ method_symbol = "#{k}=".to_sym
11
+ public_send(method_symbol, v) if respond_to?(method_symbol)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GhostRb
4
+ module Resources
5
+ # @author Rene Hernandez
6
+ # @since 0.1
7
+ class Post < BaseResource
8
+ attr_accessor :id, :title, :slug, :html, :page,
9
+ :status, :published_at, :created_at, :author_id,
10
+ :visibility, :featured, :plaintext, :author, :tags
11
+
12
+ alias page? page
13
+
14
+ alias featured? featured
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)
20
+
21
+ inst
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GhostRb
4
+ module Resources
5
+ # @author Rene Hernandez
6
+ # @since 0.1
7
+ class Tag < BaseResource
8
+ attr_accessor :id, :name, :slug, :visibility, :posts_count
9
+
10
+ def self.generate(hash)
11
+ inst = super(hash)
12
+ inst.posts_count = hash[:count][:posts].to_i if hash.key?(:count)
13
+
14
+ inst
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GhostRb
4
+ module Resources
5
+ # @author Rene Hernandez
6
+ # @since 0.1
7
+ class User < BaseResource
8
+ attr_accessor :id, :bio, :location, :name, :slug,
9
+ :visibility, :website, :posts_count
10
+
11
+ def self.generate(hash)
12
+ inst = super(hash)
13
+ inst.posts_count = hash[:count][:posts].to_i if hash.key?(:count)
14
+
15
+ inst
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GhostRb
4
+ VERSION = '0.2.0'
5
+ end
metadata ADDED
@@ -0,0 +1,179 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ghost_rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Rene Hernandez
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-10-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httpclient
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.14'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.14'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.9'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.9'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.49'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.49'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.15'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.15'
111
+ description:
112
+ email:
113
+ - renehr9102@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".codeclimate.yml"
119
+ - ".gitignore"
120
+ - ".rspec"
121
+ - ".rubocop.yml"
122
+ - ".travis.yml"
123
+ - Gemfile
124
+ - LICENSE.txt
125
+ - README.md
126
+ - Rakefile
127
+ - bin/console
128
+ - bin/httpclient
129
+ - bin/setup
130
+ - docs/404.html
131
+ - docs/Gemfile
132
+ - docs/Gemfile.lock
133
+ - docs/_config.yml
134
+ - docs/_includes/head.html
135
+ - docs/_includes/page-footer.html
136
+ - docs/_includes/page-header.html
137
+ - docs/_layouts/default.html
138
+ - docs/_layouts/page.html
139
+ - docs/css/cayman.css
140
+ - docs/css/normalize.css
141
+ - docs/index.md
142
+ - ghost_rb.gemspec
143
+ - lib/ghost_rb.rb
144
+ - lib/ghost_rb/client.rb
145
+ - lib/ghost_rb/controllers/base_controller.rb
146
+ - lib/ghost_rb/controllers/posts_controller.rb
147
+ - lib/ghost_rb/controllers/tags_controller.rb
148
+ - lib/ghost_rb/errors.rb
149
+ - lib/ghost_rb/resources/base_resource.rb
150
+ - lib/ghost_rb/resources/hydratable.rb
151
+ - lib/ghost_rb/resources/post.rb
152
+ - lib/ghost_rb/resources/tag.rb
153
+ - lib/ghost_rb/resources/user.rb
154
+ - lib/ghost_rb/version.rb
155
+ homepage: https://github.com/renehernandez/ghost_rb
156
+ licenses:
157
+ - MIT
158
+ metadata: {}
159
+ post_install_message:
160
+ rdoc_options: []
161
+ require_paths:
162
+ - lib
163
+ required_ruby_version: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ required_rubygems_version: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ requirements: []
174
+ rubyforge_project:
175
+ rubygems_version: 2.6.13
176
+ signing_key:
177
+ specification_version: 4
178
+ summary: GhostRb is a REST API client to interact with a given Ghost blog
179
+ test_files: []