Class: Theme

Inherits:
ActiveRecord::Base
  • Object
show all
Extended by:
FriendlyId
Defined in:
app/models/theme.rb

Constant Summary collapse

THEME_STRUCTURE =
['stylesheets', 'javascripts', 'images', 'templates', 'fonts']

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Attribute Details

.base_layouts_views_pathObject

Returns the value of attribute base_layouts_views_path.



9
10
11
# File 'app/models/theme.rb', line 9

def base_layouts_views_path
  @base_layouts_views_path
end

.knitkit_website_fonts_pathObject

Returns the value of attribute knitkit_website_fonts_path.



9
10
11
# File 'app/models/theme.rb', line 9

def knitkit_website_fonts_path
  @knitkit_website_fonts_path
end

.knitkit_website_images_pathObject

Returns the value of attribute knitkit_website_images_path.



9
10
11
# File 'app/models/theme.rb', line 9

def knitkit_website_images_path
  @knitkit_website_images_path
end

.knitkit_website_javascripts_pathObject

Returns the value of attribute knitkit_website_javascripts_path.



9
10
11
# File 'app/models/theme.rb', line 9

def knitkit_website_javascripts_path
  @knitkit_website_javascripts_path
end

.knitkit_website_stylesheets_pathObject

Returns the value of attribute knitkit_website_stylesheets_path.



9
10
11
# File 'app/models/theme.rb', line 9

def knitkit_website_stylesheets_path
  @knitkit_website_stylesheets_path
end

Class Method Details

.base_dir(website) ⇒ Object



86
87
88
# File 'app/models/theme.rb', line 86

def base_dir(website)
  "#{root_dir}/sites/#{website.iid}/themes"
end

.find_theme_root(file) ⇒ Object



245
246
247
248
249
250
251
252
253
254
255
256
# File 'app/models/theme.rb', line 245

