diff options
| -rw-r--r-- | examplerun.bat | 2 | ||||
| -rw-r--r-- | jinja_helpers.py | 26 | ||||
| -rw-r--r-- | requirements.txt | 4 | ||||
| -rw-r--r-- | smarker.conf | 4 | ||||
| -rw-r--r-- | templates/html.jinja2 | 0 | ||||
| -rw-r--r-- | templates/md.jinja2 | 114 | 
6 files changed, 137 insertions, 13 deletions
| diff --git a/examplerun.bat b/examplerun.bat index 338908c..01e133c 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
 +python .\mark.py -s 100301654.zip -a .\ExampleAssessments\example.yml -f md
  rm 100301654.zip
\ No newline at end of file diff --git a/jinja_helpers.py b/jinja_helpers.py index cf68748..faf6266 100644 --- a/jinja_helpers.py +++ b/jinja_helpers.py @@ -1,7 +1,11 @@  """Functions in this module will be avaliable to call in jinja templates""" +import datetime  import yaml  import re +def get_datetime(): +    return str(datetime.datetime.now()) +  def recurse_class_tree_text(tree, indent = 4):      return yaml.dump(tree, indent = indent).replace(": {}", "") @@ -12,14 +16,6 @@ def flatten_struct(struct):          out[key] = s[key]      return out -def _get_helpers(): -    import reflect -    import os - -    r = reflect.Reflect(os.getcwd()) -    r.import_module("jinja_helpers") -    return {k: v[0] for k, v in r.get_functions("jinja_helpers").items()} -  def get_required_num_args(funcname):      return int(re.findall(r"(?<=\()(\d+)(?=\))", funcname)[0]) @@ -29,6 +25,12 @@ def bool_to_yesno(b:bool):      else:          return "NO" +def bool_to_checkbox(b:bool): +    if b: +        return "[x]" +    else: +        return "[ ]" +  def len_documentation(comments, docs):      """This function isn't in jinja"""      if comments == "None": @@ -46,6 +48,14 @@ def len_documentation(comments, docs):  def get_source_numlines(source):      return "%d lines (%d characters)" % (source.count("\n"), len(source)) +def _get_helpers(): +    import reflect +    import os + +    r = reflect.Reflect(os.getcwd()) +    r.import_module("jinja_helpers") +    return {k: v[0] for k, v in r.get_functions("jinja_helpers").items()} +  if __name__ == "__main__":      # import json      # with open("100301654_report.json", "r") as f: diff --git a/requirements.txt b/requirements.txt index 466a437..f88b5ac 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@  Jinja2==3.0.3 +misaka==2.1.1 +Pygments==2.10.0  PyYAML==6.0 -pytest
\ No newline at end of file +pytest diff --git a/smarker.conf b/smarker.conf index 523f892..aa5a415 100644 --- a/smarker.conf +++ b/smarker.conf @@ -7,9 +7,7 @@ passwd = smarkerPassword  [md]
  show_full_docs = True
  show_source = True
 -show_numlines = True
  [txt]
  show_full_docs = True
 -show_source = True
 -show_numlines = True
