포럼 한국어 번역 플러그인을 복구하고 배포 검사를 보강
비어 있던 운영 플러그인 경로를 전용 서비스 원본으로 복구했다. 음성 입장 안내와 주변 메뉴 및 관리자 번역을 실제 화면에서 확인했다. 관리자 주소용 내부 이름을 보존하고 보드 메뉴 두 곳의 제목을 복구했다. 검사: Ruby 문법과 YAML 11개 통과. 활성 번역 6004개와 음성 번역 561개 누락 0개. 일반 화면과 관리자 번역 및 보드 자산의 제공 해시를 확인했다. PC와 390픽셀 모바일 안내창 및 관리자 메뉴 주소를 확인했다. 운영: app 컨테이너만 갱신. DB 구조 변경과 데이터 이전 없음. 백업: /var/discourse/shared/standalone/backups/forum-korean-20261015-1150 설정 백업은 별도 비밀 디렉터리의 권한 600 파일로 보관했다. 제한: DB 복원 시험과 다음 컨테이너 재생성은 이번 검사에 포함하지 않았다. Trilium: Ubuntu 서버 운영 아래 Discourse 한국어 배포에 기록했다.
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "json"
|
||||
require "digest"
|
||||
require "yaml"
|
||||
|
||||
abort "한국어 보완 플러그인을 불러오지 못했습니다." unless Discourse.plugins.any? { |plugin| plugin.name == "itosm-korean-localization" }
|
||||
abort "이전 한국어 플러그인이 중복 설치되어 있습니다." if Discourse.plugins.any? { |plugin| plugin.name == "itosm-admin-korean" }
|
||||
I18n.with_locale(:ko) do
|
||||
boards = Discourse.plugins.find { |plugin| plugin.name == "boards" }
|
||||
if boards
|
||||
serialized = AdminPluginSerializer.new(boards, root: false).as_json
|
||||
abort "플러그인 내부 이름이 번역되어 관리자 링크가 손상됩니다." unless serialized[:name] == "boards"
|
||||
abort "보드 표시 이름 번역 누락" unless serialized[:humanized_name] == "보드"
|
||||
end
|
||||
end
|
||||
|
||||
expected = {
|
||||
"title" => "대화방에 참여하기 전에 확인해 주세요.",
|
||||
"join" => "대화방 참여",
|
||||
"cancel" => "취소",
|
||||
"dont_show_again" => "다시 표시하지 않기",
|
||||
}
|
||||
expected.each do |key, value|
|
||||
actual = I18n.t("js.voice.mesh_privacy_warning.#{key}", locale: :ko, fallback: false)
|
||||
abort "음성 대화방 번역 불일치: #{key}" unless actual == value
|
||||
end
|
||||
body = I18n.t("js.voice.mesh_privacy_warning.body", locale: :ko, fallback: false)
|
||||
abort "음성 대화방 개인정보 안내 번역 누락" unless body.include?("다른 참여자가 내 IP 주소를 확인할 수 있습니다.")
|
||||
|
||||
def flatten_translations(hash, prefix = "", result = {})
|
||||
hash.each do |key, value|
|
||||
path = prefix.empty? ? key.to_s : "#{prefix}.#{key}"
|
||||
value.is_a?(Hash) ? flatten_translations(value, path, result) : result[path] = value
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
korean = flatten_translations(I18n.backend.send(:translations).fetch(:ko))
|
||||
TranslationOverride.where(locale: "ko").pluck(:translation_key, :value).each { |key, value| korean[key] = value }
|
||||
active_keys = Discourse.plugins.select(&:enabled?).flat_map do |plugin|
|
||||
Dir.glob(Rails.root.join("plugins", plugin.directory_name, "config/locales/*.en.yml")).flat_map do |path|
|
||||
flatten_translations(YAML.safe_load_file(path, aliases: true).fetch("en", {})).keys
|
||||
end
|
||||
end.uniq
|
||||
|
||||
# 한국어는 단수와 복수에 같은 표현을 사용하므로 other가 있으면 one도 충족합니다.
|
||||
missing = active_keys.reject do |key|
|
||||
korean.key?(key) || (key.end_with?(".one") && korean.key?(key.sub(/\.one$/, ".other")))
|
||||
end
|
||||
abort "활성 플러그인 한국어 번역 누락 #{missing.size}개: #{missing.first(10).join(', ')}" unless missing.empty?
|
||||
|
||||
# 영어 대체 표시를 정상 번역으로 오인하지 않도록 한국어 묶음의 내용 해시를 반환합니다.
|
||||
bundles = %w[main admin].to_h do |bundle|
|
||||
content = ExtraLocalesController.bundle_js(bundle, locale: :ko)
|
||||
[bundle, { url: ExtraLocalesController.url(bundle, locale: :ko), sha256: Digest::SHA256.hexdigest(content) }]
|
||||
end
|
||||
if Discourse.plugins.any? { |plugin| plugin.name == "boards" }
|
||||
filename = Plugin::JsManager.read_manifest("boards").dig("main", "fileName")
|
||||
board_js = File.read(Rails.root.join("app/assets/generated/boards/js/plugins", filename))
|
||||
abort "보드 메뉴 제목 컴파일 누락" unless board_js.include?("보드 메뉴") && board_js.include?("열 메뉴")
|
||||
bundles["boards"] = {url: "/assets/js/plugins/#{filename}", sha256: Digest::SHA256.hexdigest(board_js)}
|
||||
end
|
||||
puts JSON.generate(bundles: bundles, active_plugin_keys: active_keys.size, missing: missing.size)
|
||||
Reference in New Issue
Block a user