Mini Shell
#!/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