hancock_cms_cache 1.0.2

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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +4 -0
  6. data/README.md +35 -0
  7. data/Rakefile +2 -0
  8. data/app/assets/javascripts/hancock/rails_admin/plugins/cache.coffee +4 -0
  9. data/app/assets/javascripts/hancock/rails_admin/plugins/cache/custom/ui.coffee +0 -0
  10. data/app/assets/stylesheets/hancock/rails_admin/plugins/cache.sass +3 -0
  11. data/app/assets/stylesheets/hancock/rails_admin/plugins/cache/custom/theming.sass +0 -0
  12. data/app/controllers/concerns/hancock/cache/action.rb +58 -0
  13. data/app/controllers/concerns/hancock/cache/ajax_csrf.rb +25 -0
  14. data/app/controllers/concerns/hancock/cache/fragments.rb +34 -0
  15. data/app/controllers/concerns/hancock/cache/no_cache.rb +12 -0
  16. data/app/helpers/hancock/cache/cache_helper.rb +167 -0
  17. data/app/models/concerns/hancock/cache/cacheable.rb +164 -0
  18. data/app/models/concerns/hancock/cache/cleared_stack.rb +43 -0
  19. data/app/models/concerns/hancock/cache/decorators/fragment.rb +41 -0
  20. data/app/models/concerns/hancock/cache/loadable.rb +44 -0
  21. data/app/models/concerns/hancock/cache/snapshotable.rb +49 -0
  22. data/app/models/hancock/cache/fragment.rb +11 -0
  23. data/app/views/hancock/_assets.html.slim +24 -0
  24. data/app/views/layouts/application.html.slim +33 -0
  25. data/app/views/rails_admin/main/hancock_cache_global_clear.html.slim +25 -0
  26. data/bin/console +14 -0
  27. data/bin/setup +8 -0
  28. data/config/initializers/cache_detector.rb +53 -0
  29. data/config/initializers/hancock_cache.rb +7 -0
  30. data/config/locales/hancock.cache.ru.yml +59 -0
  31. data/hancock_cms_cache.gemspec +34 -0
  32. data/lib/generators/hancock/cache/config/config_generator.rb +13 -0
  33. data/lib/generators/hancock/cache/config/templates/hancock_cache.erb +14 -0
  34. data/lib/generators/hancock/cache/models/decorators_generator.rb +24 -0
  35. data/lib/generators/hancock/cache/models/fragment_generator.rb +39 -0
  36. data/lib/generators/hancock/cache/models/templates/fragment.erb +38 -0
  37. data/lib/hancock/cache/admin.rb +37 -0
  38. data/lib/hancock/cache/admin/fragment.rb +140 -0
  39. data/lib/hancock/cache/configuration.rb +38 -0
  40. data/lib/hancock/cache/engine.rb +20 -0
  41. data/lib/hancock/cache/models/fragment.rb +310 -0
  42. data/lib/hancock/cache/models/mongoid/fragment.rb +259 -0
  43. data/lib/hancock/cache/rails_admin_ext/hancock_cache_clear.rb +95 -0
  44. data/lib/hancock/cache/rails_admin_ext/hancock_cache_dump_snapshot.rb +92 -0
  45. data/lib/hancock/cache/rails_admin_ext/hancock_cache_global_clear.rb +74 -0
  46. data/lib/hancock/cache/rails_admin_ext/hancock_cache_restore_snapshot.rb +92 -0
  47. data/lib/hancock/cache/rails_admin_ext/hancock_touch.rb +95 -0
  48. data/lib/hancock/cache/rails_admin_settings_patch.rb +185 -0
  49. data/lib/hancock/cache/version.rb +5 -0
  50. data/lib/hancock_cms_cache.rb +34 -0
  51. data/release.sh +6 -0
  52. metadata +141 -0
