Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | # preprocess-locale.py |
michael@0 | 2 | # Any copyright is dedicated to the Public Domain. |
michael@0 | 3 | # http://creativecommons.org/publicdomain/zero/1.0/ |
michael@0 | 4 | |
michael@0 | 5 | # preprocess-locale.py provides two functions depending on the arguments passed |
michael@0 | 6 | # to it when invoked. |
michael@0 | 7 | # |
michael@0 | 8 | # Preprocesses installer locale properties files and creates a basic NSIS nlf |
michael@0 | 9 | # file when invoked with --preprocess-locale. |
michael@0 | 10 | # |
michael@0 | 11 | # Converts a UTF-8 file to a new UTF-16LE file when invoked with |
michael@0 | 12 | # --convert-utf8-utf16le. |
michael@0 | 13 | |
michael@0 | 14 | from codecs import BOM_UTF16_LE |
michael@0 | 15 | from os.path import join, isfile |
michael@0 | 16 | import sys |
michael@0 | 17 | from optparse import OptionParser |
michael@0 | 18 | |
michael@0 | 19 | def open_utf16le_file(path): |
michael@0 | 20 | """ |
michael@0 | 21 | Returns an opened file object with a a UTF-16LE byte order mark. |
michael@0 | 22 | """ |
michael@0 | 23 | fp = open(path, "w+b") |
michael@0 | 24 | fp.write(BOM_UTF16_LE) |
michael@0 | 25 | return fp |
michael@0 | 26 | |
michael@0 | 27 | def get_locale_strings(path, prefix, middle, add_cr): |
michael@0 | 28 | """ |
michael@0 | 29 | Returns a string created by converting an installer locale properties file |
michael@0 | 30 | into the format required by NSIS locale files. |
michael@0 | 31 | |
michael@0 | 32 | Parameters: |
michael@0 | 33 | path - the path to the installer locale properties file to preprocess |
michael@0 | 34 | prefix - a string to prefix each line with |
michael@0 | 35 | middle - a string to insert between the name and value for each line |
michael@0 | 36 | add_cr - boolean for whether to add an NSIS carriage return before NSIS |
michael@0 | 37 | linefeeds when there isn't one already |
michael@0 | 38 | """ |
michael@0 | 39 | output = "" |
michael@0 | 40 | fp = open(path, "r") |
michael@0 | 41 | for line in fp: |
michael@0 | 42 | line = line.strip() |
michael@0 | 43 | if line == "" or line[0] == "#": |
michael@0 | 44 | continue |
michael@0 | 45 | |
michael@0 | 46 | name, value = line.split("=", 1) |
michael@0 | 47 | value = value.strip() # trim whitespace from the start and end |
michael@0 | 48 | if value and value[-1] == "\"" and value[0] == "\"": |
michael@0 | 49 | value = value[1:-1] # remove " from the start and end |
michael@0 | 50 | |
michael@0 | 51 | if add_cr: |
michael@0 | 52 | value = value.replace("\\n", "\\r\\n") # prefix $\n with $\r |
michael@0 | 53 | value = value.replace("\\r\\r", "\\r") # replace $\r$\r with $\r |
michael@0 | 54 | |
michael@0 | 55 | value = value.replace("\"", "$\\\"") # prefix " with $\ |
michael@0 | 56 | value = value.replace("\\r", "$\\r") # prefix \r with $ |
michael@0 | 57 | value = value.replace("\\n", "$\\n") # prefix \n with $ |
michael@0 | 58 | value = value.replace("\\t", "$\\t") # prefix \t with $ |
michael@0 | 59 | |
michael@0 | 60 | output += prefix + name.strip() + middle + " \"" + value + "\"\n" |
michael@0 | 61 | fp.close() |
michael@0 | 62 | return output |
michael@0 | 63 | |
michael@0 | 64 | def lookup(path, l10ndirs): |
michael@0 | 65 | for d in l10ndirs: |
michael@0 | 66 | if isfile(join(d, path)): |
michael@0 | 67 | return join(d, path) |
michael@0 | 68 | return join(l10ndirs[-1], path) |
michael@0 | 69 | |
michael@0 | 70 | def preprocess_locale_files(config_dir, l10ndirs): |
michael@0 | 71 | """ |
michael@0 | 72 | Preprocesses the installer localized properties files into the format |
michael@0 | 73 | required by NSIS and creates a basic NSIS nlf file. |
michael@0 | 74 | |
michael@0 | 75 | Parameters: |
michael@0 | 76 | config_dir - the path to the destination directory |
michael@0 | 77 | l10ndirs - list of paths to search for installer locale files |
michael@0 | 78 | """ |
michael@0 | 79 | |
michael@0 | 80 | # Create the main NSIS language file |
michael@0 | 81 | fp = open_utf16le_file(join(config_dir, "overrideLocale.nsh")) |
michael@0 | 82 | locale_strings = get_locale_strings(lookup("override.properties", |
michael@0 | 83 | l10ndirs), |
michael@0 | 84 | "LangString ^", |
michael@0 | 85 | " 0 ", |
michael@0 | 86 | False) |
michael@0 | 87 | fp.write(unicode(locale_strings, "utf-8").encode("utf-16-le")) |
michael@0 | 88 | fp.close() |
michael@0 | 89 | |
michael@0 | 90 | # Create the Modern User Interface language file |
michael@0 | 91 | fp = open_utf16le_file(join(config_dir, "baseLocale.nsh")) |
michael@0 | 92 | fp.write((u""";NSIS Modern User Interface - Language File |
michael@0 | 93 | ;Compatible with Modern UI 1.68 |
michael@0 | 94 | ;Language: baseLocale (0) |
michael@0 | 95 | !insertmacro MOZ_MUI_LANGUAGEFILE_BEGIN \"baseLocale\" |
michael@0 | 96 | !define MUI_LANGNAME \"baseLocale\" |
michael@0 | 97 | """).encode("utf-16-le")) |
michael@0 | 98 | locale_strings = get_locale_strings(lookup("mui.properties", l10ndirs), |
michael@0 | 99 | "!define ", " ", True) |
michael@0 | 100 | fp.write(unicode(locale_strings, "utf-8").encode("utf-16-le")) |
michael@0 | 101 | fp.write(u"!insertmacro MOZ_MUI_LANGUAGEFILE_END\n".encode("utf-16-le")) |
michael@0 | 102 | fp.close() |
michael@0 | 103 | |
michael@0 | 104 | # Create the custom language file for our custom strings |
michael@0 | 105 | fp = open_utf16le_file(join(config_dir, "customLocale.nsh")) |
michael@0 | 106 | locale_strings = get_locale_strings(lookup("custom.properties", |
michael@0 | 107 | l10ndirs), |
michael@0 | 108 | "LangString ", |
michael@0 | 109 | " 0 ", |
michael@0 | 110 | True) |
michael@0 | 111 | fp.write(unicode(locale_strings, "utf-8").encode("utf-16-le")) |
michael@0 | 112 | fp.close() |
michael@0 | 113 | |
michael@0 | 114 | def create_nlf_file(moz_dir, ab_cd, config_dir): |
michael@0 | 115 | """ |
michael@0 | 116 | Create a basic NSIS nlf file. |
michael@0 | 117 | |
michael@0 | 118 | Parameters: |
michael@0 | 119 | moz_dir - the path to top source directory for the toolkit source |
michael@0 | 120 | ab_cd - the locale code |
michael@0 | 121 | config_dir - the path to the destination directory |
michael@0 | 122 | """ |
michael@0 | 123 | rtl = "-" |
michael@0 | 124 | |
michael@0 | 125 | # Check whether the locale is right to left from locales.nsi. |
michael@0 | 126 | fp = open(join(moz_dir, |
michael@0 | 127 | "toolkit/mozapps/installer/windows/nsis/locales.nsi"), |
michael@0 | 128 | "r") |
michael@0 | 129 | for line in fp: |
michael@0 | 130 | line = line.strip() |
michael@0 | 131 | if line == "!define " + ab_cd + "_rtl": |
michael@0 | 132 | rtl = "RTL" |
michael@0 | 133 | break |
michael@0 | 134 | |
michael@0 | 135 | fp.close() |
michael@0 | 136 | |
michael@0 | 137 | # Create the main NSIS language file with RTL for right to left locales |
michael@0 | 138 | # along with the default codepage, font name, and font size represented |
michael@0 | 139 | # by the '-' character. |
michael@0 | 140 | fp = open_utf16le_file(join(config_dir, "baseLocale.nlf")) |
michael@0 | 141 | fp.write((u"""# Header, don't edit |
michael@0 | 142 | NLF v6 |
michael@0 | 143 | # Start editing here |
michael@0 | 144 | # Language ID |
michael@0 | 145 | 0 |
michael@0 | 146 | # Font and size - dash (-) means default |
michael@0 | 147 | - |
michael@0 | 148 | - |
michael@0 | 149 | # Codepage - dash (-) means ANSI code page |
michael@0 | 150 | - |
michael@0 | 151 | # RTL - anything else than RTL means LTR |
michael@0 | 152 | %s |
michael@0 | 153 | """ % rtl).encode("utf-16-le")) |
michael@0 | 154 | fp.close() |
michael@0 | 155 | |
michael@0 | 156 | def preprocess_locale_file(config_dir, |
michael@0 | 157 | l10ndirs, |
michael@0 | 158 | properties_filename, |
michael@0 | 159 | output_filename): |
michael@0 | 160 | """ |
michael@0 | 161 | Preprocesses a single localized properties file into the format |
michael@0 | 162 | required by NSIS and creates a basic NSIS nlf file. |
michael@0 | 163 | |
michael@0 | 164 | Parameters: |
michael@0 | 165 | config_dir - the path to the destination directory |
michael@0 | 166 | l10ndirs - list of paths to search for installer locale files |
michael@0 | 167 | properties_filename - the name of the properties file to search for |
michael@0 | 168 | output_filename - the output filename to write |
michael@0 | 169 | """ |
michael@0 | 170 | |
michael@0 | 171 | # Create the custom language file for our custom strings |
michael@0 | 172 | fp = open_utf16le_file(join(config_dir, output_filename)) |
michael@0 | 173 | locale_strings = get_locale_strings(lookup(properties_filename, |
michael@0 | 174 | l10ndirs), |
michael@0 | 175 | "LangString ", |
michael@0 | 176 | " 0 ", |
michael@0 | 177 | True) |
michael@0 | 178 | fp.write(unicode(locale_strings, "utf-8").encode("utf-16-le")) |
michael@0 | 179 | fp.close() |
michael@0 | 180 | |
michael@0 | 181 | |
michael@0 | 182 | def convert_utf8_utf16le(in_file_path, out_file_path): |
michael@0 | 183 | """ |
michael@0 | 184 | Converts a UTF-8 file to a new UTF-16LE file |
michael@0 | 185 | |
michael@0 | 186 | Arguments: |
michael@0 | 187 | in_file_path - the path to the UTF-8 source file to convert |
michael@0 | 188 | out_file_path - the path to the UTF-16LE destination file to create |
michael@0 | 189 | """ |
michael@0 | 190 | in_fp = open(in_file_path, "r") |
michael@0 | 191 | out_fp = open_utf16le_file(out_file_path) |
michael@0 | 192 | out_fp.write(unicode(in_fp.read(), "utf-8").encode("utf-16-le")) |
michael@0 | 193 | in_fp.close() |
michael@0 | 194 | out_fp.close() |
michael@0 | 195 | |
michael@0 | 196 | if __name__ == '__main__': |
michael@0 | 197 | usage = """usage: %prog command <args> |
michael@0 | 198 | |
michael@0 | 199 | Commands: |
michael@0 | 200 | --convert-utf8-utf16le - Preprocesses installer locale properties files |
michael@0 | 201 | --preprocess-locale - Preprocesses the installer localized properties |
michael@0 | 202 | files into the format required by NSIS and |
michael@0 | 203 | creates a basic NSIS nlf file. |
michael@0 | 204 | --preprocess-single-file - Preprocesses a single properties file into the |
michael@0 | 205 | format required by NSIS |
michael@0 | 206 | --create-nlf-file - Creates a basic NSIS nlf file |
michael@0 | 207 | |
michael@0 | 208 | preprocess-locale.py --preprocess-locale <src> <locale> <code> <dest> |
michael@0 | 209 | |
michael@0 | 210 | Arguments: |
michael@0 | 211 | <src> \tthe path to top source directory for the toolkit source |
michael@0 | 212 | <locale>\tthe path to the installer's locale files |
michael@0 | 213 | <code> \tthe locale code |
michael@0 | 214 | <dest> \tthe path to the destination directory |
michael@0 | 215 | |
michael@0 | 216 | |
michael@0 | 217 | preprocess-locale.py --preprocess-single-file <src> |
michael@0 | 218 | <locale> |
michael@0 | 219 | <dest> |
michael@0 | 220 | <infile> |
michael@0 | 221 | <outfile> |
michael@0 | 222 | |
michael@0 | 223 | Arguments: |
michael@0 | 224 | <src> \tthe path to top source directory for the toolkit source |
michael@0 | 225 | <locale> \tthe path to the installer's locale files |
michael@0 | 226 | <dest> \tthe path to the destination directory |
michael@0 | 227 | <infile> \tthe properties file to process |
michael@0 | 228 | <outfile>\tthe nsh file to write |
michael@0 | 229 | |
michael@0 | 230 | |
michael@0 | 231 | preprocess-locale.py --create-nlf-file <src> |
michael@0 | 232 | <code> |
michael@0 | 233 | <dest> |
michael@0 | 234 | |
michael@0 | 235 | Arguments: |
michael@0 | 236 | <src> \tthe path to top source directory for the toolkit source |
michael@0 | 237 | <code> \tthe locale code |
michael@0 | 238 | <dest> \tthe path to the destination directory |
michael@0 | 239 | |
michael@0 | 240 | |
michael@0 | 241 | preprocess-locale.py --convert-utf8-utf16le <src> <dest> |
michael@0 | 242 | |
michael@0 | 243 | Arguments: |
michael@0 | 244 | <src> \tthe path to the UTF-8 source file to convert |
michael@0 | 245 | <dest>\tthe path to the UTF-16LE destination file to create |
michael@0 | 246 | """ |
michael@0 | 247 | |
michael@0 | 248 | preprocess_locale_args_help_string = """\ |
michael@0 | 249 | Arguments to --preprocess-locale should be: |
michael@0 | 250 | <src> <locale> <code> <dest> |
michael@0 | 251 | or |
michael@0 | 252 | <src> <code> <dest> --l10n-dir <dir> [--l10n-dir <dir> ...]""" |
michael@0 | 253 | |
michael@0 | 254 | preprocess_single_file_args_help_string = """\ |
michael@0 | 255 | Arguments to --preprocess-single_file should be: |
michael@0 | 256 | <src> <locale> <code> <dest> <infile> <outfile> |
michael@0 | 257 | or |
michael@0 | 258 | <src> <locale> <code> <dest> <infile> <outfile> |
michael@0 | 259 | --l10n-dir <dir> [--l10n-dir <dir>...]""" |
michael@0 | 260 | |
michael@0 | 261 | create_nlf_args_help_string = """\ |
michael@0 | 262 | Arguments to --create-nlf-file should be: |
michael@0 | 263 | <src> <code> <dest>""" |
michael@0 | 264 | |
michael@0 | 265 | p = OptionParser(usage=usage) |
michael@0 | 266 | p.add_option("--preprocess-locale", action="store_true", default=False, |
michael@0 | 267 | dest='preprocess') |
michael@0 | 268 | p.add_option("--preprocess-single-file", action="store_true", default=False, |
michael@0 | 269 | dest='preprocessSingle') |
michael@0 | 270 | p.add_option("--create-nlf-file", action="store_true", default=False, |
michael@0 | 271 | dest='createNlf') |
michael@0 | 272 | p.add_option("--l10n-dir", action="append", default=[], |
michael@0 | 273 | dest="l10n_dirs", |
michael@0 | 274 | help="Add directory to lookup for locale files") |
michael@0 | 275 | p.add_option("--convert-utf8-utf16le", action="store_true", default=False, |
michael@0 | 276 | dest='convert') |
michael@0 | 277 | |
michael@0 | 278 | options, args = p.parse_args() |
michael@0 | 279 | |
michael@0 | 280 | foundOne = False |
michael@0 | 281 | if (options.preprocess): |
michael@0 | 282 | foundOne = True |
michael@0 | 283 | if (options.convert): |
michael@0 | 284 | if(foundOne): |
michael@0 | 285 | p.error("More than one command specified") |
michael@0 | 286 | else: |
michael@0 | 287 | foundOne = True |
michael@0 | 288 | if (options.preprocessSingle): |
michael@0 | 289 | if(foundOne): |
michael@0 | 290 | p.error("More than one command specified") |
michael@0 | 291 | else: |
michael@0 | 292 | foundOne = True |
michael@0 | 293 | if (options.createNlf): |
michael@0 | 294 | if(foundOne): |
michael@0 | 295 | p.error("More than one command specified") |
michael@0 | 296 | else: |
michael@0 | 297 | foundOne = True |
michael@0 | 298 | |
michael@0 | 299 | if (not foundOne): |
michael@0 | 300 | p.error("No command specified") |
michael@0 | 301 | |
michael@0 | 302 | if options.preprocess: |
michael@0 | 303 | if len(args) not in (3,4): |
michael@0 | 304 | p.error(preprocess_locale_args_help_string) |
michael@0 | 305 | |
michael@0 | 306 | # Parse args |
michael@0 | 307 | pargs = args[:] |
michael@0 | 308 | moz_dir = pargs[0] |
michael@0 | 309 | if len(pargs) == 4: |
michael@0 | 310 | l10n_dirs = [pargs[1]] |
michael@0 | 311 | del pargs[1] |
michael@0 | 312 | else: |
michael@0 | 313 | if not options.l10n_dirs: |
michael@0 | 314 | p.error(preprocess_locale_args_help_string) |
michael@0 | 315 | l10n_dirs = options.l10n_dirs |
michael@0 | 316 | ab_cd = pargs[1] |
michael@0 | 317 | config_dir = pargs[2] |
michael@0 | 318 | |
michael@0 | 319 | # Create the output files |
michael@0 | 320 | create_nlf_file(moz_dir, ab_cd, config_dir) |
michael@0 | 321 | preprocess_locale_files(config_dir, l10n_dirs) |
michael@0 | 322 | elif options.preprocessSingle: |
michael@0 | 323 | if len(args) not in (4,5): |
michael@0 | 324 | p.error(preprocess_single_file_args_help_string) |
michael@0 | 325 | |
michael@0 | 326 | # Parse args |
michael@0 | 327 | pargs = args[:] |
michael@0 | 328 | moz_dir = pargs[0] |
michael@0 | 329 | if len(pargs) == 5: |
michael@0 | 330 | l10n_dirs = [pargs[1]] |
michael@0 | 331 | del pargs[1] |
michael@0 | 332 | else: |
michael@0 | 333 | if not options.l10n_dirs: |
michael@0 | 334 | p.error(preprocess_single_file_args_help_string) |
michael@0 | 335 | l10n_dirs = options.l10n_dirs |
michael@0 | 336 | config_dir = pargs[1] |
michael@0 | 337 | in_file = pargs[2] |
michael@0 | 338 | out_file = pargs[3] |
michael@0 | 339 | |
michael@0 | 340 | # Create the output files |
michael@0 | 341 | preprocess_locale_file(config_dir, |
michael@0 | 342 | l10n_dirs, |
michael@0 | 343 | in_file, |
michael@0 | 344 | out_file) |
michael@0 | 345 | elif options.createNlf: |
michael@0 | 346 | if len(args) != 3: |
michael@0 | 347 | p.error(create_nlf_args_help_string) |
michael@0 | 348 | |
michael@0 | 349 | # Parse args |
michael@0 | 350 | pargs = args[:] |
michael@0 | 351 | moz_dir = pargs[0] |
michael@0 | 352 | ab_cd = pargs[1] |
michael@0 | 353 | config_dir = pargs[2] |
michael@0 | 354 | |
michael@0 | 355 | # Create the output files |
michael@0 | 356 | create_nlf_file(moz_dir, ab_cd, config_dir) |
michael@0 | 357 | elif options.convert: |
michael@0 | 358 | if len(args) != 2: |
michael@0 | 359 | p.error("--convert-utf8-utf16le needs both of <src> <dest>") |
michael@0 | 360 | convert_utf8_utf16le(*args) |