[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [Git][tpo/applications/tor-browser-build][main] 3 commits: Bug 40955: Translate the Windows installer.



Title: GitLab

Pier Angelo Vendrame pushed to branch main at The Tor Project / Applications / tor-browser-build

Commits:

  • ae09131d
    by Pier Angelo Vendrame at 2024-06-06T16:54:48+02:00
    Bug 40955: Translate the Windows installer.
    
    Define the user facing strings with LangString in languages.nsh.
    
  • 4634a7b2
    by Pier Angelo Vendrame at 2024-06-06T16:56:52+02:00
    Bug 40955: Translate the Windows installer.
    
    Add a script to add the translated strings to languages.nsh.
    
    Currently, our localization platform (Weblate) does not support NSIS
    files. Therefore, we use another standard format, and, before creating
    the installer, we inject the translated strings to an NSIS script.
    
  • 5ac07d83
    by Pier Angelo Vendrame at 2024-06-06T16:56:53+02:00
    Bug 40955: Translate the Windows installer.
    
    Update the browser build script to apply the Windows installer
    localization.
    

11 changed files:

Changes:

  • projects/browser/build
    ... ... @@ -296,17 +296,17 @@ done
    296 296
       tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/nsis') %]
    
    297 297
       export PATH="/var/tmp/dist/nsis/bin:$PATH"
    
    298 298
     
    
    299
    -  mv $rootdir/windows-installer $distdir/windows-installer
    
    300
    -  mv $rootdir/defines.nsh $distdir/windows-installer/
    
    299
    +  mv defines.nsh windows-installer/
    
    301 300
       [% IF !c('var/testbuild') -%]
    
    302
    -    source $distdir/windows-installer/language-map.sh
    
    303 301
         supported_locales="[% tmpl(c('var/locales').join(' ')) %]"
    
    304
    -    for code in $supported_locales; do
    
    305
    -      if [[ -n ${nsis_languages[$code]} ]]; then
    
    306
    -        echo '!insertmacro MUI_LANGUAGE "'${nsis_languages[$code]}'"' >> $distdir/windows-installer/languages.nsh
    
    307
    -      fi
    
    308
    -    done
    
    302
    +    tar -xf "[% c('input_files_by_name/translation-base-browser') %]"
    
    303
    +    python3 windows-installer/add-strings.py --enable-languages translation-base-browser $supported_locales >> windows-installer/languages.nsh
    
    304
    +    [% IF c("var/mullvad-browser") -%]
    
    305
    +      tar -xf "[% c('input_files_by_name/translation-mullvad-browser') %]"
    
    306
    +      python3 windows-installer/add-strings.py translation-mullvad-browser $supported_locales >> windows-installer/languages.nsh
    
    307
    +    [% END -%]
    
    309 308
       [% END -%]
    
    309
    +  mv windows-installer $distdir/windows-installer
    
    310 310
     
    
    311 311
       [% IF c('var/mullvad-browser') -%]
    
    312 312
         pushd $distdir/windows-installer
    

  • projects/browser/config
    ... ... @@ -134,6 +134,14 @@ input_files:
    134 134
         enable: '[% c("var/windows") %]'
    
    135 135
       - filename: pe_checksum_fix.py
    
    136 136
         enable: '[% c("var/windows") %]'
    
    137
    +  - project: translation
    
    138
    +    name: translation-base-browser
    
    139
    +    pkg_type: base-browser
    
    140
    +    enable: '[% c("var/windows") && !c("var/testbuild") %]'
    
    141
    +  - project: translation
    
    142
    +    name: translation-mullvad-browser
    
    143
    +    pkg_type: mullvad-browser
    
    144
    +    enable: '[% c("var/mullvad-browser") && c("var/windows") && !c("var/testbuild") %]'
    
    137 145
       # To generate a new keystore, see how-to-generate-keystore.txt
    
    138 146
       - filename: android-qa.keystore
    
    139 147
         enable: '[% c("var/android") %]'
    

  • projects/browser/windows-installer/add-strings.py
    1
    +#!/usr/bin/env python3
    
    2
    +import argparse
    
    3
    +import configparser
    
    4
    +from pathlib import Path
    
    5
    +import sys
    
    6
    +
    
    7
    +
    
    8
    +def nsis_escape(string):
    
    9
    +    return string.replace("$", "$$").replace('"', r"$\"")
    
    10
    +
    
    11
    +
    
    12
    +parser = argparse.ArgumentParser()
    
    13
    +parser.add_argument(
    
    14
    +    "--enable-languages",
    
    15
    +    action="store_true",
    
    16
    +    help="Enable the passed languages on NSIS (needs to be done only once)",
    
    17
    +)
    
    18
    +parser.add_argument(
    
    19
    +    "directory",
    
    20
    +    type=Path,
    
    21
    +    help="Directory where the installer strings have been extracted",
    
    22
    +)
    
    23
    +parser.add_argument("langs", nargs="+")
    
    24
    +args = parser.parse_args()
    
    25
    +
    
    26
    +# This does not contain en-US, as en-US strings should already be in
    
    27
    +# languages.nsh.
    
    28
    +languages = {
    
    29
    +    "ar": "Arabic",
    
    30
    +    "ca": "Catalan",
    
    31
    +    "cs": "Czech",
    
    32
    +    "da": "Danish",
    
    33
    +    "de": "German",
    
    34
    +    "el": "Greek",
    
    35
    +    "es-ES": "Spanish",
    
    36
    +    "fa": "Farsi",
    
    37
    +    "fi": "Finnish",
    
    38
    +    "fr": "French",
    
    39
    +    "ga-IE": "ScotsGaelic",
    
    40
    +    "he": "Hebrew",
    
    41
    +    "hu": "Hungarian",
    
    42
    +    "id": "Indonesian",
    
    43
    +    "is": "Icelandic",
    
    44
    +    "it": "Italian",
    
    45
    +    "ja": "Japanese",
    
    46
    +    "ka": "Georgian",
    
    47
    +    "ko": "Korean",
    
    48
    +    "lt": "Lithuanian",
    
    49
    +    "mk": "Macedonian",
    
    50
    +    "ms": "Malay",
    
    51
    +    # Burmese not available on NSIS
    
    52
    +    # "my": "Burmese",
    
    53
    +    "nb-NO": "Norwegian",
    
    54
    +    "nl": "Dutch",
    
    55
    +    "pl": "Polish",
    
    56
    +    "pt-BR": "PortugueseBR",
    
    57
    +    "ro": "Romanian",
    
    58
    +    "ru": "Russian",
    
    59
    +    "sq": "Albanian",
    
    60
    +    "sv-SE": "Swedish",
    
    61
    +    "th": "Thai",
    
    62
    +    "tr": "Turkish",
    
    63
    +    "uk": "Ukrainian",
    
    64
    +    "vi": "Vietnamese",
    
    65
    +    "zh-CN": "SimpChinese",
    
    66
    +    "zh-TW": "TradChinese",
    
    67
    +    # Nightly-only at the moment
    
    68
    +    "be": "Belarusian",
    
    69
    +    "bg": "Bulgarian",
    
    70
    +    "pt-PT": "Portuguese",
    
    71
    +}
    
    72
    +
    
    73
    +replacements = {
    
    74
    +    "min_windows_version": {
    
    75
    +        "program": "${PROJECT_NAME}",
    
    76
    +        "version": "7",
    
    77
    +    },
    
    78
    +    "welcome_title": ("${DISPLAY_NAME}",),
    
    79
    +    "mb_intro": ("${PROJECT_NAME}",),
    
    80
    +    "standalone_description": ("${PROJECT_NAME}",),
    
    81
    +}
    
    82
    +
    
    83
    +
    
    84
    +def read_strings(code):
    
    85
    +    strings = configparser.ConfigParser(interpolation=None)
    
    86
    +    strings.read(args.directory / code / "windows-installer/strings.ini")
    
    87
    +    if "strings" not in strings:
    
    88
    +        return {}
    
    89
    +    strings = strings["strings"]
    
    90
    +    for key, value in strings.items():
    
    91
    +        strings[key] = nsis_escape(value.replace("\n", "").replace("\r", ""))
    
    92
    +    return strings
    
    93
    +
    
    94
    +
    
    95
    +strings_en = read_strings("en-US")
    
    96
    +if not strings_en:
    
    97
    +    print("Strings not found for en-US.", file=sys.stderr)
    
    98
    +    sys.exit(1)
    
    99
    +
    
    100
    +for code in args.langs:
    
    101
    +    if code not in languages:
    
    102
    +        print(f"Unknown or unsupported language {code}.", file=sys.stderr)
    
    103
    +        continue
    
    104
    +    lang = languages[code]
    
    105
    +    if args.enable_languages:
    
    106
    +        print(f'!insertmacro MUI_LANGUAGE "{lang}"')
    
    107
    +
    
    108
    +    strings = read_strings(code)
    
    109
    +    for key, string in strings_en.items():
    
    110
    +        tr = strings.get(key)
    
    111
    +        # Use an explicit if in case the string is found but it is empty.
    
    112
    +        if tr:
    
    113
    +            string = tr
    
    114
    +        if key in replacements:
    
    115
    +            string = string % replacements[key]
    
    116
    +        print(f'LangString {key} ${{LANG_{lang}}} "{string}"')
    
    117
    +    print()

  • projects/browser/windows-installer/browser-install.nsi
    ... ... @@ -89,7 +89,7 @@ Function SetupType
    89 89
       Pop $0
    
    90 90
       !insertmacro MUI_INTERNAL_FULLWINDOW_LOADWIZARDIMAGE "" $0 $PLUGINSDIR\${WELCOME_IMAGE} $1
    
    91 91
     
    
    92
    -  ${NSD_CreateLabel} 120u 10u 195u 28u "Welcome to the ${DISPLAY_NAME} Installer"
    
    92
    +  ${NSD_CreateLabel} 120u 10u 195u 28u "$(welcome_title)"
    
    93 93
       Pop $0
    
    94 94
       SetCtlColors $0 "${MUI_TEXTCOLOR}" "${MUI_BGCOLOR}"
    
    95 95
       CreateFont $2 "$(^Font)" "12" "700"
    
    ... ... @@ -99,18 +99,18 @@ Function SetupType
    99 99
       Pop $0
    
    100 100
       SetCtlColors $0 "${MUI_TEXTCOLOR}" "${MUI_BGCOLOR}"
    
    101 101
     
    
    102
    -  ${NSD_CreateLabel} 120u 105u 195u 12u "Installation Type"
    
    102
    +  ${NSD_CreateLabel} 120u 105u 195u 12u "$(installation_type)"
    
    103 103
       Pop $0
    
    104 104
       SetCtlColors $0 "" ${MUI_BGCOLOR}
    
    105 105
     
    
    106 106
       ${If} $existingInstall == ""
    
    107
    -    ${NSD_CreateRadioButton} 120u 117u 160u 12u "Standard"
    
    107
    +    ${NSD_CreateRadioButton} 120u 117u 160u 12u "$(standard)"
    
    108 108
         Pop $typeRadioStandard
    
    109 109
       ${Else}
    
    110
    -    ${NSD_CreateRadioButton} 120u 117u 160u 12u "Update current installation"
    
    110
    +    ${NSD_CreateRadioButton} 120u 117u 160u 12u "$(update_current)"
    
    111 111
         Pop $typeRadioStandard
    
    112 112
       ${EndIf}
    
    113
    -  ${NSD_CreateRadioButton} 120u 129u 160u 12u "Advanced"
    
    113
    +  ${NSD_CreateRadioButton} 120u 129u 160u 12u "$(advanced)"
    
    114 114
       Pop $typeRadioAdvanced
    
    115 115
     
    
    116 116
       SetCtlColors $typeRadioStandard "" ${MUI_BGCOLOR}
    
    ... ... @@ -149,7 +149,7 @@ Function SetupTypeUpdate
    149 149
         ${If} $existingInstall == ""
    
    150 150
           SendMessage $typeNextButton ${WM_SETTEXT} 0 "STR:$(^InstallBtn)"
    
    151 151
         ${Else}
    
    152
    -      SendMessage $typeNextButton ${WM_SETTEXT} 0 "STR:&Update"
    
    152
    +      SendMessage $typeNextButton ${WM_SETTEXT} 0 "STR:$(update_button)"
    
    153 153
         ${EndIf}
    
    154 154
       ${EndIf}
    
    155 155
     FunctionEnd
    
    ... ... @@ -170,18 +170,18 @@ Function AdvancedSetup
    170 170
         Return
    
    171 171
       ${EndIf}
    
    172 172
     
    
    173
    -  !insertmacro MUI_HEADER_TEXT "Advanced setup" ""
    
    173
    +  !insertmacro MUI_HEADER_TEXT "$(advanced_setup)" ""
    
    174 174
       nsDialogs::Create 1018
    
    175 175
       Pop $0
    
    176 176
       ${If} $0 == error
    
    177 177
         Abort
    
    178 178
       ${EndIf}
    
    179 179
     
    
    180
    -  ${NSD_CreateCheckbox} 0 18% 100% 6% "Create a desktop shortcut"
    
    180
    +  ${NSD_CreateCheckbox} 0 18% 100% 6% "$(desktop_shortcut)"
    
    181 181
       Pop $advancedCheckboxDesktop
    
    182
    -  ${NSD_CreateCheckbox} 0 30% 100% 6% "Standalone installation"
    
    182
    +  ${NSD_CreateCheckbox} 0 30% 100% 6% "$(standalone_installation)"
    
    183 183
       Pop $advancedCheckboxStandalone
    
    184
    -  ${NSD_CreateLabel} 4% 37% 95% 50% "Choose the standalone installation if you want to install Mullvad Browser in its own dedicated folder, without adding it to the Start menu and to the list of applications."
    
    184
    +  ${NSD_CreateLabel} 4% 37% 95% 50% "$(standalone_description)"
    
    185 185
       Pop $0
    
    186 186
       ${NSD_OnClick} $advancedCheckboxStandalone AdvancedSetupCheckboxClick
    
    187 187
       ${NSD_OnClick} $advancedCheckboxDesktop AdvancedSetupCheckboxClick
    

  • projects/browser/windows-installer/browser-portable.nsi
    ... ... @@ -10,7 +10,7 @@
    10 10
       ; Misuse the option to show the readme to create the shortcuts.
    
    11 11
       ; Less ugly than MUI_PAGE_COMPONENTS.
    
    12 12
       !define MUI_FINISHPAGE_SHOWREADME
    
    13
    -  !define MUI_FINISHPAGE_SHOWREADME_TEXT "&Add Start Menu && Desktop shortcuts"
    
    13
    +  !define MUI_FINISHPAGE_SHOWREADME_TEXT "$(add_shortcuts)"
    
    14 14
       !define MUI_FINISHPAGE_SHOWREADME_FUNCTION "CreateShortcuts"
    
    15 15
     
    
    16 16
       !define MUI_PAGE_CUSTOMFUNCTION_LEAVE CheckIfTargetDirectoryExists
    

  • projects/browser/windows-installer/common.nsh
    ... ... @@ -62,7 +62,7 @@
    62 62
     ; Helper functions
    
    63 63
     Function CheckRequirements
    
    64 64
       ${IfNot} ${AtLeastWin7}
    
    65
    -    MessageBox MB_USERICON|MB_OK "${PROJECT_NAME} requires at least Windows 7"
    
    65
    +    MessageBox MB_USERICON|MB_OK "$(min_windows_version)"
    
    66 66
         SetErrorLevel 1
    
    67 67
         Quit
    
    68 68
       ${EndIf}
    
    ... ... @@ -70,7 +70,7 @@ FunctionEnd
    70 70
     
    
    71 71
     Function CheckIfTargetDirectoryExists
    
    72 72
       ${If} ${FileExists} "$INSTDIR\*.*"
    
    73
    -    MessageBox MB_YESNO "The destination directory already exists. Do you want to continue anyway?" IDYES +2
    
    73
    +    MessageBox MB_YESNO "$(destination_exists)" IDYES +2
    
    74 74
         Abort
    
    75 75
       ${EndIf}
    
    76 76
     FunctionEnd

  • projects/browser/windows-installer/defines.nsh.in
    ... ... @@ -35,8 +35,7 @@
    35 35
       !define URL_UPDATE "https://github.com/mullvad/mullvad-browser/releases/[% c('var/torbrowser_version') %]"
    
    36 36
       !define URL_HELP "https://mullvad.net/help/tag/browser/"
    
    37 37
     
    
    38
    -  ; TODO: This will likely be localized in the future.
    
    39
    -  !define INTRO_TEXT "Mullvad Browser is a privacy-focused web browser designed to minimize tracking and fingerprinting."
    
    38
    +  !define INTRO_TEXT "$(mb_intro)"
    
    40 39
     [% ELSE -%]
    
    41 40
       ; Not defined for Tor Browser
    
    42 41
       !define APP_DIR "TorProject"
    
    ... ... @@ -48,5 +47,6 @@
    48 47
       !define URL_UPDATE "https://blog.torproject.org/new[% IF c('var/alpha') %]-alpha[% END %]-release-tor-browser-[% c('var/torbrowser_version') FILTER remove('\.') %]"
    
    49 48
       !define URL_HELP "https://tb-manual.torproject.org/"
    
    50 49
     
    
    50
    +  ; TODO: Localize if we actually start using it.
    
    51 51
       !define INTRO_TEXT "Tor Browser. Protect yourself against tracking, surveillance, and censorship."
    
    52 52
     [% END -%]

  • projects/browser/windows-installer/extract-strings.py
    1
    +#!/usr/bin/env python3
    
    2
    +import re
    
    3
    +
    
    4
    +
    
    5
    +with open("languages.nsh") as f:
    
    6
    +    strings = re.findall(
    
    7
    +        r'LangString (\S+) \${LANG_ENGLISH} "(.+)"$', f.read(), re.I | re.M
    
    8
    +    )
    
    9
    +print("[strings]")
    
    10
    +for key, value in strings:
    
    11
    +    print(f"{key}={value}")

  • projects/browser/windows-installer/language-map.sh deleted
    1
    -#!/bin/bash
    
    2
    -
    
    3
    -# Usually NSIS uses English name with capital first letter.
    
    4
    -# You can check the exact language names on NSIS's archive or here:
    
    5
    -# https://sourceforge.net/p/nsis/code/HEAD/tree/NSIS/trunk/Contrib/Language%20files/
    
    6
    -
    
    7
    -declare -A nsis_languages
    
    8
    -nsis_languages[ar]="Arabic"
    
    9
    -nsis_languages[ca]="Catalan"
    
    10
    -nsis_languages[cs]="Czech"
    
    11
    -nsis_languages[da]="Danish"
    
    12
    -nsis_languages[de]="German"
    
    13
    -nsis_languages[el]="Greek"
    
    14
    -nsis_languages[es-ES]="Spanish"
    
    15
    -nsis_languages[fa]="Farsi"
    
    16
    -nsis_languages[fi]="Finnish"
    
    17
    -nsis_languages[fr]="French"
    
    18
    -nsis_languages[ga-IE]="ScotsGaelic"
    
    19
    -nsis_languages[he]="Hebrew"
    
    20
    -nsis_languages[hu]="Hungarian"
    
    21
    -nsis_languages[id]="Indonesian"
    
    22
    -nsis_languages[is]="Icelandic"
    
    23
    -nsis_languages[it]="Italian"
    
    24
    -nsis_languages[ja]="Japanese"
    
    25
    -nsis_languages[ka]="Georgian"
    
    26
    -nsis_languages[ko]="Korean"
    
    27
    -nsis_languages[lt]="Lithuanian"
    
    28
    -nsis_languages[mk]="Macedonian"
    
    29
    -nsis_languages[ms]="Malay"
    
    30
    -# nsis_languages[my]="Burmese" # Not available on NSIS
    
    31
    -nsis_languages[nb-NO]="Norwegian"
    
    32
    -nsis_languages[nl]="Dutch"
    
    33
    -nsis_languages[pl]="Polish"
    
    34
    -nsis_languages[pt-BR]="PortugueseBR"
    
    35
    -nsis_languages[ro]="Romanian"
    
    36
    -nsis_languages[ru]="Russian"
    
    37
    -nsis_languages[sq]="Albanian"
    
    38
    -nsis_languages[sv-SE]="Swedish"
    
    39
    -nsis_languages[th]="Thai"
    
    40
    -nsis_languages[tr]="Turkish"
    
    41
    -nsis_languages[uk]="Ukrainian"
    
    42
    -nsis_languages[vi]="Vietnamese"
    
    43
    -nsis_languages[zh-CN]="SimpChinese"
    
    44
    -nsis_languages[zh-TW]="TradChinese"
    
    45
    -
    
    46
    -# Currently nightly only
    
    47
    -nsis_languages[be]="Belarusian"
    
    48
    -nsis_languages[bg]="Bulgarian"
    
    49
    -nsis_languages[pt-PT]="Portuguese"

  • projects/browser/windows-installer/languages.nsh
    1 1
     ;--------------------------------
    
    2 2
     ; Additional languages
    
    3 3
       !insertmacro MUI_LANGUAGE "English" ; Always available
    
    4
    -  ; The rest of the languages will be added here during the build.
    4
    +
    
    5
    +  ; Base Browser strings
    
    6
    +  LangString add_shortcuts ${LANG_ENGLISH} "&Add Start menu and desktop icons"
    
    7
    +  ; Use %(program)s instead of ${PROJECT_NAME}  and %(version)s instead of 7
    
    8
    +  ; when sending the string from localization.
    
    9
    +  LangString min_windows_version ${LANG_ENGLISH} "${PROJECT_NAME} requires Windows 7 or later."
    
    10
    +  LangString destination_exists ${LANG_ENGLISH} "The destination folder already exists. Do you want to continue anyway?"
    
    11
    +
    
    12
    +  ; Mullvad Browser strings
    
    13
    +  ; Use %s instead of ${DISPLAY_NAME} for localization.
    
    14
    +  LangString welcome_title ${LANG_ENGLISH} "Welcome to the ${DISPLAY_NAME} installer"
    
    15
    +  ; Use %s instead of ${PROJECT_NAME} for localization
    
    16
    +  LangString mb_intro ${LANG_ENGLISH} "${PROJECT_NAME} is a privacy-focused web browser designed to minimize tracking and fingerprinting."
    
    17
    +  LangString installation_type ${LANG_ENGLISH} "Installation type"
    
    18
    +  LangString standard ${LANG_ENGLISH} "Standard"
    
    19
    +  LangString update_current ${LANG_ENGLISH} "Update current installation"
    
    20
    +  LangString advanced ${LANG_ENGLISH} "Advanced"
    
    21
    +  LangString update_button ${LANG_ENGLISH} "&Update"
    
    22
    +  LangString advanced_setup ${LANG_ENGLISH} "Advanced Installation"
    
    23
    +  LangString desktop_shortcut ${LANG_ENGLISH} "Add desktop icon"
    
    24
    +  LangString standalone_installation ${LANG_ENGLISH} "Standalone installation"
    
    25
    +  ; Use %s instead of ${PROJECT_NAME} for localization
    
    26
    +  LangString standalone_description ${LANG_ENGLISH} "Choose the standalone installation if you want to install ${PROJECT_NAME} in its own dedicated folder, without adding it to the Start menu and to the list of applications."
    
    27
    +
    
    28
    +  ; The rest of the languages and translated strings will be added here by
    
    29
    +  ; add-strings.py.

  • rbm.conf
    ... ... @@ -110,7 +110,7 @@ var:
    110 110
       exe_name: firefox
    
    111 111
       locale_ja: ja
    
    112 112
       # When adding new languages, add the equivalent NSIS name to
    
    113
    -  # projects/browser/windows-installer/language-map.sh.
    
    113
    +  # projects/browser/windows-installer/add-strings.py.
    
    114 114
       locales:
    
    115 115
         - ar
    
    116 116
         - ca
    

  • _______________________________________________
    tor-commits mailing list
    tor-commits@xxxxxxxxxxxxxxxxxxxx
    https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits