locomotivecms_mounter_pull_19 1.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +7 -0
  6. data/Gemfile.lock +131 -0
  7. data/MIT-LICENSE +20 -0
  8. data/NOTES +4 -0
  9. data/README.md +26 -0
  10. data/Rakefile +37 -0
  11. data/TODO +82 -0
  12. data/init.rb +2 -0
  13. data/lib/locomotive/mounter.rb +106 -0
  14. data/lib/locomotive/mounter/config.rb +21 -0
  15. data/lib/locomotive/mounter/engine_api.rb +205 -0
  16. data/lib/locomotive/mounter/exceptions.rb +44 -0
  17. data/lib/locomotive/mounter/extensions/compass.rb +38 -0
  18. data/lib/locomotive/mounter/extensions/httmultiparty.rb +22 -0
  19. data/lib/locomotive/mounter/extensions/sprockets.rb +46 -0
  20. data/lib/locomotive/mounter/extensions/tilt/css.rb +31 -0
  21. data/lib/locomotive/mounter/fields.rb +254 -0
  22. data/lib/locomotive/mounter/models/base.rb +42 -0
  23. data/lib/locomotive/mounter/models/content_asset.rb +84 -0
  24. data/lib/locomotive/mounter/models/content_entry.rb +372 -0
  25. data/lib/locomotive/mounter/models/content_field.rb +190 -0
  26. data/lib/locomotive/mounter/models/content_select_option.rb +29 -0
  27. data/lib/locomotive/mounter/models/content_type.rb +274 -0
  28. data/lib/locomotive/mounter/models/editable_element.rb +27 -0
  29. data/lib/locomotive/mounter/models/page.rb +442 -0
  30. data/lib/locomotive/mounter/models/site.rb +28 -0
  31. data/lib/locomotive/mounter/models/snippet.rb +55 -0
  32. data/lib/locomotive/mounter/models/theme_asset.rb +148 -0
  33. data/lib/locomotive/mounter/models/translation.rb +28 -0
  34. data/lib/locomotive/mounter/mounting_point.rb +65 -0
  35. data/lib/locomotive/mounter/reader/api.rb +64 -0
  36. data/lib/locomotive/mounter/reader/api/base.rb +67 -0
  37. data/lib/locomotive/mounter/reader/api/content_assets_reader.rb +39 -0
  38. data/lib/locomotive/mounter/reader/api/content_entries_reader.rb +142 -0
  39. data/lib/locomotive/mounter/reader/api/content_types_reader.rb +76 -0
  40. data/lib/locomotive/mounter/reader/api/pages_reader.rb +192 -0
  41. data/lib/locomotive/mounter/reader/api/site_reader.rb +42 -0
  42. data/lib/locomotive/mounter/reader/api/snippets_reader.rb +61 -0
  43. data/lib/locomotive/mounter/reader/api/theme_assets_reader.rb +42 -0
  44. data/lib/locomotive/mounter/reader/api/translations_reader.rb +30 -0
  45. data/lib/locomotive/mounter/reader/file_system.rb +43 -0
  46. data/lib/locomotive/mounter/reader/file_system/base.rb +65 -0
  47. data/lib/locomotive/mounter/reader/file_system/content_assets_reader.rb +90 -0
  48. data/lib/locomotive/mounter/reader/file_system/content_entries_reader.rb +97 -0
  49. data/lib/locomotive/mounter/reader/file_system/content_types_reader.rb +88 -0
  50. data/lib/locomotive/mounter/reader/file_system/pages_reader.rb +211 -0
  51. data/lib/locomotive/mounter/reader/file_system/site_reader.rb +27 -0
  52. data/lib/locomotive/mounter/reader/file_system/snippets_reader.rb +115 -0
  53. data/lib/locomotive/mounter/reader/file_system/theme_assets_reader.rb +83 -0
  54. data/lib/locomotive/mounter/reader/file_system/translations_reader.rb +36 -0
  55. data/lib/locomotive/mounter/reader/runner.rb +89 -0
  56. data/lib/locomotive/mounter/utils/hash.rb +31 -0
  57. data/lib/locomotive/mounter/utils/output.rb +124 -0
  58. data/lib/locomotive/mounter/utils/string.rb +40 -0
  59. data/lib/locomotive/mounter/utils/yaml.rb +125 -0
  60. data/lib/locomotive/mounter/utils/yaml_front_matters_template.rb +45 -0
  61. data/lib/locomotive/mounter/version.rb +8 -0
  62. data/lib/locomotive/mounter/writer/api.rb +74 -0
  63. data/lib/locomotive/mounter/writer/api/base.rb +172 -0
  64. data/lib/locomotive/mounter/writer/api/content_assets_writer.rb +74 -0
  65. data/lib/locomotive/mounter/writer/api/content_entries_writer.rb +227 -0
  66. data/lib/locomotive/mounter/writer/api/content_types_writer.rb +151 -0
  67. data/lib/locomotive/mounter/writer/api/pages_writer.rb +250 -0
  68. data/lib/locomotive/mounter/writer/api/site_writer.rb +125 -0
  69. data/lib/locomotive/mounter/writer/api/snippets_writer.rb +111 -0
  70. data/lib/locomotive/mounter/writer/api/theme_assets_writer.rb +201 -0
  71. data/lib/locomotive/mounter/writer/api/translations_writer.rb +85 -0
  72. data/lib/locomotive/mounter/writer/file_system.rb +44 -0
  73. data/lib/locomotive/mounter/writer/file_system/base.rb +70 -0
  74. data/lib/locomotive/mounter/writer/file_system/content_assets_writer.rb +38 -0
  75. data/lib/locomotive/mounter/writer/file_system/content_entries_writer.rb +33 -0
  76. data/lib/locomotive/mounter/writer/file_system/content_types_writer.rb +32 -0
  77. data/lib/locomotive/mounter/writer/file_system/pages_writer.rb +93 -0
  78. data/lib/locomotive/mounter/writer/file_system/site_writer.rb +30 -0
  79. data/lib/locomotive/mounter/writer/file_system/snippets_writer.rb +59 -0
  80. data/lib/locomotive/mounter/writer/file_system/theme_assets_writer.rb +72 -0
  81. data/lib/locomotive/mounter/writer/file_system/translations_writer.rb +29 -0
  82. data/lib/locomotive/mounter/writer/runner.rb +73 -0
  83. data/locomotivecms_mounter.gemspec +64 -0
  84. metadata +539 -0
