diff options
| -rw-r--r-- | examplerun.bat | 2 | ||||
| -rw-r--r-- | examplerun.sh | 2 | ||||
| -rw-r--r-- | jinja_helpers.py | 39 | ||||
| -rw-r--r-- | mark.py | 8 | ||||
| -rw-r--r-- | misc_classes.py | 15 | ||||
| -rw-r--r-- | reflect.py | 2 | ||||
| -rw-r--r-- | requirements.txt | 4 | ||||
| -rw-r--r-- | templates/tex.jinja2 | 26 | 
8 files changed, 94 insertions, 4 deletions
| diff --git a/examplerun.bat b/examplerun.bat index d595bca..00b0a80 100644 --- a/examplerun.bat +++ b/examplerun.bat @@ -1,3 +1,3 @@  zip -r 100301654.zip .\ExampleSubmission\
 -python .\mark.py -s 100301654.zip -a .\ExampleAssessments\example.yml -f md -o auto --md_show_all_run_output True
 +python .\mark.py -s 100301654.zip -a .\ExampleAssessments\example.yml -f yaml -o auto
  rm 100301654.zip
\ No newline at end of file diff --git a/examplerun.sh b/examplerun.sh index 0b06453..1b8e5b2 100644 --- a/examplerun.sh +++ b/examplerun.sh @@ -1,3 +1,3 @@  zip -r 100301654.zip ./ExampleSubmission/ -python ./mark.py -s 100301654.zip -a ./ExampleAssessments/example.yml -f text -o auto +python ./mark.py -s 100301654.zip -a ./ExampleAssessments/example.yml -f tex -o auto  rm 100301654.zip
\ No newline at end of file diff --git a/jinja_helpers.py b/jinja_helpers.py index e72db35..ca0748d 100644 --- a/jinja_helpers.py +++ b/jinja_helpers.py @@ -1,7 +1,14 @@  """Functions in this module will be avaliable to call in jinja templates""" +import subprocess +import lxml.html  import datetime +import tempfile +import shutil +import pdfkit  import yaml +import json  import re +import os  def get_datetime():      return str(datetime.datetime.now()) @@ -9,6 +16,38 @@ def get_datetime():  def recurse_class_tree_text(tree, indent = 4):      return yaml.dump(tree, indent = indent).replace(": {}", "") +def recurse_class_tree_forest(tree): +    return re.sub(r"\"|:|\{\}|,", "", json.dumps(tree, indent=4)).replace("{", "[").replace("}", "]") + +def junit_xml_to_html(junit_xml, student_id): +    # setup tempfiles for the junit xml and html +    with tempfile.NamedTemporaryFile(suffix = ".xml", mode = "w", delete = False) as xml_f: +        xml_f.write(junit_xml) +    html_path = os.path.join(tempfile.mkdtemp(), "junit.html") + +    # convert the junit xml to html +    subprocess.run(["junit2html", xml_f.name, html_path]) + +    # remove the html elements we don't like +    root = lxml.html.parse(html_path) +    for toremove in root.xpath("/html/body/h1"): +        toremove.getparent().remove(toremove) +    for toremove in root.xpath("/html/body/table"): +        toremove.getparent().remove(toremove) +    for toremove in root.xpath("/html/body/p"): +        toremove.getparent().remove(toremove) + +    # convert the html to pdf +    out_fname = "%s_test_report.pdf" % student_id +    pdfkit.from_string(lxml.etree.tostring(root).decode(), out_fname) + +    # remove the tempfiles +    input("%s continue..." % html_path) +    shutil.rmtree(os.path.split(html_path)[0]) +    os.remove(xml_f.name) + +    return out_fname +  def flatten_struct(struct):      # print("Attempting to flatten: ", struct)      out = {} @@ -28,8 +28,12 @@ def main(**kwargs):          elif kwargs["format"] == "json":              strout = json.dumps(output, indent = 4)          else: -            with open(os.path.join("templates", "%s.jinja2" % kwargs["format"]), "r") as f: -                jinja_template = jinja2.Template(f.read()) +            fp = os.path.join("templates", "%s.jinja2" % kwargs["format"]) +            if kwargs["format"] == "tex": +                jinja_template = misc_classes.latex_jinja_env.get_template("tex.jinja2") +            else: +                with open(fp, "r") as f: +                    jinja_template = jinja2.Template(f.read())              strout = jinja_template.render(**output, **jinja_helpers._get_helpers(), **kwargs) diff --git a/misc_classes.py b/misc_classes.py index 9fdded3..5bf16c1 100644 --- a/misc_classes.py +++ b/misc_classes.py @@ -2,8 +2,23 @@ from dataclasses import dataclass  import tempfile
  import zipfile
  import shutil
 +import jinja2
  import os
 +latex_jinja_env = jinja2.Environment(
 +	block_start_string = '((*',
 +	block_end_string = '*))',
 +	variable_start_string = '(((',
 +	variable_end_string = ')))',
 +	comment_start_string = "((#",
 +	comment_end_string = '#))',
 +	line_statement_prefix = '%%',
 +	line_comment_prefix = '%#',
 +	trim_blocks = True,
 +	autoescape = False,
 +	loader = jinja2.FileSystemLoader(os.path.abspath('templates'))
 +)
 +
  @dataclass
  class ExtractZipToTempDir(tempfile.TemporaryDirectory):
      zip_file:str
 @@ -158,6 +158,7 @@ class Reflect:                      self.get_class_full_name(i)                       for i in reversed(list(inspect.getmro(class_[0])))                  ]) +          tree = {}          added = []  # the expander makes duplicates. keep a list to remove them                          # sadly a collections.Counter doesnt work with lists of lists     @@ -166,6 +167,7 @@ class Reflect:                  setTree(tree, [i for i in reversed(s)][::-1])                  added.append(s) +        # print(tree)          # return inspect.getclasstree(classes)          return tree diff --git a/requirements.txt b/requirements.txt index 6d0d84b..5b00312 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,9 @@ +# sudo apt-get install wkhtmltopdf
  Jinja2==3.0.3
  misaka==2.1.1
  Pygments==2.10.0
  PyYAML==6.0
  pytest
 +junit2html
 +pdfkit
 +lxml
 diff --git a/templates/tex.jinja2 b/templates/tex.jinja2 new file mode 100644 index 0000000..bcc6aab --- /dev/null +++ b/templates/tex.jinja2 @@ -0,0 +1,26 @@ +\documentclass{article}
 +
 +\usepackage[margin=1in]{geometry} % margins
 +\usepackage{forest} % for the class tree
 +\usepackage{pdfpages}
 +
 +\author{((( student_no )))}
 +\title{((( name ))) - Automatic marking report}
 +
 +\begin{document}
 +
 +\maketitle
 +\section{Class Tree}
 +
 +\begin{figure}[h]
 +    \centering
 +    \begin{forest}
 +        ((( recurse_class_tree_forest(class_tree)|indent(8, False) )))
 +    \end{forest}
 +    \caption{Class inheritance tree}
 +\end{figure}
 +
 +\section{Tests}
 +\includepdf[pages={1-},scale=0.9]{((( junit_xml_to_html(test_results["junitxml"], student_no) )))}
 +
 +\end{document}
\ No newline at end of file | 
