class MagLove::Commands::Theme

Public Instance Methods

create() click to toggle source
# File lib/maglove/commands/theme.rb, line 176
def create
  info("▸ Creating new theme '#{theme.identifier}'")

  error!("Missing yaml config 'name'") unless theme.name
  error!("Missing yaml config 'base_version'") unless theme.base_version
  typeloft_theme = magloft_api.typeloft_themes.find_by_identifier(theme.identifier)
  error!("This theme already exists") unless typeloft_theme.nil?
  magloft_api.typeloft_themes.create(identifier: theme.identifier, name: theme.name, description: theme.description, base_version: theme.base_version)
  info("▸ Theme successfully created!")
end
delete() click to toggle source
# File lib/maglove/commands/theme.rb, line 190
def delete
  info("▸ Deleting theme '#{theme.identifier}'")
  typeloft_theme = magloft_api.typeloft_themes.find_by_identifier(theme.identifier)
  error!("Could not find a theme with identifier '#{theme.identifier}'") if typeloft_theme.nil?
  typeloft_theme.destroy
  info("▸ Theme successfully deleted!")
end
list() click to toggle source
# File lib/maglove/commands/theme.rb, line 200
def list
  info("▸ Listing themes")
  magloft_api.typeloft_themes.all.each do |typeloft_theme|
    info("~> #{typeloft_theme.identifier} (NAME: #{typeloft_theme.name}, ACTIVE: #{typeloft_theme.active ? 'YES' : 'NO'})")
  end
end
push() click to toggle source
# File lib/maglove/commands/theme.rb, line 42
def push
  info("▸ Pushing theme '#{theme.identifier}' to MagLoft")

  # validate theme
  error!("Theme '#{theme.identifier}' not found") unless theme.identifier
  begin
    typeloft_theme = magloft_api.typeloft_themes.find_by_identifier(theme.identifier)
  rescue MagLoft::ApiCaller::UnauthorizedError
    error!("▸ You are not allowed to access the MagLoft API.")
  end
  if typeloft_theme.nil?
    info("▸ To create a new theme, run: maglove theme:create --theme '#{theme.identifier}'")
    error!("Theme '#{theme.identifier}' was not yet created.")
  end

  # invoke asset compilation
  invoke(Fonts, :compile, [], {})
  invoke(Assets, :compile, [], { theme: theme.identifier })
  invoke(Assets, :compress, [], { theme: theme.identifier })

  # update theme
  info("▸ Synchronizing Metadata")
  typeloft_theme.base_version = theme.base_version
  typeloft_theme.name = theme.name
  typeloft_theme.description = theme.description
  typeloft_theme.widgets = theme.widgets
  typeloft_theme.fonts = theme.fonts
  typeloft_theme.save

  # upload blocks
  info("▸ Synchronizing Blocks")
  theme_blocks = typeloft_theme.typeloft_blocks.all
  theme_blocks_map = Hash[theme_blocks.map { |block| [block.identifier, block] }]
  if theme.src_dir.dir("blocks").exists?
    block_files = theme.src_dir.dir("blocks").children("**/*.haml")
    block_files.each do |block_file|
      block_identifier = block_file.basename
      if (block = theme_blocks_map[block_identifier])
        block.name = block_file.basename.titlecase
        block.contents = block_file.read
        block.contents.length
        if block.changed?
          info "▸ Updating Block '#{block_identifier}'"
          block.save
        end
      else
        info "▸ Creating Block '#{block_identifier}'"
        typeloft_theme.typeloft_blocks.create(identifier: block_identifier, name: block_file.basename.titlecase, contents: block_file.read)
      end
    end
  end

  # upload images
  info("▸ Synchronizing Images")
  theme_images = typeloft_theme.typeloft_images.all
  theme_images_map = Hash[theme_images.map { |image| [image.remote_file, image] }]
  hydra = Typhoeus::Hydra.new
  theme.dist_dir.children("images/**/*.{jpg,png,gif,svg}").each do |image_file|
    remote_file = "themes/#{theme.identifier}/#{image_file.relative_path}"
    image_file_md5 = Digest::MD5.hexdigest(image_file.read)
    if (existing_image = theme_images_map[remote_file])
      if image_file_md5 != existing_image.md5
        info("▸ Updating Image '#{remote_file}'")
        existing_image.md5 = image_file_md5
        hydra.queue(existing_image.queue_upload(image_file.to_s) { debug("▸ Finished updating Image '#{remote_file}'") })
        existing_image.save
      end
    else
      info("▸ Creating Image '#{remote_file}'")
      new_image = typeloft_theme.typeloft_images.create(remote_file: remote_file, title: image_file.basename.titlecase, md5: image_file_md5)
      hydra.queue(new_image.queue_upload(image_file.to_s) { info("▸ Finished creating Image '#{remote_file}'") })
    end
  end
  hydra.run

  # upload css/js
  info("▸ Synchronizing JavaScript")
  typeloft_theme.upload_javascript(theme.dist_dir.file("theme.js").to_s)
  info("▸ Synchronizing Stylesheet")
  typeloft_theme.upload_stylesheet(theme.dist_dir.file("theme.css").to_s)

  # upload templates
  info("▸ Synchronizing Templates")
  theme_templates = typeloft_theme.typeloft_templates.all
  theme_templates_map = Hash[theme_templates.map { |template| [template.identifier, template] }]
  templates = theme.templates
  templates.each_with_index do |template_identifier, position|
    template_file = theme.src_dir.file("templates/#{template_identifier}.haml")
    next unless !template_file.nil? and template_file.exists?
    if (template = theme_templates_map[template_identifier])
      template.title = template_identifier.titlecase
      template.contents = template_file.read
      template.position = position
      if template.changed?
        info "▸ Updating Template '#{template_identifier}'"
        template.save
      end
    else
      info "▸ Creating Template '#{template_identifier}'"
      typeloft_theme.typeloft_templates.create(identifier: template_identifier, title: template_identifier.titlecase, contents: template_file.read, position: position)
    end
  end

  # update thumbnails
  if options.thumbnails
    invoke(:thumbnails, [], { theme: theme.identifier })
    hydra = Typhoeus::Hydra.new

    info("▸ Synchronizing Template Thumbnails")
    typeloft_theme.typeloft_templates.all.each do |template|
      thumbnail_file = theme.dist_dir.dir("templates").file("#{template.identifier}.png")
      if thumbnail_file.exists?
        info("~> Uploading Thumbnail for '#{template.identifier}'")
        hydra.queue(template.queue_upload_thumbnail(thumbnail_file.to_s) { info("▸ Finished uploading Thumbnail for '#{template.identifier}'") })
      end
    end

    info("▸ Synchronizing Block Thumbnails")
    typeloft_theme.typeloft_blocks.all.each do |block|
      thumbnail_file = theme.dist_dir.dir("blocks").file("#{block.identifier}.png")
      if thumbnail_file.exists?
        info("~> Uploading Thumbnail for '#{block.identifier}'")
        hydra.queue(block.queue_upload_thumbnail(thumbnail_file.to_s) { info("▸ Finished uploading Thumbnail for '#{block.identifier}'") })
      end
    end
    hydra.run
  end

  info("▸ Successfully Pushed Theme")
