Mini Shell

Direktori : /usr/share/imunify360-webshield/
Upload File :
Current File : //usr/share/imunify360-webshield/build_includes.py

#!/opt/imunify360/venv/bin/python3

import codecs
import functools
import os
import re
import subprocess
import sys

import jinja2
from babel.messages.pofile import read_po

EXT = 'html'
LANG_BASENAME = 'lang.conf'
LANG_LINE = '"~^{lang}" {lang};'
LOCALE_PATH = 'locale'

INCLUDE = '{{["{path}/" .. (ngx.var.{item}_lang or "en") .. "/{name}.{ext}"]}}'
CURRENT_LOCALE = '{{{{ngx.var.{item}_lang or "en"}}}}'

VARIABLES = {
    'client_ip': '{{ngx.var.wsuserip or ngx.var.remote_addr}}',
    "domain": '{{ngx.var.host or "Server"}}',
    "webshield": True,
}


def _gettext(message, **_):
    name = _normalize(message)
    item = ''
    return INCLUDE.format(path=LOCALE_PATH, item=item, name=name, ext=EXT)


def _captcha_gettext(message, **_):
    name = _normalize(message)
    item = 'captcha'
    return INCLUDE.format(path=LOCALE_PATH, item=item, name=name, ext=EXT)


def _splashscreen_gettext(message, **_):
    name = _normalize(message)
    item = 'splashscreen'
    return INCLUDE.format(path=LOCALE_PATH, item=item, name=name, ext=EXT)


@functools.lru_cache()
def _normalize(s):
    s = re.sub('<.*?>', '', s)
    s = re.sub('{.*?}', '', s)
    s = s.lower()
    s = re.sub('[^a-z0-9 ]', '', s)
    s = re.sub('\s+', '_', s)
    return s


def _mkdir_p(path):
    try:
        os.makedirs(path)
    except FileExistsError:
        pass


class Template:

    items = {
        'captcha': _captcha_gettext,
        'splashscreen': _splashscreen_gettext}

    def __init__(self, tpl_path, item):
        path, self.filename = os.path.split(tpl_path)
        jinja_env = jinja2.Environment(
            extensions=['jinja2.ext.i18n'],
            loader=jinja2.FileSystemLoader(path or './'),
        )
        jinja_env.globals['_'] = self.items.get(item, _gettext)
        self.jinja_env = jinja_env

    def render(self, context):
        return self.jinja_env.get_template(self.filename).render(context)


def render_template(item, source, destination_dir):
    template = os.path.join(source, item, 'templates', 'index.html')
    destination = os.path.join(destination_dir, item)
    _mkdir_p(destination)
    fullname = os.path.join(destination, 'index.html')
    _vars = dict(VARIABLES, current_locale=CURRENT_LOCALE.format(item=item))
    with codecs.open(fullname, 'w', encoding='utf-8') as w:
        render = Template(template, item).render(_vars)
        w.write(render)


def _make_locale(item, translation_dir, destination_dir, lang):
    path = os.path.join(translation_dir, lang, 'LC_MESSAGES', 'messages.po')
    with codecs.open(path, encoding='utf-8') as r:
        po = read_po(r)

    locale = os.path.join(destination_dir, LOCALE_PATH, lang)
    _mkdir_p(locale)
    _vars = dict(VARIABLES, current_locale=CURRENT_LOCALE.format(item=item))
    for message in po:
        if message.id:
            basename = os.extsep.join([_normalize(message.id), EXT])
            msg = message.string or message.id
            rendered = msg.format(
                client_ip=_vars['client_ip'],
                current_locale=_vars['current_locale'],
                domain=_vars['domain'],
                webshield=_vars['webshield'])
            fullname = os.path.join(locale, basename)
            with codecs.open(fullname, 'w', encoding='utf-8') as w:
                w.write(rendered)


def convert_translations(item, source, dst_prefix):
    translation_dir = os.path.join(source, item, 'translations', 'locale')
    destination_dir = os.path.join(dst_prefix, item)
    locales = os.listdir(translation_dir)
    for lang in locales:
        _make_locale(item, translation_dir, destination_dir, lang)
    return locales


def print_lang(name, locales, target):
    if target is not None:
        conf_dir = os.path.join(target, name)
        _mkdir_p(conf_dir)
        conf_path = os.path.join(conf_dir, LANG_BASENAME)
        with codecs.open(conf_path, 'w', encoding='utf-8') as w:
            for lang in sorted(locales):
                w.write(LANG_LINE.format(lang=lang) + '\n')
    else:
        for lang in sorted(locales):
            print(LANG_LINE.format(lang=lang))


def copy_static(source, destination, prefix):
    static_src = os.path.join(source, prefix, 'static')
    if os.path.isdir(static_src):
        static_dst = os.path.join(
            destination, prefix, 'a9bc224bd710f56d27affffddc764239b58c3faa0')
        _mkdir_p(static_dst)

        # '/.' is a special syntax of 'cp' command, meaning copying
        # the contents of the directory, not the directory itself
        cmd = ['cp', '-r', static_src + '/.', static_dst + '/']
        subprocess.call(cmd,
                        stdout=subprocess.DEVNULL,
                        stderr=subprocess.DEVNULL)


def main():
    items = sys.argv[1].split(',')
    src = sys.argv[2]
    dst = sys.argv[3]
    target = sys.argv[4] if len(sys.argv) > 4 else None
    for item in items:
        render_template(item, src, dst)
        locales = convert_translations(item, src, dst)
        print_lang(item, locales, target)
        copy_static(src, dst, item)


if __name__ == '__main__':
    main()

Zerion Mini Shell 1.0