diff --git a/src/canvaslms/cli/assignments.nw b/src/canvaslms/cli/assignments.nw index 7e2b024..ba9cb69 100644 --- a/src/canvaslms/cli/assignments.nw +++ b/src/canvaslms/cli/assignments.nw @@ -17,6 +17,7 @@ import canvasapi import canvaslms.cli.courses as courses import canvaslms.hacks.canvasapi import csv +import json import os import pypandoc import re @@ -141,7 +142,7 @@ We add the subparser for [[assignments]]. assignments_parser = subp.add_parser("assignments", help="Lists assignments of a course", description="Lists assignments of a course. " - "Output, CSV-format: ") + <>) assignments_parser.set_defaults(func=assignments_command) add_assignment_option(assignments_parser) @ Now, that [[assignments_command]] function must take three arguments: @@ -157,11 +158,21 @@ def assignments_command(config, canvas, args): We then simply get the filtered list from the processing of the assignment options, stored in [[assignment_list]] above. -Then we will print the most useful attributes (mentioned in the help text -above) of an assignment in CSV format. +Then we will print the most useful attributes. +<>= +"Output, CSV-format: " +" " +" " <>= for assignment in assignment_list: - output.writerow([assignment.assignment_group.name, assignment.name]) + output.writerow([ + assignment.course.course_code, + assignment.assignment_group.name, + assignment.name, + assignment.due_at, + assignment.unlock_at, + assignment.lock_at + ]) @ @@ -252,15 +263,85 @@ The assignment contents given by Canvas is HTML, we want to pipe that through <>= def format_assignment(assignment): """Returns an assignment formatted for the terminal""" - instruction = pypandoc.convert_text( - assignment.description, "md", format="html") + text = f""" +<> - return f"""# {assignment.name} +""" -{instruction} + if assignment.description: + instruction = pypandoc.convert_text( + assignment.description, "md", format="html") + text += f"## Instruction\n\n{instruction}\n\n" + <> + else: + <> + text += f"## Assignment data\n\n```json\n{format_json(assignment)}\n```\n" -URL: {assignment.html_url} -Submissions: {assignment.submissions_download_url}""" + return text +@ + +\subsection{Assignment metadata} + +Now let's look at the metadata to add. +<>= +# {assignment.name} + +## Metadata + +- Unlocks: {assignment.unlock_at if assignment.unlock_at else None} +- Due: {assignment.due_at if assignment.due_at else None} +- Locks: {assignment.lock_at if assignment.lock_at else None} +- Ungraded submissions: {assignment.needs_grading_count} +- Submission type: {assignment.submission_types} +- URL: {assignment.html_url} +- Submissions: {assignment.submissions_download_url} +@ + +\subsection{Assignment rubric} + +We want to format the rubric as well. +<>= +try: + text += f"## Rubric\n\n{format_rubric(assignment.rubric)}\n\n" +except AttributeError: + pass +@ + +We'll do this with [[format_rubric]]. +It should output a markdown representation of the rubric. +<>= +def format_rubric(rubric): + """ + Returns a markdown representation of the rubric + """ + if not rubric: + return "No rubric set." + + text = "" + for criterion in rubric: + text += f"- {criterion['description']}\n" + text += f" - Points: {criterion['points']}\n" + text += f" - Ratings: " + text += "; ".join([ + f"{rating['description'].strip()} ({rating['points']})" + for rating in criterion["ratings"] + ]) + "\n" + text += f"\n```\n{criterion['long_description']}\n```\n\n" + + return text +@ + +\subsection{Assignment data as raw JSON} + +We also want to format the assignment data as JSON. +We must extract all attributes from the assignment object. +<>= +def format_json(assignment): + """Returns a JSON representation of the assignment""" + return json.dumps({ + key: str(value) for key, value in assignment.__dict__.items() + if not key.startswith("_") + }, indent=2) @