summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/client/app/src/lang/omnijar.rs
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/crashreporter/client/app/src/lang/omnijar.rs')
-rw-r--r--toolkit/crashreporter/client/app/src/lang/omnijar.rs103
1 files changed, 103 insertions, 0 deletions
diff --git a/toolkit/crashreporter/client/app/src/lang/omnijar.rs b/toolkit/crashreporter/client/app/src/lang/omnijar.rs
new file mode 100644
index 0000000000..2d2c34dd8d
--- /dev/null
+++ b/toolkit/crashreporter/client/app/src/lang/omnijar.rs
@@ -0,0 +1,103 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use super::language_info::LanguageInfo;
+use crate::std::{
+ env::current_exe,
+ fs::File,
+ io::{BufRead, BufReader, Read},
+ path::Path,
+};
+use anyhow::Context;
+use zip::read::ZipArchive;
+
+/// Read the appropriate localization fluent definitions from the omnijar files.
+///
+/// Returns (locale name, fluent definitions).
+pub fn read() -> anyhow::Result<LanguageInfo> {
+ let mut path = current_exe().context("failed to get current executable")?;
+ path.pop();
+ path.push("omni.ja");
+
+ let mut zip = read_omnijar_file(&path)?;
+ let locales = {
+ let buf = BufReader::new(
+ zip.by_name("res/multilocale.txt")
+ .context("failed to read multilocale file in zip archive")?,
+ );
+ let line = buf
+ .lines()
+ .next()
+ .ok_or(anyhow::anyhow!("multilocale file was empty"))?
+ .context("failed to read first line of multilocale file")?;
+ line.split(",")
+ .map(|s| s.trim().to_owned())
+ .collect::<Vec<_>>()
+ };
+
+ let (locale, ftl_definitions) = 'defs: {
+ for locale in &locales {
+ match read_strings(locale, &mut zip) {
+ Ok(v) => break 'defs (locale.to_string(), v),
+ Err(e) => log::warn!("{e:#}"),
+ }
+ }
+ anyhow::bail!("failed to find any usable localized strings in the omnijar")
+ };
+
+ // The brand ftl is in the browser omnijar.
+ path.pop();
+ path.push("browser");
+ path.push("omni.ja");
+
+ let ftl_branding = 'branding: {
+ for locale in &locales {
+ match read_branding(&locale, &mut zip) {
+ Ok(v) => break 'branding v,
+ Err(e) => log::warn!("failed to read branding from omnijar: {e:#}"),
+ }
+ }
+ log::info!("using fallback branding info");
+ LanguageInfo::default().ftl_branding
+ };
+
+ Ok(LanguageInfo {
+ identifier: locale,
+ ftl_definitions,
+ ftl_branding,
+ })
+}
+
+/// Read the localized strings from the given zip archive (omnijar).
+fn read_strings(locale: &str, archive: &mut ZipArchive<File>) -> anyhow::Result<String> {
+ let mut file = archive
+ .by_name(&format!(
+ "localization/{locale}/crashreporter/crashreporter.ftl"
+ ))
+ .with_context(|| format!("failed to locate localization file for {locale}"))?;
+
+ let mut ftl_definitions = String::new();
+ file.read_to_string(&mut ftl_definitions)
+ .with_context(|| format!("failed to read localization file for {locale}"))?;
+
+ Ok(ftl_definitions)
+}
+
+/// Read the branding information from the given zip archive (omnijar).
+fn read_branding(locale: &str, archive: &mut ZipArchive<File>) -> anyhow::Result<String> {
+ let mut file = archive
+ .by_name(&format!("localization/{locale}/branding/brand.ftl"))
+ .with_context(|| format!("failed to locate branding localization file for {locale}"))?;
+ let mut s = String::new();
+ file.read_to_string(&mut s)
+ .with_context(|| format!("failed to read branding localization file for {locale}"))?;
+ Ok(s)
+}
+
+fn read_omnijar_file(path: &Path) -> anyhow::Result<ZipArchive<File>> {
+ ZipArchive::new(
+ File::open(&path).with_context(|| format!("failed to open {}", path.display()))?,
+ )
+ .with_context(|| format!("failed to read zip archive in {}", path.display()))
+}