# Add tools directory to path import sys sys.path.append('../../../tools') import json, re, os, waflib, sys, string, subprocess, tempfile import pbpack import polib from collections import OrderedDict from resources.resource_map.resource_generator_font import FontResourceGenerator def make_lang(ctx): lang_code = waflib.Options.options.lang lang_path = os.path.join(ctx.path.abspath(), lang_code) pot_path = os.path.abspath('build/src/fw/tintin.pot'); if not os.path.exists(pot_path): waflib.Logs.pprint('RED', 'Error: could not find tintin.pot. Please run ./waf build first') return po_path = os.path.join(lang_path, 'tintin.po') msginit_cmd = ['msginit', '-l', lang_code, '--no-translator', '-i', pot_path] if not os.path.exists(lang_path): # create folders and init po file from template os.mkdir(lang_path) with open(os.path.join(lang_path, "lang_map.json"), "w") as f: f.write(FILE_LANG_MAP.substitute({'lang': lang_code})) if not os.path.exists(po_path): msginit_cmd += ['-o', po_path] subprocess.call(msginit_cmd) else: # Save the existing po file header po_file_header_entry = polib.pofile(po_path).metadata_as_entry() po_file_header = str(po_file_header_entry) # Empty the po file and write back the header with open(po_path, 'w') as po_file: po_file.write(po_file_header) # Generate the new po file and merge it with the existing file new_po_file = tempfile.NamedTemporaryFile(delete=True) msginit_cmd += ['-o', new_po_file.name] subprocess.call(msginit_cmd) subprocess.call(['msgmerge', '--lang=' + lang_code, '--update', po_path, new_po_file.name]) def pack_all_langs(ctx): language_codes = os.walk(ctx.path.abspath()).next()[1] for language_code in language_codes: pack_lang_code(ctx, language_code) def pack_lang(ctx): lang_code = waflib.Options.options.lang pack_lang_code(ctx, lang_code) def pack_lang_code(ctx, lang_code): lang_path = os.path.join(ctx.path.abspath(), lang_code) build_path = os.path.join(ctx.path.get_bld().abspath(), lang_code) resource_path = os.path.join(lang_path, 'lang_map.json') resource_map = json.loads(open(resource_path, mode='r').read()); resource_data = OrderedDict() if not os.path.exists(build_path): os.makedirs(build_path) # Handle the "strings" object. Has the attributes "lang", "name", and "file". # We need to write the first entry into our pbpack for the .mo file strings = resource_map['strings'] name = strings['name'] if strings['file'] == "": # No .mo file? resource_data[name] = b'' else: po_path = os.path.join(lang_path, strings['file']) # Check that the file contains no untranslated strings if subprocess.check_output(['msgattrib', '--untranslated', po_path]) != '': waflib.Logs.pprint('RED', 'Warning: This PO file contains untranslated strings!') mo_path = os.path.join(build_path, strings['file'] + '.' + name + '.mo') os.system('msgfmt -c -v -o {} {}'.format(mo_path, po_path)) waflib.Logs.pprint('CYAN', 'Created mo at {}'.format(mo_path)) with open(mo_path, 'r') as f: resource_data[name] = f.read() ui_codepoints_path = os.path.join(build_path, 'codepoints.json') os.system('python {} {} --output={}'.format('tools/generate_codepoint_requirements.py', po_path, ui_codepoints_path)) # Generate a resource for each entry in the "fonts" list. for entry in resource_map['fonts']: name = entry['name'] if 'alias' in entry: # Aliased resource # Handle aliases here by copying the data and adding it to the pbpack multiple times, # as the pbpack will handle the deduplication. waflib.Logs.pprint('CYAN', 'Aliasing {} to {}'.format(entry['alias'], name)) resource_data[name] = resource_data[entry['alias']] elif entry['file'] == '': # Empty resource, just write an empty resource to the pbpack waflib.Logs.pprint('CYAN', 'Building empty resource {}'.format(name)) resource_data[name] = b'' else: # Finally, a real font resource! Generate it using the same tools as our normal # resource build. waflib.Logs.pprint('CYAN', 'Building font resource {}'.format(name)) # Make the lang_map.json look more like the usual resource_map.json file format entry['type'] = 'font' # Normally definitions_from_dict returns a list to handle entries that define multiple # resources, but we only ever expect to get one definition per entry here. d = FontResourceGenerator.definitions_from_dict(ctx, entry, '')[0] if d.character_list is None: # By default, we only include codepoints needed for the UI, but it can be overridden d.character_list = ui_codepoints_path else: d.character_list = os.path.join(lang_path, d.character_list) # Now build the font data font_path = os.path.join(lang_path, entry['file']) font_data = FontResourceGenerator.build_font_data(font_path, d) resource_data[name] = font_data # Now write all the resource data to a pbpack lp = pbpack.ResourcePack(False) for r in resource_data.values(): lp.add_resource(r) language_pack = os.path.join(build_path, lang_code + '.pbl') with open(language_pack, 'wb+') as lp_file: lp.serialize(lp_file) waflib.Logs.pprint('CYAN', 'Created language pack at {}'.format(language_pack)) FILE_LANG_MAP = string.Template(""" { "strings": { "lang": "${lang}", "name": "STRINGS", "file": "tintin.po" }, "fonts": [{ "name": "GOTHIC_14_EXTENDED", "file": "" }, { "name": "GOTHIC_14_BOLD_EXTENDED", "file": "" }, { "name": "GOTHIC_18_EXTENDED", "file": "" }, { "name": "GOTHIC_18_BOLD_EXTENDED", "file": "" }, { "name": "GOTHIC_24_EXTENDED", "file": "" }, { "name": "GOTHIC_24_BOLD_EXTENDED", "file": "" }, { "name": "GOTHIC_28_EXTENDED", "file": "" }, { "name": "GOTHIC_28_BOLD_EXTENDED", "file": "" }, { "name": "BITHAM_18_LIGHT_SUBSET_EXTENDED", "file": "" }, { "name": "BITHAM_30_BLACK_EXTENDED", "file": "" }, { "name": "BITHAM_34_LIGHT_SUBSET_EXTENDED", "file": "" }, { "name": "BITHAM_34_MEDIUM_NUMBERS_EXTENDED", "file": "" }, { "name": "BITHAM_42_BOLD_EXTENDED", "file": "" }, { "name": "BITHAM_42_LIGHT_EXTENDED", "file": "" }, { "name": "BITHAM_42_MEDIUM_NUMBERS_EXTENDED", "file": "" }, { "name": "ROBOTO_CONDENSED_21_EXTENDED", "file": "" }, { "name": "ROBOTO_BOLD_SUBSET_49_EXTENDED", "file": "" }, { "name": "DROID_SERIF_28_BOLD_EXTENDED", "file": "" }], "images": [] } """) # vim:filetype=python