11-localize_browser 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #!/bin/sh
  2. set -e
  3. echo "Localize each supported browser locale"
  4. # Import the TBB_INSTALL and TBB_EXT variables and
  5. # supported_tor_browser_locales()
  6. . /usr/local/lib/tails-shell-library/tor-browser.sh
  7. # Import set_simple_config_key()
  8. . /usr/local/lib/tails-shell-library/common.sh
  9. # Import language_code_from_locale()
  10. . /usr/local/lib/tails-shell-library/localization.sh
  11. # Import TAILS_WIKI_SUPPORTED_LANGUAGES
  12. . /etc/amnesia/environment
  13. TBB_LOCALIZED_SEARCHPLUGINS_DIR="${TBB_INSTALL}/distribution/searchplugins/locale/"
  14. BROWSER_LOCALIZATION_DIR="/usr/share/tails/browser-localization"
  15. DESCRIPTIONS_FILE="${BROWSER_LOCALIZATION_DIR}/descriptions"
  16. BRANDING_TEMPLATE_FILE="${BROWSER_LOCALIZATION_DIR}/amnesia.properties-template"
  17. BRANDING_DIR="/usr/local/share/tor-browser-extensions/branding@amnesia.boum.org/"
  18. NO_SPELLCHECKER_LOCALES="ja ko nl pl tr zh"
  19. apt-get --yes install imagemagick
  20. # Sanity check that each supported Tor Browser locale has a
  21. # description for how to localize it further.
  22. BROKEN_LOCALES=""
  23. for LOCALE in $(supported_tor_browser_locales); do
  24. if ! grep -q "^${LOCALE}:" "${DESCRIPTIONS_FILE}" 2>/dev/null; then
  25. BROKEN_LOCALES="${BROKEN_LOCALES} ${LOCALE}"
  26. fi
  27. done
  28. if [ -n "${BROKEN_LOCALES}" ]; then
  29. echo "The following supported browser locales lack search plugin descriptions in ${DESCRIPTIONS_FILE}:${BROKEN_LOCALES}" >&2
  30. exit 1
  31. fi
  32. # This very long while-loop is fed the DESCRIPTIONS_FILE (IO
  33. # redirection at the bottom), which describes how we will localize
  34. # each supported Tor Browser locale. The format is:
  35. # MOZILLA_LOCALE:LOCATION:LOCALIZED_LANG:STARTPAGE_LANG:STARTPAGE_LANG_UI
  36. # Note that we're forced to pick some representative location for the
  37. # language-only locales, like Egypt (EG) for Arabic (ar).
  38. while IFS=: read MOZILLA_LOCALE LOCATION LOCALIZED_LANG STARTPAGE_LANG STARTPAGE_LANG_UI; do
  39. if [ -z "${MOZILLA_LOCALE}" ] || [ -z "${LOCATION}" ] || \
  40. [ -z "${LOCALIZED_LANG}" ] || [ -z "${STARTPAGE_LANG}" ]; then
  41. echo "Something is wrong with ${DESCRIPTIONS_FILE}" >&2
  42. echo "Description: ${MOZILLA_LOCALE}:${LOCATION}:${LOCALIZED_LANG}:${STARTPAGE_LANG}:${STARTPAGE_LANG_UI}" >&2
  43. exit 1
  44. fi
  45. echo "- Localizing ${MOZILLA_LOCALE} for browsers..."
  46. # In some places we'll need the locale in xx_YY format instead of
  47. # Mozilla's xx-YY fromat. Over all, the greatest difficulty in
  48. # this whole script is really to know when to use the correct
  49. # locale format, since Firefox isn't very consistent in it.
  50. if echo "${MOZILLA_LOCALE}" | grep -q '-'; then
  51. NORMAL_LOCALE="$(echo "${MOZILLA_LOCALE}" | tr - _)"
  52. else
  53. NORMAL_LOCALE="${MOZILLA_LOCALE}_${LOCATION}"
  54. fi
  55. LANG_CODE="$(language_code_from_locale "${NORMAL_LOCALE}")"
  56. TARGET_SEARCHPLUGINS_DIR="${TBB_LOCALIZED_SEARCHPLUGINS_DIR}/${MOZILLA_LOCALE}"
  57. mkdir -p "${TARGET_SEARCHPLUGINS_DIR}"
  58. if [ -z "${STARTPAGE_LANG_UI}" ]; then
  59. STARTPAGE_LANG_UI=english
  60. fi
  61. sed -e "s/\${LOCALIZED_LANG}/${LOCALIZED_LANG}/" \
  62. -e "s/\${LANG}/${STARTPAGE_LANG}/" \
  63. -e "s/\${LANG_UI}/${STARTPAGE_LANG}/" \
  64. "${BROWSER_LOCALIZATION_DIR}/startpage.xml-template" > \
  65. "${TARGET_SEARCHPLUGINS_DIR}/startpage-${MOZILLA_LOCALE}.xml"
  66. DDG_PLUGIN="${TARGET_SEARCHPLUGINS_DIR}/ddg-${MOZILLA_LOCALE}.xml"
  67. DDG_LANG_UI="${NORMAL_LOCALE}"
  68. if [ "${DDG_LANG_UI}" = "vi_VN" ]; then
  69. # DDG uses a non-standard locale for Vietnamese
  70. DDG_LANG_UI="vi_VI"
  71. fi
  72. sed -e "s/\${LOCALIZED_LANG}/${LOCALIZED_LANG}/" \
  73. -e "s/\${LANG_UI}/${DDG_LANG_UI}/" \
  74. "${BROWSER_LOCALIZATION_DIR}/ddg.xml-template" > \
  75. "${DDG_PLUGIN}"
  76. # We generate a Wikipedia plugin with localized icons since we
  77. # want to provide both English and the locale's plugin, and
  78. # Firefox' new search bar only shows icons; the description (which
  79. # is localized) is only shown in a pop-up nowdays, so it's easy to
  80. # mix them up.
  81. CAPITALIZED_LANG_CODE="$(echo "${LANG_CODE}" | tr 'a-z' 'A-Z')"
  82. LOCALIZED_WIKIPEDIA_ICON_PATH="/tmp/wikipedia-icon-${LANG_CODE}.png"
  83. WIKIPEDIA_SEARCH_ICON_BASE64_PATH="${LOCALIZED_WIKIPEDIA_ICON_PATH}.base64"
  84. WIKIPEDIA_ICON_TEMPLATE="${BROWSER_LOCALIZATION_DIR}/Wikipedia-icon.png"
  85. convert "${WIKIPEDIA_ICON_TEMPLATE}" \
  86. -gravity SouthEast -pointsize 130 -font Liberation-Sans-Bold \
  87. -fill black -annotate 0 "${CAPITALIZED_LANG_CODE}" \
  88. +set date:create +set date:modify -define png:exclude-chunk=time \
  89. -resize 16x16 "${LOCALIZED_WIKIPEDIA_ICON_PATH}"
  90. base64 "${LOCALIZED_WIKIPEDIA_ICON_PATH}" | tr -d "\n" > \
  91. "${WIKIPEDIA_SEARCH_ICON_BASE64_PATH}"
  92. sed -e "s/\${LANG_CODE}/${LANG_CODE}/" \
  93. -e "s/\${LOCALIZED_LANG}/${LOCALIZED_LANG}/" \
  94. -e "/\${BASE64_PNG_16x16}/ r ${WIKIPEDIA_SEARCH_ICON_BASE64_PATH}" \
  95. -e "/\${BASE64_PNG_16x16}/d" \
  96. "${BROWSER_LOCALIZATION_DIR}/wikipedia.xml-template" > \
  97. "${TARGET_SEARCHPLUGINS_DIR}/wikipedia-${MOZILLA_LOCALE}.xml"
  98. rm "${LOCALIZED_WIKIPEDIA_ICON_PATH}" \
  99. "${WIKIPEDIA_SEARCH_ICON_BASE64_PATH}"
  100. # We use the branding@amnesia.org extension to set some per-locale
  101. # default prefs that set the appropriate localization options.
  102. TARGET_BRANDING_DIR="${BRANDING_DIR}/chrome/locale/${MOZILLA_LOCALE}"
  103. echo "locale amnesiabranding ${MOZILLA_LOCALE} chrome/locale/${MOZILLA_LOCALE}/" >> "${BRANDING_DIR}/chrome.manifest"
  104. mkdir -p "${TARGET_BRANDING_DIR}"
  105. TARGET_BRANDING_FILE="${TARGET_BRANDING_DIR}/amnesia.properties"
  106. cp "${BRANDING_TEMPLATE_FILE}" "${TARGET_BRANDING_FILE}"
  107. for KEY in browser.search.defaultenginename \
  108. browser.search.selectedEngine; do
  109. PLUGIN="DuckDuckGo - ${LOCALIZED_LANG}"
  110. if ! grep -q "<ShortName>${PLUGIN}</ShortName>" "${DDG_PLUGIN}"; then
  111. echo "Trying to make search plugin '${PLUGIN}' the default for ${MOZILLA_LOCALE} but it unexpectedly wasn't the one we generated earlier" >&2
  112. exit 1
  113. fi
  114. set_simple_config_key "${TARGET_BRANDING_FILE}" "${KEY}" "${PLUGIN}"
  115. done
  116. TBB_DICTIONARIES_DIR="${TBB_INSTALL}/dictionaries"
  117. unset SPELLCHECKER_LOCALE
  118. for LOCALE in "${NORMAL_LOCALE}" "${LANG_CODE}"; do
  119. if [ -e "${TBB_DICTIONARIES_DIR}/${LOCALE}.dic" ]; then
  120. SPELLCHECKER_LOCALE="${LOCALE}"
  121. fi
  122. done
  123. if [ -z "${SPELLCHECKER_LOCALE}" ]; then
  124. if echo "${NO_SPELLCHECKER_LOCALES}" | grep -qw "${LANG_CODE}"; then
  125. SPELLCHECKER_LOCALE="en_US"
  126. else
  127. echo "No spellchecker found for ${MOZILLA_LOCALE}" >&2
  128. exit 1
  129. fi
  130. fi
  131. set_simple_config_key "${TARGET_BRANDING_FILE}" \
  132. "spellchecker.dictionary" \
  133. "${SPELLCHECKER_LOCALE}"
  134. HOMEPAGE="https://tails.boum.org/home/"
  135. if echo "${TAILS_WIKI_SUPPORTED_LANGUAGES}" | grep -qw "${LANG_CODE}"; then
  136. HOMEPAGE="${HOMEPAGE}index.${LANG_CODE}.html"
  137. fi
  138. set_simple_config_key "${TARGET_BRANDING_FILE}" \
  139. "browser.startup.homepage" "${HOMEPAGE}"
  140. done < "${DESCRIPTIONS_FILE}"
  141. # This directory is not needed after build time.
  142. rm -r "${BROWSER_LOCALIZATION_DIR}"
  143. # Remove unwanted browser search plugins bundled in the Tor Browser.
  144. # Note for posterity: the searchplugins/list.txt file must not be
  145. # removed! It must list the filename (excl. .xml) of each plugin
  146. # present, otherwise they won't work. It's not a problem to list
  147. # nonexisting ones, so as long as we delete plugins we do not have to
  148. # alter it.
  149. 7z d -tzip "${TBB_INSTALL}/browser/omni.ja" \
  150. 'chrome/en-US/locale/browser/searchplugins/ddg*.xml' \
  151. 'chrome/en-US/locale/browser/searchplugins/startpage*.xml' \
  152. 'chrome/en-US/locale/browser/searchplugins/wikipedia*.xml' \
  153. 'chrome/en-US/locale/browser/searchplugins/yahoo*.xml'
  154. for pack in "${TBB_EXT}"/langpack-*.xpi; do
  155. 7z d -tzip "${pack}" \
  156. 'browser/chrome/*/locale/browser/searchplugins/ddg*.xml' \
  157. 'browser/chrome/*/locale/browser/searchplugins/startpage*.xml' \
  158. 'browser/chrome/*/locale/browser/searchplugins/wikipedia*.xml' \
  159. 'browser/chrome/*/locale/browser/searchplugins/yahoo*.xml'
  160. done
  161. # We want our localized English Wikipedia plugin to be available in
  162. # all locales.
  163. (
  164. cd "${TBB_LOCALIZED_SEARCHPLUGINS_DIR}"
  165. for dir in *; do
  166. if [ -d "${dir}" ] && [ "${dir}" != en-US ]; then
  167. (
  168. cd "${dir}"
  169. cp -a ../en-US/wikipedia-en-US.xml .
  170. )
  171. fi
  172. done
  173. )
  174. # All generated and modified files must remain world-readable.
  175. chmod -R a+rX "${TBB_LOCALIZED_SEARCHPLUGINS_DIR}" \
  176. "${BRANDING_DIR}" \
  177. "${TBB_EXT}"
  178. apt-get --yes purge imagemagick