alchemy-custom-model 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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