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,36 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Reader
4
+ module FileSystem
5
+
6
+ class TranslationsReader < Base
7
+
8
+ # Build the list of translations based on the config/translations.yml file
9
+ #
10
+ # @return [ Hash ] Hash whose the key is the translation key
11
+ #
12
+ def read
13
+ config_path = File.join(self.runner.path, 'config', 'translations.yml')
14
+
15
+ {}.tap do |translations|
16
+ if File.exists?(config_path)
17
+ (self.read_yaml(config_path) || []).each do |translation|
18
+ key, values = translation
19
+
20
+ entry = Locomotive::Mounter::Models::Translation.new({
21
+ key: key,
22
+ values: values
23
+ })
24
+
25
+ translations[key] = entry
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,89 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Reader
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
+ # Read the content of a site (pages, snippets, ...etc) and create the corresponding mounting point.
19
+ #
20
+ # @param [ Hash ] parameters The parameters.
21
+ #
22
+ # @return [ Object ] The mounting point object storing all the information about the site
23
+ #
24
+ def run!(parameters = {})
25
+ self.parameters = parameters.symbolize_keys
26
+
27
+ self.prepare
28
+
29
+ self.build_mounting_point
30
+ end
31
+
32
+ # Reload with the same origin parameters a part of a site from a list of
33
+ # resources each described by a simple name (site, pages, ...etc) taken from
34
+ # the corresponding reader class name.
35
+ #
36
+ # @param [ Array/ String ] list An array of resource(s) or just the resource
37
+ #
38
+ def reload(*list)
39
+ Locomotive::Mounter.with_locale(self.mounting_point.default_locale) do
40
+ [*list].flatten.each do |name|
41
+ reader_name = "#{name.to_s.camelize}Reader"
42
+
43
+ reader = self.readers.detect do |_reader|
44
+ _reader.name.demodulize == reader_name
45
+ end
46
+
47
+ if reader
48
+ self.mounting_point.register_resource(name, reader.new(self).read)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ # Before building the mounting point.
55
+ # Can be defined by reader runners
56
+ def prepare
57
+ end
58
+
59
+ # Ordered list of atomic readers
60
+ #
61
+ # @return [ Array ] List of classes
62
+ #
63
+ def readers
64
+ raise Locomotive::Mounter::ImplementationIsMissingException.new('readers are missing')
65
+ end
66
+
67
+ protected
68
+
69
+ def build_mounting_point
70
+ Locomotive::Mounter::MountingPoint.new.tap do |mounting_point|
71
+ self.mounting_point = mounting_point
72
+
73
+ self.readers.each do |reader|
74
+ name = reader.name.gsub(/(Reader)$/, '').demodulize.underscore
75
+
76
+ self.mounting_point.register_resource(name, reader.new(self).read)
77
+ end
78
+
79
+ if self.respond_to?(:path)
80
+ self.mounting_point.path = self.path
81
+ end
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,31 @@
1
+ unless Hash.instance_methods.include?(:deep_stringify_keys)
2
+ class Hash
3
+
4
+ # Return a new hash with all keys converted to strings.
5
+ # This includes the keys from the root hash and from all
6
+ # nested hashes.
7
+ def deep_stringify_keys
8
+ result = {}
9
+ each do |key, value|
10
+ result[key.to_s] = value.is_a?(Hash) ? value.deep_stringify_keys : value
11
+ end
12
+ result
13
+ end
14
+
15
+ end
16
+ end
17
+
18
+ unless Hash.instance_methods.include?(:deep_symbolize_keys)
19
+ class Hash
20
+
21
+ # See http://iain.nl/writing-yaml-files
22
+ def deep_symbolize_keys
23
+ {}.tap do |new_hash|
24
+ self.each do |key, value|
25
+ new_hash.merge!(key.to_sym => (value.is_a?(Hash) ? value.deep_symbolize_keys : value))
26
+ end
27
+ end
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,124 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Utils
4
+ module Output
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+
10
+ @@buffer_enabled = false
11
+ @@buffer_log = ''
12
+
13
+ end
14
+
15
+ protected
16
+
17
+ # Print the the title for each kind of resource.
18
+ #
19
+ def output_title(action = :pushing)
20
+ msg = "* #{action.to_s.capitalize} #{self.class.name.gsub(/(Writer|Reader)$/, '').demodulize}"
21
+ self.log msg.colorize(background: :white, color: :black) + "\n"
22
+ end
23
+
24
+ # Print the current locale.
25
+ #
26
+ def output_locale
27
+ locale = Locomotive::Mounter.locale.to_s
28
+ self.log " #{locale.colorize(background: :blue, color: :white)}\n"
29
+ end
30
+
31
+ def truncate(string, length = 50, separator = '[...]')
32
+ if string.length > length
33
+ string[0..(length - separator.length)] + separator
34
+ else
35
+ string
36
+ end
37
+ end
38
+
39
+ # Print the message about the creation / update of a resource.
40
+ #
41
+ # @param [ Object ] resource The resource (Site, Page, ...etc).
42
+ #
43
+ def output_resource_op(resource)
44
+ self.log self.resource_message(resource)
45
+ end
46
+
47
+ # Print the message about the creation / update of a resource.
48
+ #
49
+ # @param [ Object ] resource The resource (Site, Page, ...etc).
50
+ # @param [ Symbol ] status :success, :error, :skipped
51
+ # @param [ String ] errors The error messages
52
+ #
53
+ def output_resource_op_status(resource, status = :success, errors = nil)
54
+ status_label = case status
55
+ when :success then 'done'.colorize(color: :green)
56
+ when :error then 'error'.colorize(color: :red)
57
+ when :skipped then 'skipped'.colorize(color: :magenta)
58
+ when :same then 'same'.colorize(color: :magenta)
59
+ when :not_translated then 'not translated (itself or parent)'.colorize(color: :yellow)
60
+ end
61
+
62
+ spaces = '.' * (80 - self.resource_message(resource).size)
63
+ self.log "#{spaces}[#{status_label}]\n"
64
+
65
+ if errors && status == :error
66
+ self.log "#{errors.colorize(color: :red)}\n"
67
+ end
68
+ end
69
+
70
+ # Return the message about the creation / update of a resource.
71
+ #
72
+ # @param [ Object ] resource The resource (Site, Page, ...etc).
73
+ #
74
+ # @return [ String ] The message
75
+ #
76
+ def resource_message(resource)
77
+ op_label = resource.persisted? ? 'updating': 'creating'
78
+ " #{op_label} #{truncate(resource.to_s)}"
79
+ end
80
+
81
+ # Log a message to the console or the logger depending on the options
82
+ # of the runner. Info is the log level if case the logger has been chosen.
83
+ #
84
+ # @param [ String ] message The message to log.
85
+ #
86
+ def log(message)
87
+ # puts "buffer ? #{@@buffer_enabled.inspect}"
88
+ if @@buffer_enabled
89
+ @@buffer_log << message
90
+ else
91
+ if self.runner.parameters[:console]
92
+ print message
93
+ else
94
+ Mounter.logger.info message #.gsub(/\n$/, '')
95
+ end
96
+ end
97
+ end
98
+
99
+ # Put in a buffer the logs generated when executing the block.
100
+ # It means that they will not output unless the flush_log_buffer
101
+ # method is called.
102
+ #
103
+ # @return [ Object ] Thee value returned by the call of the block
104
+ #
105
+ def buffer_log(&block)
106
+ @@buffer_log = ''
107
+ @@buffer_enabled = true
108
+ if block_given?
109
+ block.call.tap { @@buffer_enabled = false }
110
+ end
111
+ end
112
+
113
+ # Flush the logs put in a buffer.
114
+ #
115
+ def flush_log_buffer
116
+ @@buffer_enabled = false
117
+ self.log(@@buffer_log)
118
+ @@buffer_log = ''
119
+ end
120
+
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ ## String
4
+
5
+ class String #:nodoc
6
+
7
+ def permalink(underscore = false)
8
+ # if the slug includes one "_" at least, we consider that the "_" is used instead of "-".
9
+ _permalink = if !self.index('_').nil?
10
+ self.to_url(replace_whitespace_with: '_')
11
+ else
12
+ self.to_url
13
+ end
14
+
15
+ underscore ? _permalink.underscore : _permalink
16
+ end
17
+
18
+ def permalink!(underscore = false)
19
+ replace(self.permalink(underscore))
20
+ end
21
+
22
+ alias :parameterize! :permalink!
23
+
24
+ end
25
+
26
+
27
+ # class String #:nodoc
28
+
29
+ # def permalink(underscore = false)
30
+ # permalink = self.to_ascii.parameterize
31
+ # underscore ? permalink.underscore : permalink
32
+ # end
33
+
34
+ # def permalink!(underscore = false)
35
+ # replace(self.permalink(underscore))
36
+ # end
37
+
38
+ # alias :parameterize! :permalink!
39
+
40
+ # end
@@ -0,0 +1,125 @@
1
+ # http://stackoverflow.com/questions/9556546/is-there-a-way-to-tell-psych-in-ruby-to-using-inline-mode
2
+ # https://gist.github.com/2023978
3
+
4
+ require 'psych'
5
+ require 'stringio'
6
+
7
+ # Public: A Psych extension to enable choosing output styles for specific
8
+ # objects.
9
+ #
10
+ # Thanks to Tenderlove for help in <http://stackoverflow.com/q/9640277/11687>
11
+ #
12
+ # Examples
13
+ #
14
+ # data = {
15
+ # response: { body: StyledYAML.literal(json_string), status: 200 },
16
+ # person: StyledYAML.inline({ 'name' => 'Stevie', 'age' => 12 }),
17
+ # array: StyledYAML.inline(%w[ apples bananas oranges ])
18
+ # }
19
+ #
20
+ # StyledYAML.dump data, $stdout
21
+ #
22
+ module StyledYAML
23
+ # Tag strings to be output using literal style
24
+ def self.literal obj
25
+ obj.extend LiteralScalar
26
+ return obj
27
+ end
28
+
29
+ # http://www.yaml.org/spec/1.2/spec.html#id2795688
30
+ module LiteralScalar
31
+ def yaml_style() Psych::Nodes::Scalar::LITERAL end
32
+ end
33
+
34
+ # Tag Hashes or Arrays to be output all on one line
35
+ def self.inline obj
36
+ case obj
37
+ when Hash then obj.extend FlowMapping
38
+ when Array then obj.extend FlowSequence
39
+ else
40
+ warn "#{self}: unrecognized type to inline (#{obj.class.name})"
41
+ end
42
+ return obj
43
+ end
44
+
45
+ # http://www.yaml.org/spec/1.2/spec.html#id2790832
46
+ module FlowMapping
47
+ def yaml_style() Psych::Nodes::Mapping::FLOW end
48
+ end
49
+
50
+ # http://www.yaml.org/spec/1.2/spec.html#id2790320
51
+ module FlowSequence
52
+ def yaml_style() Psych::Nodes::Sequence::FLOW end
53
+ end
54
+
55
+ # Custom tree builder class to recognize scalars tagged with `yaml_style`
56
+ class TreeBuilder < Psych::TreeBuilder
57
+ attr_writer :next_sequence_or_mapping_style
58
+
59
+ def initialize(*args)
60
+ super
61
+ @next_sequence_or_mapping_style = nil
62
+ end
63
+
64
+ def next_sequence_or_mapping_style default_style
65
+ style = @next_sequence_or_mapping_style || default_style
66
+ @next_sequence_or_mapping_style = nil
67
+ style
68
+ end
69
+
70
+ def scalar value, anchor, tag, plain, quoted, style
71
+ if style_any?(style) and value.respond_to?(:yaml_style) and style = value.yaml_style
72
+ if style_literal? style
73
+ plain = false
74
+ quoted = true
75
+ end
76
+ end
77
+ super
78
+ end
79
+
80
+ def style_any?(style) Psych::Nodes::Scalar::ANY == style end
81
+
82
+ def style_literal?(style) Psych::Nodes::Scalar::LITERAL == style end
83
+
84
+ %w[sequence mapping].each do |type|
85
+ class_eval <<-RUBY
86
+ def start_#{type}(anchor, tag, implicit, style)
87
+ style = next_sequence_or_mapping_style(style)
88
+ super
89
+ end
90
+ RUBY
91
+ end
92
+ end
93
+
94
+ # Custom tree class to handle Hashes and Arrays tagged with `yaml_style`
95
+ class YAMLTree < Psych::Visitors::YAMLTree
96
+ %w[Hash Array Psych_Set Psych_Omap].each do |klass|
97
+ class_eval <<-RUBY
98
+ def visit_#{klass} o
99
+ if o.respond_to? :yaml_style
100
+ @emitter.next_sequence_or_mapping_style = o.yaml_style
101
+ end
102
+ super
103
+ end
104
+ RUBY
105
+ end
106
+ end
107
+
108
+ # A Psych.dump alternative that uses the custom TreeBuilder
109
+ def self.dump obj, io = nil, options = {}
110
+ real_io = io || StringIO.new(''.encode('utf-8'))
111
+ visitor = YAMLTree.new(options, TreeBuilder.new)
112
+ visitor << obj
113
+ ast = visitor.tree
114
+
115
+ begin
116
+ ast.yaml real_io
117
+ rescue
118
+ # The `yaml` method was introduced in later versions, so fall back to
119
+ # constructing a visitor
120
+ Psych::Visitors::Emitter.new(real_io).accept ast
121
+ end
122
+
123
+ io ? io : real_io.string
124
+ end
125
+ end