2020-03-30 08:25:29 +00:00
|
|
|
import hashlib
|
2019-03-26 09:50:28 +00:00
|
|
|
import logging
|
|
|
|
import os
|
|
|
|
import shutil
|
2020-03-30 08:25:29 +00:00
|
|
|
import subprocess
|
2019-03-26 09:50:28 +00:00
|
|
|
|
2020-04-01 09:45:48 +00:00
|
|
|
import closure
|
2019-03-26 09:50:28 +00:00
|
|
|
import cssmin
|
|
|
|
import htmlmin
|
2020-02-18 14:19:44 +00:00
|
|
|
import jinja2
|
2019-03-26 09:50:28 +00:00
|
|
|
import jsmin
|
|
|
|
|
2020-03-30 08:25:29 +00:00
|
|
|
import mdx_clickhouse
|
|
|
|
|
2020-02-18 14:19:44 +00:00
|
|
|
|
2020-03-13 19:35:03 +00:00
|
|
|
def copy_icons(args):
|
|
|
|
logging.info('Copying icons')
|
|
|
|
icons_dir = os.path.join(args.output_dir, 'images', 'icons')
|
|
|
|
os.makedirs(icons_dir)
|
|
|
|
for icon in [
|
|
|
|
'github',
|
|
|
|
'edit',
|
|
|
|
'external-link'
|
|
|
|
]:
|
|
|
|
icon = '%s.svg' % icon
|
|
|
|
icon_src = os.path.join(args.website_dir, 'images', 'feathericons', 'icons', icon)
|
|
|
|
icon_dst = os.path.join(icons_dir, icon)
|
|
|
|
shutil.copy2(icon_src, icon_dst)
|
|
|
|
|
|
|
|
|
2019-03-26 09:50:28 +00:00
|
|
|
def build_website(args):
|
|
|
|
logging.info('Building website')
|
2020-02-18 14:19:44 +00:00
|
|
|
env = jinja2.Environment(
|
2020-03-13 19:35:03 +00:00
|
|
|
loader=jinja2.FileSystemLoader(args.website_dir),
|
2020-03-30 08:25:29 +00:00
|
|
|
extensions=[
|
|
|
|
'jinja2.ext.i18n',
|
|
|
|
'jinja2_highlight.HighlightExtension'
|
|
|
|
]
|
2020-02-18 14:19:44 +00:00
|
|
|
)
|
2020-03-13 19:35:03 +00:00
|
|
|
env.extend(jinja2_highlight_cssclass='syntax p-3 my-3')
|
2020-03-30 08:25:29 +00:00
|
|
|
translations_dir = os.path.join(args.website_dir, 'locale')
|
|
|
|
env.install_gettext_translations(
|
|
|
|
mdx_clickhouse.get_translations(translations_dir, 'en'),
|
|
|
|
newstyle=True
|
|
|
|
)
|
2020-02-18 14:19:44 +00:00
|
|
|
|
2019-03-26 09:50:28 +00:00
|
|
|
shutil.copytree(
|
|
|
|
args.website_dir,
|
|
|
|
args.output_dir,
|
|
|
|
ignore=shutil.ignore_patterns(
|
|
|
|
'*.md',
|
|
|
|
'*.sh',
|
2020-03-30 08:25:29 +00:00
|
|
|
'*.css',
|
|
|
|
'*.js',
|
2019-03-26 09:50:28 +00:00
|
|
|
'build',
|
|
|
|
'docs',
|
|
|
|
'public',
|
2020-03-13 19:35:03 +00:00
|
|
|
'node_modules',
|
|
|
|
'templates',
|
|
|
|
'feathericons'
|
2019-03-26 09:50:28 +00:00
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2020-02-18 14:19:44 +00:00
|
|
|
for root, _, filenames in os.walk(args.output_dir):
|
|
|
|
for filename in filenames:
|
2020-03-22 12:12:53 +00:00
|
|
|
if filename == 'main.html':
|
|
|
|
continue
|
|
|
|
|
2020-02-18 14:19:44 +00:00
|
|
|
path = os.path.join(root, filename)
|
2020-03-30 08:25:29 +00:00
|
|
|
if not (filename.endswith('.html') or filename.endswith('.js')):
|
2020-02-18 14:19:44 +00:00
|
|
|
continue
|
|
|
|
logging.info('Processing %s', path)
|
|
|
|
with open(path, 'rb') as f:
|
|
|
|
content = f.read().decode('utf-8')
|
|
|
|
|
|
|
|
template = env.from_string(content)
|
|
|
|
content = template.render(args.__dict__)
|
|
|
|
|
|
|
|
with open(path, 'wb') as f:
|
|
|
|
f.write(content.encode('utf-8'))
|
|
|
|
|
2019-03-26 09:50:28 +00:00
|
|
|
|
2020-03-30 11:39:26 +00:00
|
|
|
def get_css_in(args):
|
|
|
|
return [
|
|
|
|
f"'{args.website_dir}/css/bootstrap.css'",
|
|
|
|
f"'{args.website_dir}/css/docsearch.css'",
|
|
|
|
f"'{args.website_dir}/css/base.css'",
|
|
|
|
f"'{args.website_dir}/css/docs.css'",
|
2020-03-30 08:25:29 +00:00
|
|
|
f"'{args.website_dir}/css/highlight.css'"
|
2020-03-30 11:39:26 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def get_js_in(args):
|
|
|
|
return [
|
|
|
|
f"'{args.website_dir}/js/jquery-3.4.1.js'",
|
|
|
|
f"'{args.website_dir}/js/popper.js'",
|
|
|
|
f"'{args.website_dir}/js/bootstrap.js'",
|
|
|
|
f"'{args.website_dir}/js/base.js'",
|
|
|
|
f"'{args.website_dir}/js/index.js'",
|
|
|
|
f"'{args.website_dir}/js/docsearch.js'",
|
|
|
|
f"'{args.website_dir}/js/docs.js'"
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def minify_website(args):
|
|
|
|
css_in = ' '.join(get_css_in(args))
|
2020-03-30 08:25:29 +00:00
|
|
|
css_out = f'{args.output_dir}/css/base.css'
|
|
|
|
if args.minify:
|
|
|
|
command = f"purifycss -w '*algolia*' --min {css_in} '{args.output_dir}/*.html' " \
|
|
|
|
f"'{args.output_dir}/docs/en/**/*.html' '{args.website_dir}/js/**/*.js' > {css_out}"
|
|
|
|
else:
|
|
|
|
command = f'cat {css_in} > {css_out}'
|
|
|
|
logging.info(command)
|
|
|
|
output = subprocess.check_output(command, shell=True)
|
|
|
|
logging.debug(output)
|
|
|
|
with open(css_out, 'rb') as f:
|
|
|
|
css_digest = hashlib.sha3_224(f.read()).hexdigest()[0:8]
|
|
|
|
|
2020-03-30 11:39:26 +00:00
|
|
|
js_in = get_js_in(args)
|
2020-03-30 08:25:29 +00:00
|
|
|
js_out = f'{args.output_dir}/js/base.js'
|
|
|
|
if args.minify:
|
|
|
|
js_in = [js[1:-1] for js in js_in]
|
|
|
|
closure_args = [
|
|
|
|
'--js', *js_in, '--js_output_file', js_out,
|
|
|
|
'--compilation_level', 'SIMPLE',
|
|
|
|
'--dependency_mode', 'NONE',
|
|
|
|
'--third_party', '--use_types_for_optimization',
|
2020-03-31 10:35:56 +00:00
|
|
|
'--isolation_mode', 'IIFE'
|
2020-03-30 08:25:29 +00:00
|
|
|
]
|
|
|
|
logging.info(closure_args)
|
|
|
|
if closure.run(*closure_args):
|
|
|
|
raise RuntimeError('failed to run closure compiler')
|
|
|
|
|
|
|
|
else:
|
|
|
|
logging.info(command)
|
|
|
|
js_in = ' '.join(js_in)
|
|
|
|
output = subprocess.check_output(f'cat {js_in} > {js_out}', shell=True)
|
|
|
|
logging.debug(output)
|
|
|
|
with open(js_out, 'rb') as f:
|
|
|
|
js_digest = hashlib.sha3_224(f.read()).hexdigest()[0:8]
|
|
|
|
logging.info(js_digest)
|
|
|
|
|
2020-02-14 09:34:57 +00:00
|
|
|
if args.minify:
|
2020-02-18 14:19:44 +00:00
|
|
|
logging.info('Minifying website')
|
2020-02-14 09:34:57 +00:00
|
|
|
for root, _, filenames in os.walk(args.output_dir):
|
|
|
|
for filename in filenames:
|
|
|
|
path = os.path.join(root, filename)
|
|
|
|
if not (
|
|
|
|
filename.endswith('.html') or
|
2020-03-30 08:25:29 +00:00
|
|
|
filename.endswith('.css')
|
2020-02-14 09:34:57 +00:00
|
|
|
):
|
|
|
|
continue
|
2020-02-18 14:19:44 +00:00
|
|
|
|
2020-02-14 09:34:57 +00:00
|
|
|
logging.info('Minifying %s', path)
|
|
|
|
with open(path, 'rb') as f:
|
|
|
|
content = f.read().decode('utf-8')
|
2020-02-18 14:20:53 +00:00
|
|
|
if filename.endswith('.html'):
|
2020-04-10 14:56:09 +00:00
|
|
|
if not content.startswith('<!-- Redirect: '):
|
|
|
|
content = htmlmin.minify(content, remove_empty_space=False)
|
2020-03-30 08:25:29 +00:00
|
|
|
content = content.replace('base.css?css_digest', f'base.css?{css_digest}')
|
|
|
|
content = content.replace('base.js?js_digest', f'base.js?{js_digest}')
|
2020-02-18 14:20:53 +00:00
|
|
|
elif filename.endswith('.css'):
|
|
|
|
content = cssmin.cssmin(content)
|
|
|
|
elif filename.endswith('.js'):
|
|
|
|
content = jsmin.jsmin(content)
|
2020-02-14 09:34:57 +00:00
|
|
|
with open(path, 'wb') as f:
|
|
|
|
f.write(content.encode('utf-8'))
|