mirror of
https://github.com/discourse/discourse.git
synced 2025-06-06 11:54:41 +08:00
116 lines
3.3 KiB
Ruby
116 lines
3.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class ExtraLocalesController < ApplicationController
|
|
layout false
|
|
|
|
skip_before_action :check_xhr,
|
|
:preload_json,
|
|
:redirect_to_login_if_required,
|
|
:redirect_to_profile_if_required,
|
|
:verify_authenticity_token
|
|
|
|
OVERRIDES_BUNDLE = "overrides"
|
|
SHA1_HASH_LENGTH = 40
|
|
MF_BUNDLE = "mf"
|
|
ADMIN_BUNDLE = "admin"
|
|
WIZARD_BUNDLE = "wizard"
|
|
|
|
SITE_SPECIFIC_BUNDLES = [OVERRIDES_BUNDLE, MF_BUNDLE]
|
|
SHARED_BUNDLES = [ADMIN_BUNDLE, WIZARD_BUNDLE]
|
|
|
|
class << self
|
|
def js_digests
|
|
@js_digests ||= { site_specific: {}, shared: {} }
|
|
end
|
|
|
|
def bundle_js_hash(bundle, locale:)
|
|
bundle_key = "#{bundle}_#{locale}"
|
|
if bundle.in?(SITE_SPECIFIC_BUNDLES)
|
|
site = RailsMultisite::ConnectionManagement.current_db
|
|
|
|
js_digests[:site_specific][site] ||= {}
|
|
js_digests[:site_specific][site][bundle_key] ||= begin
|
|
js = bundle_js(bundle, locale: locale)
|
|
js.present? ? digest_for_content(js) : nil
|
|
end
|
|
elsif bundle.in?(SHARED_BUNDLES)
|
|
js_digests[:shared][bundle_key] ||= digest_for_content(bundle_js(bundle, locale: locale))
|
|
else
|
|
raise "Unknown bundle: #{bundle}"
|
|
end
|
|
end
|
|
|
|
def url(bundle, locale: I18n.locale)
|
|
hash = bundle_js_hash(bundle, locale:)
|
|
|
|
base = "#{GlobalSetting.cdn_url}#{Discourse.base_path}"
|
|
path = "/extra-locales/#{hash}/#{locale}/#{bundle}.js"
|
|
query = SITE_SPECIFIC_BUNDLES.include?(bundle) ? "?__ws=#{Discourse.current_hostname}" : ""
|
|
"#{base}#{path}#{query}"
|
|
end
|
|
|
|
def client_overrides_exist?(locale: I18n.locale)
|
|
bundle_js_hash(OVERRIDES_BUNDLE, locale: locale).present?
|
|
end
|
|
|
|
def bundle_js(bundle, locale:)
|
|
locale_str = locale.to_s
|
|
bundle_str = "#{bundle}_js"
|
|
|
|
I18n.with_locale(locale) do
|
|
case bundle
|
|
when OVERRIDES_BUNDLE
|
|
JsLocaleHelper.output_client_overrides(locale_str)
|
|
when MF_BUNDLE
|
|
JsLocaleHelper.output_MF(locale_str)
|
|
else
|
|
JsLocaleHelper.output_extra_locales(bundle_str, locale_str)
|
|
end
|
|
end
|
|
end
|
|
|
|
def bundle_js_with_hash(bundle, locale:)
|
|
js = bundle_js(bundle, locale: locale)
|
|
[js, digest_for_content(js)]
|
|
end
|
|
|
|
def clear_cache!(all_sites: false)
|
|
site = RailsMultisite::ConnectionManagement.current_db
|
|
if all_sites
|
|
js_digests[:site_specific].clear
|
|
js_digests[:shared].clear
|
|
else
|
|
js_digests[:site_specific].delete(site)
|
|
end
|
|
end
|
|
|
|
def digest_for_content(js)
|
|
Digest::SHA1.hexdigest(js)
|
|
end
|
|
end
|
|
|
|
def show
|
|
bundle = params[:bundle]
|
|
raise Discourse::NotFound if !valid_bundle?(bundle)
|
|
|
|
locale = params[:locale]
|
|
raise Discourse::NotFound if !I18n.available_locales.include?(locale.to_sym)
|
|
|
|
digest = params[:digest]
|
|
if digest.present?
|
|
raise Discourse::InvalidParameters.new(:digest) unless digest.to_s.size == SHA1_HASH_LENGTH
|
|
end
|
|
|
|
content, hash = ExtraLocalesController.bundle_js_with_hash(bundle, locale:)
|
|
immutable_for(1.year) if hash == digest
|
|
|
|
render plain: content, content_type: "application/javascript"
|
|
end
|
|
|
|
private
|
|
|
|
def valid_bundle?(bundle)
|
|
bundle.in?(SITE_SPECIFIC_BUNDLES) || bundle.in?(SHARED_BUNDLES)
|
|
end
|
|
end
|