ghost_rb 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: []