end
server() click to toggle source
# File lib/maglove/commands/theme.rb, line 7
def server
  invoke(Assets, :compile, [], { theme: theme.identifier })
  invoke(Fonts, :compile, [], {})
  info("▸ starting server for theme '#{theme.identifier}' on '127.0.0.1:#{options.port}'")
  require 'maglove/server'
  MagLove::Server.start(options.port, theme.identifier, theme.templates)
end
thumbnails() click to toggle source
# File lib/maglove/commands/theme.rb, line 17
def thumbnails
  require "powersnap"
  invoke(Fonts, :compile, [], {})
  invoke(Assets, :compile, [], theme: theme.identifier)

  info("▸ Generating Template Thumbnails")
  output_dir = theme.dist_dir.dir("templates")
  urls = output_dir.children("*.html").map { |file| "file://#{file.absolute_path}" }
  powersnap = Powersnap.new(urls)
  response = powersnap.generate(dir: output_dir.to_s, width: 768, height: 1024, pattern: "{basename}.png", zoom: 1.0, page: false)
  error!("Error generating thumbnails. Make sure npm module 'powersnap' is installed globally") if response["status"] != "success"

  info("▸ Generating Block Thumbnails")
  output_dir = theme.dist_dir.dir("blocks")
  if output_dir.exists?
    urls = output_dir.children("*.html").map { |file| "file://#{file.absolute_path}" }
    powersnap = Powersnap.new(urls)
    powersnap.generate(dir: output_dir.to_s, width: 512, height: 200, pattern: "{basename}.png", zoom: 1.0, page: true)
  end
end