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']

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_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



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

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

.find_theme_root(file) ⇒ Object



239
240
241
242
243
244
245
246
247
248
249
250
# File 'app/models/theme.rb', line 239

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



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

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



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

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.create(:name => theme_name, :theme_id => theme_id, :website => website).tap do |theme|
    theme.import(file)
  end
end

.import_download_item(tempfile, website) ⇒ Object



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

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



99
100
101
102
103
# File 'app/models/theme.rb', line 99

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



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

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

.root_in_path(path) ⇒ Object



252
253
254
255
256
257
258
259
260
261
262
263
# File 'app/models/theme.rb', line 252

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



265
266
267
# File 'app/models/theme.rb', line 265

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

.valid_theme?(file) ⇒ Boolean

Returns:

  • (Boolean)


105
106
107
108
109
110
111
112
113
114
115
# File 'app/models/theme.rb', line 105

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



167
168
169
170
171
172
# File 'app/models/theme.rb', line 167

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

#activate!Object



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

def activate!
  update_attributes! :active => true
end

#create_layouts_for_widget(widget) ⇒ Object



160
161
162
163
164
165
# File 'app/models/theme.rb', line 160

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



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

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)
end

#deactivate!Object



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

def deactivate!
  update_attributes! :active => false
end

#delete_theme_files!Object



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

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



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'app/models/theme.rb', line 214

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)


234
235
236
# File 'app/models/theme.rb', line 234

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



174
175
176
177
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
# File 'app/models/theme.rb', line 174

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
        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

#import_download_item_file(file) ⇒ Object



20
21
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
# File 'app/models/theme.rb', line 20

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



153
154
155
156
157
158
# File 'app/models/theme.rb', line 153

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



131
132
133
# File 'app/models/theme.rb', line 131

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

#should_generate_new_friendly_id?Boolean

Returns:

  • (Boolean)


122
123
124
# File 'app/models/theme.rb', line 122

def should_generate_new_friendly_id?
  new_record?
end

#themed_widgetsObject



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

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



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

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