@@ -0,0 +1,259 @@
1
+ module Hancock::Cache
2
+ module Models::Mongoid
3
+ module Fragment
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+
8
+ include Hancock::Cache::Snapshotable
9
+
10
+ index({name: 1}, {unique: true, background: true})
11
+ index({last_clear_user_id: 1, last_clear_time: 1}, {background: true})
12
+
13
+ field :name, type: String, localize: false, default: ""
14
+ scope :by_name, -> (_name) {
15
+ if _name.is_a?(Array)
16
+ where(:name.in => _name.compact.map(&:strip))
17
+ else
18
+ if _name.is_a?(String)
19
+ where(name: (_name and _name.strip))
20
+ else
21
+ where(name: _name)
22
+ end
23
+ end
24
+ }
25
+ scope :by_name_from_view, -> (_name) {
26
+ by_name(self.name_from_view(_name))
27
+ }
28
+ scope :find_by_name, -> (_name) {
29
+ by_name(_name).first
30
+ }
31
+ scope :find_by_name_from_view, -> (_name) {
32
+ by_name_from_view(_name).first
33
+ }
34
+
35
+ field :desc, type: String, localize: Hancock::Cache.config.localize, default: ""
36
+ field :virtual_path, type: String, localize: false, default: ""
37
+ field :is_html, type: Boolean, default: true
38
+
39
+ field :is_action_cache, type: Boolean, default: false
40
+ scope :is_action_cache, -> {
41
+ where(is_action_cache: true)
42
+ }
43
+
44
+ field :on_ram, type: Boolean, default: false
45
+ scope :on_ram, -> {
46
+ where(on_ram: true)
47
+ }
48
+ attr_accessor :on_ram_data
49
+ def load_data_on_ram
50
+ if self.on_ram and !self.name.blank?
51
+ self.on_ram_data = Rails.cache.read(self.name)
52
+ end
53
+ end
54
+
55
+ field :last_clear_time, type: DateTime
56
+ if Hancock.rails4?
57
+ belongs_to :last_clear_user, class_name: Mongoid::Userstamp.config.user_model_name, autosave: false
58
+ else
59
+ belongs_to :last_clear_user, class_name: Mongoid::Userstamp.config.user_model_name, autosave: false, optional: true, required: false
60
+
61
+ if relations.has_key?("updater") and defined?(::Mongoid::History)
62
+ belongs_to :updater, class_name: ::Mongoid::History.modifier_class_name, optional: true, validate: false
63
+ _validators.delete(:updater)
64
+ _validate_callbacks.each do |callback|
65
+ if callback.raw_filter.respond_to?(:attributes) and callback.raw_filter.attributes.include?(:updater)
66
+ _validate_callbacks.delete(callback)
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ has_and_belongs_to_many :parents, class_name: "Hancock::Cache::Fragment", inverse_of: nil
73
+ field :parent_names, type: Array, default: []
74
+ def set_parent_names
75
+ self.parent_names = self.parents.distinct(:name)
76
+ end
77
+ def set_parent_names!
78
+ self.set_parent_names and self.save
79
+ end
80
+ def update_parent_names!
81
+ self.set_parent_names and self.class.where(id: self.id).update(parent_names: self.parent_names)
82
+ end
83
+ before_save do
84
+ if self.parent_ids_changed?
85
+ self.set_parent_names
86
+ end
87
+ self
88
+ end
89
+ def set_parent_ids
90
+ self.parent_ids = self.class.by_name(self.parent_names).distinct(:_id) unless self.parent_names.blank?
91
+ end
92
+ def set_parent_ids!
93
+ self.set_parent_ids and self.save
94
+ end
95
+ def update_parent_ids!
96
+ self.set_parent_ids and self.class.where(id: self.id).update(parent_ids: self.parent_ids, parent_names: self.parent_names)
97
+ end
98
+
99
+ def reset_parents
100
+ self.parent_ids = self.parents.distinct(:_id)
101
+ end
102
+ def reset_parents!
103
+ self.reset_parents and self.save
104
+ end
105
+ def self.reset_parents!
106
+ self.all.map(&:reset_parents!)
107
+ end
108
+
109
+ def name_n_desc
110
+ "#{self.name}<hr>#{self.desc}".html_safe
111
+ end
112
+ def parents_str
113
+ self.parents.map(&:name).join(", ")
114
+ end
115
+ def name_n_desc_n_parents
116
+ "#{self.name}<hr>#{self.desc}<hr>#{parents_str}".html_safe
117
+ end
118
+
119
+ def last_clear_data
120
+ "#{self.last_clear_time}<hr>#{self.last_clear_user}".html_safe
121
+ end
122
+ def snapshot_data
123
+ "#{self.last_dump_snapshot_time}<hr>#{self.last_restore_snapshot_time}<hr>#{self.get_snapshot(false)}".html_safe
124
+ end
125
+
126
+ def data(prettify = true)
127
+ _data = Rails.cache.read(self.name)
128
+ if prettify
129
+ if self.is_html
130
+ "<pre>#{CGI::escapeHTML(Nokogiri::HTML.fragment(_data).to_xhtml(indent: 2))}</pre>".html_safe
131
+ else
132
+ _data
133
+ end
134
+ else
135
+ _data
136
+ end
137
+ end
138
+
139
+ def set_last_clear_user(forced_user = nil)
140
+ unless forced_user
141
+ return false unless Mongoid::Userstamp.has_current_user?
142
+ self.last_clear_user = Mongoid::Userstamp.current_user
143
+ else
144
+ self.last_clear_user = forced_user
145
+ end
146
+ end
147
+
148
+ def self.set_for_object(key_name, obj)
149
+ if key_name.is_a?(Array)
150
+ return key_name.map do |k|
151
+ set_for_object(k, obj) unless k.blank?
152
+ end
153
+ else
154
+ _frag = self.where(name: key_name).first
155
+ _frag and _frag.set_for_object obj
156
+ end
157
+ end
158
+ def self.set_for_objects(key_name, _class)
159
+ if key_name.is_a?(Array)
160
+ return key_name.map do |k|
161
+ set_for_objects(k, _class) unless k.blank?
162
+ end
163
+ else
164
+ _frag = self.where(name: key_name).first
165
+ _frag and _frag.set_for_objects _class
166
+ end
167
+ end
168
+
169
+ # def set_for_object(obj)
170
+ # if obj.is_a?(Hash)
171
+ # if obj[:model].present?
172
+ # if obj[:ids].present?
173
+ # return obj[:ids].map do |_id|
174
+ # set_for_object({model: obj[:model], id: _id}) unless _id.blank?
175
+ # end
176
+ # else
177
+ # if obj[:id].nil?
178
+ # return set_for_objects(obj[:model])
179
+ # else
180
+ # obj = obj[:model].where(id: obj[:id]).first
181
+ # end
182
+ # end
183
+ # else
184
+ # return false
185
+ # end
186
+ #
187
+ # elsif obj.is_a?(Array)
188
+ # return obj.map do |_obj|
189
+ # set_for_object(_obj) unless _obj.blank?
190
+ # end
191
+ # end
192
+ #
193
+ # if obj
194
+ # if obj.is_a?(Class)
195
+ # set_for_objects obj
196
+ # else
197
+ # unless obj.cache_keys.include?(self.name)
198
+ # obj.set(cache_keys_str: (obj.cache_keys << self.name).uniq.join("\n"))
199
+ # obj.reload
200
+ # end
201
+ # end
202
+ # end
203
+ # end
204
+ # def set_for_objects(_class)
205
+ # _class.all.map { |obj|
206
+ # unless obj.cache_keys.include?(self.name)
207
+ # obj.set(cache_keys_str: (obj.cache_keys << self.name).uniq.join("\n"))
208
+ # obj.reload
209
+ # end
210
+ # }
211
+ # end
212
+
213
+ def self.set_for_setting(key_name, setting_obj)
214
+ if key_name.is_a?(Array)
215
+ return key_name.map do |k|
216
+ set_for_setting(k, setting_obj) unless k.blank?
217
+ end
218
+ else
219
+ _frag = self.where(name: key_name).first
220
+ _frag and _frag.set_for_setting setting_obj
221
+ end
222
+ end
223
+ # def set_for_setting(setting_obj)
224
+ # if defined?(RailsAdminModelSettings)
225
+ # if setting_obj.is_a?(Hash)
226
+ # unless setting_obj[:keys].present?
227
+ # if setting_obj[:key].nil?
228
+ # return set_for_setting({ns: setting_obj[:ns], key: //})
229
+ # else
230
+ # setting_obj = RailsAdminSettings::Setting.where(ns: setting_obj[:ns], key: setting_obj[:key]).first
231
+ # end
232
+ #
233
+ # else
234
+ # return setting_obj[:keys].map do |k|
235
+ # set_for_setting({ns: setting_obj[:ns], key: k}) unless k.blank?
236
+ # end
237
+ # end
238
+ #
239
+ # elsif setting_obj.is_a?(Array)
240
+ # return setting_obj.map do |obj|
241
+ # set_for_setting(obj) unless obj.blank?
242
+ # end
243
+ # end
244
+ #
245
+ # setting_obj and set_for_object(setting_obj) and setting_obj.reload
246
+ # end
247
+ # end
248
+
249
+ end
250
+
251
+ class_methods do
252
+ def track_history?
253
+ false
254
+ end
255
+ end
256
+
257
+ end
258
+ end
259
+ end
@@ -0,0 +1,95 @@
1
+ require 'rails_admin/config/actions'
2
+
3
+ module RailsAdmin
4
+ module Config
5
+ module Actions
6
+ class HancockCacheClear < Base
7
+ RailsAdmin::Config::Actions.register(self)
8
+
9
+ # Is the action acting on the root level (Example: /admin/contact)
10
+ register_instance_option :root? do
11
+ false
12
+ end
13
+
14
+ register_instance_option :collection? do
15
+ false
16
+ end
17
+
18
+ # Is the action on an object scope (Example: /admin/team/1/edit)
19
+ register_instance_option :member? do
20
+ true
21
+ end
22
+
23
+ register_instance_option :controller do
24
+ proc do
25
+ ajax_link = Proc.new do |fv, badge|
26
+ # can_edit_obj = can?(:edit, @object)
27
+ # render json: {
28
+ # text: fv.html_safe,
29
+ # href: hancock_cache_clear_path(model_name: @abstract_model, id: @object.id),
30
+ # class: 'label ' + badge,
31
+ # url: index_path(model_name: @abstract_model)
32
+ # }
33
+ end
34
+ if params['id'].present?
35
+ begin
36
+ @object = @abstract_model.model.unscoped.find(params['id'])
37
+ if @object.clear!
38
+ if params['ajax'].present?
39
+ ajax_link.call('♻', 'label-success')
40
+ else
41
+ flash[:success] = I18n.t('admin.hancock_cache_clear.cleared', obj: @object, name: @object.name)
42
+ # unless @object.parents.blank?
43
+ # flash[:info] = "Также, возможно необходимо сбросить кеш с этми ключами: #{@object.parents_str}"
44
+ # end
45
+ end
46
+ else
47
+ if params['ajax'].present?
48
+ render plain: @object.errors.full_messages.join(', '), layout: false, status: 422
49
+ else
50
+ flash[:error] = @object.errors.full_messages.join(', ')
51
+ end
52
+ end
53
+ rescue Exception => e
54
+ if params['ajax'].present?
55
+ render plain: I18n.t('admin.hancock_cache_clear.error', err: e.to_s), status: 422
56
+ else
57
+ flash[:error] = I18n.t('admin.hancock_cache_clear.error', err: e.to_s)
58
+ end
59
+ end
60
+ else
61
+ if params['ajax'].present?
62
+ render plain: I18n.t('admin.hancock_cache_clear.no_id'), status: 422
63
+ else
64
+ flash[:error] = I18n.t('admin.hancock_cache_clear.no_id')
65
+ end
66
+ end
67
+
68
+ unless params['ajax'].present?
69
+ begin
70
+ fallback_location = index_path(model_name: @abstract_model, id: @object.id)
71
+ rescue
72
+ fallback_location = index_path(model_name: @abstract_model)
73
+ end
74
+ redirect_back(fallback_location: fallback_location)
75
+ end
76
+
77
+ end
78
+ end
79
+
80
+ register_instance_option :link_icon do
81
+ 'icon-trash'
82
+ end
83
+
84
+ register_instance_option :pjax? do
85
+ false
86
+ end
87
+
88
+ register_instance_option :http_methods do
89
+ [:get]
90
+ end
91
+
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,92 @@
1
+ require 'rails_admin/config/actions'
2
+
3
+ module RailsAdmin
4
+ module Config
5
+ module Actions
6
+ class HancockCacheDumpSnapshot < Base
7
+ RailsAdmin::Config::Actions.register(self)
8
+
9
+ # Is the action acting on the root level (Example: /admin/contact)
10
+ register_instance_option :root? do
11
+ false
12
+ end
13
+
14
+ register_instance_option :collection? do
15
+ false
16
+ end
17
+
18
+ # Is the action on an object scope (Example: /admin/team/1/edit)
19
+ register_instance_option :member? do
20
+ true
21
+ end
22
+
23
+ register_instance_option :controller do
24
+ proc do
25
+ ajax_link = Proc.new do |fv, badge|
26
+ # can_edit_obj = can?(:edit, @object)
27
+ # render json: {
28
+ # text: fv.html_safe,
29
+ # href: hancock_cache_clear_path(model_name: @abstract_model, id: @object.id),
30
+ # class: 'label ' + badge,
31
+ # url: index_path(model_name: @abstract_model)
32
+ # }
33
+ end
34
+ if params['id'].present?
35
+ begin
36
+ @object = @abstract_model.model.unscoped.find(params['id'])
37
+ if @object.dump_snapshot!
38
+ if params['ajax'].present?
39
+ ajax_link.call('♻', 'label-success')
40
+ else
41
+ flash[:success] = I18n.t('admin.hancock_cache_dump_snapshot.dumped', obj: @object)
42
+ end
43
+ else
44
+ if params['ajax'].present?
45
+ render plain: @object.errors.full_messages.join(', '), layout: false, status: 422
46
+ else
47
+ flash[:error] = @object.errors.full_messages.join(', ')
48
+ end
49
+ end
50
+ rescue Exception => e
51
+ if params['ajax'].present?
52
+ render plain: I18n.t('admin.hancock_cache_dump_snapshot.error', err: e.to_s), status: 422
53
+ else
54
+ flash[:error] = I18n.t('admin.hancock_cache_dump_snapshot.error', err: e.to_s)
55
+ end
56
+ end
57
+ else
58
+ if params['ajax'].present?
59
+ render plain: I18n.t('admin.hancock_cache_dump_snapshot.no_id'), status: 422
60
+ else
61
+ flash[:error] = I18n.t('admin.hancock_cache_dump_snapshot.no_id')
62
+ end
63
+ end
64
+
65
+ unless params['ajax'].present?
66
+ begin
67
+ fallback_location = index_path(model_name: @abstract_model, id: @object.id)
68
+ rescue
69
+ fallback_location = index_path(model_name: @abstract_model)
70
+ end
71
+ redirect_back(fallback_location: fallback_location)
72
+ end
73
+
74
+ end
75
+ end
76
+
77
+ register_instance_option :link_icon do
78
+ 'fa fa-save'
79
+ end
80
+
81
+ register_instance_option :pjax? do
82
+ false
83
+ end
84
+
85
+ register_instance_option :http_methods do
86
+ [:get]
87
+ end
88
+
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,74 @@
1
+ require 'rails_admin/config/actions'
2
+
3
+ module RailsAdmin
4
+ module Config
5
+ module Actions
6
+ class HancockCacheGlobalClear < Base
7
+ RailsAdmin::Config::Actions.register(self)
8
+
9
+ # Is the action acting on the root level (Example: /admin/contact)
10
+ register_instance_option :root? do
11
+ false
12
+ end
13
+
14
+ register_instance_option :collection? do
15
+ true
16
+ end
17
+
18
+ # Is the action on an object scope (Example: /admin/team/1/edit)
19
+ register_instance_option :member? do
20
+ false
21
+ end
22
+
23
+ register_instance_option :route_fragment do
24
+ 'hancock_cache_global_clear'
25
+ end
26
+
27
+ register_instance_option :controller do
28
+ Proc.new do |klass|
29
+ # @config = ::HancockCacheGlobalClear::Configuration.new @abstract_model
30
+ if request.get?
31
+ render action: @action.template_name
32
+
33
+ elsif request.post?
34
+ case params[:type].to_s
35
+ when "global"
36
+ begin
37
+ Rails.cache.clear
38
+ ::Hancock::Cache::Fragment.all.to_a.map(&:clear_dry!)
39
+ flash[:success] = 'Весь кеш очищен'
40
+ rescue Exception => ex
41
+ flash[:error] = 'Ошибка'
42
+ end
43
+ when "fragments"
44
+ begin
45
+ # Hancock::Cache::Fragment.all.to_a.map do |f|
46
+ # f.clear!
47
+ # end
48
+ ::Hancock::Cache::Fragment.clear_all
49
+ flash[:success] = 'Кеш очищен'
50
+ rescue Exception => ex
51
+ flash[:error] = 'Ошибка'
52
+ end
53
+ else
54
+ flash[:error] = 'Неверно указан тип кеша для сброса'
55
+ end
56
+
57
+ redirect_to hancock_cache_global_clear_path(model_name: 'hancock~cache~fragment'.freeze)
58
+
59
+ end
60
+ end
61
+ end
62
+
63
+ register_instance_option :link_icon do
64
+ 'icon-refresh'
65
+ end
66
+
67
+ register_instance_option :http_methods do
68
+ [:get, :post]
69
+ end
70
+
71
+ end
72
+ end
73
+ end
74
+ end