alchemy-custom-model 0.1.0

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 (82) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +147 -0
  4. data/Rakefile +32 -0
  5. data/app/assets/config/alchemy_custom_model_manifest.js +3 -0
  6. data/app/assets/images/alchemy-custom-model/no_image.png +0 -0
  7. data/app/assets/javascripts/alchemy-custom-model/change_language.js +11 -0
  8. data/app/assets/javascripts/alchemy-custom-model/common_init.js +16 -0
  9. data/app/assets/javascripts/alchemy-custom-model/custom_admin_element_editor.js.coffee +25 -0
  10. data/app/assets/javascripts/alchemy-custom-model/custom_tiny_mce.js.coffee.erb +95 -0
  11. data/app/assets/javascripts/alchemy-custom-model/el_finder.js.coffee.erb +241 -0
  12. data/app/assets/javascripts/alchemy-custom-model/elfinder_ui_manifest.js +4 -0
  13. data/app/assets/javascripts/alchemy-custom-model/manifest.js +23 -0
  14. data/app/assets/javascripts/alchemy-custom-model/nested_attributes_sortable.js.coffee +25 -0
  15. data/app/assets/javascripts/alchemy-custom-model/select2filter.js +51 -0
  16. data/app/assets/javascripts/alchemy-custom-model/subobjects.js +98 -0
  17. data/app/assets/javascripts/alchemy-custom-model/total_page_elfinder.js.coffee +15 -0
  18. data/app/assets/stylesheets/alchemy-custom-model/custom_elfinder.css.scss +130 -0
  19. data/app/assets/stylesheets/alchemy-custom-model/custom_style.css.scss +228 -0
  20. data/app/assets/stylesheets/alchemy-custom-model/custom_tiny_mce.scss +6 -0
  21. data/app/assets/stylesheets/alchemy-custom-model/manifest.css +16 -0
  22. data/app/controllers/alchemy/custom/model/admin/base_controller.rb +189 -0
  23. data/app/controllers/alchemy/custom/model/admin/files_controller.rb +106 -0
  24. data/app/controllers/alchemy/pages_controller_decorator.rb +1 -0
  25. data/app/helpers/alchemy/custom/model/admin/base_helper.rb +379 -0
  26. data/app/helpers/alchemy/custom/model/base_helper.rb +18 -0
  27. data/app/helpers/alchemy/custom/model/custom_model_helper.rb +112 -0
  28. data/app/helpers/alchemy/pages_helper_decorator.rb +95 -0
  29. data/app/models/admin_override_to_param.rb +9 -0
  30. data/app/models/application_record.rb +9 -0
  31. data/app/views/alchemy/custom/model/admin/base/_buttons_tool.html.erb +16 -0
  32. data/app/views/alchemy/custom/model/admin/base/_gallery_item.html.erb +4 -0
  33. data/app/views/alchemy/custom/model/admin/base/_language_tree_select.html.erb +9 -0
  34. data/app/views/alchemy/custom/model/admin/base/_search_box.html.erb +19 -0
  35. data/app/views/alchemy/custom/model/admin/base/_seo.html.erb +8 -0
  36. data/app/views/alchemy/custom/model/admin/base/_table.html.erb +33 -0
  37. data/app/views/alchemy/custom/model/admin/base/_title.html.erb +3 -0
  38. data/app/views/alchemy/custom/model/admin/base/edit.html.erb +18 -0
  39. data/app/views/alchemy/custom/model/admin/base/index.html.erb +39 -0
  40. data/app/views/alchemy/custom/model/admin/base/new.html.erb +19 -0
  41. data/app/views/alchemy/custom/model/admin/files/error_notice.json.jbuilder +1 -0
  42. data/app/views/alchemy/custom/model/admin/files/ui.html.erb +13 -0
  43. data/config/initializers/elfinder_abilities.rb +1 -0
  44. data/config/locales/en.yml +11 -0
  45. data/config/locales/it.yml +21 -0
  46. data/config/routes.rb +8 -0
  47. data/lib/alchemy-custom-model.rb +29 -0
  48. data/lib/alchemy/custom/model/el_finder.rb +17 -0
  49. data/lib/alchemy/custom/model/el_finder/ability.rb +16 -0
  50. data/lib/alchemy/custom/model/el_finder/connector.rb +435 -0
  51. data/lib/alchemy/custom/model/el_finder/image.rb +35 -0
  52. data/lib/alchemy/custom/model/el_finder/path_name.rb +220 -0
  53. data/lib/alchemy/custom/model/el_finder/paths.rb +21 -0
  54. data/lib/alchemy/custom/model/el_finder/paths/active_record_reference.rb +50 -0
  55. data/lib/alchemy/custom/model/el_finder/paths/base.rb +298 -0
  56. data/lib/alchemy/custom/model/el_finder/paths/component_file.rb +59 -0
  57. data/lib/alchemy/custom/model/el_finder/paths/component_files.rb +34 -0
  58. data/lib/alchemy/custom/model/el_finder/paths/file.rb +23 -0
  59. data/lib/alchemy/custom/model/el_finder/paths/files.rb +25 -0
  60. data/lib/alchemy/custom/model/el_finder/paths/image.rb +42 -0
  61. data/lib/alchemy/custom/model/el_finder/paths/images.rb +31 -0
  62. data/lib/alchemy/custom/model/el_finder/paths/root.rb +24 -0
  63. data/lib/alchemy/custom/model/el_finder/volumes.rb +18 -0
  64. data/lib/alchemy/custom/model/el_finder/volumes/alchemy_file.rb +197 -0
  65. data/lib/alchemy/custom/model/el_finder/volumes/alchemy_files.rb +51 -0
  66. data/lib/alchemy/custom/model/el_finder/volumes/alchemy_images.rb +69 -0
  67. data/lib/alchemy/custom/model/el_finder/volumes/base.rb +149 -0
  68. data/lib/alchemy/custom/model/el_finder/volumes/component_attribute.rb +130 -0
  69. data/lib/alchemy/custom/model/engine.rb +40 -0
  70. data/lib/alchemy/custom/model/global_id_setter.rb +35 -0
  71. data/lib/alchemy/custom/model/model_decoration.rb +82 -0
  72. data/lib/alchemy/custom/model/pages_controller_dec.rb +132 -0
  73. data/lib/alchemy/custom/model/translation_scope.rb +18 -0
  74. data/lib/alchemy/custom/model/version.rb +7 -0
  75. data/lib/alchemy/touching_decorator.rb +12 -0
  76. data/lib/tasks/alchemy_custom_model_tasks.rake +41 -0
  77. data/vendor/elfinder/css/elfinder.full.css +5117 -0
  78. data/vendor/elfinder/css/elfinder.min.css +9 -0
  79. data/vendor/elfinder/css/theme.css +349 -0
  80. data/vendor/elfinder/js/elfinder.full.js +34270 -0
  81. data/vendor/elfinder/js/elfinder.min.js +25 -0
  82. metadata +194 -0
