rooftop-rails 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/concerns/rooftop/rails/nested_resource.rb +1 -1
- data/app/controllers/rooftop/rails/webhooks_controller.rb +38 -0
- data/app/helpers/rooftop/rails/menu_helper.rb +30 -0
- data/app/models/concerns/rooftop/rails/object_cache.rb +96 -0
- data/config/routes.rb +1 -1
- data/lib/rooftop/rails.rb +4 -2
- data/lib/rooftop/rails/engine.rb +21 -1
- data/lib/rooftop/rails/version.rb +1 -1
- metadata +7 -6
- data/app/controllers/rooftop_rails/webhooks_controller.rb +0 -5
- data/app/helpers/rooftop/webhooks_helper.rb +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44f03f4480ef66da90df9283ee01437c7e24fb1f
|
4
|
+
data.tar.gz: 5d5bcfd4bbe1fc4d4d73ca638226bd35c04da30e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45f27bfd588ba45324abae25ee6d798faaf78a74f91237009ee838d9a2275ff37fbb4f123476d09adbe3c1e8cb7a920d407da8572d27183866995b0c15e12afc
|
7
|
+
data.tar.gz: a1263337fc73348789ed7f3ea001532ca0556ba706a22326f87f46f5bd03d62ff23f6daa0e90e9df312fc416a7bd5797de9474f5a6cbe0a9376882d8fda86b61
|
@@ -13,7 +13,7 @@ module Rooftop
|
|
13
13
|
# By adding a call to `nested_rooftop_resource` in your controller class, the following happens:
|
14
14
|
# - The resource model you identify has Rooftop::Rails::NestedModel mixed into it
|
15
15
|
# - Methods for finding a model object and validating that the path is correct are added
|
16
|
-
#
|
16
|
+
# @example
|
17
17
|
# class PagesController
|
18
18
|
# include Rooftop::Rails::NestedResource
|
19
19
|
# nested_rooftop_resource :page
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Rooftop::Rails::WebhooksController < ActionController::Base
|
2
|
+
# if Rooftop::Rails.configuration.authenticate_webhooks
|
3
|
+
# http_basic_authenticate_with name: Rooftop::Rails.configuration.webhooks_username,
|
4
|
+
# password: Rooftop::Rails.configuration.webhooks_password
|
5
|
+
# end
|
6
|
+
|
7
|
+
skip_before_filter :verify_authenticity_token, :only => [:create]
|
8
|
+
|
9
|
+
#this is where we receive a webhook, via a POST
|
10
|
+
def create
|
11
|
+
# Rooftop will POST data to this endpoint, and we can decide what to do with it.
|
12
|
+
# The data included in the POST is as follows:
|
13
|
+
|
14
|
+
request.format = :json
|
15
|
+
update_type = params[:status]
|
16
|
+
|
17
|
+
# All we do here is publish an ActiveSupport::Notification, which is subscribed to
|
18
|
+
# elsewhere. In this gem are subscription options for timestamp or object caching,
|
19
|
+
# implement your own and subscribe in an initializer.
|
20
|
+
ActiveSupport::Notifications.instrument("rooftop.#{update_type}", params)
|
21
|
+
|
22
|
+
#must return an ok
|
23
|
+
render nothing: true
|
24
|
+
end
|
25
|
+
|
26
|
+
def debug
|
27
|
+
render text: "Debug method works ok"
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def webhook_params
|
33
|
+
params.permit!
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Rooftop
|
2
|
+
module Rails
|
3
|
+
module MenuHelper
|
4
|
+
|
5
|
+
# Given a Rooftop::Menus::Item, return a path for it, or nil if we can't.
|
6
|
+
def path_for_menu_item(item)
|
7
|
+
begin
|
8
|
+
# for links elsewhere, return the url as-is
|
9
|
+
if item.object_type == "custom"
|
10
|
+
return item.url
|
11
|
+
end
|
12
|
+
|
13
|
+
# otherwise we need to determine if we have a nested resource
|
14
|
+
if item.object_ancestor_slugs.present?
|
15
|
+
# we have a nested tree of slugs
|
16
|
+
resource_id = item.object_ancestor_slugs.split(",").push(item.object_slug).join("/")
|
17
|
+
else
|
18
|
+
resource_id = item.object_slug
|
19
|
+
end
|
20
|
+
|
21
|
+
return Rooftop::Rails::RouteResolver.new(item.object_type, resource_id).resolve
|
22
|
+
rescue
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Rooftop
|
2
|
+
module Rails
|
3
|
+
# This mixin adds object caching when you call find(). It overloads the find() method to cache the result, and read that instead if possible.
|
4
|
+
module ObjectCache
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
# Utility method to get the cache key for the instance.
|
10
|
+
def cache_key
|
11
|
+
"#{self.class.cache_key_base}/#{self.id}"
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
|
16
|
+
# Base of the cache key for this class.
|
17
|
+
def cache_key_base
|
18
|
+
"rooftop/#{self.to_s.underscore}"
|
19
|
+
end
|
20
|
+
|
21
|
+
# Redeclare the find() method, with caching. Only pass uncached keys to the super method.
|
22
|
+
def find(*ids)
|
23
|
+
if Rooftop::Rails.configuration.perform_object_caching
|
24
|
+
ids.uniq!
|
25
|
+
uncached_ids = ids.reject {|i| ::Rails.cache.read("#{cache_key_base}/#{i}").present?}
|
26
|
+
[super(*uncached_ids)].flatten.reject(&:blank?).collect do |object|
|
27
|
+
::Rails.logger.debug("Caching #{cache_key_base}/#{object.id}")
|
28
|
+
::Rails.cache.write(object.cache_key,object)
|
29
|
+
end
|
30
|
+
all_objects = ids.collect do |id|
|
31
|
+
::Rails.cache.read("#{cache_key_base}/#{id}")
|
32
|
+
end
|
33
|
+
|
34
|
+
all_objects.length == 1 ? all_objects.first : all_objects
|
35
|
+
else
|
36
|
+
super
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def where(args)
|
41
|
+
#Sort the arguments, and any keys which are arrays
|
42
|
+
args = Hash[args.sort.each {|k,v| v.sort! if v.is_a?(Array)}]
|
43
|
+
# Generate a hash for keying the cache of the results
|
44
|
+
args_hash = Digest::MD5.hexdigest(args.to_s)
|
45
|
+
cache_key = "#{cache_key_base}/collection_query/#{args_hash}"
|
46
|
+
# first see if we have a collection which matches the args
|
47
|
+
cached_collection = ::Rails.cache.read(cache_key)
|
48
|
+
# if it's present, then we can return it directly.
|
49
|
+
if cached_collection.present?
|
50
|
+
return cached_collection
|
51
|
+
else
|
52
|
+
# If not, then we need to call super() to get it from the API
|
53
|
+
collection = super(args)
|
54
|
+
# and write it into the cache
|
55
|
+
::Rails.cache.write(cache_key,collection)
|
56
|
+
# We also iterate over the collection and cache each object, and cache the argument hash against each object
|
57
|
+
collection.each do |object|
|
58
|
+
# This is a bit funky and circular. We store an array of hashes for queries to which this object belongs.
|
59
|
+
# If the object cache needs to be removed, we can iterate through those hashes and clear the collection caches too.
|
60
|
+
collection_query_hash_key = "#{object.cache_key}/collection_hashes"
|
61
|
+
collection_hashes = ::Rails.cache.read(collection_query_hash_key) || []
|
62
|
+
collection_hashes << args_hash
|
63
|
+
::Rails.cache.write(collection_query_hash_key, collection_hashes)
|
64
|
+
# this is the object cache - i.e. it'll respond with a cache lookup for Page.find(14) or whatever
|
65
|
+
::Rails.cache.write(object.cache_key,object)
|
66
|
+
end
|
67
|
+
collection
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# A method to expire the relevant caches for a collection of objects or ids
|
72
|
+
# @param args [Array] of either objects which respond to `.id`, or ids themselves
|
73
|
+
def expire_cache_for(*args)
|
74
|
+
args = args.collect {|a| a.respond_to?(:id) ? a.id : a}
|
75
|
+
# the caches we need to clear are:
|
76
|
+
# - the object cache
|
77
|
+
# - any collection caches which included this object
|
78
|
+
args.each do |id|
|
79
|
+
object_cache_key = "#{cache_key_base}/#{id}"
|
80
|
+
collection_keys = (::Rails.cache.read("#{object_cache_key}/collection_hashes") || []).collect do |hash|
|
81
|
+
"#{cache_key_base}/collection_query/#{hash}"
|
82
|
+
end
|
83
|
+
collection_keys << "#{object_cache_key}/collection_hashes"
|
84
|
+
[collection_keys + [object_cache_key]].flatten.each do |key|
|
85
|
+
::Rails.cache.delete(key)
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/config/routes.rb
CHANGED
data/lib/rooftop/rails.rb
CHANGED
@@ -27,7 +27,8 @@ module Rooftop
|
|
27
27
|
:preview_password,
|
28
28
|
:preview_domain,
|
29
29
|
:enable_preview_domain,
|
30
|
-
:
|
30
|
+
:perform_http_response_caching,
|
31
|
+
:perform_object_caching,
|
31
32
|
:cache_store,
|
32
33
|
:cache_logger,
|
33
34
|
:ssl_options,
|
@@ -36,7 +37,8 @@ module Rooftop
|
|
36
37
|
|
37
38
|
def initialize
|
38
39
|
@authenticate_webhooks = true
|
39
|
-
@
|
40
|
+
@perform_http_response_caching = ::Rails.configuration.action_controller.perform_caching
|
41
|
+
@perform_object_caching = ::Rails.configuration.action_controller.perform_caching
|
40
42
|
@cache_store = ::Rails.cache
|
41
43
|
@cache_logger = ::Rails.logger
|
42
44
|
@ssl_options = {}
|
data/lib/rooftop/rails/engine.rb
CHANGED
@@ -18,7 +18,7 @@ module Rooftop
|
|
18
18
|
config.advanced_options = Rooftop::Rails.configuration.advanced_options
|
19
19
|
config.api_path = Rooftop::Rails.configuration.api_path
|
20
20
|
config.url = Rooftop::Rails.configuration.url || "https://#{config.site_name}.rooftopcms.io"
|
21
|
-
config.perform_caching = Rooftop::Rails.configuration.
|
21
|
+
config.perform_caching = Rooftop::Rails.configuration.perform_http_response_caching
|
22
22
|
config.cache_store = Rooftop::Rails.configuration.cache_store
|
23
23
|
config.cache_logger = Rooftop::Rails.configuration.cache_logger
|
24
24
|
config.ssl_options = Rooftop::Rails.configuration.ssl_options
|
@@ -35,6 +35,26 @@ module Rooftop
|
|
35
35
|
initializer "add_helpers" do
|
36
36
|
ActiveSupport.on_load(:action_view) do
|
37
37
|
include Rooftop::Rails::ContentHelper
|
38
|
+
include Rooftop::Rails::MenuHelper
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
initializer "add_caching_to_rooftop_models" do
|
43
|
+
::Rails.application.eager_load!
|
44
|
+
Rooftop::Base.included_classes.each do |klass|
|
45
|
+
klass.send(:include, Rooftop::Rails::ObjectCache)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
initializer "clear_caches_on_webhook_notification" do
|
50
|
+
ActiveSupport::Notifications.subscribe(/rooftop.*/) do |name, start, finish, id, payload|
|
51
|
+
content_type = payload[:type]
|
52
|
+
if Rooftop.configuration.post_type_mapping[content_type].present?
|
53
|
+
klass = Rooftop.configuration.post_type_mapping[content_type]
|
54
|
+
else
|
55
|
+
klass = content_type.classify.constantize
|
56
|
+
end
|
57
|
+
klass.send(:expire_cache_for, payload[:id])
|
38
58
|
end
|
39
59
|
end
|
40
60
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rooftop-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Error Studio
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: require_all
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.0.
|
61
|
+
version: 0.0.6
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.0.
|
68
|
+
version: 0.0.6
|
69
69
|
description: This gem provides utility methods and a mountable engine for Rails applications
|
70
70
|
using the Rooftop gem
|
71
71
|
email:
|
@@ -76,10 +76,11 @@ extra_rdoc_files: []
|
|
76
76
|
files:
|
77
77
|
- Rakefile
|
78
78
|
- app/controllers/concerns/rooftop/rails/nested_resource.rb
|
79
|
-
- app/controllers/
|
79
|
+
- app/controllers/rooftop/rails/webhooks_controller.rb
|
80
80
|
- app/helpers/rooftop/rails/content_helper.rb
|
81
|
-
- app/helpers/rooftop/
|
81
|
+
- app/helpers/rooftop/rails/menu_helper.rb
|
82
82
|
- app/models/concerns/rooftop/rails/nested_model.rb
|
83
|
+
- app/models/concerns/rooftop/rails/object_cache.rb
|
83
84
|
- config/routes.rb
|
84
85
|
- lib/rooftop/rails.rb
|
85
86
|
- lib/rooftop/rails/development_constraint.rb
|