def postprocess_translations(reduce_diff_hacks=False):
    print('Checking and postprocessing...')
    if reduce_diff_hacks:
        global _orig_escape_cdata
        _orig_escape_cdata = ET._escape_cdata
        ET._escape_cdata = escape_cdata
    for (filename, filepath) in all_ts_files():
        os.rename(filepath, (filepath + '.orig'))
    have_errors = False
    for (filename, filepath) in all_ts_files('.orig'):
        parser = ET.XMLParser(encoding='utf-8')
        with open((filepath + '.orig'), 'rb') as f:
            data = f.read()
        data = remove_invalid_characters(data)
        tree = ET.parse(io.BytesIO(data), parser=parser)
        root = tree.getroot()
        for context in root.findall('context'):
            for message in context.findall('message'):
                numerus = (message.get('numerus') == 'yes')
                source = message.find('source').text
                translation_node = message.find('translation')
                if numerus:
                    translations = [i.text for i in translation_node.findall('numerusform')]
                else:
                    translations = [translation_node.text]
                for translation in translations:
                    if (translation is None):
                        continue
                    errors = []
                    valid = check_format_specifiers(source, translation, errors, numerus)
                    for error in errors:
                        print(('%s: %s' % (filename, error)))
                    if (not valid):
                        translation_node.clear()
                        translation_node.set('type', 'unfinished')
                        have_errors = True
                for location in message.findall('location'):
                    message.remove(location)
                if (translation_node.get('type') == 'unfinished'):
                    context.remove(message)
        num_messages = 0
        for context in root.findall('context'):
            for message in context.findall('message'):
                num_messages += 1
        if (num_messages < MIN_NUM_MESSAGES):
            print(('Removing %s, as it contains only %i messages' % (filepath, num_messages)))
            continue
        if reduce_diff_hacks:
            out = io.BytesIO()
            tree.write(out, encoding='utf-8')
            out = out.getvalue()
            out = out.replace(b' />', b'/>')
            with open(filepath, 'wb') as f:
                f.write(out)
        else:
            tree.write(filepath, encoding='utf-8')
    return have_errors
def postprocess_translations(reduce_diff_hacks=False):
    print('Checking and postprocessing...')
    if reduce_diff_hacks:
        global _orig_escape_cdata
        _orig_escape_cdata = ET._escape_cdata
        ET._escape_cdata = escape_cdata
    for (filename, filepath) in all_ts_files():
        os.rename(filepath, (filepath + '.orig'))
    have_errors = False
    for (filename, filepath) in all_ts_files('.orig'):
        parser = ET.XMLParser(encoding='utf-8')
        with open((filepath + '.orig'), 'rb') as f:
            data = f.read()
        data = remove_invalid_characters(data)
        tree = ET.parse(io.BytesIO(data), parser=parser)
        root = tree.getroot()
        for context in root.findall('context'):
            for message in context.findall('message'):
                numerus = (message.get('numerus') == 'yes')
                source = message.find('source').text
                translation_node = message.find('translation')
                if numerus:
                    translations = [i.text for i in translation_node.findall('numerusform')]
                else:
                    translations = [translation_node.text]
                for translation in translations:
                    if (translation is None):
                        continue
                    errors = []
                    valid = check_format_specifiers(source, translation, errors, numerus)
                    for error in errors:
                        print(('%s: %s' % (filename, error)))
                    if (not valid):
                        translation_node.clear()
                        translation_node.set('type', 'unfinished')
                        have_errors = True
                for location in message.findall('location'):
                    message.remove(location)
                if (translation_node.get('type') == 'unfinished'):
                    context.remove(message)
        num_messages = 0
        for context in root.findall('context'):
            for message in context.findall('message'):
                num_messages += 1
        if (num_messages < MIN_NUM_MESSAGES):
            print(('Removing %s, as it contains only %i messages' % (filepath, num_messages)))
            continue
        if reduce_diff_hacks:
            out = io.BytesIO()
            tree.write(out, encoding='utf-8')
            out = out.getvalue()
            out = out.replace(b' />', b'/>')
            with open(filepath, 'wb') as f:
                f.write(out)
        else:
            tree.write(filepath, encoding='utf-8')
    return have_errors