rooftop-rails 0.0.2 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0ce7b53b614dba3b91d76917209fdd360b3074ee
4
- data.tar.gz: 9b3034dca31a3d7011d635b46639e519ebb90a51
3
+ metadata.gz: 44f03f4480ef66da90df9283ee01437c7e24fb1f
4
+ data.tar.gz: 5d5bcfd4bbe1fc4d4d73ca638226bd35c04da30e
5
5
  SHA512:
6
- metadata.gz: 7420b709d0dd54f2e485a87240a50e319806df71870d730d022d71529bf4a09407d1674fee1a29c2eb68b8cdea539d9e24c6451848533096f8d68d9985624f8e
7
- data.tar.gz: dc72a561f64cb5e2ab552771ca5bfe61cba476117d9a39be140090cf44fb29db9b2eac4794d5750c71f12e431e7644f33037f28769a4e09f5d22fcaa4416a8e4
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
- # For example:
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
@@ -1,4 +1,4 @@
1
- Rails.application.routes.draw do
1
+ Rooftop::Rails::Engine.routes.draw do
2
2
  resources :webhooks, only: [:create], defaults: { format: :json } do
3
3
  collection do
4
4
  scope constraints: Rooftop::Rails::DevelopmentConstraint do
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
- :perform_caching,
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
- @perform_caching = ::Rails.configuration.action_controller.perform_caching
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 = {}
@@ -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.perform_caching
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
@@ -1,5 +1,5 @@
1
1
  module Rooftop
2
2
  module Rails
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  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.2
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-09 00:00:00.000000000 Z
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.5
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.5
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/rooftop_rails/webhooks_controller.rb
79
+ - app/controllers/rooftop/rails/webhooks_controller.rb
80
80
  - app/helpers/rooftop/rails/content_helper.rb
81
- - app/helpers/rooftop/webhooks_helper.rb
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
@@ -1,5 +0,0 @@
1
- class Rooftop::Rails::WebhooksController < ::ApplicationController
2
- def create
3
- return render text: "CREATE"
4
- end
5
- end
@@ -1,2 +0,0 @@
1
- module Rooftop::Rails::WebhooksHelper
2
- end