lookingglass/hyperglass/render/__init__.py
2019-06-07 18:33:49 -07:00

150 lines
5.3 KiB
Python

# https://github.com/checktheroads/hyperglass
"""
Renders Jinja2 & Sass templates for use by the front end application
"""
# Standard Imports
import os
import subprocess
# Module Imports
import sass
import toml
import jinja2
from logzero import logger
from markdown2 import Markdown
from flask import render_template
# Project Imports
import hyperglass
from hyperglass import configuration
# Module Directories
working_directory = os.path.dirname(os.path.abspath(__file__))
hyperglass_root = os.path.dirname(hyperglass.__file__)
file_loader = jinja2.FileSystemLoader(working_directory)
env = jinja2.Environment(loader=file_loader)
# Configuration Imports
branding = configuration.branding()
general = configuration.general()
networks = configuration.networks()
defaults = {
"footer": """
+++
+++
By using {{ site_title }}, you agree to be bound by the following terms of use: All queries \
executed on this page are logged for analysis and troubleshooting. Users are prohibited from \
automating queries, or attempting to process queries in bulk. This service is provided on a best \
effort basis, and {{ org_name }} makes no availability or performance warranties or guarantees \
whatsoever.
""",
"bgp_aspath": r"""
+++
title = "Supported AS Path Patterns"
+++
{{ site_title }} accepts the following `AS_PATH` regular expression patterns:
| Expression | Match |
| :----------------------- | ----------------------------------------------------: |
| `_65000$` | Originated by AS65000 |
| `^65000\_` | Received from AS65000 |
| `_65000_` | Via AS65000 |
| `_65000_65001_` | Via AS65000 and AS65001 |
| `_65000(_.+_)65001$` | Anything from AS65001 that passed through AS65000 |
""",
"bgp_community": """
+++
title = "BGP Communities"
+++
{{ site_title }} makes use of the following BGP communities:
| Community | Description |
| :-------- | :---------- |
| `65000:1` | Example 1 |
| `65000:2` | Example 2 |
| `65000:3` | Example 3 |
""",
}
def content(file_name):
"""Converts Markdown documents to HTML, renders Jinja2 variables, renders TOML frontmatter \
variables, returns dictionary of variables and HTML content"""
html_classes = {"table": "table"}
markdown = Markdown(
extras={
"break-on-newline": True,
"code-friendly": True,
"tables": True,
"html-classes": html_classes,
}
)
delim = "+++"
file = os.path.join(working_directory, f"templates/content/{file_name}.md")
frontmatter_dict = None
if os.path.exists(file):
with open(file, "r") as file_raw:
file_read = file_raw.read()
_, frontmatter, content_md = file_read.split(delim)
frontmatter_dict = {file_name: toml.loads(frontmatter)}
content_md_template = jinja2.Environment(loader=jinja2.BaseLoader).from_string(
content_md
)
else:
content_read = defaults[file_name]
_, frontmatter, content_md = content_read.split(delim)
frontmatter_dict = {file_name: toml.loads(frontmatter)}
content_md_template = jinja2.Environment(loader=jinja2.BaseLoader).from_string(
content_md
)
content_rendered = content_md_template.render(
**general, **branding, **frontmatter_dict
)
content_html = markdown.convert(content_rendered)
frontmatter_dict[file_name]["content"] = content_html
return frontmatter_dict
def html(t):
"""Renders Jinja2 HTML templates"""
content_name_list = ["footer", "bgp_aspath", "bgp_community"]
content_dict = {}
for content_name in content_name_list:
# content_file = os.path.join(working_directory, f"templates/content/{c}.md")
content_data = content(content_name)
content_dict.update(content_data)
if t == "index":
template = env.get_template("templates/index.html")
elif t == "429":
template = env.get_template("templates/429.html")
elif t == "500":
template = env.get_template("templates/500.html")
return template.render(
**general, **branding, **content_dict, device_networks=networks
)
def css():
"""Renders Jinja2 template to Sass file, then compiles Sass as CSS"""
scss_file = os.path.join(hyperglass_root, "static/sass/hyperglass.scss")
css_file = os.path.join(hyperglass_root, "static/css/hyperglass.css")
# Renders Jinja2 template as Sass file
try:
template_file = "templates/hyperglass.scss"
template = env.get_template(template_file)
rendered_output = template.render(**branding)
with open(scss_file, "w") as scss_output:
scss_output.write(rendered_output)
except:
logger.error(f"Error rendering Jinja2 template {template_file}.")
raise
# Compiles Sass to CSS
try:
generated_sass = sass.compile(filename=scss_file)
with open(css_file, "w") as css_output:
css_output.write(generated_sass)
logger.info(f"Compiled Sass file {scss_file} to CSS file {css_file}.")
except:
logger.error(f"Error compiling Sass in file {scss_file}.")
raise