Skip to content

Commit

Permalink
Replace HTML template of table-generator with some Python code
Browse files Browse the repository at this point in the history
Although this is not as nice to read, getting rid of Tempita is worth
it. Since we dump most data as JSON, the template was not that large
anymore anyway.
Part of #480.
  • Loading branch information
PhilippWendler committed May 8, 2020
1 parent b08e68d commit b8a5bbc
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 90 deletions.
57 changes: 18 additions & 39 deletions benchexec/tablegenerator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,10 @@
import benchexec.model as model
import benchexec.result as result
import benchexec.util
from benchexec.tablegenerator import util
from benchexec.tablegenerator import htmltable, util
from benchexec.tablegenerator.columns import Column, ColumnType
import zipfile

# Workaround for making Tempita work on Python 3.8+ Remove as part of #480
import cgi

if not hasattr(cgi, "escape"):
import html

cgi.escape = html.escape

# Process pool for parallel work.
# Some of our loops are CPU-bound (e.g., statistics calculations), thus we use
Expand Down Expand Up @@ -83,12 +76,7 @@
for path in ["vendors.min.", "bundle.min."]
]

TEMPLATE_FILE_NAME = os.path.join(os.path.dirname(__file__), "template.{format}")

TEMPLATE_FORMATS = ["html", "csv"]
TEMPLATE_NAMESPACE = {
"json": util.to_json,
}

_BYTE_FACTOR = 1000 # bytes in a kilobyte

Expand Down Expand Up @@ -1990,35 +1978,26 @@ def write_table_in_format(template_format, outfile, template_values, show_table)
write_csv_table(out, *args)
else:
write_csv_table(sys.stdout, *args)
return

# read template
Template = tempita.HTMLTemplate if template_format == "html" else tempita.Template
template_file = TEMPLATE_FILE_NAME.format(format=template_format)
template_content = util.read_bundled_file(template_file)
template = Template(template_content, namespace=TEMPLATE_NAMESPACE)

result = template.substitute(**template_values)

# write file
if not outfile:
print(result, end="")
else:
# Force HTML file to be UTF-8 regardless of system encoding because it actually
# declares itself to be UTF-8 in a meta tag.
encoding = "utf-8" if template_format == "html" else None
with open(outfile, "w", encoding=encoding) as file:
file.write(result)
assert template_format == "html"
if outfile:
# Force HTML file to be UTF-8 regardless of system encoding because it actually
# declares itself to be UTF-8 in a meta tag.
with open(outfile, "w", encoding="utf-8") as out:
htmltable.write_html_table(out, template_values)

if show_table:
try:
subprocess.Popen(
["xdg-open", outfile],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
except OSError:
pass
if show_table:
try:
subprocess.Popen(
["xdg-open", outfile],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
except OSError:
pass
else:
htmltable.write_html_table(sys.stdout, template_values)


def basename_without_ending(file):
Expand Down
85 changes: 85 additions & 0 deletions benchexec/tablegenerator/htmltable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# BenchExec is a framework for reliable benchmarking.
# This file is part of BenchExec.
#
# Copyright (C) 2007-2019 Dirk Beyer
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import json

from benchexec import __version__


def write_html_table(out, template_values):
def write_tags(tag_name, contents):
for content in contents:
out.write("<")
out.write(tag_name)
out.write(">\n")
out.write(content)
out.write("\n</")
out.write(tag_name)
out.write(">\n")

def write_json_part(name, value=None, last=False):
out.write(' "')
out.write(name)
out.write('": ')
out.write(json.dumps(value or template_values[name], sort_keys=True))
if not last:
out.write(",")
out.write("\n")

out.write(
"""<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="generator" content="BenchExec table-generator {version}">
<title>{title} &ndash; BenchExec results</title>
""".format(
title=template_values["title"], version=__version__
)
)
write_tags("style", template_values["app_css"])
out.write(
"""</head>
<body>
<div id="root"></div>
<noscript>
This is an interactive table for viewing results produced by
<a href="https://github.com/sosy-lab/benchexec" target="_blank" rel="noopener noreferrer">BenchExec</a>.
Please enable JavaScript to use it.
</noscript>
<script>
const data = {
"""
)
write_json_part("version", __version__)
write_json_part("head")
write_json_part("tools")
write_json_part("rows")
write_json_part("stats", last=True)
out.write(
"""};
window.data = data;
</script>
"""
)
write_tags("script", template_values["app_js"])
out.write("</body>\n</html>\n")
45 changes: 0 additions & 45 deletions benchexec/tablegenerator/template.html

This file was deleted.

6 changes: 0 additions & 6 deletions benchexec/tablegenerator/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,10 @@
from decimal import Decimal
import glob
import io
import json
import logging
import os
from urllib.parse import quote as url_quote
import urllib.request
import tempita
import benchexec.util


Expand Down Expand Up @@ -213,10 +211,6 @@ def flatten(list_):
return [value for sublist in list_ for value in sublist]


def to_json(obj):
return tempita.html(json.dumps(obj, sort_keys=True))


def prepare_run_sets_for_js(run_sets):
# Almost all run_set attributes are relevant, use blacklist here
run_set_exclude_keys = {"filename"}
Expand Down

0 comments on commit b8a5bbc

Please sign in to comment.