spontaneous 0.2.0.alpha7 → 0.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +10 -4
- data/Readme.markdown +1 -1
- data/application/css/definitions.css.scss +5 -0
- data/application/css/dialogue.css.scss +62 -0
- data/application/js/content.js +1 -1
- data/application/js/dom.js +1 -1
- data/application/js/event_source.js +3 -0
- data/application/js/{field_types/date_field.js → field/date.js} +2 -2
- data/application/js/{field_types/file_field.js → field/file.js} +2 -2
- data/application/js/{field_types/image_field.js → field/image.js} +54 -20
- data/application/js/{field_types/long_string_field.js → field/long_string.js} +2 -2
- data/application/js/{field_types/markdown_field.js → field/markdown.js} +2 -2
- data/application/js/{field_types/select_field.js → field/select.js} +2 -2
- data/application/js/{field_types/string_field.js → field/string.js} +21 -7
- data/application/js/{field_types/webvideo_field.js → field/webvideo.js} +2 -2
- data/application/js/field.js +2 -2
- data/application/js/publish.js +99 -19
- data/application/js/spontaneous.js +8 -8
- data/application/js/top_bar.js +6 -4
- data/db/migrations/20130109125023_add_page_publish_lock.rb +17 -0
- data/db/migrations/20130111161934_convert_bcrypt_passwords.rb +22 -0
- data/db/migrations/20130114120000_create_revision_tables.rb +106 -0
- data/db/migrations/20130116220423_add_index_to_archive.rb +9 -0
- data/lib/spontaneous/box.rb +53 -18
- data/lib/spontaneous/box_style.rb +2 -3
- data/lib/spontaneous/change.rb +39 -13
- data/lib/spontaneous/cli/fields.rb +29 -0
- data/lib/spontaneous/cli/init.rb +2 -2
- data/lib/spontaneous/cli/migrate.rb +0 -1
- data/lib/spontaneous/cli/server.rb +14 -10
- data/lib/spontaneous/cli/site.rb +20 -9
- data/lib/spontaneous/cli.rb +8 -6
- data/lib/spontaneous/collections/box_set.rb +11 -0
- data/lib/spontaneous/collections/field_set.rb +24 -1
- data/lib/spontaneous/concern.rb +37 -0
- data/lib/spontaneous/config.rb +3 -4
- data/lib/spontaneous/crypt/version.rb +130 -0
- data/lib/spontaneous/crypt.rb +84 -0
- data/lib/spontaneous/data_mapper/content_model/associations.rb +199 -0
- data/lib/spontaneous/data_mapper/content_model/column_accessors.rb +52 -0
- data/lib/spontaneous/data_mapper/content_model/instance_hooks.rb +34 -0
- data/lib/spontaneous/data_mapper/content_model/serialization.rb +54 -0
- data/lib/spontaneous/data_mapper/content_model/timestamps.rb +39 -0
- data/lib/spontaneous/data_mapper/content_model.rb +343 -0
- data/lib/spontaneous/data_mapper/content_table.rb +103 -0
- data/lib/spontaneous/data_mapper/dataset.rb +194 -0
- data/lib/spontaneous/data_mapper/scope.rb +195 -0
- data/lib/spontaneous/data_mapper.rb +161 -0
- data/lib/spontaneous/facet.rb +2 -2
- data/lib/spontaneous/field/base.rb +418 -0
- data/lib/spontaneous/field/date.rb +54 -0
- data/lib/spontaneous/{field_version.rb → field/field_version.rb} +1 -1
- data/lib/spontaneous/field/file.rb +100 -0
- data/lib/spontaneous/{field_types/image_field.rb → field/image.rb} +33 -33
- data/lib/spontaneous/{field_types/location_field.rb → field/location.rb} +2 -2
- data/lib/spontaneous/{field_types/long_string_field.rb → field/long_string.rb} +3 -3
- data/lib/spontaneous/field/markdown.rb +36 -0
- data/lib/spontaneous/{field_types/select_field.rb → field/select.rb} +4 -5
- data/lib/spontaneous/field/string.rb +17 -0
- data/lib/spontaneous/field/update.rb +156 -0
- data/lib/spontaneous/field/webvideo.rb +310 -0
- data/lib/spontaneous/field.rb +80 -0
- data/lib/spontaneous/generators/site/Gemfile.tt +2 -2
- data/lib/spontaneous/generators/site/config/environments/development.rb.tt +1 -1
- data/lib/spontaneous/generators/site/config/environments/production.rb.tt +1 -1
- data/lib/spontaneous/generators/site/lib/content.rb.tt +6 -0
- data/lib/spontaneous/generators/site/schema/box.rb.tt +3 -2
- data/lib/spontaneous/generators/site/schema/page.rb.tt +3 -1
- data/lib/spontaneous/generators/site/schema/piece.rb.tt +3 -1
- data/lib/spontaneous/generators/site/templates/layouts/standard.html.cut.tt +3 -1
- data/lib/spontaneous/generators/site.rb +4 -3
- data/lib/spontaneous/image_size.rb +8 -1
- data/lib/spontaneous/layout.rb +5 -1
- data/lib/spontaneous/loader.rb +2 -5
- data/lib/spontaneous/media/file.rb +11 -2
- data/lib/spontaneous/media/temp_file.rb +23 -0
- data/lib/spontaneous/media.rb +20 -39
- data/lib/spontaneous/{plugins → model/box}/allowed_types.rb +38 -17
- data/lib/spontaneous/model/box.rb +18 -0
- data/lib/spontaneous/{plugins → model/core}/aliases.rb +10 -14
- data/lib/spontaneous/{plugins → model/core}/boxes.rb +2 -2
- data/lib/spontaneous/{plugins → model/core}/content_groups.rb +2 -2
- data/lib/spontaneous/model/core/editor_class.rb +4 -0
- data/lib/spontaneous/{plugins → model/core}/entries.rb +19 -7
- data/lib/spontaneous/{plugins → model/core}/entry.rb +3 -3
- data/lib/spontaneous/{plugins → model/core}/fields.rb +38 -5
- data/lib/spontaneous/{plugins → model/core}/instance_code.rb +2 -2
- data/lib/spontaneous/{plugins → model/core}/media.rb +2 -12
- data/lib/spontaneous/{plugins → model/core}/modifications.rb +7 -6
- data/lib/spontaneous/model/core/page_search.rb +36 -0
- data/lib/spontaneous/{plugins → model/core}/permissions.rb +4 -4
- data/lib/spontaneous/{plugins → model/core}/prototypes.rb +4 -4
- data/lib/spontaneous/{plugins → model/core}/publishing.rb +93 -115
- data/lib/spontaneous/{plugins → model/core}/render.rb +2 -2
- data/lib/spontaneous/{plugins → model/core}/schema_hierarchy.rb +7 -11
- data/lib/spontaneous/model/core/schema_id.rb +65 -0
- data/lib/spontaneous/{plugins → model/core}/schema_title.rb +2 -2
- data/lib/spontaneous/{plugins → model/core}/serialisation.rb +2 -2
- data/lib/spontaneous/{plugins → model/core}/styles.rb +2 -2
- data/lib/spontaneous/{plugins → model/core}/supertype.rb +2 -2
- data/lib/spontaneous/{plugins → model/core}/visibility.rb +7 -48
- data/lib/spontaneous/model/core.rb +143 -0
- data/lib/spontaneous/{plugins → model/page}/controllers.rb +3 -3
- data/lib/spontaneous/{plugins → model}/page/formats.rb +2 -2
- data/lib/spontaneous/{plugins → model/page}/layouts.rb +2 -2
- data/lib/spontaneous/model/page/locks.rb +14 -0
- data/lib/spontaneous/{plugins → model/page}/page_tree.rb +3 -3
- data/lib/spontaneous/{plugins → model/page}/paths.rb +30 -12
- data/lib/spontaneous/{plugins → model}/page/request.rb +2 -2
- data/lib/spontaneous/{plugins → model/page}/site_map.rb +2 -2
- data/lib/spontaneous/model/page/site_timestamps.rb +44 -0
- data/lib/spontaneous/{page.rb → model/page.rb} +49 -28
- data/lib/spontaneous/{piece.rb → model/piece.rb} +7 -6
- data/lib/spontaneous/model.rb +97 -0
- data/lib/spontaneous/output/context.rb +1 -1
- data/lib/spontaneous/output/format.rb +4 -0
- data/lib/spontaneous/output/template/renderer.rb +2 -2
- data/lib/spontaneous/output.rb +2 -2
- data/lib/spontaneous/page_lock.rb +62 -0
- data/lib/spontaneous/page_piece.rb +1 -1
- data/lib/spontaneous/permissions/access_key.rb +9 -4
- data/lib/spontaneous/permissions/user.rb +19 -9
- data/lib/spontaneous/permissions.rb +2 -5
- data/lib/spontaneous/plugins/application/facets.rb +1 -2
- data/lib/spontaneous/plugins/application/features.rb +1 -1
- data/lib/spontaneous/plugins/application/paths.rb +1 -1
- data/lib/spontaneous/plugins/application/render.rb +1 -1
- data/lib/spontaneous/plugins/application/serialisation.rb +1 -1
- data/lib/spontaneous/plugins/application/state.rb +30 -1
- data/lib/spontaneous/plugins/application/system.rb +12 -12
- data/lib/spontaneous/prototypes/box_prototype.rb +1 -1
- data/lib/spontaneous/prototypes/field_prototype.rb +3 -6
- data/lib/spontaneous/prototypes/style_prototype.rb +1 -1
- data/lib/spontaneous/publishing/immediate.rb +77 -49
- data/lib/spontaneous/publishing/revision.rb +355 -0
- data/lib/spontaneous/publishing/simultaneous.rb +10 -49
- data/lib/spontaneous/publishing.rb +1 -0
- data/lib/spontaneous/rack/around_back.rb +1 -1
- data/lib/spontaneous/rack/around_front.rb +2 -4
- data/lib/spontaneous/rack/around_preview.rb +1 -1
- data/lib/spontaneous/rack/back.rb +80 -63
- data/lib/spontaneous/rack/cacheable_file.rb +2 -2
- data/lib/spontaneous/rack/cookie_authentication.rb +1 -1
- data/lib/spontaneous/rack/front.rb +1 -1
- data/lib/spontaneous/rack/helpers.rb +8 -9
- data/lib/spontaneous/{page_controller.rb → rack/page_controller.rb} +1 -1
- data/lib/spontaneous/rack/public.rb +3 -3
- data/lib/spontaneous/rack.rb +15 -15
- data/lib/spontaneous/schema/uid.rb +4 -1
- data/lib/spontaneous/schema.rb +57 -24
- data/lib/spontaneous/search/database.rb +12 -1
- data/lib/spontaneous/search/index.rb +34 -6
- data/lib/spontaneous/search/results.rb +1 -1
- data/lib/spontaneous/server.rb +3 -3
- data/lib/spontaneous/simultaneous.rb +53 -0
- data/lib/spontaneous/{plugins/site → site}/features.rb +2 -2
- data/lib/spontaneous/{plugins/site → site}/helpers.rb +2 -3
- data/lib/spontaneous/{plugins/site → site}/hooks.rb +2 -2
- data/lib/spontaneous/{plugins/site → site}/instance.rb +4 -6
- data/lib/spontaneous/{plugins/site → site}/level.rb +2 -2
- data/lib/spontaneous/{plugins/site → site}/map.rb +4 -4
- data/lib/spontaneous/{plugins/site → site}/paths.rb +2 -2
- data/lib/spontaneous/site/publishing.rb +89 -0
- data/lib/spontaneous/{plugins/site → site}/schema.rb +4 -4
- data/lib/spontaneous/{plugins/site → site}/search.rb +2 -2
- data/lib/spontaneous/{plugins/site → site}/selectors.rb +15 -7
- data/lib/spontaneous/{plugins/site → site}/state.rb +2 -2
- data/lib/spontaneous/{plugins/site → site}/storage.rb +2 -2
- data/lib/spontaneous/{plugins/site → site}/url.rb +2 -2
- data/lib/spontaneous/site.rb +31 -14
- data/lib/spontaneous/state.rb +5 -6
- data/lib/spontaneous/style.rb +3 -2
- data/lib/spontaneous/utils/database/mysql_dumper.rb +13 -0
- data/lib/spontaneous/utils/database/postgres_dumper.rb +5 -0
- data/lib/spontaneous/version.rb +1 -1
- data/lib/spontaneous.rb +34 -89
- data/spontaneous.gemspec +112 -114
- data/test/experimental/test_crypt.rb +158 -0
- data/test/experimental/test_features.rb +3 -3
- data/test/fixtures/example_application/config/environments/development.rb +1 -1
- data/test/fixtures/example_application/lib/content.rb +5 -0
- data/test/fixtures/example_application/schema/page.rb +2 -1
- data/test/fixtures/example_application/schema/piece.rb +3 -2
- data/test/fixtures/serialisation/class_hash.yaml.erb +5 -5
- data/test/fixtures/serialisation/root_hash.yaml.erb +8 -0
- data/test/functional/test_application.rb +12 -1
- data/test/functional/test_back.rb +80 -48
- data/test/functional/test_front.rb +39 -46
- data/test/functional/test_user_manager.rb +3 -9
- data/test/javascript/test_markdown.rb +2 -2
- data/test/test_helper.rb +78 -23
- data/test/unit/test_alias.rb +21 -15
- data/test/unit/test_asset_bundler.rb +3 -3
- data/test/unit/test_assets.rb +2 -2
- data/test/unit/test_async.rb +7 -6
- data/test/unit/test_authentication.rb +43 -37
- data/test/unit/test_boxes.rb +46 -21
- data/test/unit/test_changesets.rb +65 -20
- data/test/unit/test_config.rb +9 -9
- data/test/unit/test_content.rb +50 -51
- data/test/unit/test_content_inheritance.rb +6 -20
- data/test/unit/test_datamapper.rb +1330 -0
- data/test/unit/test_datamapper_content.rb +214 -0
- data/test/unit/test_fields.rb +543 -54
- data/test/unit/test_formats.rb +2 -3
- data/test/unit/test_generators.rb +6 -6
- data/test/unit/test_helpers.rb +1 -1
- data/test/unit/test_image_size.rb +10 -5
- data/test/unit/test_images.rb +17 -18
- data/test/unit/test_layouts.rb +18 -3
- data/test/unit/test_media.rb +74 -49
- data/test/unit/test_modifications.rb +43 -43
- data/test/unit/test_page.rb +7 -10
- data/test/unit/test_permissions.rb +3 -10
- data/test/unit/test_piece.rb +5 -6
- data/test/unit/test_plugins.rb +7 -14
- data/test/unit/test_prototypes.rb +3 -3
- data/test/unit/test_publishing.rb +49 -27
- data/test/unit/test_render.rb +46 -15
- data/test/unit/test_revisions.rb +124 -127
- data/test/unit/test_schema.rb +53 -58
- data/test/unit/test_search.rb +64 -16
- data/test/unit/test_serialisation.rb +4 -11
- data/test/unit/test_site.rb +11 -12
- data/test/unit/test_structure.rb +2 -5
- data/test/unit/test_styles.rb +22 -24
- data/test/unit/test_type_hierarchy.rb +7 -5
- data/test/unit/test_visibility.rb +79 -55
- metadata +128 -102
- data/lib/sequel/plugins/content_table_inheritance.rb +0 -203
- data/lib/sequel/plugins/scoped_table_name.rb +0 -54
- data/lib/spontaneous/content.rb +0 -129
- data/lib/spontaneous/field_types/date_field.rb +0 -56
- data/lib/spontaneous/field_types/field.rb +0 -302
- data/lib/spontaneous/field_types/file_field.rb +0 -68
- data/lib/spontaneous/field_types/markdown_field.rb +0 -38
- data/lib/spontaneous/field_types/string_field.rb +0 -19
- data/lib/spontaneous/field_types/webvideo_field.rb +0 -313
- data/lib/spontaneous/field_types.rb +0 -38
- data/lib/spontaneous/generators/site/lib/site.rb.tt +0 -4
- data/lib/spontaneous/plugins/field/editor_class.rb +0 -13
- data/lib/spontaneous/plugins/page/site_timestamps.rb +0 -28
- data/lib/spontaneous/plugins/page_search.rb +0 -63
- data/lib/spontaneous/plugins/schema_id.rb +0 -68
- data/lib/spontaneous/plugins/site/publishing.rb +0 -75
- data/lib/spontaneous/rack/fiber_pool.rb +0 -26
- data/test/unit/test_table_scoping.rb +0 -80
@@ -4,8 +4,7 @@ require 'tempfile'
|
|
4
4
|
require 'mini_magick'
|
5
5
|
require 'delegate'
|
6
6
|
|
7
|
-
module Spontaneous
|
8
|
-
module FieldTypes
|
7
|
+
module Spontaneous::Field
|
9
8
|
|
10
9
|
class ImageOptimizer
|
11
10
|
def self.run(source_image)
|
@@ -63,7 +62,7 @@ module Spontaneous
|
|
63
62
|
|
64
63
|
def render(format=:html, *args)
|
65
64
|
case format
|
66
|
-
when :html
|
65
|
+
when "html", :html
|
67
66
|
to_html(*args)
|
68
67
|
else
|
69
68
|
value
|
@@ -108,8 +107,8 @@ module Spontaneous
|
|
108
107
|
end
|
109
108
|
end
|
110
109
|
|
111
|
-
class
|
112
|
-
|
110
|
+
class Image < File
|
111
|
+
has_editor
|
113
112
|
include ImageFieldUtilities
|
114
113
|
|
115
114
|
def self.accepts
|
@@ -137,7 +136,13 @@ module Spontaneous
|
|
137
136
|
end
|
138
137
|
|
139
138
|
def self.size_definitions
|
140
|
-
@size_definitions ||= superclass.respond_to?(:size_definitions) ? superclass.size_definitions.dup : {}
|
139
|
+
@size_definitions ||= superclass.respond_to?(:size_definitions) ? superclass.size_definitions.dup : { :__ui__ => ui_preview_size }
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.ui_preview_size
|
143
|
+
Proc.new {
|
144
|
+
width 300
|
145
|
+
}
|
141
146
|
end
|
142
147
|
|
143
148
|
def image?
|
@@ -153,6 +158,16 @@ module Spontaneous
|
|
153
158
|
value
|
154
159
|
end
|
155
160
|
|
161
|
+
def serialize_pending_file(file)
|
162
|
+
attrs = ImageProcessor.new(file).serialize
|
163
|
+
attrs.delete(:path)
|
164
|
+
attrs.merge(super)
|
165
|
+
end
|
166
|
+
|
167
|
+
def page_lock_description
|
168
|
+
"Processing image '#{pending_value[:value][:filename]}'"
|
169
|
+
end
|
170
|
+
|
156
171
|
# original is special and should always be defined
|
157
172
|
def original
|
158
173
|
@original ||= sizes[:original]
|
@@ -180,15 +195,20 @@ module Spontaneous
|
|
180
195
|
|
181
196
|
# formats are irrelevant to image/file fields
|
182
197
|
def outputs
|
183
|
-
[:original].concat(self.class.size_definitions.map { |name, process| name })
|
198
|
+
[:original, :__ui__].concat(self.class.size_definitions.map { |name, process| name })
|
184
199
|
end
|
185
200
|
|
186
201
|
def value(format=:html, *args)
|
187
202
|
sizes[:original].src
|
188
203
|
end
|
189
204
|
|
205
|
+
def set_value!(value, process = true)
|
206
|
+
@sizes = nil
|
207
|
+
super
|
208
|
+
end
|
209
|
+
|
190
210
|
def generate(output, media_file)
|
191
|
-
return { :src => media_file } if media_file.is_a?(String)#File.exist?(image_path)
|
211
|
+
return { :src => media_file } if media_file.is_a?(::String)#File.exist?(image_path)
|
192
212
|
image = ImageProcessor.new(media_file)
|
193
213
|
# Create a tempfile here that will be kept open for the duration of the block
|
194
214
|
# this is used in #apply to hold a copy of the processed image data rather than
|
@@ -205,32 +225,14 @@ module Spontaneous
|
|
205
225
|
result.serialize
|
206
226
|
end
|
207
227
|
|
208
|
-
def preprocess(image_path)
|
209
|
-
filename = mimetype = nil
|
210
|
-
case image_path
|
211
|
-
when Hash
|
212
|
-
mimetype = image_path[:type]
|
213
|
-
filename = image_path[:filename]
|
214
|
-
image_path = image_path[:tempfile].path
|
215
|
-
when String
|
216
|
-
# return image_path unless File.exist?(image_path)
|
217
|
-
filename = ::File.basename(image_path)
|
218
|
-
end
|
219
|
-
return image_path unless File.exist?(image_path)
|
220
|
-
# media_path = owner.make_media_file(image_path, filename)
|
221
|
-
media_file = Spontaneous::Media::File.new(owner, filename, mimetype)
|
222
|
-
media_file.copy(image_path)
|
223
|
-
set_unprocessed_value(File.expand_path(media_file.filepath))
|
224
|
-
# media_path
|
225
|
-
# image_path
|
226
|
-
media_file
|
227
|
-
end
|
228
228
|
|
229
229
|
def export(user = nil)
|
230
230
|
super(user).merge({
|
231
231
|
:processed_value => processed_values
|
232
232
|
})
|
233
233
|
end
|
234
|
+
|
235
|
+
self.register(:image, :photo)
|
234
236
|
end
|
235
237
|
|
236
238
|
|
@@ -314,7 +316,7 @@ module Spontaneous
|
|
314
316
|
end
|
315
317
|
|
316
318
|
def composite(other_image_path, output_extension = "jpg", &block)
|
317
|
-
File.open(other_image_path) do |other_image|
|
319
|
+
::File.open(other_image_path) do |other_image|
|
318
320
|
new_image = image.composite(other_image, output_extension, &block)
|
319
321
|
image.path = new_image.path
|
320
322
|
end
|
@@ -398,7 +400,7 @@ module Spontaneous
|
|
398
400
|
end
|
399
401
|
|
400
402
|
def filesize
|
401
|
-
File.size(path)
|
403
|
+
::File.size(path)
|
402
404
|
end
|
403
405
|
|
404
406
|
def width
|
@@ -446,7 +448,7 @@ module Spontaneous
|
|
446
448
|
:width => width,
|
447
449
|
:height => height,
|
448
450
|
:filesize => filesize,
|
449
|
-
:path => path
|
451
|
+
:path => @media_file.path
|
450
452
|
}
|
451
453
|
end
|
452
454
|
|
@@ -455,7 +457,5 @@ module Spontaneous
|
|
455
457
|
end
|
456
458
|
end
|
457
459
|
|
458
|
-
ImageField.register(:image, :photo)
|
459
460
|
|
460
|
-
end
|
461
461
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
module Spontaneous::
|
4
|
-
class
|
5
|
-
|
3
|
+
module Spontaneous::Field
|
4
|
+
class LongString < Base
|
5
|
+
has_editor
|
6
6
|
|
7
7
|
def generate_html(value)
|
8
8
|
escape_html(value).gsub(/[\r\n]+/, "<br />")
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'kramdown'
|
4
|
+
|
5
|
+
module Spontaneous::Field
|
6
|
+
class Markdown < Base
|
7
|
+
has_editor
|
8
|
+
|
9
|
+
def outputs
|
10
|
+
[:html]
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate_html(input)
|
14
|
+
input.to_html
|
15
|
+
end
|
16
|
+
|
17
|
+
def preprocess(input)
|
18
|
+
# convert lines ending with newlines into a <br/>
|
19
|
+
# as official Markdown syntax isn't suitable for
|
20
|
+
# casual users
|
21
|
+
# code taken from:
|
22
|
+
# http://github.github.com/github-flavored-markdown/
|
23
|
+
output = input.gsub(/^[\w\<][^\n]*\n+/) do |x|
|
24
|
+
x =~ /\n{2}/ ? x : (x.strip!; x << " \n")
|
25
|
+
end
|
26
|
+
|
27
|
+
# prevent foo_bar_baz from ending up with an italic word in the middle
|
28
|
+
output.gsub!(/(^(?! {4}|\t)\w+_\w+_\w[\w_]*)/) do |x|
|
29
|
+
x.gsub('_', '\_') if x.split('').sort.to_s[0..1] == '__'
|
30
|
+
end
|
31
|
+
Kramdown::Document.new(output)
|
32
|
+
end
|
33
|
+
|
34
|
+
self.register(:markdown, :text, :richtext)
|
35
|
+
end
|
36
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
module Spontaneous::
|
3
|
+
module Spontaneous::Field
|
4
4
|
# Provides a select field in the UI.
|
5
5
|
#
|
6
6
|
# Options for the select are provided by passing an :options value in the field config.
|
@@ -35,8 +35,8 @@ module Spontaneous::FieldTypes
|
|
35
35
|
# To retrieve the associated label use `field.value(:label)` or `field.label`
|
36
36
|
# ("Value 1" or "Value 2" in the exampel above).
|
37
37
|
#
|
38
|
-
class
|
39
|
-
|
38
|
+
class Select < Base
|
39
|
+
has_editor
|
40
40
|
|
41
41
|
def self.static_option_list?
|
42
42
|
return false if configured_option_list.is_a?(Proc)
|
@@ -104,6 +104,5 @@ module Spontaneous::FieldTypes
|
|
104
104
|
end
|
105
105
|
|
106
106
|
self.register
|
107
|
-
end #
|
107
|
+
end # Select
|
108
108
|
end
|
109
|
-
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Spontaneous::Field
|
4
|
+
class String < Base
|
5
|
+
has_editor
|
6
|
+
|
7
|
+
def preprocess(value)
|
8
|
+
Spontaneous::Utils::SmartQuotes.smarten(value.to_s)
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate_html(value)
|
12
|
+
escape_html(value)
|
13
|
+
end
|
14
|
+
|
15
|
+
self.register :string, :title
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Spontaneous::Field
|
4
|
+
|
5
|
+
class Update
|
6
|
+
def self.perform(fields, user, asynchronous = false)
|
7
|
+
self.new(fields, user).run(asynchronous)
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def self.asynchronous_update_class
|
12
|
+
Spontaneous::Site.resolve_background_mode(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(fields, user)
|
16
|
+
@fields, @user = fields, user
|
17
|
+
end
|
18
|
+
|
19
|
+
def run(asynchronous = false)
|
20
|
+
fields.each do |field, value|
|
21
|
+
field.pending_value = value
|
22
|
+
end
|
23
|
+
|
24
|
+
immediate, asynchronous = partition_fields(asynchronous)
|
25
|
+
|
26
|
+
Immediate.process(immediate)
|
27
|
+
|
28
|
+
launch_asynchronous_update(asynchronous)
|
29
|
+
end
|
30
|
+
|
31
|
+
def partition_fields(asynchronous)
|
32
|
+
fields = self.fields.keys
|
33
|
+
return [fields, []] unless asynchronous
|
34
|
+
filter = proc { |f| f.asynchronous? }
|
35
|
+
async = fields.select(&filter)
|
36
|
+
immediate = fields.reject(&filter)
|
37
|
+
[immediate, async]
|
38
|
+
end
|
39
|
+
|
40
|
+
def fields
|
41
|
+
writable_fields
|
42
|
+
end
|
43
|
+
|
44
|
+
def owners(fields)
|
45
|
+
fields.map(&:owner).uniq
|
46
|
+
end
|
47
|
+
|
48
|
+
def writable_fields
|
49
|
+
@fields.reject { |f, v| !f.writable?(@user)}
|
50
|
+
end
|
51
|
+
|
52
|
+
def launch_asynchronous_update(fields)
|
53
|
+
return if fields.empty?
|
54
|
+
# Keep the saving command here rather than in the field
|
55
|
+
# because all the fields most probably belong to
|
56
|
+
# the same owner
|
57
|
+
owners(fields).each(&:save_fields)
|
58
|
+
fields.each do |field|
|
59
|
+
prepare_asynchronous_update(field)
|
60
|
+
end
|
61
|
+
updater = self.class.asynchronous_update_class
|
62
|
+
updater.process(fields)
|
63
|
+
end
|
64
|
+
|
65
|
+
def prepare_asynchronous_update(field)
|
66
|
+
field.before_asynchronous_update
|
67
|
+
Spontaneous::PageLock.lock_field(field)
|
68
|
+
end
|
69
|
+
|
70
|
+
class Immediate
|
71
|
+
def self.process(fields)
|
72
|
+
self.new(fields).run
|
73
|
+
end
|
74
|
+
|
75
|
+
def initialize(fields)
|
76
|
+
@fields = Array(fields)
|
77
|
+
end
|
78
|
+
|
79
|
+
def run
|
80
|
+
@fields.each do |field|
|
81
|
+
field.process_pending_value
|
82
|
+
end
|
83
|
+
save
|
84
|
+
end
|
85
|
+
|
86
|
+
# This is made more complex by the need to verify that:
|
87
|
+
#
|
88
|
+
# a. this update has not been superceded by a more recent one and
|
89
|
+
# b. other fields on the owner have not been updated synchronously since
|
90
|
+
# this update was launched.
|
91
|
+
#
|
92
|
+
# (a) is verified by only saving fields that pass the #validate_update!
|
93
|
+
# test.
|
94
|
+
#
|
95
|
+
# (b) by calling Content#save_fields on a reloaded version of the owner
|
96
|
+
# and by the fact that only the fields that have been modified by this
|
97
|
+
# updater are re-serialized.
|
98
|
+
#
|
99
|
+
def save
|
100
|
+
valid_fields = @fields.reject { |field| field.conflicted_update? }
|
101
|
+
remove_update_lock(valid_fields)
|
102
|
+
field_map = valid_fields.group_by { |f| f.owner }
|
103
|
+
field_map.each do |owner, fields|
|
104
|
+
reload(owner).save_fields(fields)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# We need to save against a fresh version of the owning content
|
109
|
+
# because with long-running updates (video transcoding for example)
|
110
|
+
# it's quite likely that some non-asynchronous fields have been modified
|
111
|
+
# during the processing period.
|
112
|
+
#
|
113
|
+
# The #save_fields method only re-serializes the fields it's passed
|
114
|
+
# so we can update the fields we have updated without over-writing the db
|
115
|
+
# versions of any other fields.
|
116
|
+
def reload(owner)
|
117
|
+
Spontaneous::Content.scope! do
|
118
|
+
o = Spontaneous::Content.get(owner.content_instance.id)
|
119
|
+
return o.boxes[owner.box_name] if Spontaneous::Box === owner
|
120
|
+
o
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
def remove_update_lock(fields)
|
126
|
+
fields.each do |field|
|
127
|
+
Spontaneous::PageLock.unlock_field(field)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def owners
|
132
|
+
@fields.map(&:owner).uniq.compact
|
133
|
+
end
|
134
|
+
|
135
|
+
# Load these everytime to ensure they are updated with their
|
136
|
+
# correct lock status
|
137
|
+
def pages
|
138
|
+
page_ids = owners.map(&:page).uniq.compact.map(&:id)
|
139
|
+
page_ids.map { |id| Spontaneous::Content.get(id) }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class Simultaneous < Immediate
|
144
|
+
def run
|
145
|
+
params = { "fields" => @fields.map { |f| f.id } }
|
146
|
+
begin
|
147
|
+
Spontaneous::Simultaneous.fire(:update_fields, params)
|
148
|
+
rescue Spontaneous::Simultaneous::Error
|
149
|
+
Immediate.process(@fields)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
Spontaneous::Simultaneous.register(:update_fields, "field update", :logfile => "log/fields.log")
|