@@ -0,0 +1,59 @@
1
+ module Alchemy::Custom::Model::ElFinder
2
+ module Paths
3
+ class ComponentFile < ActiveRecordReference
4
+
5
+ def active_record_class
6
+ self.volume.attribute_class
7
+ end
8
+
9
+ def alchemy_record
10
+ return @_alch_record_cache if @_alch_record_cache
11
+ base = active_record_instance
12
+ self.volume.file_link_ref.split('.').each {|m| base = base.try(m)}
13
+ @_alch_record_cache = base
14
+ end
15
+
16
+ def file
17
+ case alchemy_record
18
+ when ::Alchemy::Attachment
19
+ alchemy_record.file
20
+ when ::Alchemy::Picture
21
+ alchemy_record.image_file
22
+ end
23
+ end
24
+
25
+
26
+ def file=(val)
27
+ case alchemy_record
28
+ when ::Alchemy::Attachment
29
+ alchemy_record.file = val
30
+ when ::Alchemy::Picture
31
+ alchemy_record.image_file = val
32
+ end
33
+ end
34
+
35
+ delegate :save, to: :alchemy_record
36
+
37
+ def full_fill_paylod(payload)
38
+ payload[:tmb] = self.tmb
39
+ payload
40
+ end
41
+
42
+
43
+ def tmb
44
+ case alchemy_record
45
+ when ::Alchemy::Attachment
46
+ ''
47
+ when ::Alchemy::Picture
48
+ file.thumb('100x100#').url
49
+ end
50
+
51
+ end
52
+
53
+ def is_image?
54
+ alchemy_record.is_a? ::Alchemy::Picture
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,34 @@
1
+ module Alchemy::Custom::Model::ElFinder
2
+ module Paths
3
+ class ComponentFiles < Base
4
+
5
+
6
+ def children(with_directory = true)
7
+
8
+ @volume.record.send(@volume.attribute).collect do |p|
9
+
10
+ build_file_path(p)
11
+
12
+ end
13
+
14
+ end
15
+
16
+ ##
17
+ # Costruisce il singolo file, passandogli l'active record di alchemy (Picture o Attachment)
18
+ #
19
+ # @param [Alchemy::Picture | Alchemy::Attachment] p
20
+ def build_file_path(p)
21
+
22
+ base_class = ComponentFile
23
+
24
+
25
+ file_path = base_class.new(@root, "#{self.path}/#{base_class.file_to_uri(p)}", volume: self.volume)
26
+
27
+ file_path.active_record_instance = p
28
+
29
+ file_path
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,23 @@
1
+ module Alchemy::Custom::Model::ElFinder
2
+ module Paths
3
+ class File < ActiveRecordReference
4
+
5
+ def full_fill_paylod(payload)
6
+ payload[:original_url] = ::Alchemy::Engine.routes.url_helpers.download_attachment_path(id: active_record_instance.id, name: active_record_instance.urlname)
7
+ payload
8
+ end
9
+
10
+
11
+ def active_record_class
12
+ ::Alchemy::Attachment
13
+ end
14
+
15
+
16
+ def global_id
17
+ active_record_instance.to_signed_global_id.to_s
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,25 @@
1
+ module Alchemy::Custom::Model::ElFinder
2
+ module Paths
3
+ class Files < Base
4
+
5
+ def children(with_directory = true)
6
+ ::Alchemy::Attachment.all.collect {|p|
7
+ build_file_path(p)
8
+ }
9
+ end
10
+
11
+ def build_file_path(p)
12
+ base_class = Paths::File
13
+
14
+ Rails.logger.debug {"#{@root}-#{self.path}"}
15
+ image = base_class.new(@root, "#{self.path}/#{base_class.file_to_uri(p)}")
16
+
17
+ image.active_record_instance = p
18
+
19
+ image
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,42 @@
1
+ module Alchemy::Custom::Model::ElFinder
2
+ module Paths
3
+ class Image < Paths::File
4
+
5
+ #
6
+ # url per la thumb
7
+ def tmb
8
+ active_record_instance.image_file.thumb('100x100#').url
9
+ end
10
+
11
+ def full_fill_paylod(payload)
12
+ payload[:tmb] = self.tmb
13
+ payload[:original_url] = active_record_instance.image_file.url
14
+ payload
15
+ end
16
+
17
+ def active_record_class
18
+ ::Alchemy::Picture
19
+ end
20
+
21
+ def file
22
+ active_record_instance.image_file
23
+ end
24
+
25
+ def file=(val)
26
+ active_record_instance.image_file = val
27
+ end
28
+
29
+ delegate :save, to: :active_record_instance
30
+
31
+ def is_image?
32
+ true
33
+ end
34
+
35
+
36
+ def dim
37
+ "#{active_record_instance.image_file_width}x#{active_record_instance.image_file_height}"
38
+ end
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,31 @@
1
+ module Alchemy::Custom::Model::ElFinder
2
+ module Paths
3
+ class Images < Base
4
+
5
+
6
+ def children(with_directory = true)
7
+ ::Alchemy::Picture.all.collect {|p|
8
+ build_file_path(p)
9
+ }
10
+ end
11
+
12
+ ##
13
+ # Costruisce il singolo file, passandogli l'active record di alchemy (Picture o Attachment)
14
+ #
15
+ # @param [Alchemy::Picture | Alchemy::Attachment] p
16
+ def build_file_path(p)
17
+
18
+ base_class = Paths::Image
19
+
20
+ Rails.logger.debug {"#{@root}-#{self.path}"}
21
+ image = base_class.new(@root, "#{self.path}/#{base_class.file_to_uri(p)}")
22
+
23
+ image.active_record_instance = p
24
+
25
+ image
26
+ end
27
+
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,24 @@
1
+ module Alchemy::Custom::Model::ElFinder
2
+ module Paths
3
+ class Root < Base
4
+
5
+ def is_root?
6
+ true
7
+ end
8
+
9
+ def with_sub_dirs?
10
+ true
11
+ end
12
+
13
+
14
+ def children(with_directory = true)
15
+ [
16
+ Images.new(@root, 'images', volume: @volume),
17
+ Files.new(@root, 'files', volume: @volume)
18
+ ]
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,18 @@
1
+ module Alchemy
2
+ module Custom
3
+ module Model
4
+ module ElFinder::Volumes
5
+ extend ActiveSupport::Autoload
6
+
7
+ autoload :AlchemyFile
8
+ autoload :AlchemyFiles
9
+ autoload :AlchemyImages
10
+ autoload :Base
11
+ autoload :ComponentAttribute
12
+
13
+ # eager_autoload do
14
+ # end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,197 @@
1
+ module Alchemy::Custom::Model::ElFinder
2
+ module Volumes
3
+ class AlchemyFile < Base
4
+
5
+ def initialize(options = {root: '/alchemy_library', name: 'Alchemy Library', id: 'alchemy_library', url: '/'})
6
+ super
7
+ end
8
+
9
+
10
+ def cwd(target = nil)
11
+
12
+ target = Paths::Root.new(@root) if target.nil?
13
+
14
+ Rails.logger.debug {"CWD:#{target.inspect} "}
15
+ path_info(target)
16
+
17
+ end
18
+
19
+ def decode(hash)
20
+ super do |path|
21
+ case path.to_s
22
+ when 'images'
23
+ Paths::Images.new(@root, path, volume: self)
24
+ when 'files'
25
+ Paths::Files.new(@root, path, volume: self)
26
+ when /images\/*/
27
+ Paths::Image.new(@root, path, volume: self)
28
+ when /files\/*/
29
+ Paths::File.new(@root, path, volume: self)
30
+ when @root, '.'
31
+ Paths::Root.new(@root, path, volume: self)
32
+ else
33
+ Rails.logger.debug {"PATH BASE:#{path}"}
34
+ if block_given?
35
+ Rails.logger.debug {"YIELDING:#{self.class.name}"}
36
+ yield(path)
37
+ else
38
+ Paths::Base.new(@root, path, volume: self)
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def path_info(target)
45
+ is_dir = target.directory?
46
+ mime = target.mime_type
47
+ name = @name if target.is_root?
48
+ name ||= target.name
49
+
50
+ dirs = 0
51
+ if is_dir
52
+ # check if has sub directories
53
+ dirs = 1 if target.with_sub_dirs?
54
+ end
55
+
56
+ size = 0
57
+ unless is_dir
58
+ size = target.size
59
+ end
60
+
61
+ result = {
62
+ name: name,
63
+ hash: encode(target.path.to_s),
64
+ mime: mime,
65
+ ts: target.mtime.to_i,
66
+ size: size,
67
+ dirs: dirs,
68
+ read: 1,
69
+ write: 1,
70
+ locked: 0,
71
+ class: target.class.name,
72
+ tmb: nil,
73
+ global_id: target.global_id
74
+ }
75
+
76
+ result = target.full_fill_paylod(result)
77
+
78
+ if target.is_root?
79
+ result[:volumeid] = "#{@id}_"
80
+ else
81
+ result[:phash] = encode(target.dirname.path.to_s)
82
+ end
83
+
84
+ result
85
+ end
86
+
87
+ def files(target = '.')
88
+ Rails.logger.debug {"FILES PER : #{target.inspect}"}
89
+ unless target.is_a?(Paths::Base)
90
+ if target == '.'
91
+ target = Paths::Root.new(@root, '.', volume: self)
92
+ else
93
+ Rails.logger.debug {target.inspect}
94
+ target = PathName.new(@root, target)
95
+ end
96
+ end
97
+
98
+ #Elenco tutte le cartelle
99
+ files = target.children.map {|p| path_info(p)}
100
+
101
+ #inserisco sempre anche il padre delle cartelle
102
+ files << cwd(target)
103
+ files
104
+ end
105
+
106
+ def pathname(target)
107
+ target.fisical_path
108
+ end
109
+
110
+ def upload(target, upload)
111
+ response = {}
112
+ select = []
113
+ added = []
114
+ upload.to_a.each do |file|
115
+ if file.respond_to?(:tempfile)
116
+ the_file = file.tempfile
117
+ else
118
+ the_file = file
119
+ end
120
+ if upload_max_size_in_bytes > 0 && File.size(the_file.path) > upload_max_size_in_bytes
121
+ response[:error] ||= "Some files were not uploaded"
122
+ response[:errorData][@options[:original_filename_method].call(file)] = 'File exceeds the maximum allowed filesize'
123
+ else
124
+
125
+ dst = yield(file)
126
+
127
+ select << encode(dst)
128
+ added << path_info(dst)
129
+ end
130
+ end
131
+ response[:select] = select unless select.empty?
132
+ response[:added] = added unless added.empty?
133
+
134
+
135
+ response
136
+ end
137
+
138
+
139
+ ##
140
+ # Copia un file di alchemy in questo volume
141
+ #
142
+ # @param [ElFinder::Paths::Base] src
143
+ # @return [ElFinder::Paths::Base]
144
+ def copy(src)
145
+ raise 'Non si può copiare nella cartella di alchemy'
146
+ end
147
+
148
+ ##
149
+ # Ricerca nel volume
150
+ # @param [String] type tipo di ricerca
151
+ # @param [String] q query di ricerca
152
+ def search(type:, q:)
153
+ query_search = yield
154
+ query_search.uniq.collect do |p|
155
+ path_info(root_path.build_file_path(p))
156
+ end
157
+ end
158
+
159
+ def rm(target)
160
+ raise "To Implement"
161
+ end
162
+
163
+ def upload_max_size_in_bytes
164
+ 999999999
165
+ end
166
+
167
+ def duplicable?(target)
168
+ false
169
+ end
170
+
171
+ private
172
+
173
+ ##
174
+ # Costruisce la query di ricerca
175
+ #
176
+ # @param [ActiveRecord::Base] klass
177
+ # @param [String] type tipo di ricerca
178
+ # @param [String] q query di ricerca
179
+ # @param [Symbol] mime_attribute campo da usare per la ricerca del mime
180
+ def search_query_build(klass:, type:, q:, mime_attribute:)
181
+ case type
182
+ when 'AlchemyTags'
183
+ klass.tagged_with(q)
184
+ when 'mimes'
185
+ klass.where(mime_attribute => q)
186
+ when 'full_search'
187
+ ransack_query = "#{klass.searchable_alchemy_resource_attributes.join('_or_')}_cont"
188
+ klass.ransack(ransack_query.to_sym => q).result
189
+ else
190
+ klass.none
191
+ end
192
+ end
193
+
194
+
195
+ end
196
+ end
197
+ end