locomotivecms_mounter 1.0.0.alpha4 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/locomotive/mounter/engine_api.rb +5 -0
- data/lib/locomotive/mounter/fields.rb +5 -5
- data/lib/locomotive/mounter/models/base.rb +2 -1
- data/lib/locomotive/mounter/models/content_entry.rb +34 -6
- data/lib/locomotive/mounter/models/content_field.rb +2 -0
- data/lib/locomotive/mounter/models/content_type.rb +3 -0
- data/lib/locomotive/mounter/models/page.rb +12 -1
- data/lib/locomotive/mounter/reader/api/content_assets_reader.rb +1 -1
- data/lib/locomotive/mounter/reader/api/content_entries_reader.rb +4 -3
- data/lib/locomotive/mounter/reader/api/content_types_reader.rb +4 -4
- data/lib/locomotive/mounter/reader/api/pages_reader.rb +4 -3
- data/lib/locomotive/mounter/reader/api/site_reader.rb +1 -1
- data/lib/locomotive/mounter/reader/api/snippets_reader.rb +1 -1
- data/lib/locomotive/mounter/reader/api/theme_assets_reader.rb +1 -1
- data/lib/locomotive/mounter/reader/api/translations_reader.rb +2 -2
- data/lib/locomotive/mounter/reader/api.rb +4 -0
- data/lib/locomotive/mounter/reader/file_system/pages_reader.rb +4 -1
- data/lib/locomotive/mounter/version.rb +1 -1
- data/lib/locomotive/mounter/writer/api/base.rb +3 -10
- data/lib/locomotive/mounter/writer/api/pages_writer.rb +1 -0
- data/lib/locomotive/mounter/writer/api/theme_assets_writer.rb +20 -11
- data/lib/locomotive/mounter/writer/api/translations_writer.rb +1 -1
- data/lib/locomotive/mounter/writer/api.rb +4 -0
- data/lib/locomotive/mounter/writer/file_system/translations_writer.rb +2 -2
- data/lib/locomotive/mounter/writer/runner.rb +18 -8
- metadata +36 -4
@@ -33,6 +33,11 @@ module Locomotive
|
|
33
33
|
raise WrongCredentials.new("#{response['message']} (#{response.code})")
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
37
|
+
def self.teardown
|
38
|
+
Locomotive::Mounter::EngineApi.default_options[:base_uri] = nil
|
39
|
+
Locomotive::Mounter::EngineApi.default_options[:default_params] = {}
|
40
|
+
end
|
36
41
|
|
37
42
|
end
|
38
43
|
|
@@ -48,10 +48,11 @@ module Locomotive
|
|
48
48
|
|
49
49
|
attributes.each do |name, value|
|
50
50
|
unless self.class._fields.key?(name.to_sym) || self.respond_to?(:"#{name}=")
|
51
|
+
next if name.to_s == 'id'
|
51
52
|
raise FieldDoesNotExistException.new "[#{self.class.inspect}] setting an unknown attribute '#{name}' with the value '#{value.inspect}'"
|
52
53
|
end
|
53
54
|
|
54
|
-
if self.
|
55
|
+
if self.localized_field?(name) && value.is_a?(Hash)
|
55
56
|
self.send(:"#{name}_translations=", value)
|
56
57
|
else
|
57
58
|
self.send(:"#{name}=", value)
|
@@ -103,7 +104,7 @@ module Locomotive
|
|
103
104
|
#
|
104
105
|
# @return [ Boolean ] True if the field is localized
|
105
106
|
#
|
106
|
-
def
|
107
|
+
def localized_field?(name)
|
107
108
|
method_name = :"#{name}_localized?"
|
108
109
|
self.respond_to?(method_name) && self.send(method_name)
|
109
110
|
end
|
@@ -171,10 +172,9 @@ module Locomotive
|
|
171
172
|
def getter(name, options = {})
|
172
173
|
value = self.instance_variable_get(:"@#{name}")
|
173
174
|
if options[:localized]
|
174
|
-
(value || {})[Locomotive::Mounter.locale]
|
175
|
-
else
|
176
|
-
value
|
175
|
+
value = (value || {})[Locomotive::Mounter.locale]
|
177
176
|
end
|
177
|
+
value
|
178
178
|
end
|
179
179
|
|
180
180
|
def setter(name, value, options = {})
|
@@ -6,11 +6,12 @@ module Locomotive
|
|
6
6
|
|
7
7
|
include Locomotive::Mounter::Fields
|
8
8
|
|
9
|
-
attr_accessor :_id, :mounting_point
|
9
|
+
attr_accessor :_id, :mounting_point, :created_at, :updated_at
|
10
10
|
|
11
11
|
## methods ##
|
12
12
|
|
13
13
|
def initialize(attributes = {})
|
14
|
+
self.created_at = self.updated_at = Time.now
|
14
15
|
self.mounting_point = attributes.delete(:mounting_point)
|
15
16
|
super
|
16
17
|
end
|
@@ -20,11 +20,20 @@ module Locomotive
|
|
20
20
|
alias :_permalink= :_slug=
|
21
21
|
|
22
22
|
## callbacks ##
|
23
|
-
# set_callback :initialize, :after, :set_slug
|
24
23
|
set_callback :initialize, :after, :set_default_main_locale
|
25
24
|
|
26
25
|
## methods ##
|
27
26
|
|
27
|
+
# By definition, if the label field defined in the content type is
|
28
|
+
# localized, then the content entry will be considered as localized.
|
29
|
+
#
|
30
|
+
# @return [ Boolean ] True if the label field is localized.
|
31
|
+
#
|
32
|
+
def localized?
|
33
|
+
field = self.content_type.label_field
|
34
|
+
!!field.try(:localized)
|
35
|
+
end
|
36
|
+
|
28
37
|
# Return the internal label used to identify a content entry
|
29
38
|
# in a YAML file for instance. It is based on the first field
|
30
39
|
# of the related content type.
|
@@ -80,10 +89,6 @@ module Locomotive
|
|
80
89
|
|
81
90
|
self.dynamic_fields.each do |field|
|
82
91
|
value = self.localized_dynamic_attribute_value(field)
|
83
|
-
|
84
|
-
# value = (self.dynamic_attributes || {})[field.name.to_sym]
|
85
|
-
# value = value.try(:[], Locomotive::Mounter.locale) unless field.is_relationship? || !field.localized
|
86
|
-
|
87
92
|
block.call(field, value)
|
88
93
|
end
|
89
94
|
end
|
@@ -231,12 +236,35 @@ module Locomotive
|
|
231
236
|
self._slug = self.next_unique_slug if self.slug_already_taken?
|
232
237
|
end
|
233
238
|
end
|
239
|
+
|
240
|
+
self.fill_with_default_slug
|
241
|
+
end
|
242
|
+
|
243
|
+
# In case the content entry is not localized, we need to make sure
|
244
|
+
# it has an non empty slug for each locale of the site.
|
245
|
+
#
|
246
|
+
def fill_with_default_slug
|
247
|
+
return if self.localized?
|
248
|
+
|
249
|
+
# we do not want to add a new translation because the content entry
|
250
|
+
# is not truly "localized".
|
251
|
+
__locales = self._locales.dup
|
252
|
+
|
253
|
+
default_slug = self._slug_translations[self.mounting_point.default_locale]
|
254
|
+
|
255
|
+
self.mounting_point.locales.each do |locale|
|
256
|
+
Locomotive::Mounter.with_locale(locale) do
|
257
|
+
self._slug = default_slug if self._slug.blank?
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
self._locales = __locales
|
234
262
|
end
|
235
263
|
|
236
264
|
# Once the entry has been initialized, we keep track of the current locale
|
237
265
|
#
|
238
266
|
def set_default_main_locale
|
239
|
-
self.main_locale =
|
267
|
+
self.main_locale = self.content_type.mounting_point.default_locale
|
240
268
|
end
|
241
269
|
|
242
270
|
# Return the next available unique slug as a string
|
@@ -12,6 +12,7 @@ module Locomotive
|
|
12
12
|
field :position, default: 0
|
13
13
|
field :required, default: false
|
14
14
|
field :localized, default: false
|
15
|
+
field :class_slug
|
15
16
|
|
16
17
|
# text
|
17
18
|
field :text_formatting
|
@@ -27,6 +28,7 @@ module Locomotive
|
|
27
28
|
|
28
29
|
alias :target :class_name
|
29
30
|
alias :target= :class_name=
|
31
|
+
alias :raw_select_options= :select_options=
|
30
32
|
|
31
33
|
## callbacks ##
|
32
34
|
set_callback :initialize, :after, :prepare_attributes
|
@@ -58,6 +58,9 @@ module Locomotive
|
|
58
58
|
#
|
59
59
|
def build_entry(attributes)
|
60
60
|
ContentEntry.new(content_type: self).tap do |entry|
|
61
|
+
# set the link to the mounting point
|
62
|
+
entry.mounting_point = self.mounting_point
|
63
|
+
|
61
64
|
# do not forget that we are manipulating dynamic fields
|
62
65
|
attributes.each do |k, v|
|
63
66
|
begin
|
@@ -98,6 +98,17 @@ module Locomotive
|
|
98
98
|
self._locales = locales.map(&:to_sym)
|
99
99
|
end
|
100
100
|
|
101
|
+
# Set the content type, attribute required for templatized page.
|
102
|
+
# @deprecated. Use content_type= instead.
|
103
|
+
#
|
104
|
+
# @param [ Object ] content_type The content type
|
105
|
+
#
|
106
|
+
def model=(content_type)
|
107
|
+
Locomotive::Mounter.logger.warn 'The model attribute is deprecated. Use content_type instead.'
|
108
|
+
self.content_type = content_type
|
109
|
+
end
|
110
|
+
|
111
|
+
|
101
112
|
# Modified setter in order to set correctly the slug
|
102
113
|
#
|
103
114
|
# @param [ String ] fullpath The fullpath
|
@@ -354,7 +365,7 @@ module Locomotive
|
|
354
365
|
# @return [ Hash ] The safe params
|
355
366
|
#
|
356
367
|
def to_safe_params
|
357
|
-
fields = %w(listed published handle cache_strategy redirect_url response_type templatized content_type_id position)
|
368
|
+
fields = %w(title slug listed published handle cache_strategy redirect_url response_type templatized content_type_id position)
|
358
369
|
|
359
370
|
params = self.attributes.delete_if do |k, v|
|
360
371
|
!fields.include?(k.to_s) || (!v.is_a?(FalseClass) && v.blank?)
|
@@ -76,7 +76,7 @@ module Locomotive
|
|
76
76
|
# @return [ Object] The attributes understandable by the content entry
|
77
77
|
#
|
78
78
|
def filter_attributes(content_type, original_attributes)
|
79
|
-
attributes = original_attributes.clone.keep_if { |k, v| %w(_id _slug seo_title meta_keywords meta_description _position).include?(k) }
|
79
|
+
attributes = original_attributes.clone.keep_if { |k, v| %w(_id _slug seo_title meta_keywords meta_description _position created_at updated_at).include?(k) }
|
80
80
|
|
81
81
|
content_type.fields.each do |field|
|
82
82
|
value = (case field.type
|
@@ -85,7 +85,7 @@ module Locomotive
|
|
85
85
|
when :text
|
86
86
|
self.replace_urls_by_content_assets(original_attributes[field.name])
|
87
87
|
when :select
|
88
|
-
field.
|
88
|
+
field.find_select_option(original_attributes[field.name]).try(:name)
|
89
89
|
when :date
|
90
90
|
original_attributes["formatted_#{field.name}"]
|
91
91
|
when :belongs_to, :many_to_many
|
@@ -101,7 +101,7 @@ module Locomotive
|
|
101
101
|
end
|
102
102
|
|
103
103
|
attributes
|
104
|
-
end
|
104
|
+
end
|
105
105
|
|
106
106
|
# Some entries have what it is called "relationships" field
|
107
107
|
# which can be only resolved once all the entries have been fetched
|
@@ -127,6 +127,7 @@ module Locomotive
|
|
127
127
|
# @return [ String ] The content with local urls
|
128
128
|
#
|
129
129
|
def replace_urls_by_content_assets(content)
|
130
|
+
return "" unless content
|
130
131
|
self.mounting_point.content_assets.each do |path, asset|
|
131
132
|
content.gsub!(path, asset.local_filepath)
|
132
133
|
end
|
@@ -55,15 +55,15 @@ module Locomotive
|
|
55
55
|
def enable_relationships
|
56
56
|
self.items.each do |_, content_type|
|
57
57
|
content_type.fields.find_all(&:is_relationship?).each do |field|
|
58
|
-
# look for the target content type from its
|
59
|
-
target = self.items.
|
60
|
-
field.class_name = target
|
58
|
+
# look for the target content type from its slug
|
59
|
+
target = self.items.keys.find { |k| k == field.class_slug }
|
60
|
+
field.class_name = target
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
65
|
def safe_attributes
|
66
|
-
%w(name slug description order_by order_direction label_field_name group_by_field_id public_submission_accounts entries_custom_fields klass_name)
|
66
|
+
%w(name slug description order_by order_direction label_field_name group_by_field_id public_submission_accounts entries_custom_fields klass_name created_at updated_at)
|
67
67
|
end
|
68
68
|
|
69
69
|
end
|
@@ -98,7 +98,7 @@ module Locomotive
|
|
98
98
|
|
99
99
|
# content type
|
100
100
|
if content_type_slug = attributes.delete('target_klass_slug')
|
101
|
-
attributes['content_type'] = self.mounting_point.content_types[content_type_slug] #.values.find { |ct| ct._id == content_type_id }
|
101
|
+
attributes['content_type'] = self.mounting_point.content_types[content_type_slug] #.values.find { |ct| ct._id == content_type_id }
|
102
102
|
end
|
103
103
|
|
104
104
|
self.pages[fullpath] = Locomotive::Mounter::Models::Page.new(attributes)
|
@@ -128,7 +128,7 @@ module Locomotive
|
|
128
128
|
end
|
129
129
|
|
130
130
|
# Only keep the minimal attributes from a list of
|
131
|
-
# editable elements hashes. It also replaces the url to
|
131
|
+
# editable elements hashes. It also replaces the url to
|
132
132
|
# content assets by their corresponding local ones.
|
133
133
|
#
|
134
134
|
# @param [ Array ] list The list of the editable elements with all the attributes
|
@@ -149,7 +149,8 @@ module Locomotive
|
|
149
149
|
%w(_id title slug handle fullpath translated_in target_klass_slug
|
150
150
|
published listed templatized editable_elements
|
151
151
|
redirect_url cache_strategy response_type position
|
152
|
-
seo_title meta_keywords meta_description raw_template
|
152
|
+
seo_title meta_keywords meta_description raw_template
|
153
|
+
created_at updated_at)
|
153
154
|
end
|
154
155
|
|
155
156
|
# Output simply the tree structure of the pages.
|
@@ -108,7 +108,10 @@ module Locomotive
|
|
108
108
|
attributes[:title] = File.basename(fullpath).humanize
|
109
109
|
attributes[:fullpath] = fullpath
|
110
110
|
|
111
|
-
|
111
|
+
page = Locomotive::Mounter::Models::Page.new(attributes)
|
112
|
+
page.mounting_point = self.mounting_point
|
113
|
+
|
114
|
+
self.pages[fullpath] = page
|
112
115
|
end
|
113
116
|
|
114
117
|
self.pages[fullpath]
|
@@ -12,6 +12,8 @@ module Locomotive
|
|
12
12
|
|
13
13
|
delegate :default_locale, :locales, :site, to: :mounting_point
|
14
14
|
|
15
|
+
delegate :force?, to: :runner
|
16
|
+
|
15
17
|
def initialize(mounting_point, runner)
|
16
18
|
self.mounting_point = mounting_point
|
17
19
|
self.runner = runner
|
@@ -24,16 +26,6 @@ module Locomotive
|
|
24
26
|
self.output_title
|
25
27
|
end
|
26
28
|
|
27
|
-
# By setting the force option to true, some resources (site, content assets, ...etc)
|
28
|
-
# may overide the content of the remote engine during the push operation.
|
29
|
-
# By default, its value is false.
|
30
|
-
#
|
31
|
-
# @return [ Boolean ] True if the force option has been set to true
|
32
|
-
#
|
33
|
-
def force?
|
34
|
-
self.runner.parameters[:force] || false
|
35
|
-
end
|
36
|
-
|
37
29
|
# By setting the data option to true, user content (content entries and
|
38
30
|
# editable elements from page) can be pushed too.
|
39
31
|
# By default, its value is false.
|
@@ -253,6 +245,7 @@ module Locomotive
|
|
253
245
|
when :success then 'done'.colorize(color: :green)
|
254
246
|
when :error then 'error'.colorize(color: :red)
|
255
247
|
when :skipped then 'skipped'.colorize(color: :magenta)
|
248
|
+
when :same then 'same'.colorize(color: :magenta)
|
256
249
|
when :not_translated then 'not translated (itself or parent)'.colorize(color: :yellow)
|
257
250
|
end
|
258
251
|
|
@@ -37,27 +37,36 @@ module Locomotive
|
|
37
37
|
self.output_resource_op theme_asset
|
38
38
|
|
39
39
|
status = :skipped
|
40
|
+
errors = []
|
40
41
|
file = self.build_temp_file(theme_asset)
|
41
42
|
params = theme_asset.to_params.merge(source: file, performing_plain_text: false)
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
44
|
+
begin
|
45
|
+
if theme_asset.persisted?
|
46
|
+
# we only update it if the size has changed or if the force option has been set.
|
47
|
+
if self.force? || self.theme_asset_changed?(theme_asset, file)
|
48
|
+
response = self.put :theme_assets, theme_asset._id, params
|
49
|
+
status = self.response_to_status(response)
|
50
|
+
else
|
51
|
+
status = :same
|
52
|
+
end
|
53
|
+
else
|
54
|
+
response = self.post :theme_assets, params, nil, true
|
55
|
+
status = self.response_to_status(response)
|
56
|
+
end
|
57
|
+
rescue Exception => e
|
58
|
+
if self.force?
|
59
|
+
status, errors = :error, e.message
|
60
|
+
else
|
61
|
+
raise e
|
49
62
|
end
|
50
|
-
else
|
51
|
-
response = self.post :theme_assets, params, nil, true
|
52
|
-
|
53
|
-
status = self.response_to_status(response)
|
54
63
|
end
|
55
64
|
|
56
65
|
# very important. we do not want a huge number of non-closed file descriptor.
|
57
66
|
file.close
|
58
67
|
|
59
68
|
# track the status
|
60
|
-
self.output_resource_op_status theme_asset, status
|
69
|
+
self.output_resource_op_status theme_asset, status, errors
|
61
70
|
end
|
62
71
|
|
63
72
|
# make the stuff like they were before
|
@@ -13,7 +13,7 @@ module Locomotive
|
|
13
13
|
super
|
14
14
|
|
15
15
|
# set the unique identifier to each local translation
|
16
|
-
self.get(:translations, nil, true).each do |attributes|
|
16
|
+
(self.get(:translations, nil, true) || []).each do |attributes|
|
17
17
|
translation = self.translations[attributes['key']]
|
18
18
|
|
19
19
|
translation._id = attributes['id'] if translation
|
@@ -11,8 +11,8 @@ module Locomotive
|
|
11
11
|
|
12
12
|
def write
|
13
13
|
self.open_file('config/translations.yml') do |file|
|
14
|
-
file.write self.mounting_point.translations.
|
15
|
-
|
14
|
+
file.write self.mounting_point.translations.each_with_object({}) do |hash,translation|
|
15
|
+
hash[translation.key] = translation.values
|
16
16
|
end.to_yaml
|
17
17
|
end
|
18
18
|
end
|
@@ -48,19 +48,29 @@ module Locomotive
|
|
48
48
|
"#{name}_writer".camelize
|
49
49
|
end.try(:insert, 0, 'SiteWriter')
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
51
|
+
self.writers.each do |klass|
|
52
|
+
next if only && !only.include?(klass.name.demodulize)
|
53
|
+
writer = klass.new(self.mounting_point, self)
|
54
|
+
writer.prepare
|
55
|
+
begin
|
56
56
|
writer.write
|
57
|
+
rescue Exception => e
|
58
|
+
Locomotive::Mounter.logger.error e.backtrace
|
59
|
+
puts "\n\nBlocking Error: #{e.message.colorize(:red)}"
|
57
60
|
end
|
58
|
-
rescue Exception => e
|
59
|
-
Locomotive::Mounter.logger.error e.backtrace
|
60
|
-
puts "\n\nBlocking Error: #{e.message.colorize(:red)}"
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
+
# By setting the force option to true, some resources (site, content assets, ...etc)
|
65
|
+
# may overide the content of the remote engine during the push operation.
|
66
|
+
# By default, its value is false.
|
67
|
+
#
|
68
|
+
# @return [ Boolean ] True if the force option has been set to true
|
69
|
+
#
|
70
|
+
def force?
|
71
|
+
self.parameters[:force] || false
|
72
|
+
end
|
73
|
+
|
64
74
|
end
|
65
75
|
|
66
76
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: locomotivecms_mounter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.1
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Didier Lafforgue
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-04-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: tilt
|
@@ -379,6 +379,38 @@ dependencies:
|
|
379
379
|
- - ~>
|
380
380
|
- !ruby/object:Gem::Version
|
381
381
|
version: 0.0.1
|
382
|
+
- !ruby/object:Gem::Dependency
|
383
|
+
name: vcr
|
384
|
+
requirement: !ruby/object:Gem::Requirement
|
385
|
+
none: false
|
386
|
+
requirements:
|
387
|
+
- - '='
|
388
|
+
- !ruby/object:Gem::Version
|
389
|
+
version: 2.4.0
|
390
|
+
type: :development
|
391
|
+
prerelease: false
|
392
|
+
version_requirements: !ruby/object:Gem::Requirement
|
393
|
+
none: false
|
394
|
+
requirements:
|
395
|
+
- - '='
|
396
|
+
- !ruby/object:Gem::Version
|
397
|
+
version: 2.4.0
|
398
|
+
- !ruby/object:Gem::Dependency
|
399
|
+
name: webmock
|
400
|
+
requirement: !ruby/object:Gem::Requirement
|
401
|
+
none: false
|
402
|
+
requirements:
|
403
|
+
- - '='
|
404
|
+
- !ruby/object:Gem::Version
|
405
|
+
version: 1.9.3
|
406
|
+
type: :development
|
407
|
+
prerelease: false
|
408
|
+
version_requirements: !ruby/object:Gem::Requirement
|
409
|
+
none: false
|
410
|
+
requirements:
|
411
|
+
- - '='
|
412
|
+
- !ruby/object:Gem::Version
|
413
|
+
version: 1.9.3
|
382
414
|
description: Mount any LocomotiveCMS site, from a template on the filesystem, a zip
|
383
415
|
file or even an online engine
|
384
416
|
email:
|
@@ -471,7 +503,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
471
503
|
version: '0'
|
472
504
|
segments:
|
473
505
|
- 0
|
474
|
-
hash: -
|
506
|
+
hash: -3971524882032378901
|
475
507
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
476
508
|
none: false
|
477
509
|
requirements:
|