Source

python-doc-ja / tools / cmp_pot.py

The locale branch has multiple heads

Full commit
# -*- coding: utf-8 -*-

# locale/en/ と locale/ja/ 以下にある pot ファイルを比較して
# locale/html/ に html ファイルを作成する

import re
import os
import glob
import sys
from collections import defaultdict
import polib
import jinja2

exclude_pattern = '^documenting/'

index_template = jinja2.Template(u"""\
<html>
<body>
<ul>
{% for link, sizes, diff in index -%}
<li><a href="{{ link|e }}">{{ link|e }}</a><span{{ ' style="color:red"' if diff }}>({{ sizes|join(', ') }})<span></li>
{%- endfor %}
</ul>
</body>
</html>
""")

table_template = jinja2.Template(u"""\
<html>
<body>
<table border="1"{{ ' bordercolor="red"' if mismatch }}>
{% for row in table -%}
<tr>
{% for cell in row -%}
<td><pre>{{ cell|e }}</pre></td>
{%- endfor %}
</tr>
{%- endfor %}
</table>
</body>
</html>
""")


def find_files(root, pattern):
    for dirpath, dirnames, filenames in os.walk(root):
        for filename in glob.glob(os.path.join(dirpath, pattern)):
            path = os.path.join(dirpath, filename)
            if os.path.isfile(path):
                yield os.path.relpath(path, root)


def split_pot(sources, outdir):
    all_entries = defaultdict(lambda: defaultdict(list))
    for i, (source, reverse) in enumerate(sources):
        po = polib.pofile(source)
        for j, entry in enumerate(po):
            for occur in entry.occurrences:
                target, line = occur
                all_entries[target][i].append((int(line), j, reverse, entry))

    src_po = polib.pofile(sources[0][0])
    for target in all_entries:
        poname = re.sub(r'^(?:.*?/){2}(.*)\.rst$', r'\1.po', target)
        fpath = os.path.join(outdir, poname)

        pofiles = [None] * len(sources)
        for i, values in sorted(all_entries[target].items()):
            po = pofiles[i] = polib.POFile(fpath=fpath, wrapwidth=sys.maxint)
            po.header = src_po.header
            po.metadata = src_po.metadata
            for line, _, reverse, entry in sorted(values):
                kw = {
                    "occurrences": [(target, str(line))],
                    }
                text = entry.msgid.replace('\n', ' ')
                if reverse:
                    kw["msgstr"] = text
                else:
                    kw["msgid"] = text
                entry = polib.POEntry(**kw)
                po.append(entry)
        yield poname, pofiles


def main():
    here = os.path.dirname(os.path.abspath(__file__))
    localedir = os.path.join(os.path.dirname(here), 'locale')
    en_files = list(find_files(os.path.join(localedir, 'en'), '*.pot'))
    ja_files = list(find_files(os.path.join(localedir, 'ja'), '*.pot'))
    index = []
    for filename in sorted(set(en_files).union(ja_files)):
        sources = []
        if filename in en_files:
            sources.append((os.path.join(localedir, 'en', filename), False))
        if filename in ja_files:
            sources.append((os.path.join(localedir, 'ja', filename), True))
        outdir = os.path.join(localedir, 'html')
        for poname, pofiles in split_pot(sources, outdir):
            if re.match(exclude_pattern, poname):
                continue
            print poname
            sizes = []
            for pofile in pofiles:
                if pofile:
                    size = len(pofile)
                else:
                    size = 0
                sizes.append(size)
            table = []
            for i in xrange(max(sizes)):
                row = []
                for pofile in pofiles:
                    if pofile and i < len(pofile):
                        cell = pofile[i].__unicode__(wrapwidth=60)
                    else:
                        cell = ""
                    row.append(cell)
                table.append(row)
            mismatch = False
            for pofile in pofiles:
                if pofile is None or len(pofile) != size:
                    mismatch = True
            outpath = os.path.join(outdir, re.sub(r'^(../)+', '', poname))
            dirpath = os.path.dirname(outpath)
            if not os.path.exists(dirpath):
                os.makedirs(dirpath)
            content = table_template.render(table=table, mismatch=mismatch)
            index.append((os.path.relpath(outpath + '.html', outdir),
                          sizes, len(set(sizes)) > 1))
            with open(outpath + '.html', 'w') as wf:
                wf.write(content.encode('utf-8'))

    content = index_template.render(index=sorted(index))
    with open(os.path.join(outdir, 'index.html'), 'w') as wf:
        wf.write(content.encode('utf-8'))


if __name__ == '__main__':
    main()