@@ -0,0 +1,38 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Writer
4
+ module FileSystem
5
+
6
+ class ContentAssetsWriter < Base
7
+
8
+ # It creates the content assets folder
9
+ def prepare
10
+ super
11
+ self.create_folder 'public'
12
+ end
13
+
14
+ # It writes all the content assets into files
15
+ def write
16
+ self.mounting_point.content_assets.each do |_, asset|
17
+ self.output_resource_op asset
18
+
19
+ self.open_file(self.target_asset_path(asset), 'wb') do |file|
20
+ file.write(asset.content)
21
+ end
22
+
23
+ self.output_resource_op_status asset
24
+ end
25
+ end
26
+
27
+ protected
28
+
29
+ def target_asset_path(asset)
30
+ File.join('public', asset.folder, asset.filename)
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,33 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Writer
4
+ module FileSystem
5
+
6
+ class ContentEntriesWriter < Base
7
+
8
+ # It creates the data folder
9
+ def prepare
10
+ super
11
+ self.create_folder 'data'
12
+ end
13
+
14
+ # It writes all the content types into files
15
+ def write
16
+ self.mounting_point.content_types.each do |filename, content_type|
17
+ self.output_resource_op content_type
18
+
19
+ entries = (content_type.entries || []).map(&:to_hash)
20
+
21
+ self.open_file("data/#{filename}.yml") do |file|
22
+ file.write(entries.to_yaml)
23
+ end
24
+
25
+ self.output_resource_op_status content_type
26
+ end
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,32 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Writer
4
+ module FileSystem
5
+
6
+ class ContentTypesWriter < Base
7
+
8
+ # It creates the content types folder
9
+ def prepare
10
+ super
11
+ self.create_folder 'app/content_types'
12
+ end
13
+
14
+ # It writes all the content types into files
15
+ def write
16
+ self.mounting_point.content_types.each do |filename, content_type|
17
+ self.output_resource_op content_type
18
+
19
+ self.open_file("app/content_types/#{filename}.yml") do |file|
20
+ file.write(content_type.to_yaml)
21
+ end
22
+
23
+ self.output_resource_op_status content_type
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,93 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Writer
4
+ module FileSystem
5
+
6
+ class PagesWriter < Base
7
+
8
+ # It creates the pages folder
9
+ def prepare
10
+ super
11
+ self.create_folder 'app/views/pages'
12
+ end
13
+
14
+ # It writes all the pages into files
15
+ def write
16
+ self.write_page(self.mounting_point.pages['index'])
17
+
18
+ self.write_page(self.mounting_point.pages['404'])
19
+ end
20
+
21
+ protected
22
+
23
+ # Write the information about a page into the filesystem.
24
+ # Called itself recursively. Called at first by the write method
25
+ #
26
+ # @param [ Object ] page The page
27
+ # @param [ String ] path The parent path
28
+ #
29
+ def write_page(page, path = '')
30
+ self.output_resource_op page
31
+
32
+ # Note: we assume the current locale is the default one
33
+ page.translated_in.each do |locale|
34
+ default_locale = locale.to_sym == self.mounting_point.default_locale.to_sym
35
+
36
+ # we do not need the localized version of the filepath
37
+ filepath = page.fullpath.dasherize
38
+
39
+ Locomotive::Mounter.with_locale(locale) do
40
+ # we assume the filepath is already localized
41
+ self.write_page_to_fs(page, filepath, default_locale ? nil : locale)
42
+ end
43
+ end
44
+
45
+ self.output_resource_op_status page
46
+
47
+ # also write the nested pages
48
+ (page.children || []).each do |child|
49
+ self.write_page(child, page.depth == 0 ? '' : page.slug)
50
+ end
51
+ end
52
+
53
+ # Write into the filesystem the file about the page which will store
54
+ # information about this page + template.
55
+ # The file is localized meaning a same page could generate a file for each translation.
56
+ #
57
+ # @param [ Object ] page The page
58
+ # @param [ String ] filepath The path to the file describing the page (not localized)
59
+ # @param [ Locale ] locale The locale, nil if default locale
60
+ #
61
+ #
62
+ def write_page_to_fs(page, filepath, locale)
63
+ # puts filepath.inspect
64
+ _filepath = "#{filepath}.liquid"
65
+ _filepath.gsub!(/.liquid$/, ".#{locale}.liquid") if locale
66
+
67
+ _filepath = File.join('app', 'views', 'pages', _filepath)
68
+
69
+ self.replace_content_asset_urls(page.source)
70
+
71
+ self.open_file(_filepath) do |file|
72
+ file.write(page.to_yaml)
73
+ end
74
+ end
75
+
76
+ # The content assets on the remote engine follows the format: /sites/<id>/assets/<type>/<file>
77
+ # This method replaces these urls by their local representation. <type>/<file>
78
+ #
79
+ # @param [ String ] content The text where the assets will be replaced.
80
+ #
81
+ def replace_content_asset_urls(content)
82
+ return if content.blank?
83
+ content.force_encoding('utf-8').gsub!(/[("']\/sites\/[0-9a-f]{24}\/assets\/(([^;.]+)\/)*([a-zA-Z_\-0-9]+)\.[a-z]{2,3}[)"']/) do |path|
84
+ "/#{$3}"
85
+ end
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,30 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Writer
4
+ module FileSystem
5
+
6
+ class SiteWriter < Base
7
+
8
+ # It creates the config folder
9
+ def prepare
10
+ super
11
+ self.create_folder 'config'
12
+ end
13
+
14
+ # It fills the config/site.yml file
15
+ def write
16
+ self.open_file('config/site.yml') do |file|
17
+ self.output_resource_op self.mounting_point.site
18
+
19
+ file.write(self.mounting_point.site.to_yaml)
20
+
21
+ self.output_resource_op_status self.mounting_point.site
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,59 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Writer
4
+ module FileSystem
5
+
6
+ class SnippetsWriter < Base
7
+
8
+ # It creates the snippets folder
9
+ def prepare
10
+ super
11
+ self.create_folder 'app/views/snippets'
12
+ end
13
+
14
+ # It writes all the snippets into files
15
+ def write
16
+ self.mounting_point.snippets.each do |filepath, snippet|
17
+ self.output_resource_op snippet
18
+
19
+ # Note: we assume the current locale is the default one
20
+ snippet.translated_in.each do |locale|
21
+ default_locale = locale.to_sym == self.mounting_point.default_locale.to_sym
22
+
23
+ Locomotive::Mounter.with_locale(locale) do
24
+ self.write_snippet_to_fs(snippet, filepath, default_locale ? nil : locale)
25
+ end
26
+ end
27
+
28
+ self.output_resource_op_status snippet
29
+ end
30
+ end
31
+
32
+ protected
33
+
34
+ # Write into the filesystem the file which stores the snippet template
35
+ # The file is localized meaning a same snippet could generate a file for each translation.
36
+ #
37
+ # @param [ Object ] snippet The snippet
38
+ # @param [ String ] filepath The path to the file
39
+ # @param [ Locale ] locale The locale, nil if default locale
40
+ #
41
+ def write_snippet_to_fs(snippet, filepath, locale)
42
+ _filepath = "#{filepath}.liquid"
43
+ _filepath.gsub!(/.liquid$/, ".#{locale}.liquid") if locale
44
+
45
+ unless snippet.template.blank?
46
+ _filepath = File.join('app', 'views', 'snippets', _filepath)
47
+
48
+ self.open_file(_filepath) do |file|
49
+ file.write(snippet.source)
50
+ end
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,72 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Writer
4
+ module FileSystem
5
+
6
+ class ThemeAssetsWriter < Base
7
+
8
+ # Create the theme assets folders
9
+ #
10
+ def prepare
11
+ super
12
+ self.create_folder 'public'
13
+ end
14
+
15
+ # Write all the snippets into files
16
+ #
17
+ def write
18
+ self.theme_assets_by_priority.each do |asset|
19
+ self.output_resource_op asset
20
+
21
+ self.open_file(self.target_asset_path(asset), 'wb') do |file|
22
+ content = asset.content
23
+
24
+ if asset.stylesheet_or_javascript?
25
+ self.replace_asset_urls(content)
26
+ end
27
+
28
+ file.write(content)
29
+ end
30
+
31
+ self.output_resource_op_status asset
32
+ end
33
+ end
34
+
35
+ protected
36
+
37
+ # The urls stored on the remote engine follows the format: /sites/<id>/theme/<type>/<file>
38
+ # This method replaces these urls by their local representation. <type>/<file>
39
+ #
40
+ # @param [ String ] content
41
+ #
42
+ def replace_asset_urls(content)
43
+ return if content.blank?
44
+ content.force_encoding('utf-8').gsub!(/[("']([^)"';]*)\/sites\/[0-9a-f]{24}\/theme\/(([^;.]+)\/)*([a-zA-Z_\-0-9]+\.[a-z]{2,3})[)"']/) do |path|
45
+ "#{path.first}/#{$2 + $4}#{path.last}"
46
+ end
47
+ end
48
+
49
+ # Return the path where will be copied the asset
50
+ #
51
+ # @param [ String ] asset The asset
52
+ #
53
+ # @return [ String ] The relative path of the asset locally
54
+ #
55
+ def target_asset_path(asset)
56
+ File.join('public', asset.folder, asset.filename)
57
+ end
58
+
59
+ # List of theme assets sorted by their priority.
60
+ #
61
+ # @return [ Array ] Sorted list of the theme assets
62
+ #
63
+ def theme_assets_by_priority
64
+ self.mounting_point.theme_assets.sort { |a, b| a.priority <=> b.priority }
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,29 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Writer
4
+ module FileSystem
5
+
6
+ class TranslationsWriter < Base
7
+
8
+ def prepare
9
+ super
10
+ self.create_folder 'config'
11
+ end
12
+
13
+ def write
14
+ content = self.mounting_point.translations.each_with_object({}) do |(key,translation), hash|
15
+ hash[key] = translation.values
16
+ end
17
+
18
+ content = content.empty? ? '' : content.to_yaml
19
+
20
+ self.open_file('config/translations.yml') do |file|
21
+ file.write content
22
+ end
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,73 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Writer
4
+
5
+ class Runner
6
+
7
+ attr_accessor :kind, :parameters, :mounting_point
8
+
9
+ def initialize(kind)
10
+ self.kind = kind
11
+
12
+ # avoid to load all the ruby files at the startup, only when we need it
13
+ base_dir = File.join(File.dirname(__FILE__), kind.to_s)
14
+ require File.join(base_dir, 'base.rb')
15
+ Dir[File.join(base_dir, '*.rb')].each { |lib| require lib }
16
+ end
17
+
18
+ # Write the data of a mounting point instance to a target folder
19
+ #
20
+ # @param [ Hash ] parameters The parameters. It should contain the mounting_point and target_path keys.
21
+ #
22
+ def run!(parameters = {})
23
+ self.parameters = parameters.symbolize_keys
24
+
25
+ self.mounting_point = self.parameters.delete(:mounting_point)
26
+
27
+ self.prepare
28
+
29
+ self.write_all
30
+ end
31
+
32
+ # Before starting to write anything
33
+ # Can be defined by writer runners
34
+ def prepare
35
+ end
36
+
37
+ # List of all the writers
38
+ #
39
+ # @return [ Array ] List of the writer classes
40
+ #
41
+ def writers
42
+ raise Locomotive::Mounter::ImplementationIsMissingException.new("[#{self.kind}] Writers are missing")
43
+ end
44
+
45
+ # Execute all the writers
46
+ def write_all
47
+ only = parameters[:only].try(:map) do |name|
48
+ "#{name}_writer".camelize
49
+ end.try(:insert, 0, 'SiteWriter')
50
+
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
+ writer.write
56
+ end
57
+ end
58
+
59
+ # By setting the force option to true, some resources (site, content assets, ...etc)
60
+ # may overide the content of the remote engine during the push operation.
61
+ # By default, its value is false.
62
+ #
63
+ # @return [ Boolean ] True if the force option has been set to true
64
+ #
65
+ def force?
66
+ self.parameters[:force] || false
67
+ end
68
+
69
+ end
70
+
71
+ end
72
+ end
73
+ end