\ No newline at end of file +show_source = True
\ No newline at end of file diff --git a/templates/html.jinja2 b/templates/html.jinja2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/templates/html.jinja2 diff --git a/templates/md.jinja2 b/templates/md.jinja2 new file mode 100644 index 0000000..400da26 --- /dev/null +++ b/templates/md.jinja2 @@ -0,0 +1,114 @@ +{%- macro expand_function(function_name, function_contents, x = "Function") -%} + - `{{ function_name }}`: +{%- if function_contents["present"] %} +    - **Arguments:**  +        - `{{ function_contents["arguments"] }}`  +        - {{ bool_to_checkbox(function_contents["minimum_arguments"] >= get_required_num_args(function_name)) }} Enough?  +    - **Documentation**: +        - {{ len_documentation(function_contents["documentation"]["comments"], function_contents["documentation"]["doc"]) }} characters long +{%- if md_show_full_docs == "True" %} +        - Comments: +            {%- if function_contents["documentation"]["comments"] == "None" %} +            - [ ] No comments present +{%- else %} +{{ code_block(function_contents["documentation"]["comments"])|indent(12, True) }} +{%- endif %} +        - Docstring: +{%- if function_contents["documentation"]["doc"] == "None" %} +            - [ ] No docstring present +{%- else %} +{{ code_block(function_contents["documentation"]["doc"])|indent(12, True) }} +{%- endif -%} +{%- endif %} +     - **Source**: +        - {{ get_source_numlines(function_contents["source_code"]) }} +{%- if md_show_source == "True" %} +        - Code: +{{ code_block(function_contents["source_code"])|indent(12, True) }} +{%- endif %} +{%- else %} +    - [ ] {{ x }} not present +{%- endif %} +{%- endmacro -%} + +{%- macro code_block(code) -%} +``` +{{ code }} +``` +{%- endmacro -%} + +# {{ name }} - Student ID: {{ student_no }} Automatic marking report  +Report generated at {{ get_datetime() }} +## Class Tree:  + +``` +{{ recurse_class_tree_text(class_tree) }} +``` + +## File Analysis + +{%- set flat_files = flatten_struct(files) %} +{% for filename, files_contents in flat_files.items() %} +### File `{{ filename }}`: +{%- if files_contents["present"] -%} +{%- if files_contents["has_exception"] %} +*** File cannot be run - has compile time exception *** +Please note that this file cannot be analysed or have tests preformed upon it-  +    this can lead to the whole test suite failing if another module imports this. + - Exception Type: `{{ files_contents["exception"]["type"] }}` + - Exception String: `{{ files_contents["exception"]["str"] }}` + - Full Traceback: +``` +{{ files_contents["exception"]["traceback"] }} +``` +{%- else %} + - #### Documentation: +    {%- set len_docs = len_documentation(files_contents["documentation"]["comments"], files_contents["documentation"]["doc"]) %} +    - {{ len_docs }} characters long +{%- if md_show_full_docs == "True" %} +    - ##### Comments: +{%- if files_contents["documentation"]["comments"] == "None" %} +        - [ ] No comments present +{%- else %} +{{ code_block(files_contents["documentation"]["comments"])|indent(8, True) }} +{%- endif %} +    - ##### Docstring: +{%- if files_contents["documentation"]["doc"] == "None" %} +        - [ ] No docstring present +{%- else %} +{{ code_block(files_contents["documentation"]["doc"])|indent(8, True) }} +{%- endif -%} +{%- endif %} +{%- if "classes" in files_contents.keys() %} +    - #### Classes: +{%- set flat_classes = flatten_struct(files_contents["classes"]) -%} +{% for class_name, class_contents in flat_classes.items() %} +        - ##### `{{ class_name}}`: +{%- if "methods" in class_contents.keys() %} +            - ###### Methods: +{%- set flat_methods = flatten_struct(class_contents["methods"]) -%} +{%- for method_name, method_contents in flat_methods.items() %} +{{ expand_function(method_name, method_contents, "Method")|indent(16, True) }} +{%- endfor -%} +{%- endif -%} +{%- endfor -%} +{%- endif -%} +{% if "functions" in files_contents.keys() %} +    - #### Functions: +{%- set flat_functions = flatten_struct(files_contents["functions"]) %} +{%- for function_name, function_contents in flat_functions.items() %} +{{ expand_function(function_name, function_contents)|indent(8, True) }} +{%- endfor -%} +{%- endif -%} +{%- endif -%} +{% else %} + - [ ] File not present +{% endif %} +{% endfor %} + +{% if out != "stdout" and format != "html" -%} +## Tests: +``` +{{ test_results["pytest_report"].replace("\n", "") }} +``` +{%- endif -%}
\ No newline at end of file | 