def find_theme_root(file)
  theme_root = ''
  Zip::ZipFile.open(file.path) do |zip|
    zip.each do |entry|
      entry.name.sub!(/__MACOSX\//, '')
      if theme_root = root_in_path(entry.name)
        break
      end
    end
  end
  theme_root
end

.find_theme_root_from_file(file) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
# File 'app/models/theme.rb', line 68

def find_theme_root_from_file(file)
  theme_root = ''
  Zip::ZipFile.open(file) do |zip|
    zip.each do |entry|
      entry.name.sub!(/__MACOSX\//, '')
      if theme_root == root_in_path(entry.name)
        break
      end
    end
  end
  theme_root
end

.import(file, website) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
# File 'app/models/theme.rb', line 90

def import(file, website)
  name_and_id = file.original_filename.to_s.gsub(/(^.*(\\|\/))|(\.zip$)/, '')
  theme_name = name_and_id.split('[').first
  theme_id = name_and_id.split('[').last.gsub(']', '')
  return false unless valid_theme?(file)
  theme = Theme.create(:name => theme_name, :theme_id => theme_id, :website => website).tap do |theme|
    theme.import(file)
  end

  theme
end

.import_download_item(tempfile, website) ⇒ Object



58
59
60
61
62
63
64
65
# File 'app/models/theme.rb', line 58

def import_download_item(tempfile, website)
  name_and_id = tempfile.gsub(/(^.*(\\|\/))|(\.zip$)/, '')
  theme_name = name_and_id.split('[').first
  theme_id = name_and_id.split('[').last.gsub(']', '')
  Theme.create(:name => theme_name.sub(/-theme/, ''), :theme_id => theme_id, :website_id => website.id).tap do |theme|
    theme.import_download_item_file(tempfile)
  end
end

.make_tmp_dirObject



102
103
104
105
106
# File 'app/models/theme.rb', line 102

def make_tmp_dir
  Pathname.new(Rails.root.to_s + "/tmp/themes/tmp_#{Time.now.to_i.to_s}/").tap do |dir|
    FileUtils.mkdir_p(dir) unless dir.exist?
  end
end

.root_dirObject



82
83
84
# File 'app/models/theme.rb', line 82

def root_dir
  @@root_dir ||= "#{Rails.root}/public"
end

.root_in_path(path) ⇒ Object



258
259
260
261
262
263
264
265
266
267
268
269
# File 'app/models/theme.rb', line 258

def root_in_path(path)
  root_found = false
  theme_root = ''
  path.split('/').each do |piece|
    if piece == 'about.yml' || THEME_STRUCTURE.include?(piece)
      root_found = true
    else
      theme_root += piece + '/' if !piece.match('\.') && !root_found
    end
  end
  root_found ? theme_root : false
end

.strip_path(file_name, path) ⇒ Object



271
272
273
# File 'app/models/theme.rb', line 271

def strip_path(file_name, path)
  file_name.sub(path, '')
end

.valid_theme?(file) ⇒ Boolean

Returns:

  • (Boolean)


108
109
110
111
112
113
114
115
116
117
118
# File 'app/models/theme.rb', line 108

def valid_theme?(file)
  valid = false
  Zip::ZipFile.open(file.path) do |zip|
    zip.sort.each do |entry|
      entry.name.split('/').each do |file|
        valid = true if THEME_STRUCTURE.include?(file)
      end
    end
  end
  valid
end

Instance Method Details

#aboutObject



171
172
173
174
175
176
# File 'app/models/theme.rb', line 171

def about
  %w(name author version homepage summary).inject({}) do |result, key|
    result[key] = send(key)
    result
  end
end

#activate!Object



143
144
145
# File 'app/models/theme.rb', line 143

def activate!
  update_attributes! :active => true
end

#create_layouts_for_widget(widget) ⇒ Object



164
165
166
167
168
169
# File 'app/models/theme.rb', line 164

def create_layouts_for_widget(widget)
  widget_hash = Rails.application.config.erp_app.widgets.find { |item| item[:name] == widget }
  widget_hash[:view_files].each do |view_file|
    save_theme_file(view_file[:path], :widgets, {:path_to_replace => view_file[:path].split('/views')[0], :widget_name => widget})
  end
end

#create_theme_files!Object



281
282
283
284
285
286
287
288
# File 'app/models/theme.rb', line 281

def create_theme_files!
  file_support = ErpTechSvcs::FileSupport::Base.new
  create_theme_files_for_directory_node(file_support.build_tree(Theme.base_layouts_views_path, :preload => true), :templates, :path_to_replace => Theme.base_layouts_views_path)
  create_theme_files_for_directory_node(file_support.build_tree(Theme.knitkit_website_stylesheets_path, :preload => true), :stylesheets, :path_to_replace => Theme.knitkit_website_stylesheets_path)
  create_theme_files_for_directory_node(file_support.build_tree(Theme.knitkit_website_javascripts_path, :preload => true), :javascripts, :path_to_replace => Theme.knitkit_website_javascripts_path)
  create_theme_files_for_directory_node(file_support.build_tree(Theme.knitkit_website_images_path, :preload => true), :images, :path_to_replace => Theme.knitkit_website_images_path)
  create_theme_files_for_directory_node(file_support.build_tree(Theme.knitkit_website_fonts_path, :preload => true), :fonts, :path_to_replace => Theme.knitkit_website_fonts_path)
end

#deactivate!Object



147
148
149
# File 'app/models/theme.rb', line 147

def deactivate!
  update_attributes! :active => false
end

#delete_theme_files!Object



276
277
278
279
# File 'app/models/theme.rb', line 276

def delete_theme_files!
  file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::Config.file_storage)
  file_support.delete_file(File.join(file_support.root, self.url), :force => true)
end

#exportObject



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'app/models/theme.rb', line 220

def export
  file_support = ErpTechSvcs::FileSupport::Base.new(:storage => Rails.application.config.erp_tech_svcs.file_storage)
  tmp_dir = Theme.make_tmp_dir
  (tmp_dir + "#{name}[#{theme_id}].zip").tap do |file_name|
    file_name.unlink if file_name.exist?
    Zip::ZipFile.open(file_name.to_s, Zip::ZipFile::CREATE) do |zip|
      files.each { |file|
        contents = file_support.get_contents(File.join(file_support.root, file.directory, file.name))
        relative_path = file.directory.sub("#{url}", '')
        path = FileUtils.mkdir_p(File.join(tmp_dir, relative_path))
        full_path = File.join(path, file.name)
        File.open(full_path, 'wb+') { |f| f.puts(contents) }
        zip.add(File.join(relative_path[1..relative_path.length], file.name), full_path) if ::File.exists?(full_path)
      }
      ::File.open(tmp_dir + 'about.yml', 'wb+') { |f| f.puts(about.to_yaml) }
      zip.add('about.yml', tmp_dir + 'about.yml')
    end
  end
end

#has_template?(directory, name) ⇒ Boolean

Returns:

  • (Boolean)


240
241
242
# File 'app/models/theme.rb', line 240

def has_template?(directory, name)
  self.templates.find { |item| item.directory == File.join(path, directory).gsub(Rails.root.to_s, '') and item.name == name }
end

#import(file) ⇒ Object



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'app/models/theme.rb', line 178

def import(file)
  file_support = ErpTechSvcs::FileSupport::Base.new(:storage => Rails.application.config.erp_tech_svcs.file_storage)
  file = ActionController::UploadedTempfile.new("uploaded-theme").tap do |f|
    f.puts file.read
    f.original_filename = file.original_filename
    f.read # no idea why we need this here, otherwise the zip can't be opened

  end unless file.path

  theme_root = Theme.find_theme_root(file)

  Zip::ZipFile.open(file.path) do |zip|
    zip.each do |entry|
      if entry.name == 'about.yml'
        data = ''
        entry.get_input_stream { |io| data = io.read }
        data = StringIO.new(data) if data.present?
        about = YAML.load(data)
        self.author = about['author'] if about['author']
        self.version = about['version'] if about['version']
        self.homepage = about['homepage'] if about['homepage']
        self.summary = about['summary'] if about['summary']
      else
        if entry.file?
          name = entry.name.sub(/__MACOSX\//, '')
          name = Theme.strip_path(name, theme_root)
          data = ''
          entry.get_input_stream { |io| data = io.read }
          data = StringIO.new(data) if data.present?
          theme_file = self.files.where("name = ? and directory = ?", File.basename(name), File.join(self.url, File.dirname(name))).first
          unless theme_file.nil?
            theme_file.data = data
            theme_file.save
          else
            self.add_file(data, File.join(file_support.root, self.url, name)) rescue next
          end
        end
      end
    end
  end

end

#import_download_item_file(file) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'app/models/theme.rb', line 22

def import_download_item_file(file)
  file_support = ErpTechSvcs::FileSupport::Base.new(:storage => Rails.application.config.erp_tech_svcs.file_storage)

  theme_root = Theme.find_theme_root_from_file(file)

  Zip::ZipFile.open(file) do |zip|
    zip.each do |entry|
      if entry.name == 'about.yml'
        data = ''
        entry.get_input_stream { |io| data = io.read }
        data = StringIO.new(data) if data.present?
        about = YAML.load(data)
        self.author = about['author'] if about['author']
        self.version = about['version'] if about['version']
        self.homepage = about['homepage'] if about['homepage']
        self.summary = about['summary'] if about['summary']
      else
        name = entry.name.sub(/__MACOSX\//, '')
        name = Theme.strip_path(name, theme_root)
        data = ''
        entry.get_input_stream { |io| data = io.read }
        data = StringIO.new(data) if data.present?
        theme_file = self.files.where("name = ? and directory = ?", File.basename(name), File.join(self.url, File.dirname(name))).first
        unless theme_file.nil?
          theme_file.data = data
          theme_file.save
        else
          self.add_file(data, File.join(file_support.root, self.url, name)) rescue next
        end
      end
    end
  end
  activate!
end

#non_themed_widgetsObject



157
158
159
160
161
162
# File 'app/models/theme.rb', line 157

def non_themed_widgets
  already_themed_widgets = self.themed_widgets
  Rails.application.config.erp_app.widgets.select do |widget_hash|
    !already_themed_widgets.include?(widget_hash[:name])
  end.collect { |item| item[:name] }
end

#pathObject



135
136
137
# File 'app/models/theme.rb', line 135

def path
  "#{self.class.base_dir(website)}/#{theme_id}"
end

#should_generate_new_friendly_id?Boolean

Returns:

  • (Boolean)


126
127
128
# File 'app/models/theme.rb', line 126

def should_generate_new_friendly_id?
  new_record?
end

#themed_widgetsObject



151
152
153
154
155
# File 'app/models/theme.rb', line 151

def themed_widgets
  Rails.application.config.erp_app.widgets.select do |widget_hash|
    !(self.files.where("directory like '#{File.join(self.url, 'widgets', widget_hash[:name])}%'").all.empty?)
  end.collect { |item| item[:name] }
end

#urlObject



139
140
141
# File 'app/models/theme.rb', line 139

def url
  "/public/sites/#{website.iid}/themes/#{theme_id}"
end