Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

source "https://rubygems.org"

# Specify your gem's dependencies in spooky.gemspec
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

A simple Ruby wrapper for the [Ghost](https://ghost.org) Content API.

The Ghost Content API documentation can be found [here](https://ghost.org/docs/api/v3/content/#endpoints).
The Ghost Content API documentation can be found [here](https://ghost.org/docs/content-api/).

## Installation

Expand Down Expand Up @@ -77,7 +77,7 @@ Both return a `Spooky::Post`.

#### Get posts with a filter applied

Filtering accepts simple hashes as conditions or [NQL strings for more complex filters](https://ghost.org/docs/api/v3/content/#syntax-reference).
Filtering accepts simple hashes as conditions or [NQL strings for more complex filters](https://ghost.org/docs/api/content/#syntax-reference).

```ruby
featured_posts, pagination = client.posts(filter: { featured: true })
Expand Down Expand Up @@ -125,4 +125,4 @@ The gem is available as open source under the terms of the [MIT License](http://

## Credits

This gem was originally developed by [infinityrobot](https://github.com/infinityrobot).
This gem was originally developed by [infinityrobot](https://github.com/infinityrobot).
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require "bundler/gem_tasks"
require "rubocop/rake_task"
require "rspec/core/rake_task"
Expand Down
1 change: 1 addition & 0 deletions bin/console
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

require "bundler/setup"
require "spooky"
Expand Down
9 changes: 7 additions & 2 deletions lib/spooky.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# frozen_string_literal: true

require "spooky/version"

require "spooky/is_resource"
require "active_model"
require "spooky/client"
require "spooky/post"
require "spooky/base"
require "spooky/count"
require "spooky/author"
require "spooky/tag"
require "spooky/post"
require "spooky/page"
54 changes: 37 additions & 17 deletions lib/spooky/author.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,41 @@
# frozen_string_literal: true

module Spooky
class Author
ATTRIBUTES = [
"bio",
"cover_image",
"facebook",
"id",
"location",
"meta_description",
"meta_title",
"name",
"profile_image",
"slug",
"twitter",
"url",
"website"
].freeze
class Author < Base
attribute :slug, :string
attribute :id, :string
attribute :name, :string
attribute :profile_image, :string
attribute :cover_image, :string
attribute :bio, :string
attribute :website, :string
attribute :location, :string
attribute :facebook, :string
attribute :twitter, :string
attribute :meta_title, :string
attribute :meta_description, :string
attribute :url, :string
attribute :threads, :string
attribute :bluesky, :string
attribute :mastodon, :string
attribute :tiktok, :string
attribute :instagram, :string
attribute :linkedin, :string
attribute :youtube, :string
attribute :comments, :boolean

attr_reader :count

def count=(attributes)
@count = Count.new(attributes)
end

def to_s
name.to_s
end

include IsResource
def to_param
slug.to_s
end
end
end
18 changes: 18 additions & 0 deletions lib/spooky/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

module Spooky
class Base
include ActiveModel::Model
include ActiveModel::Attributes

def attribute_writer_missing(name, value)
# Typically means they added something to the API.
# Most likely a new social network.
puts "Unexpected attribute for #{self.class.name}: \"#{name}\": \"#{value}\""
end

def persisted?
id.present?
end
end
end
104 changes: 86 additions & 18 deletions lib/spooky/client.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require "http"
require "active_support/core_ext/object/blank"
require "active_support/core_ext/string/inflections"
Expand All @@ -9,7 +11,7 @@ class Client
def initialize(attrs = {})
@api_url = ENV["GHOST_API_URL"] || attrs[:api_url]
@api_key = ENV["GHOST_CONTENT_API_KEY"] || attrs[:api_key]
@endpoint = "#{@api_url}/ghost/api/v3/content"
@endpoint = "#{@api_url}/ghost/api/content"
end

def fetch_json(resource, options = {})
Expand Down Expand Up @@ -37,33 +39,99 @@ def fetch(resource, options = {})
response.present? && [response.map { |attrs| resource_class.send(:new, attrs) }, pagination]
end

def posts(tags: false, authors: false, filter: false, page: false, limit: false)
inc = []
inc << "tags" if tags
inc << "authors" if authors
def pages(include: [], filter: false, page: false, limit: false)
options = {}
options[:include] = include unless include.empty?

options = apply_filter(options, filter)
options = apply_pagination(options, { page: page, limit: limit })

fetch("pages", options)
end

def page_by(id: nil, slug: nil)
options = {}
options[:include] = inc if inc.present?

if id.present?
response, = fetch("pages/#{id}", options)
response.present? && response.first
elsif slug.present?
response, = fetch("pages/slug/#{slug}", options)
response.present? && response.first
else
false
end
end

def posts(include: [], filter: false, page: false, limit: false)
options = {}
options[:include] = include unless include.empty?

options = apply_filter(options, filter)
options = apply_pagination(options, { page: page, limit: limit })

fetch("posts", options)
end

def post_by(id: nil, slug: nil, tags: false, authors: false)
inc = []
inc << "tags" if tags
inc << "authors" if authors
def post_by(id: nil, slug: nil, include: [])
options = {}
options[:include] = include unless include.empty?

if id.present?
response, = fetch("posts/#{id}", options)
response.present? && response.first
elsif slug.present?
response, = fetch("posts/slug/#{slug}", options)
response.present? && response.first
else
false
end
end

def authors(include: [], filter: false, page: false, limit: false)
options = {}
options[:include] = include unless include.empty?

options = apply_filter(options, filter)
options = apply_pagination(options, { page: page, limit: limit })

fetch("authors", options)
end

def author_by(id: nil, slug: nil, include: [])
options = {}
options[:include] = include unless include.empty?

if id.present?
response, = fetch("authors/#{id}", options)
response.present? && response.first
elsif slug.present?
response, = fetch("authors/slug/#{slug}", options)
response.present? && response.first
else
false
end
end

def tags(include: [], filter: false, page: false, limit: false)
options = {}
options[:include] = include unless include.empty?

options = apply_filter(options, filter)
options = apply_pagination(options, { page: page, limit: limit })

fetch("tags", options)
end

def tag_by(id: nil, slug: nil, include: [])
options = {}
options[:include] = inc if inc.present?
options[:include] = include unless include.empty?

if id.present?
response, _ = fetch("posts/#{id}", options)
response, = fetch("tags/#{id}", options)
response.present? && response.first
elsif slug.present?
response, _ = fetch("posts/slug/#{slug}", options)
response, = fetch("tags/slug/#{slug}", options)
response.present? && response.first
else
false
Expand All @@ -74,11 +142,11 @@ def post_by(id: nil, slug: nil, tags: false, authors: false)

def apply_filter(options, filter)
if filter.present?
if filter.is_a?(Hash)
options[:filter] = filter.map { |k, v| "#{k}:#{v}" }.join("+")
else
options[:filter] = filter
end
options[:filter] = if filter.is_a?(Hash)
filter.map { |k, v| "#{k}:#{v}" }.join("+")
else
filter
end
end

options
Expand Down
7 changes: 7 additions & 0 deletions lib/spooky/count.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module Spooky
class Count < Base
attribute :posts, :integer
end
end
26 changes: 0 additions & 26 deletions lib/spooky/is_resource.rb

This file was deleted.

7 changes: 7 additions & 0 deletions lib/spooky/page.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module Spooky
class Page < Post
# Per docs, "Pages are structured identically to posts.""
end
end
Loading