contentful-moderator 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0fb6754225e95bf027cc7b5c352ef5bd7ad17505
4
+ data.tar.gz: a601c93b818a0c56aa27915cc4f8f7aaa2a1efea
5
+ SHA512:
6
+ metadata.gz: 20b95c9d6b0e900fce6ab5ee7da442082bcfee9413e63d8189dfaf343bfacd246f73fbda19d91e2ef70c714b2448a8d29e99ab7817d7a6405f3355cdca98fd47
7
+ data.tar.gz: 206d4a56d620dd250acf801707df1e76a0c3f1bc1530ac7e6a4958c458a866bbb694c7876ea344d59c077e69705531c05adff21cfe2a9d5f19e46cd436df007e
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.3
4
+ before_install: gem install bundler -v 1.11.2
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at david.litvakb@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in contentful-moderator.gemspec
4
+ gemspec
@@ -0,0 +1,14 @@
1
+ guard :rspec, cmd: "bundle exec rspec" do
2
+ require "guard/rspec/dsl"
3
+ dsl = Guard::RSpec::Dsl.new(self)
4
+
5
+ # RSpec files
6
+ rspec = dsl.rspec
7
+ watch(rspec.spec_helper) { rspec.spec_dir }
8
+ watch(rspec.spec_support) { rspec.spec_dir }
9
+ watch(rspec.spec_files)
10
+
11
+ # Ruby files
12
+ ruby = dsl.ruby
13
+ dsl.watch_spec_files_for(ruby.lib_files)
14
+ end
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 David Litvak Bruno
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,153 @@
1
+ # Contentful Moderator
2
+
3
+ Moderator Server listens for incoming webhooks from Contentful to manage moderation workflows of entries.
4
+
5
+ ## Contentful
6
+ [Contentful](http://www.contentful.com) is a content management platform for web applications,
7
+ mobile apps and connected devices. It allows you to create, edit & manage content in the cloud
8
+ and publish it anywhere via powerful API. Contentful offers tools for managing editorial
9
+ teams and enabling cooperation between organizations.
10
+
11
+ ## What does `contentful-moderator` do?
12
+ The aim of `contentful-moderator` is to have developers setting up their Contentful
13
+ entries for moderated authoring workflows.
14
+
15
+ ### What is a moderated authoring workflow?
16
+
17
+ We'll explain this with a step-by-step example:
18
+
19
+ 1. Author creates an entry
20
+ 2. Author edits an entry
21
+ 3. Author submits for Review
22
+ 4. System triggers Moderation Webhook
23
+ 5. `contentful-moderator` sends email to Reviewer Team
24
+ 6. Reviewer checks entry
25
+ 1. Reviewer approves entry and publishes - *Workflow ends*
26
+ 2. Reviewer considers edits are required and submits for further editing
27
+ 7. System triggers Moderation Webhook
28
+ 8. `contentful-moderator` sends email to Authoring Team
29
+ 9. Go back to 2
30
+
31
+ ## How does it work
32
+ `contentful-moderator` provides a web endpoint to receive webhook calls from Contentful.
33
+
34
+ Every time the endpoint recieves a call it looks for the value of the fields defined in the configuration.
35
+
36
+ If any of the values match the configuration, it will send an email to the specified queue (authors or editors).
37
+
38
+ You can add multiple content types to your configuration.
39
+
40
+ ## Requirements
41
+
42
+ * An SMTP Server (like `postfix` or a GMail/Yahoo/MSN account with SMTP support)
43
+
44
+ ## Installation
45
+
46
+ Add this line to your application's Gemfile:
47
+
48
+ ```ruby
49
+ gem 'contentful-moderator'
50
+ ```
51
+
52
+ And then execute:
53
+
54
+ $ bundle
55
+
56
+ Or install it yourself as:
57
+
58
+ $ gem install contentful-moderator
59
+
60
+ ## Usage
61
+
62
+ * Create your configuration file:
63
+
64
+ You can base your configuration file from [the example `config.yml`](./example/config.yml)
65
+
66
+ ```yml
67
+ ---
68
+
69
+ endpoint: '/moderator' # Optional - defaults to '/moderator'
70
+ port: 33123 # Optional - defaults to ENV['PORT'] or 33123
71
+ content_types:
72
+ post: # ID of your Content Type (multiple Content Types can be set here)
73
+ author_field: # Required
74
+ field_id: 'author_field'
75
+ notify_reviewer_on: 'Ready for review' # Value to match - this is Exact match
76
+ email_subject: 'A submission requires review'
77
+ email_body: > # 'webhook_url' will get replaced with the Entry URL in the Contentful Web App
78
+ Dear Editor Team,
79
+
80
+
81
+ The entry 'webhook_url' is ready for review.
82
+
83
+
84
+ Cordially,
85
+
86
+
87
+ Moderator Bot
88
+ reviewer_field: # Required
89
+ field_id: 'reviewer_field'
90
+ notify_author_on: 'Needs further editing'
91
+ email_subject: 'A submission requires further editing'
92
+ email_body: >
93
+ Dear Authoring Team,
94
+
95
+
96
+ The entry 'webhook_url' requires further editing.
97
+
98
+
99
+ Cordially,
100
+
101
+
102
+ Moderator Bot
103
+ authors: # Required - List of Author Emails
104
+ - 'author@example.com'
105
+ editors: # Required - List of Editor Emails
106
+ - 'editor@example.com'
107
+ mail_origin: 'admin@example.com' # Required - Email from which the messages will be sent (on GMail this does not take effect)
108
+ mailer_settings: # Required
109
+ connection_type: 'smtp'
110
+ address: 'smtp.gmail.com'
111
+ port: 587
112
+ domain: 'example.com'
113
+ user_name: "'env_mailer_username'" # Username can be Plain-Text. But 'env_mailer_username' will get replaced with ENV['ENV_MAILER_USERNAME']
114
+ password: "'env_mailer_password'" # Same as for user_name. 'env_mailer_password' will get replaced with ENV['ENV_MAILER_PASSWORD']
115
+ authentication: 'plain'
116
+ enable_starttls_auto: true
117
+ ```
118
+
119
+ * Run the server:
120
+
121
+ ```bash
122
+ $ contentful_moderator config.yml
123
+ ```
124
+
125
+ * Configure the webhook in Contentful:
126
+
127
+ Under the space settings menu choose webhook and add a new webhook pointing to `http://YOUR_SERVER:33123/moderator`.
128
+
129
+ Keep in mind that if you modify the defaults, the URL should be changed to the values specified in the configuration.
130
+
131
+ ## Running in Heroku
132
+
133
+ * Create a `Procfile` containing:
134
+
135
+ ```
136
+ web: PORT=$PORT env bundle exec contentful_moderator config.yml
137
+ ```
138
+
139
+ That will allow Heroku to set it's own Port according to their policy.
140
+
141
+ Make sure to set your Username/Password environment variables (if you're using them).
142
+
143
+ Then proceed to `git push heroku master`.
144
+
145
+ The URL for the webhook then will be on port 80, so you should change it to: `http://YOUR_APPLICATION/moderator`.
146
+
147
+ ## Contributing
148
+
149
+ Bug reports and pull requests are welcome on GitHub at https://github.com/contentful/contentful-moderator.rb. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
150
+
151
+ ## License
152
+
153
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'contentful/moderator/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "contentful-moderator"
8
+ spec.version = Contentful::Moderator::VERSION
9
+ spec.authors = ["Contentful GmbH (David Litvak Bruno)"]
10
+ spec.email = ["david.litvak@contentful.com"]
11
+
12
+ spec.summary = %q{Contentful Moderation Workflow Gem}
13
+ spec.description = %q{Contentful Moderation Workflow Gem}
14
+ spec.homepage = "https://www.contentful.com"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_runtime_dependency 'contentful-webhook-listener', '~> 0.2'
23
+ spec.add_runtime_dependency 'mail', '~> 2.6'
24
+ spec.add_runtime_dependency 'hashie', '~> 3.4'
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.11"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rspec", "~> 3.0"
29
+ spec.add_development_dependency "guard"
30
+ spec.add_development_dependency "guard-rspec"
31
+ spec.add_development_dependency "pry"
32
+ end
@@ -0,0 +1,44 @@
1
+ ---
2
+
3
+ endpoint: '/moderator'
4
+ port: 33123
5
+ content_types:
6
+ post:
7
+ author_field:
8
+ field_id: 'author_field'
9
+ notify_reviewer_on: 'Ready for review'
10
+ email_subject: 'A submission requires review'
11
+ email_body: >
12
+ Dear Editor Team,
13
+
14
+ The entry 'webhook_url' is ready for review.
15
+
16
+ Cordially,
17
+
18
+ Moderator Bot
19
+ reviewer_field:
20
+ field_id: 'reviewer_field'
21
+ notify_author_on: 'Needs further editing'
22
+ email_subject: 'A submission requires further editing'
23
+ email_body: >
24
+ Dear Authoring Team,
25
+
26
+ The entry 'webhook_url' requires further editing.
27
+
28
+ Cordially,
29
+
30
+ Moderator Bot
31
+ authors:
32
+ - 'author@example.com'
33
+ editors:
34
+ - 'editor@example.com'
35
+ mail_origin: 'admin@example.com'
36
+ mailer_settings:
37
+ connection_type: 'smtp'
38
+ address: 'smtp.gmail.com'
39
+ port: 587
40
+ domain: 'example.com'
41
+ user_name: "'env_mailer_username'"
42
+ password: "'env_mailer_password'"
43
+ authentication: 'plain'
44
+ enable_starttls_auto: true
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'contentful/moderator'
4
+
5
+ STDOUT.sync = true
6
+
7
+ trap('TERM') do
8
+ puts "Graceful shutdown"
9
+ exit
10
+ end
11
+
12
+
13
+ def usage
14
+ puts "Usage: contentful_moderator <configuration_file>"
15
+ end
16
+
17
+ if ARGV.empty?
18
+ usage
19
+ exit(1)
20
+ end
21
+
22
+ if ['-h', '-H', '--help'].include?(ARGV.first)
23
+ usage
24
+ exit(0)
25
+ end
26
+
27
+ if File.file?(ARGV.first)
28
+ Contentful::Moderator.start(
29
+ Contentful::Moderator::Config.load(ARGV.first)
30
+ )
31
+ else
32
+ puts "File provided not found!\n"
33
+ usage
34
+ exit(1)
35
+ end
@@ -0,0 +1,42 @@
1
+ require 'logger'
2
+ require 'hashie'
3
+ require 'contentful/webhook/listener'
4
+ require 'contentful/moderator/version'
5
+ require 'contentful/moderator/config'
6
+ require 'contentful/moderator/controller'
7
+
8
+ module Contentful
9
+ module Moderator
10
+ @@config = nil
11
+
12
+ def self.config=(config)
13
+ @@config ||= (config.is_a? ::Contentful::Moderator::Config) ? config : ::Contentful::Moderator::Config.new(config)
14
+ end
15
+
16
+ def self.config
17
+ @@config
18
+ end
19
+
20
+ def self.start(config = {})
21
+ fail "Moderator not configured" if config.nil? && !block_given?
22
+
23
+ if block_given?
24
+ yield(config) if block_given?
25
+ end
26
+ self.config = config
27
+
28
+ logger = Logger.new(STDOUT)
29
+ ::Contentful::Webhook::Listener::Server.start do |server_config|
30
+ server_config[:port] = config.port
31
+ server_config[:logger] = logger
32
+ server_config[:endpoints] = [
33
+ {
34
+ endpoint: config.endpoint,
35
+ controller: ::Contentful::Moderator::Controller,
36
+ timeout: 0
37
+ }
38
+ ]
39
+ end.join
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,108 @@
1
+ require 'hashie'
2
+ require 'yaml'
3
+
4
+ module Contentful
5
+ module Moderator
6
+ class Config
7
+ DEFAULT_PORT = 33123
8
+ DEFAULT_ENDPOINT = '/moderator'
9
+
10
+ attr_reader :config
11
+
12
+ def self.load(path)
13
+ new(Hashie::Mash.load(path))
14
+ end
15
+
16
+ def initialize(config = {})
17
+ @config = Hashie::Mash.new(config)
18
+
19
+ @config.port = (ENV.key?('PORT') ? ENV['PORT'].to_i : DEFAULT_PORT) unless @config.port?
20
+ @config.endpoint = DEFAULT_ENDPOINT unless @config.endpoint?
21
+
22
+ fail ':content_types not set' unless @config.content_types? && !@config.content_types.empty?
23
+ fail ':authors not set' unless @config.authors? && !@config.authors.empty?
24
+ fail ':editors not set' unless @config.editors? && !@config.editors.empty?
25
+ fail ':mail_origin not set' unless @config.mail_origin?
26
+ fail ':mailer_settings not properly configured' unless mailer_configured?
27
+
28
+ configure_mailer
29
+ end
30
+
31
+ def port
32
+ @config.port
33
+ end
34
+
35
+ def endpoint
36
+ @config.endpoint
37
+ end
38
+
39
+ def authors
40
+ @config.authors
41
+ end
42
+
43
+ def editors
44
+ @config.editors
45
+ end
46
+
47
+ def content_types
48
+ @config.content_types
49
+ end
50
+
51
+ def mail_origin
52
+ @config.mail_origin
53
+ end
54
+
55
+ def mailer_settings
56
+ @config.mailer_settings
57
+ end
58
+
59
+ def mailer_username
60
+ return ENV['ENV_MAILER_USERNAME'] if config.mailer_settings.user_name == "'env_mailer_username'"
61
+ config.mailer_settings.user_name
62
+ end
63
+
64
+ def mailer_password
65
+ return ENV['ENV_MAILER_PASSWORD'] if config.mailer_settings.password == "'env_mailer_password'"
66
+ config.mailer_settings.password
67
+ end
68
+
69
+ def mailer_configured?
70
+ return false unless @config.mailer_settings?
71
+ return false unless @config.mailer_settings.connection_type
72
+ return false unless @config.mailer_settings.address
73
+ return false unless @config.mailer_settings.port
74
+ return false unless @config.mailer_settings.domain
75
+
76
+ # Optionals - Explicitly left here as reminder
77
+ #
78
+ # return false unless @config.mailer_settings.user_name
79
+ # return false unless @config.mailer_settings.password
80
+ # return false unless @config.mailer_settings.authentication
81
+ # return false unless @config.mailer_settings.enable_starttls_auto
82
+ # return false unless @config.mailer_settings.openssl_verify_mode
83
+ # return false unless @config.mailer_settings.ssl
84
+ # return false unless @config.mailer_settings.tls
85
+
86
+ true
87
+ end
88
+
89
+ def configure_mailer
90
+ this = self
91
+ Mail.defaults do
92
+ delivery_method this.config.mailer_settings.connection_type.to_sym, {
93
+ address: this.config.mailer_settings.address,
94
+ port: this.config.mailer_settings.port,
95
+ domain: this.config.mailer_settings.domain,
96
+ user_name: this.mailer_username,
97
+ password: this.mailer_password,
98
+ authentication: this.config.mailer_settings.authentication,
99
+ enable_starttls_auto: this.config.mailer_settings.enable_starttls_auto,
100
+ openssl_verify_mode: this.config.mailer_settings.openssl_verify_mode,
101
+ ssl: this.config.mailer_settings.ssl,
102
+ tls: this.config.mailer_settings.tls
103
+ }
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,101 @@
1
+ require 'mail'
2
+ require 'contentful/webhook/listener/controllers/webhook_aware'
3
+
4
+ module Contentful
5
+ module Moderator
6
+ class Controller < ::Contentful::Webhook::Listener::Controllers::WebhookAware
7
+ def auto_save
8
+ return unless webhook.entry?
9
+ return unless notificable?(webhook)
10
+ logger.debug("Workflow Webhook Received for '#{webhook.space_id}/#{webhook.id}': Checking for Notifications")
11
+
12
+ emails = []
13
+ emails << notify_authors(webhook) if notify_author?(webhook)
14
+ emails << notify_reviewers(webhook) if notify_reviewer?(webhook)
15
+
16
+ send_emails(emails)
17
+
18
+ logger.debug("\tDone!")
19
+ end
20
+ alias_method :save, :auto_save
21
+
22
+ def config
23
+ ::Contentful::Moderator.config
24
+ end
25
+
26
+ def send_emails(emails)
27
+ emails.each do |email|
28
+ email.deliver!
29
+ end
30
+ end
31
+
32
+ def notify_authors(webhook)
33
+ logger.debug("\tCreating Author Notification Email")
34
+ this = self
35
+ ::Mail.new do
36
+ from this.config.mail_origin
37
+ to this.config.authors
38
+ subject this.reviewer_field(webhook).email_subject
39
+ body this.email_body(:reviewer, webhook)
40
+ end
41
+ end
42
+
43
+ def notify_reviewers(webhook)
44
+ logger.debug("\tCreating Reviewer Notification Email")
45
+ this = self
46
+ ::Mail.new do
47
+ from this.config.mail_origin
48
+ to this.config.editors
49
+ subject this.author_field(webhook).email_subject
50
+ body this.email_body(:author, webhook)
51
+ end
52
+ end
53
+
54
+ def email_body(type, webhook)
55
+ self.send("#{type}_field", webhook).email_body.gsub("'webhook_url'", webhook_url(webhook))
56
+ end
57
+
58
+ def webhook_content_type(webhook)
59
+ webhook.sys['contentType']['sys']['id']
60
+ end
61
+
62
+ def content_type(webhook)
63
+ config.content_types[webhook_content_type(webhook)]
64
+ end
65
+
66
+ def notificable?(webhook)
67
+ config.content_types.keys.include?(webhook_content_type(webhook))
68
+ end
69
+
70
+ def notify_author?(webhook)
71
+ field = webhook.fields[reviewer_field(webhook).field_id]
72
+ if field.is_a? Hash
73
+ return field[field.keys.first] == reviewer_field(webhook).notify_author_on
74
+ else
75
+ return field == reviewer_field(webhook).notify_author_on
76
+ end
77
+ end
78
+
79
+ def notify_reviewer?(webhook)
80
+ field = webhook.fields[author_field(webhook).field_id]
81
+ if field.is_a? Hash
82
+ return field[field.keys.first] == author_field(webhook).notify_reviewer_on
83
+ else
84
+ return field == author_field(webhook).notify_reviewer_on
85
+ end
86
+ end
87
+
88
+ def author_field(webhook)
89
+ content_type(webhook).author_field
90
+ end
91
+
92
+ def reviewer_field(webhook)
93
+ content_type(webhook).reviewer_field
94
+ end
95
+
96
+ def webhook_url(webhook)
97
+ "https://app.contentful.com/spaces/#{webhook.space_id}/entries/#{webhook.id}"
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,5 @@
1
+ module Contentful
2
+ module Moderator
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,187 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: contentful-moderator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Contentful GmbH (David Litvak Bruno)
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-05-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: contentful-webhook-listener
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mail
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.6'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: hashie
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.4'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: guard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: guard-rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: Contentful Moderation Workflow Gem
140
+ email:
141
+ - david.litvak@contentful.com
142
+ executables:
143
+ - contentful_moderator
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - ".gitignore"
148
+ - ".rspec"
149
+ - ".travis.yml"
150
+ - CODE_OF_CONDUCT.md
151
+ - Gemfile
152
+ - Guardfile
153
+ - LICENSE.txt
154
+ - README.md
155
+ - Rakefile
156
+ - contentful-moderator.gemspec
157
+ - example/config.yml
158
+ - exe/contentful_moderator
159
+ - lib/contentful/moderator.rb
160
+ - lib/contentful/moderator/config.rb
161
+ - lib/contentful/moderator/controller.rb
162
+ - lib/contentful/moderator/version.rb
163
+ homepage: https://www.contentful.com
164
+ licenses:
165
+ - MIT
166
+ metadata: {}
167
+ post_install_message:
168
+ rdoc_options: []
169
+ require_paths:
170
+ - lib
171
+ required_ruby_version: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ required_rubygems_version: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ requirements: []
182
+ rubyforge_project:
183
+ rubygems_version: 2.5.0
184
+ signing_key:
185
+ specification_version: 4
186
+ summary: Contentful Moderation Workflow Gem
187
+ test_files: []