FEATURE: Import and export themes in a .tar.gz format (#6916)

This commit is contained in:
David Taylor
2019-01-23 14:40:21 +00:00
committed by GitHub
parent d0129b85f4
commit afd449089f
18 changed files with 431 additions and 133 deletions

View File

@ -4,6 +4,8 @@ require_dependency 'upload_creator'
class RemoteTheme < ActiveRecord::Base
class ImportError < StandardError; end
ALLOWED_FIELDS = %w{scss embedded_scss head_tag header after_header body_tag footer}
GITHUB_REGEXP = /^https?:\/\/github\.com\//
@ -14,15 +16,22 @@ class RemoteTheme < ActiveRecord::Base
joins("JOIN themes ON themes.remote_theme_id = remote_themes.id").where.not(remote_url: "")
}
def self.update_tgz_theme(filename, user: Discourse.system_user)
def self.extract_theme_info(importer)
JSON.parse(importer["about.json"])
rescue TypeError, JSON::ParserError
raise ImportError.new I18n.t("themes.import_error.about_json")
end
def self.update_tgz_theme(filename, match_theme: false, user: Discourse.system_user)
importer = ThemeStore::TgzImporter.new(filename)
importer.import!
theme_info = JSON.parse(importer["about.json"])
theme = Theme.find_by(name: theme_info["name"])
theme_info = RemoteTheme.extract_theme_info(importer)
theme = Theme.find_by(name: theme_info["name"]) if match_theme
theme ||= Theme.new(user_id: user&.id || -1, name: theme_info["name"])
theme.component = theme_info["component"].to_s == "true"
remote_theme = new
remote_theme.theme = theme
remote_theme.remote_url = ""
@ -42,7 +51,7 @@ class RemoteTheme < ActiveRecord::Base
importer = ThemeStore::GitImporter.new(url.strip, private_key: private_key, branch: branch)
importer.import!
theme_info = JSON.parse(importer["about.json"])
theme_info = RemoteTheme.extract_theme_info(importer)
component = [true, "true"].include?(theme_info["component"])
theme = Theme.new(user_id: user&.id || -1, name: theme_info["name"], component: component)
@ -74,10 +83,11 @@ class RemoteTheme < ActiveRecord::Base
end
def update_remote_version
return unless is_git?
importer = ThemeStore::GitImporter.new(remote_url, private_key: private_key, branch: branch)
begin
importer.import!
rescue ThemeStore::GitImporter::ImportFailed => err
rescue RemoteTheme::ImportError => err
self.last_error_text = err.message
else
self.updated_at = Time.zone.now
@ -87,7 +97,6 @@ class RemoteTheme < ActiveRecord::Base
end
def update_from_remote(importer = nil, skip_update: false)
return unless remote_url
cleanup = false
unless importer
@ -95,7 +104,7 @@ class RemoteTheme < ActiveRecord::Base
importer = ThemeStore::GitImporter.new(remote_url, private_key: private_key, branch: branch)
begin
importer.import!
rescue ThemeStore::GitImporter::ImportFailed => err
rescue RemoteTheme::ImportError => err
self.last_error_text = err.message
return self
else
@ -103,7 +112,7 @@ class RemoteTheme < ActiveRecord::Base
end
end
theme_info = JSON.parse(importer["about.json"])
theme_info = RemoteTheme.extract_theme_info(importer)
theme_info["assets"]&.each do |name, relative_path|
if path = importer.real_path(relative_path)
@ -114,34 +123,15 @@ class RemoteTheme < ActiveRecord::Base
end
end
Theme.targets.keys.each do |target|
next if target == :settings || target == :translations
ALLOWED_FIELDS.each do |field|
lookup =
if field == "scss"
"#{target}.scss"
elsif field == "embedded_scss" && target == :common
"embedded.scss"
else
"#{field}.html"
end
value = importer["#{target}/#{lookup}"]
theme.set_field(target: target.to_sym, name: field, value: value)
end
end
settings_yaml = importer["settings.yaml"] || importer["settings.yml"]
theme.set_field(target: :settings, name: "yaml", value: settings_yaml)
I18n.available_locales.each do |locale|
value = importer["locales/#{locale}.yml"]
theme.set_field(target: :translations, name: locale, value: value)
end
self.license_url = theme_info["license_url"]
self.about_url = theme_info["about_url"]
importer.all_files.each do |filename|
next unless opts = ThemeField.opts_from_file_path(filename)
value = importer[filename]
theme.set_field(opts.merge(value: value))
end
if !skip_update
self.remote_updated_at = Time.zone.now
self.remote_version = importer.version
@ -214,6 +204,10 @@ class RemoteTheme < ActiveRecord::Base
"https://github.com/#{org_repo}"
end
end
def is_git?
remote_url.present?
end
end
# == Schema Information