buttercms-ruby-zwg 2.4.1
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 +7 -0
- data/.github/workflows/rubygems-publish.yml +25 -0
- data/.gitignore +23 -0
- data/.rspec +1 -0
- data/Gemfile +9 -0
- data/LICENSE +22 -0
- data/README.md +148 -0
- data/Rakefile +8 -0
- data/buttercms-ruby.gemspec +24 -0
- data/lib/buttercms/author.rb +7 -0
- data/lib/buttercms/butter_collection.rb +22 -0
- data/lib/buttercms/butter_resource.rb +96 -0
- data/lib/buttercms/category.rb +7 -0
- data/lib/buttercms/content.rb +20 -0
- data/lib/buttercms/data_store_adapters/redis.rb +26 -0
- data/lib/buttercms/data_store_adapters/redis_ssl.rb +27 -0
- data/lib/buttercms/data_store_adapters/yaml.rb +25 -0
- data/lib/buttercms/errors.rb +15 -0
- data/lib/buttercms/feed.rb +7 -0
- data/lib/buttercms/hash_to_object.rb +7 -0
- data/lib/buttercms/page.rb +25 -0
- data/lib/buttercms/post.rb +13 -0
- data/lib/buttercms/tag.rb +7 -0
- data/lib/buttercms/version.rb +3 -0
- data/lib/buttercms-ruby.rb +194 -0
- data/lib/console.rb +10 -0
- data/lib/core_ext/ostruct.rb +9 -0
- data/spec/lib/butter-ruby_spec.rb +67 -0
- data/spec/lib/buttercms/butter_collection_spec.rb +40 -0
- data/spec/lib/buttercms/butter_resource_spec.rb +46 -0
- data/spec/lib/buttercms/content_spec.rb +33 -0
- data/spec/lib/buttercms/hash_to_object_spec.rb +19 -0
- data/spec/spec_helper.rb +8 -0
- metadata +104 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 54ecb3cd54e93defe79a22aca4f2e3a82c4f507cb6e3c1c57382f7690f0c3837
|
|
4
|
+
data.tar.gz: 9cd1b5498b7752d50cd560463fe99ed1866d9c9864bb85cce0dad8d50d1d64aa
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 1416c28751442d8e03235efef34aa742f0cec6eeed5d93b14fff5d519283e700c9d790e7e4e7e1c58b0ab6217cd40274a54bb944cb46c3a8a6c480ae51b6a7f8
|
|
7
|
+
data.tar.gz: 219c0bc189f17ecc58ac4cc7d33cde89c516d394f087af6365cb215d2787df63221bd4a281680d94d46fb65cfd6ecf660e4a1364b41aac364cf61d1421dc8ea6
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# This workflow will publish a gem to rubygems.org when a release is created
|
|
2
|
+
# For more information see: # https://github.com/discourse/publish-rubygems-action
|
|
3
|
+
|
|
4
|
+
name: Publish Gem
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches:
|
|
9
|
+
- master
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish:
|
|
13
|
+
if: github.ref == 'refs/heads/master' && github.event_name == 'push' && contains(github.event.head_commit.message, 'chore(release)')
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v3
|
|
18
|
+
|
|
19
|
+
- name: Release Gem
|
|
20
|
+
uses: discourse/publish-rubygems-action@v2
|
|
21
|
+
env:
|
|
22
|
+
RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
|
|
23
|
+
RELEASE_COMMAND: rake release
|
|
24
|
+
GIT_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com
|
|
25
|
+
GIT_NAME: github-actions[bot]
|
data/.gitignore
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
.bundle
|
|
4
|
+
.config
|
|
5
|
+
.yardoc
|
|
6
|
+
Gemfile.lock
|
|
7
|
+
InstalledFiles
|
|
8
|
+
_yardoc
|
|
9
|
+
coverage
|
|
10
|
+
doc/
|
|
11
|
+
lib/bundler/man
|
|
12
|
+
pkg
|
|
13
|
+
rdoc
|
|
14
|
+
spec/reports
|
|
15
|
+
test/tmp
|
|
16
|
+
test/version_tmp
|
|
17
|
+
tmp
|
|
18
|
+
.DS_Store
|
|
19
|
+
.ruby-version
|
|
20
|
+
.rvmrc
|
|
21
|
+
*.rdb
|
|
22
|
+
*.store
|
|
23
|
+
test.rb
|
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--format documentation --color
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2015 Butter
|
|
4
|
+
https://buttercms.com/
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in
|
|
14
|
+
all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
22
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# ButterCMS API Ruby Client
|
|
2
|
+
|
|
3
|
+
## Documentation
|
|
4
|
+
|
|
5
|
+
For a comprehensive list of examples, check out the [API documentation](https://buttercms.com/docs/api/).
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
To setup your project, follow these steps:
|
|
10
|
+
|
|
11
|
+
1. Install using `gem install buttercms-ruby` or by adding to your `Gemfile`:
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
gem 'buttercms-ruby'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
2. Set your API token.
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
require 'buttercms-ruby'
|
|
21
|
+
|
|
22
|
+
ButterCMS::api_token = "YourToken"
|
|
23
|
+
|
|
24
|
+
# Fetch content from test mode (eg. for your staging website)
|
|
25
|
+
# ButterCMS::test_mode = true
|
|
26
|
+
|
|
27
|
+
# Set read timeout (Default is 5.0)
|
|
28
|
+
# ButterCMS::read_timeout = 5.0
|
|
29
|
+
|
|
30
|
+
# Set open timeout (Default is 2.0)
|
|
31
|
+
# ButterCMS::open_timeout = 2.0
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Pages
|
|
35
|
+
|
|
36
|
+
https://buttercms.com/docs/api/?ruby#pages
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
params = {page: 1, page_size: 10, locale: 'en', preview: 1, 'fields.headline': 'foo bar', levels: 2} # optional
|
|
41
|
+
pages = ButterCMS::Page.list('news', params)
|
|
42
|
+
|
|
43
|
+
page = ButterCMS::Page.get('news', 'hello-world', params)
|
|
44
|
+
|
|
45
|
+
pages = ButterCMS::Page.search('query', params)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Collections
|
|
49
|
+
|
|
50
|
+
https://buttercms.com/docs/api/?ruby#retrieve-a-collection
|
|
51
|
+
|
|
52
|
+
```ruby
|
|
53
|
+
# list each instance of a given collection with meta data for fetching the next page.
|
|
54
|
+
params = { page: 1, page_size: 10, locale: 'en', preview: 1, 'fields.headline': 'foo bar', levels: 2 } # optional
|
|
55
|
+
ButterCMS::Content.list('collection1', params)
|
|
56
|
+
|
|
57
|
+
# list instances for multiple collections, this will not return meta data for pagination control.
|
|
58
|
+
ButterCMS::Content.fetch(['collection1', 'collection2'], params)
|
|
59
|
+
|
|
60
|
+
# Test mode can be used to setup a staging website for previewing Collections or for testing content during local development. To fetch content from test mode add the following configuration:
|
|
61
|
+
ButterCMS::test_mode = true
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Blog Engine
|
|
65
|
+
|
|
66
|
+
https://buttercms.com/docs/api/?ruby#blog-engine
|
|
67
|
+
|
|
68
|
+
```ruby
|
|
69
|
+
posts = ButterCMS::Post.all({:page => 1, :page_size => 10})
|
|
70
|
+
puts posts.first.title
|
|
71
|
+
puts posts.meta.next_page
|
|
72
|
+
|
|
73
|
+
posts = ButterCMS::Post.search("my favorite post", {page: 1, page_size: 10})
|
|
74
|
+
puts posts.first.title
|
|
75
|
+
|
|
76
|
+
post = ButterCMS::Post.find("post-slug")
|
|
77
|
+
puts post.title
|
|
78
|
+
|
|
79
|
+
# Create a Post.
|
|
80
|
+
ButterCMS::write_api_token = "YourWriteToken"
|
|
81
|
+
ButterCMS::Post.create({
|
|
82
|
+
slug: 'blog-slug',
|
|
83
|
+
title: 'blog-title'
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
# Update a Post
|
|
87
|
+
ButterCMS::Post.update('blog-slug', {
|
|
88
|
+
title: 'blog-title-v2'
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
# Create a page
|
|
92
|
+
ButterCMS::Page.create({
|
|
93
|
+
slug: 'page-slug',
|
|
94
|
+
title: 'page-title',
|
|
95
|
+
status: 'published',
|
|
96
|
+
"page-type": 'page_type',
|
|
97
|
+
fields: {
|
|
98
|
+
meta_title: 'test meta title'
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
# update a Page
|
|
103
|
+
ButterCMS::Page.update('page-slug-2', {
|
|
104
|
+
status: 'published',
|
|
105
|
+
fields: {
|
|
106
|
+
meta_title: 'test meta title'
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
author = ButterCMS::Author.find("author-slug")
|
|
113
|
+
puts author.first_name
|
|
114
|
+
|
|
115
|
+
category = ButterCMS::Category.find("category-slug")
|
|
116
|
+
puts category.name
|
|
117
|
+
|
|
118
|
+
tags = ButterCMS::Tag.all
|
|
119
|
+
p tags
|
|
120
|
+
|
|
121
|
+
rss_feed = ButterCMS::Feed.find(:rss)
|
|
122
|
+
puts rss_feed.data
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
## Fallback Data Store
|
|
127
|
+
|
|
128
|
+
This client supports automatic fallback to a data store when API requests fail. When a data store is set, on every successful API request the response is written to the data store. When a subsequent API request fails, the client attempts to fallback to the value in the data store. Currently, Redis and YAML Store are supported.
|
|
129
|
+
|
|
130
|
+
```ruby
|
|
131
|
+
# Use YAMLstore
|
|
132
|
+
ButterCMS::data_store = :yaml, "/File/Path/For/buttercms.store"
|
|
133
|
+
|
|
134
|
+
# Use Redis
|
|
135
|
+
ButterCMS::data_store = :redis, ENV['REDIS_URL']
|
|
136
|
+
|
|
137
|
+
# Use Redis over ssl store
|
|
138
|
+
ButterCMS.data_store = :redis_ssl, ENV["REDIS_URL"], { ca_file: "/path/to/ca.crt" }
|
|
139
|
+
|
|
140
|
+
# Set logger (optional)
|
|
141
|
+
ButterCMS::logger = MyLogger.new
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Other
|
|
145
|
+
|
|
146
|
+
View Ruby [Blog engine](https://buttercms.com/ruby-blog-engine/) and [Full CMS](https://buttercms.com/ruby-cms/) for other examples of using ButterCMS with Ruby.
|
|
147
|
+
|
|
148
|
+
### Development
|
data/Rakefile
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
|
3
|
+
|
|
4
|
+
require 'buttercms/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |s|
|
|
7
|
+
s.name = "buttercms-ruby-zwg"
|
|
8
|
+
s.version = ButterCMS::VERSION
|
|
9
|
+
s.require_paths = ["lib"]
|
|
10
|
+
s.summary = 'Ruby API client for ButterCMS'
|
|
11
|
+
s.description = 'Butter is the #1 developer rated headless CMS. See https://buttercms.com for details.'
|
|
12
|
+
s.authors = ["ButterCMS"]
|
|
13
|
+
s.email= ["support@buttercms.com"]
|
|
14
|
+
s.homepage = "https://buttercms.com/docs"
|
|
15
|
+
s.license = 'MIT'
|
|
16
|
+
|
|
17
|
+
s.add_development_dependency 'rspec'
|
|
18
|
+
s.add_development_dependency 'webmock'
|
|
19
|
+
s.required_ruby_version = '>= 1.9.3'
|
|
20
|
+
|
|
21
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
22
|
+
s.files = `git ls-files`.split("\n")
|
|
23
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
24
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module ButterCMS
|
|
2
|
+
class ButterCollection
|
|
3
|
+
include Enumerable
|
|
4
|
+
|
|
5
|
+
attr_reader :items
|
|
6
|
+
attr_reader :meta
|
|
7
|
+
|
|
8
|
+
def initialize(klass, json)
|
|
9
|
+
data = json["data"]
|
|
10
|
+
meta = json["meta"]
|
|
11
|
+
|
|
12
|
+
@meta = HashToObject.convert(meta) if meta
|
|
13
|
+
@items = data.map {|o| klass.new("data" => o) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def each(&block)
|
|
17
|
+
@items.each do |member|
|
|
18
|
+
block.call(member)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
module ButterCMS
|
|
2
|
+
class ButterResource
|
|
3
|
+
attr_reader :meta, :data
|
|
4
|
+
|
|
5
|
+
def initialize(json)
|
|
6
|
+
@json = json
|
|
7
|
+
@data = HashToObject.convert(json["data"])
|
|
8
|
+
@meta = HashToObject.convert(json["meta"]) if json["meta"]
|
|
9
|
+
|
|
10
|
+
define_attribute_methods(@data)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def marshal_dump
|
|
14
|
+
{ json: @json, data: @data, meta: @meta }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def marshal_load(dump)
|
|
18
|
+
@json = dump[:json]
|
|
19
|
+
@data = dump[:data]
|
|
20
|
+
@meta = dump[:meta]
|
|
21
|
+
|
|
22
|
+
define_attribute_methods(@data)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def inspect
|
|
26
|
+
id_string = (self.respond_to?(:id) && !self.id.nil?) ? " id=#{self.id}" : ""
|
|
27
|
+
"#<#{self.class}:0x#{self.object_id.to_s(16)}#{id_string}> JSON: " + JSON.pretty_generate(@json)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.endpoint(id = nil)
|
|
31
|
+
# Append trailing slash when id is added to path because
|
|
32
|
+
# API expects all endpoints to include trailing slashes
|
|
33
|
+
resource_path + (id ? "#{id}/" : '')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.patch_endpoint(id)
|
|
37
|
+
# Append trailing slash when id is added to path because
|
|
38
|
+
# API expects all endpoints to include trailing slashes
|
|
39
|
+
resource_path + "*/#{id}/"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.resource_path
|
|
43
|
+
raise "resource_path must be set"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.all(options = {})
|
|
47
|
+
response = ButterCMS.request(self.endpoint, options)
|
|
48
|
+
|
|
49
|
+
self.create_collection(response)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.find(id, options = {})
|
|
53
|
+
response = ButterCMS.request(self.endpoint(id), options)
|
|
54
|
+
|
|
55
|
+
self.create_object(response)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.create(options = {})
|
|
59
|
+
options[:method] = 'Post'
|
|
60
|
+
response = ButterCMS.write_request(self.endpoint, options)
|
|
61
|
+
|
|
62
|
+
self.create_object(response)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.update(id, options = {})
|
|
66
|
+
options[:method] = 'Patch'
|
|
67
|
+
_endpoint = if resource_path.include?("/pages/")
|
|
68
|
+
self.patch_endpoint(id)
|
|
69
|
+
else
|
|
70
|
+
self.endpoint(id)
|
|
71
|
+
end
|
|
72
|
+
response = ButterCMS.write_request(_endpoint, options)
|
|
73
|
+
|
|
74
|
+
self.create_object(response)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
private
|
|
78
|
+
|
|
79
|
+
def self.create_collection(response)
|
|
80
|
+
ButterCollection.new(self, response)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def self.create_object(response)
|
|
84
|
+
self.new(response)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def define_attribute_methods(methods)
|
|
88
|
+
return unless methods.respond_to?(:each_pair)
|
|
89
|
+
|
|
90
|
+
methods.each_pair do |key, value|
|
|
91
|
+
instance_variable_set("@#{key}", value)
|
|
92
|
+
self.class.send(:attr_reader, key)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module ButterCMS
|
|
2
|
+
class Content < ButterResource
|
|
3
|
+
def self.resource_path
|
|
4
|
+
"/content/"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def self.list(collection_slug, options = {})
|
|
8
|
+
response = ButterCMS.request(self.endpoint(collection_slug), options)
|
|
9
|
+
|
|
10
|
+
self.create_collection(response)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.fetch(collection_slugs, options = {})
|
|
14
|
+
params = { keys: collection_slugs.join(',') }.merge(options)
|
|
15
|
+
response = ButterCMS.request(self.resource_path, params)
|
|
16
|
+
|
|
17
|
+
self.new(response)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'redis'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
puts "WARNING: redis >= 3.0.0 is required to use the redis data store."
|
|
5
|
+
raise
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module ButterCMS
|
|
9
|
+
module DataStoreAdapters
|
|
10
|
+
class Redis
|
|
11
|
+
def initialize(options)
|
|
12
|
+
redis_url = options.first
|
|
13
|
+
|
|
14
|
+
@redis = ::Redis.new(url: redis_url)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def set(key, value)
|
|
18
|
+
@redis.set(key, value)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def get(key)
|
|
22
|
+
@redis.get(key)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'redis'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
puts "WARNING: redis >= 3.0.0 is required to use the redis data store."
|
|
5
|
+
raise
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module ButterCMS
|
|
9
|
+
module DataStoreAdapters
|
|
10
|
+
class RedisSSL
|
|
11
|
+
def initialize(options)
|
|
12
|
+
redis_url = options.first
|
|
13
|
+
ssl_params = options.second && Hash[options.second]
|
|
14
|
+
|
|
15
|
+
@redis = ::Redis.new(url: redis_url, ssl_params:)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def set(key, value)
|
|
19
|
+
@redis.set(key, value)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get(key)
|
|
23
|
+
@redis.get(key)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'yaml/store'
|
|
2
|
+
|
|
3
|
+
module ButterCMS
|
|
4
|
+
module DataStoreAdapters
|
|
5
|
+
class Yaml
|
|
6
|
+
def initialize(options)
|
|
7
|
+
file_path = options.first
|
|
8
|
+
|
|
9
|
+
@store = YAML::Store.new file_path
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def set(key, value)
|
|
13
|
+
@store.transaction do
|
|
14
|
+
@store[key] = value
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def get(key)
|
|
19
|
+
@store.transaction do
|
|
20
|
+
@store[key]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module ButterCMS
|
|
2
|
+
# Error is the top level error raised by ButterCMS
|
|
3
|
+
class Error < StandardError
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
# NotFound is raised when a resource cannot be found
|
|
7
|
+
class NotFound < Error
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class Unauthorized < Error
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class BadRequest < Error
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module ButterCMS
|
|
2
|
+
class Page < ButterResource
|
|
3
|
+
def self.resource_path
|
|
4
|
+
"/pages/"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def self.list(page_type, options = {})
|
|
8
|
+
response = ButterCMS.request(self.endpoint(page_type), options)
|
|
9
|
+
|
|
10
|
+
self.create_collection(response)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.get(page_type, slug, options = {})
|
|
14
|
+
response = ButterCMS.request(self.endpoint("#{page_type}/#{slug}"), options)
|
|
15
|
+
|
|
16
|
+
self.create_object(response)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.search(query = '', options = {})
|
|
20
|
+
response = ButterCMS.request('/pages/search/', {query: query}.merge(options))
|
|
21
|
+
|
|
22
|
+
self.create_collection(response)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module ButterCMS
|
|
2
|
+
class Post < ButterResource
|
|
3
|
+
def self.resource_path
|
|
4
|
+
"/posts/"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def self.search(query = '', options = {})
|
|
8
|
+
response = ButterCMS.request('/search/', {query: query}.merge(options))
|
|
9
|
+
|
|
10
|
+
self.create_collection(response)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'ostruct'
|
|
3
|
+
require 'logger'
|
|
4
|
+
require 'uri'
|
|
5
|
+
require 'net/http'
|
|
6
|
+
require 'pathname'
|
|
7
|
+
|
|
8
|
+
require "buttercms/errors"
|
|
9
|
+
require 'buttercms/version'
|
|
10
|
+
require 'buttercms/hash_to_object'
|
|
11
|
+
require 'buttercms/butter_collection'
|
|
12
|
+
require 'buttercms/butter_resource'
|
|
13
|
+
require 'buttercms/author'
|
|
14
|
+
require 'buttercms/category'
|
|
15
|
+
require 'buttercms/tag'
|
|
16
|
+
require 'buttercms/post'
|
|
17
|
+
require 'buttercms/feed'
|
|
18
|
+
require 'buttercms/content'
|
|
19
|
+
require 'buttercms/page'
|
|
20
|
+
|
|
21
|
+
# See https://github.com/jruby/jruby/issues/3113
|
|
22
|
+
if RUBY_VERSION < '2.0.0'
|
|
23
|
+
require_relative 'core_ext/ostruct'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module ButterCMS
|
|
27
|
+
@api_url = URI.parse('https://api.buttercms.com/v2')
|
|
28
|
+
|
|
29
|
+
class << self
|
|
30
|
+
attr_accessor :api_token
|
|
31
|
+
attr_accessor :write_api_token
|
|
32
|
+
attr_accessor :test_mode
|
|
33
|
+
attr_accessor :read_timeout
|
|
34
|
+
attr_accessor :open_timeout
|
|
35
|
+
attr_reader :data_store
|
|
36
|
+
attr_writer :logger
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.logger
|
|
40
|
+
@logger ||= Logger.new($stdout).tap do |log|
|
|
41
|
+
log.progname = "ButterCMS"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.data_store=(*args)
|
|
46
|
+
args.flatten!
|
|
47
|
+
|
|
48
|
+
if args.count < 2
|
|
49
|
+
raise ArgumentError.new "Wrong number of arguments"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
strategy = args.first
|
|
53
|
+
options = args.drop(1)
|
|
54
|
+
|
|
55
|
+
case strategy
|
|
56
|
+
when :yaml
|
|
57
|
+
require_relative 'buttercms/data_store_adapters/yaml'
|
|
58
|
+
@data_store = ButterCMS::DataStoreAdapters::Yaml.new(options)
|
|
59
|
+
when :redis
|
|
60
|
+
require_relative 'buttercms/data_store_adapters/redis'
|
|
61
|
+
@data_store = ButterCMS::DataStoreAdapters::Redis.new(options)
|
|
62
|
+
when :redis_ssl
|
|
63
|
+
require_relative 'buttercms/data_store_adapters/redis_ssl'
|
|
64
|
+
@data_store = ButterCMS::DataStoreAdapters::RedisSSL.new(options)
|
|
65
|
+
else
|
|
66
|
+
raise ArgumentError.new "Invalid ButterCMS data store #{strategy}"
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def self.api_request(path, options = {})
|
|
71
|
+
query = options.dup
|
|
72
|
+
query[:auth_token] ||= api_token
|
|
73
|
+
|
|
74
|
+
if test_mode
|
|
75
|
+
query[:test] = 1
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# If the user has passed in a "/" leading path, don't interpret that
|
|
79
|
+
# as wanting to get rid of the API prefix
|
|
80
|
+
if path.start_with?("/")
|
|
81
|
+
path = path[1..-1]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
path = Pathname.new(@api_url.path).join(path).to_s + "?#{URI.encode_www_form(query)}"
|
|
85
|
+
|
|
86
|
+
response =
|
|
87
|
+
Net::HTTP.start(@api_url.host, @api_url.port, http_options) do |http|
|
|
88
|
+
request = Net::HTTP::Get.new(path)
|
|
89
|
+
request["User-Agent"] = "ButterCMS/Ruby #{ButterCMS::VERSION}"
|
|
90
|
+
request["Accept"] = "application/json"
|
|
91
|
+
|
|
92
|
+
http.request(request)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
case response
|
|
96
|
+
when Net::HTTPNotFound
|
|
97
|
+
raise ::ButterCMS::NotFound, JSON.parse(response.body)["detail"]
|
|
98
|
+
when Net::HTTPUnauthorized
|
|
99
|
+
raise ::ButterCMS::Unauthorized, JSON.parse(response.body)['detail']
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
response.body
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def self.request(path, options = {})
|
|
106
|
+
raise ArgumentError.new "Please set your API token" unless api_token
|
|
107
|
+
|
|
108
|
+
key = "buttercms:#{path}:#{options}"
|
|
109
|
+
|
|
110
|
+
begin
|
|
111
|
+
result = api_request(path, options)
|
|
112
|
+
|
|
113
|
+
if data_store
|
|
114
|
+
data_store.set(key, result)
|
|
115
|
+
logger.info "Set key #{key}"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# TODO - more selective exception handling (SocketError)
|
|
119
|
+
rescue Exception => e
|
|
120
|
+
|
|
121
|
+
if data_store
|
|
122
|
+
if result = data_store.get(key)
|
|
123
|
+
logger.info "Fetched key #{key}"
|
|
124
|
+
|
|
125
|
+
# Log request error
|
|
126
|
+
logger.error e
|
|
127
|
+
else
|
|
128
|
+
logger.info "No data for key #{key}"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Raise request exception if there's no data store or value returned
|
|
133
|
+
raise e unless data_store && result
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
return JSON.parse(result)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def self.write_request(path, options = {})
|
|
140
|
+
raise ArgumentError.new "Please set your write API token" unless write_api_token
|
|
141
|
+
result = write_api_request(path, options)
|
|
142
|
+
|
|
143
|
+
return JSON.parse(result)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def self.write_api_request(path, options = {})
|
|
147
|
+
query = options.dup
|
|
148
|
+
token_for_request = query.delete(:auth_token) || write_api_token
|
|
149
|
+
|
|
150
|
+
path = "#{@api_url.path}#{URI.encode(path)}"
|
|
151
|
+
|
|
152
|
+
response =
|
|
153
|
+
Net::HTTP.start(@api_url.host, @api_url.port, http_options) do |http|
|
|
154
|
+
write_type = query.delete(:method) || "Post"
|
|
155
|
+
request_type = "Net::HTTP::#{write_type}".constantize
|
|
156
|
+
request = request_type.new(path)
|
|
157
|
+
request["User-Agent"] = "ButterCMS/Ruby #{ButterCMS::VERSION}"
|
|
158
|
+
request["Accept"] = "application/json"
|
|
159
|
+
request["Content-Type"] = "application/json"
|
|
160
|
+
request["Authorization"] = "Token #{token_for_request}"
|
|
161
|
+
request.body = query.except(:auth_token).to_json
|
|
162
|
+
|
|
163
|
+
http.request(request)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
case response
|
|
167
|
+
when Net::HTTPNotFound
|
|
168
|
+
raise ::ButterCMS::NotFound, JSON.parse(response.body)["detail"]
|
|
169
|
+
when Net::HTTPBadRequest
|
|
170
|
+
parsed_body = JSON.parse(response.body)
|
|
171
|
+
errors = if parsed_body.is_a?(Array)
|
|
172
|
+
parsed_body.join(' ')
|
|
173
|
+
else
|
|
174
|
+
parsed_body.map do |k, v|
|
|
175
|
+
"#{k}: #{v}"
|
|
176
|
+
end.join(" ")
|
|
177
|
+
end
|
|
178
|
+
raise ::ButterCMS::BadRequest, errors
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
response.body
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
private
|
|
185
|
+
|
|
186
|
+
def self.http_options
|
|
187
|
+
{
|
|
188
|
+
open_timeout: open_timeout || 2.0,
|
|
189
|
+
read_timeout: read_timeout || 5.0,
|
|
190
|
+
ssl_timeout: 2.0,
|
|
191
|
+
use_ssl: @api_url.scheme == "https",
|
|
192
|
+
}
|
|
193
|
+
end
|
|
194
|
+
end
|
data/lib/console.rb
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ButterCMS do
|
|
4
|
+
describe '.request' do
|
|
5
|
+
context 'with an api token' do
|
|
6
|
+
before do
|
|
7
|
+
allow(ButterCMS).to receive(:api_token).and_return('test123')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'should make an api request' do
|
|
11
|
+
request = stub_request(:get, "https://api.buttercms.com/v2?auth_token=test123")
|
|
12
|
+
.to_return(body: JSON.generate({data: {test: 'test'}}))
|
|
13
|
+
|
|
14
|
+
ButterCMS.request('')
|
|
15
|
+
expect(request).to have_been_made
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should properly escape paths" do
|
|
19
|
+
request = stub_request(
|
|
20
|
+
:get,
|
|
21
|
+
"https://api.buttercms.com/v2/pages/*/homepage%20en?auth_token=test123"
|
|
22
|
+
).to_return(body: JSON.generate({data: {test: 'test'}}))
|
|
23
|
+
|
|
24
|
+
# support leading slashes
|
|
25
|
+
ButterCMS.request('/pages/*/homepage en')
|
|
26
|
+
|
|
27
|
+
# and no leading slashes
|
|
28
|
+
ButterCMS.request('pages/*/homepage en')
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
expect(request).to have_been_made.twice
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context 'without an api token' do
|
|
36
|
+
it 'should throw an argument error' do
|
|
37
|
+
expect{ ButterCMS.request() }.to raise_error(ArgumentError)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "raises NotFound on 404" do
|
|
42
|
+
allow(ButterCMS).to receive(:api_token).and_return("test123")
|
|
43
|
+
|
|
44
|
+
request = stub_request(:get, %r{/posts/slug/})
|
|
45
|
+
.with(query: { auth_token: "test123" })
|
|
46
|
+
.to_return(status: 404, body: '{"detail":"Not found."}')
|
|
47
|
+
|
|
48
|
+
expect { ButterCMS.request("/posts/slug/") }
|
|
49
|
+
.to raise_error(ButterCMS::NotFound)
|
|
50
|
+
|
|
51
|
+
expect(request).to have_been_made
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "raises Unauthorized on 401" do
|
|
55
|
+
allow(ButterCMS).to receive(:api_token).and_return("test")
|
|
56
|
+
|
|
57
|
+
request = stub_request(:get, %r{/posts/slug/})
|
|
58
|
+
.with(query: { auth_token: "test" })
|
|
59
|
+
.to_return(status: 401, body: '{"detail":"Invalid token."}')
|
|
60
|
+
|
|
61
|
+
expect { ButterCMS.request("/posts/slug/") }
|
|
62
|
+
.to raise_error(ButterCMS::Unauthorized)
|
|
63
|
+
|
|
64
|
+
expect(request).to have_been_made
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ButterCMS::ButterCollection do
|
|
4
|
+
let(:json) { {"data" => ["foo"], "meta" => {}} }
|
|
5
|
+
let(:klass) { double('klass', :new => 'bar') }
|
|
6
|
+
|
|
7
|
+
it 'implements #items' do
|
|
8
|
+
collection = ButterCMS::ButterCollection.new(klass, json)
|
|
9
|
+
|
|
10
|
+
expect(collection.items).to match_array(["bar"])
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'implements #meta' do
|
|
14
|
+
collection = ButterCMS::ButterCollection.new(klass, json)
|
|
15
|
+
|
|
16
|
+
expect(collection.meta).to be_a(OpenStruct)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'implements #count' do
|
|
20
|
+
collection = ButterCMS::ButterCollection.new(klass, json)
|
|
21
|
+
|
|
22
|
+
expect(collection.count).to eq 1
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Marshal.load (used by Rails for caching) was not restoring the ButterResource's dynamic methods
|
|
26
|
+
# See https://github.com/ButterCMS/buttercms-ruby/issues/13
|
|
27
|
+
describe 'marshal load' do
|
|
28
|
+
subject { described_class.new(ButterCMS::ButterResource, 'data' => [{ 'name' => 'Test Name', 'description' => 'Test Description' }]) }
|
|
29
|
+
|
|
30
|
+
it 'restores the ButterResource dynamic methods' do
|
|
31
|
+
collection = Marshal.load(Marshal.dump(subject))
|
|
32
|
+
resource = collection.first
|
|
33
|
+
|
|
34
|
+
aggregate_failures do
|
|
35
|
+
expect(resource.name).to eq('Test Name')
|
|
36
|
+
expect(resource.description).to eq('Test Description')
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ButterCMS::ButterResource do
|
|
4
|
+
before do
|
|
5
|
+
allow(ButterCMS).to receive(:token).and_return('test123')
|
|
6
|
+
allow(ButterCMS).to receive(:request).and_return({"data" => [{"attribute" => 'test'}]})
|
|
7
|
+
|
|
8
|
+
allow(ButterCMS::ButterResource).to receive(:resource_path).and_return('')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe 'auto-generated methods' do
|
|
12
|
+
let(:resource) { described_class.new('data' => { 'name' => 'Test Name', 'description' => 'Test Description' }) }
|
|
13
|
+
|
|
14
|
+
it 'creates attribute reader methods for data pairs' do
|
|
15
|
+
aggregate_failures do
|
|
16
|
+
expect(resource.name).to eq('Test Name')
|
|
17
|
+
expect(resource.description).to eq('Test Description')
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe '.all' do
|
|
23
|
+
|
|
24
|
+
it 'should make a request with the correct endpoint' do
|
|
25
|
+
expect(ButterCMS).to receive(:request).with('', {})
|
|
26
|
+
ButterCMS::ButterResource.all()
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'should return a collection' do
|
|
30
|
+
objects = ButterCMS::ButterResource.all
|
|
31
|
+
expect(objects).to be_a(ButterCMS::ButterCollection)
|
|
32
|
+
expect(objects.first).to be_a(ButterCMS::ButterResource)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe '.find' do
|
|
37
|
+
it 'should make a request with the correct endpoint' do
|
|
38
|
+
expect(ButterCMS).to receive(:request).with('1/', {})
|
|
39
|
+
ButterCMS::ButterResource.find(1)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'should return one object' do
|
|
43
|
+
expect(ButterCMS::ButterResource.find(1)).to be_a(ButterCMS::ButterResource)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ButterCMS::Content do
|
|
4
|
+
before do
|
|
5
|
+
allow(ButterCMS).to receive(:token).and_return('test123')
|
|
6
|
+
allow(ButterCMS).to receive(:request).and_return({
|
|
7
|
+
"meta"=>{
|
|
8
|
+
"next_page"=>2,
|
|
9
|
+
"previous_page"=>nil,
|
|
10
|
+
"count"=>2
|
|
11
|
+
},
|
|
12
|
+
"data"=>{
|
|
13
|
+
"author"=>[
|
|
14
|
+
{ "name"=>"Charles Dickens"},
|
|
15
|
+
{ "name"=>"J.K. Rowling"}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
@response = ButterCMS::Content.list('slug', {
|
|
21
|
+
page: 1,
|
|
22
|
+
page_size: 2
|
|
23
|
+
})
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "has meta and collection info" do
|
|
27
|
+
expect(@response.meta.next_page).to eq(2)
|
|
28
|
+
expect(@response.to_a.first.data.first).to eq('author')
|
|
29
|
+
expect(@response.to_a.first.data.last.first).to have_attributes(
|
|
30
|
+
name: "Charles Dickens"
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ButterCMS::HashToObject do
|
|
4
|
+
describe '.convert' do
|
|
5
|
+
it 'converts hash to object' do
|
|
6
|
+
hash = {
|
|
7
|
+
"key1" => "value",
|
|
8
|
+
"key2" => {
|
|
9
|
+
"nested_key" => "nested value"
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
obj = ButterCMS::HashToObject.convert(hash)
|
|
14
|
+
|
|
15
|
+
expect(obj.key1).to eq 'value'
|
|
16
|
+
expect(obj.key2.nested_key).to eq "nested value"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: buttercms-ruby-zwg
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 2.4.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- ButterCMS
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2023-06-12 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rspec
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: webmock
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
description: 'Butter is the #1 developer rated headless CMS. See https://buttercms.com
|
|
42
|
+
for details.'
|
|
43
|
+
email:
|
|
44
|
+
- support@buttercms.com
|
|
45
|
+
executables: []
|
|
46
|
+
extensions: []
|
|
47
|
+
extra_rdoc_files: []
|
|
48
|
+
files:
|
|
49
|
+
- ".github/workflows/rubygems-publish.yml"
|
|
50
|
+
- ".gitignore"
|
|
51
|
+
- ".rspec"
|
|
52
|
+
- Gemfile
|
|
53
|
+
- LICENSE
|
|
54
|
+
- README.md
|
|
55
|
+
- Rakefile
|
|
56
|
+
- buttercms-ruby.gemspec
|
|
57
|
+
- lib/buttercms-ruby.rb
|
|
58
|
+
- lib/buttercms/author.rb
|
|
59
|
+
- lib/buttercms/butter_collection.rb
|
|
60
|
+
- lib/buttercms/butter_resource.rb
|
|
61
|
+
- lib/buttercms/category.rb
|
|
62
|
+
- lib/buttercms/content.rb
|
|
63
|
+
- lib/buttercms/data_store_adapters/redis.rb
|
|
64
|
+
- lib/buttercms/data_store_adapters/redis_ssl.rb
|
|
65
|
+
- lib/buttercms/data_store_adapters/yaml.rb
|
|
66
|
+
- lib/buttercms/errors.rb
|
|
67
|
+
- lib/buttercms/feed.rb
|
|
68
|
+
- lib/buttercms/hash_to_object.rb
|
|
69
|
+
- lib/buttercms/page.rb
|
|
70
|
+
- lib/buttercms/post.rb
|
|
71
|
+
- lib/buttercms/tag.rb
|
|
72
|
+
- lib/buttercms/version.rb
|
|
73
|
+
- lib/console.rb
|
|
74
|
+
- lib/core_ext/ostruct.rb
|
|
75
|
+
- spec/lib/butter-ruby_spec.rb
|
|
76
|
+
- spec/lib/buttercms/butter_collection_spec.rb
|
|
77
|
+
- spec/lib/buttercms/butter_resource_spec.rb
|
|
78
|
+
- spec/lib/buttercms/content_spec.rb
|
|
79
|
+
- spec/lib/buttercms/hash_to_object_spec.rb
|
|
80
|
+
- spec/spec_helper.rb
|
|
81
|
+
homepage: https://buttercms.com/docs
|
|
82
|
+
licenses:
|
|
83
|
+
- MIT
|
|
84
|
+
metadata: {}
|
|
85
|
+
post_install_message:
|
|
86
|
+
rdoc_options: []
|
|
87
|
+
require_paths:
|
|
88
|
+
- lib
|
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
90
|
+
requirements:
|
|
91
|
+
- - ">="
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: 1.9.3
|
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
|
+
requirements:
|
|
96
|
+
- - ">="
|
|
97
|
+
- !ruby/object:Gem::Version
|
|
98
|
+
version: '0'
|
|
99
|
+
requirements: []
|
|
100
|
+
rubygems_version: 3.1.6
|
|
101
|
+
signing_key:
|
|
102
|
+
specification_version: 4
|
|
103
|
+
summary: Ruby API client for ButterCMS
|
|
104
|
+
test_files: []
|