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,28 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Models
4
+
5
+ class Site < Base
6
+
7
+ ## fields ##
8
+ field :name
9
+ field :locales
10
+ field :subdomain
11
+ field :domains
12
+ field :seo_title, localized: true
13
+ field :meta_keywords, localized: true
14
+ field :meta_description, localized: true
15
+ field :robots_txt
16
+ field :timezone
17
+
18
+ ## methods ##
19
+
20
+ def to_s
21
+ self.name
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,55 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Models
4
+
5
+ class Snippet < Base
6
+
7
+ ## fields ##
8
+ field :name
9
+ field :slug
10
+
11
+ field :template, localized: true
12
+
13
+ ## methods ##
14
+
15
+ # Return the Liquid template based on the template_filepath property
16
+ # of the snippet. If the template is HAML, then a pre-rendering to Liquid is done.
17
+ #
18
+ # @return [ String ] The liquid template
19
+ #
20
+ def source
21
+ @source ||= {}
22
+
23
+ source = if self.template.respond_to?(:source)
24
+ # liquid or haml file
25
+ self.template.source
26
+ else
27
+ # simple string
28
+ self.template
29
+ end
30
+
31
+ @source[Locomotive::Mounter.locale] = source
32
+ end
33
+
34
+ # Return the params used for the API.
35
+ #
36
+ # @return [ Hash ] The params
37
+ #
38
+ def to_params
39
+ params = self.filter_attributes %w(name slug)
40
+
41
+ # raw_template
42
+ params[:template] = self.source rescue nil
43
+
44
+ params
45
+ end
46
+
47
+ def to_s
48
+ self.name
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,148 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Models
4
+
5
+ class ThemeAsset < Base
6
+
7
+ PRECOMPILED_CSS_TYPES = %w(sass scss less)
8
+
9
+ PRECOMPILED_JS_TYPES = %w(coffee)
10
+
11
+ PRECOMPILED_FILE_TYPES = PRECOMPILED_CSS_TYPES + PRECOMPILED_JS_TYPES
12
+
13
+ CSS_JS_SHORT_PATH_REGEXP = /^(javascripts|stylesheets|fonts)\/(.*)$/
14
+
15
+ ## fields ##
16
+ field :folder
17
+
18
+ ## other accessors ##
19
+ attr_accessor :filepath, :uri, :size
20
+
21
+ ## methods ##
22
+
23
+ # Name of the file without any precompiled extensions (.sass, .scss, ...etc)
24
+ #
25
+ # @return [ String ] Name of the file
26
+ #
27
+ def filename
28
+ return @filename if @filename
29
+
30
+ if self.uri
31
+ @filename = File.basename(self.uri.path)
32
+ else
33
+ regexps = PRECOMPILED_FILE_TYPES.map { |ext| "\.#{ext}" }.join('|')
34
+
35
+ @filename = File.basename(self.filepath).gsub(/#{regexps}/, '')
36
+ end
37
+ end
38
+
39
+ # Return the virtual path of the asset
40
+ #
41
+ # @return [ String ] The virtual path of the asset
42
+ #
43
+ def path
44
+ File.join(self.folder, self.filename)
45
+ end
46
+
47
+ # Return the path without the leading javascripts, stylesheets, fonts
48
+ # font. This is needed by Sprockets.
49
+ # Only relevant for javascripts / stylesshets files.
50
+ #
51
+ # @return [ String ] The path of the asset without the first folder
52
+ #
53
+ def short_path
54
+ self.path =~ /^(javascripts|stylesheets|fonts)\/(.*)$/
55
+ $2
56
+ end
57
+
58
+ # Return the mime type of the file based on the Mime::Types lib.
59
+ #
60
+ # @return [ String ] The mime type of the file or nil if unknown.
61
+ #
62
+ def mime_type
63
+ type = MIME::Types.type_for(self.filename)
64
+ type.empty? ? nil : type.first
65
+ end
66
+
67
+ # Is the asset a stylesheet ?
68
+ #
69
+ # @return [ Boolean ] True if the filename ends with .css
70
+ #
71
+ def stylesheet?
72
+ File.extname(self.filename) == '.css'
73
+ end
74
+
75
+ # Is the asset a javascript ?
76
+ #
77
+ # @return [ Boolean ] True if the filename ends with .js
78
+ #
79
+ def javascript?
80
+ File.extname(self.filename) == '.js'
81
+ end
82
+
83
+ def stylesheet_or_javascript?
84
+ self.stylesheet? || self.javascript?
85
+ end
86
+
87
+ # Give the priority of the asset depending of its type.
88
+ # Javascripts and stylesheets are low priority.
89
+ #
90
+ # @return [ Integer ] The priority (0 -> high, 100 -> lower)
91
+ #
92
+ def priority
93
+ self.stylesheet_or_javascript? ? 100 : 0
94
+ end
95
+
96
+ # Tell if the asset can be precompiled. For instance, less, sass, scss and
97
+ # coffeescript assets have to be precompiled.
98
+ #
99
+ # @return [ Boolean ] True if it has to be precompiled
100
+ #
101
+ def precompiled?
102
+ @extname ||= File.extname(self.filepath)[1..-1]
103
+ PRECOMPILED_FILE_TYPES.include?(@extname)
104
+ end
105
+
106
+ # Content of the asset. Pre-compile it if needed.
107
+ #
108
+ # @return [ String ] The content of the asset
109
+ #
110
+ def content
111
+ return @raw if @raw
112
+
113
+ if self.uri
114
+ @raw = HTTParty.get(self.uri.to_s).body
115
+ # elsif self.precompiled?
116
+ # template = Tilt.new(self.filepath)
117
+ # @raw = template.render
118
+ else
119
+ @raw = File.read(self.filepath)
120
+ end
121
+ end
122
+
123
+ # Get a fresh version of the content of the asset. Pre-compile it if needed.
124
+ #
125
+ # @return [ String ] The content of the asset
126
+ #
127
+ def content!
128
+ @raw = nil # force to reload it
129
+ self.content
130
+ end
131
+
132
+ # Return the params used for the API.
133
+ #
134
+ # @return [ Hash ] The params
135
+ #
136
+ def to_params
137
+ { folder: self.folder }
138
+ end
139
+
140
+ def to_s
141
+ self.path
142
+ end
143
+
144
+ end
145
+
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,28 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Models
4
+
5
+ class Translation < Base
6
+
7
+ ## fields ##
8
+ field :key
9
+ field :values
10
+
11
+ ## methods ##
12
+
13
+ def get(locale)
14
+ self.values[locale.to_s]
15
+ end
16
+
17
+ def to_params
18
+ { key: self.key, values: self.values }
19
+ end
20
+
21
+ def to_s
22
+ "Translation #{self.key} (#{self.values.keys.join(', ')})"
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,65 @@
1
+ module Locomotive
2
+ module Mounter
3
+
4
+ class MountingPoint
5
+
6
+ attr_accessor :resources, :root_page, :path
7
+
8
+ # attr_reader :sprockets
9
+
10
+ # Initializes Sprockets once the path is set
11
+ def path= dir
12
+ @path = dir
13
+
14
+ # @sprockets = Locomotive::Mounter::Extensions::Sprockets.environment
15
+ # %w(fonts stylesheets javascripts).each do |name|
16
+ # @sprockets.append_path File.join(dir, 'public', name)
17
+ # end
18
+ end
19
+
20
+ # Return all the locales defined by the site related to that mounting point.
21
+ #
22
+ # @return [ Array ] The list of the locales
23
+ #
24
+ def locales
25
+ self.site.locales || []
26
+ end
27
+
28
+ # Return the default locale which is the first locale defined for a site.
29
+ # If none, then use the current I18n locale.
30
+ #
31
+ # @return [ Symbol ] The default locale
32
+ #
33
+ def default_locale
34
+ (self.locales.first || Locomotive::Mounter.locale).to_sym
35
+ end
36
+
37
+ # Register a resource (site, pages, content types, ...etc) and its elements.
38
+ # It makes sure that all the elements get a pointer to that mounting point.
39
+ # The elements can be either an array, hash or even a single object (ex: site).
40
+ # For instance, for a page, it will be a hash whose key is the fullpath.
41
+ #
42
+ # @param [ Symbol ] name Name of the resource
43
+ # @param [ Object ] elements Element(s) related to the resource
44
+ #
45
+ def register_resource(name, elements)
46
+ self.resources ||= {}
47
+
48
+ (elements.respond_to?(:values) ? elements.values : [*elements]).each do |element|
49
+ element.mounting_point = self
50
+ end
51
+
52
+ self.resources[name.to_sym] = elements
53
+ end
54
+
55
+ def method_missing(name, *args, &block)
56
+ (self.resources || {})[name.to_sym] || super
57
+ end
58
+
59
+ def inspect
60
+ "[MountingPoint] #{(self.resources || {}).keys.inspect}"
61
+ end
62
+
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,64 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Reader
4
+ module Api
5
+
6
+ # Build a singleton instance of the Runner class.
7
+ #
8
+ # @return [ Object ] A singleton instance of the Runner class
9
+ #
10
+ def self.instance
11
+ @@instance ||= Runner.new(:api)
12
+ end
13
+
14
+ def self.teardown
15
+ @@instance = nil
16
+ end
17
+
18
+ class Runner < Locomotive::Mounter::Reader::Runner
19
+
20
+ attr_accessor :uri
21
+
22
+ # Call the LocomotiveCMS engine to get a token for
23
+ # the next API calls
24
+ def prepare
25
+ credentials = self.parameters.select { |k, _| %w(uri email password api_key).include?(k.to_s) }
26
+ self.uri = credentials[:uri]
27
+
28
+ begin
29
+ Locomotive::Mounter::EngineApi.set_token(credentials)
30
+ rescue Exception => e
31
+ raise Locomotive::Mounter::ReaderException.new("unable to get an API token: #{e.message}")
32
+ end
33
+ end
34
+
35
+ # Ordered list of atomic readers
36
+ #
37
+ # @return [ Array ] List of classes
38
+ #
39
+ def readers
40
+ [SiteReader, ContentAssetsReader, SnippetsReader, ContentTypesReader, ContentEntriesReader, PagesReader, ThemeAssetsReader, TranslationsReader]
41
+ end
42
+
43
+ # Return the uri with the scheme (http:// or https://)
44
+ #
45
+ # @return [ String ] The uri starting by http:// or https://
46
+ #
47
+ def uri_with_scheme
48
+ self.uri =~ /^http/ ? self.uri : "http://#{self.uri}"
49
+ end
50
+
51
+ # Return the base uri with the scheme ((http:// or https://)) and without the path (/locomotive/...)
52
+ #
53
+ # @return [ String ] The uri starting by http:// or https:// and without the path
54
+ #
55
+ def base_uri_with_scheme
56
+ self.uri_with_scheme.to_s[/^https?:\/\/[^\/]+/] || self.uri_with_scheme
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,67 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Reader
4
+ module Api
5
+
6
+ class Base
7
+
8
+ include Locomotive::Mounter::Utils::Output
9
+
10
+ attr_accessor :runner, :items
11
+
12
+ delegate :uri, :uri_with_scheme, :base_uri_with_scheme, to: :runner
13
+ delegate :locales, to: :mounting_point
14
+
15
+ def initialize(runner)
16
+ self.runner = runner
17
+ self.items = {}
18
+ end
19
+
20
+ def mounting_point
21
+ self.runner.mounting_point
22
+ end
23
+
24
+ def read
25
+ self.output_title(:pulling)
26
+ end
27
+
28
+ def get(resource_name, locale = nil, dont_filter_attributes = false)
29
+ attribute_names = dont_filter_attributes ? nil : self.safe_attributes
30
+
31
+ begin
32
+ Locomotive::Mounter::EngineApi.fetch(resource_name, {}, locale, attribute_names)
33
+ rescue ApiReadException => e
34
+ raise ReaderException.new(e.message)
35
+ end
36
+ end
37
+
38
+ # Build a new content asset from an url and a folder and add it
39
+ # to the global list of the content assets.
40
+ #
41
+ # @param [ String ] url The url of the content asset.
42
+ # @param [ String ] folder The folder of the content asset (optional).
43
+ #
44
+ # @return [ String ] The local path (not absolute) of the content asset.
45
+ #
46
+ def add_content_asset(url, folder = nil)
47
+ content_assets = self.mounting_point.resources[:content_assets]
48
+
49
+ if (url =~ /^https?:\/\//).nil?
50
+ url = URI.join(self.uri_with_scheme, url)
51
+ else
52
+ url = URI(url)
53
+ end
54
+
55
+ asset = Locomotive::Mounter::Models::ContentAsset.new(uri: url, folder: folder)
56
+
57
+ content_assets[url.path] = asset
58
+
59
+ asset.local_filepath
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+ end
66
+ end
67
+ end