{"id":21302675,"url":"https://github.com/magnusrodseth/webtek-grader","last_synced_at":"2025-08-22T01:22:21.435Z","repository":{"id":254100618,"uuid":"845193238","full_name":"magnusrodseth/webtek-grader","owner":"magnusrodseth","description":"✨ Developed out of frustration related to the tedious process of downloading and grading student deliverables.","archived":false,"fork":false,"pushed_at":"2024-09-23T10:02:31.000Z","size":234,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-11T20:41:56.046Z","etag":null,"topics":["clap","cli","gpt","openai","rar","tar","zip"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/webtek-grader","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/magnusrodseth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-08-20T19:07:58.000Z","updated_at":"2025-07-06T09:35:22.000Z","dependencies_parsed_at":"2024-09-09T11:20:02.380Z","dependency_job_id":"4e511027-5ffb-4444-803c-a460cd288d3c","html_url":"https://github.com/magnusrodseth/webtek-grader","commit_stats":null,"previous_names":["magnusrodseth/webtek-grader"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/magnusrodseth/webtek-grader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magnusrodseth%2Fwebtek-grader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magnusrodseth%2Fwebtek-grader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magnusrodseth%2Fwebtek-grader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magnusrodseth%2Fwebtek-grader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/magnusrodseth","download_url":"https://codeload.github.com/magnusrodseth/webtek-grader/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magnusrodseth%2Fwebtek-grader/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271570898,"owners_count":24782763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-21T02:00:08.990Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clap","cli","gpt","openai","rar","tar","zip"],"created_at":"2024-11-21T15:57:09.369Z","updated_at":"2025-08-22T01:22:21.401Z","avatar_url":"https://github.com/magnusrodseth.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Web Technologies Grader\n\n## What is it?\n\nThis project is developed out of frustration related to the tedious process of downloading and grading student deliverables. It aids in the process of unzipping the student deliverables, and leverages GPT to generate a proposal for the student feedback.\n\n## Features\n\n- 📂 **Extract deliverables**: Extracts the student deliverables from a compressed file.\n- 🧪 **Validate deliverables**: Validates the HTML, CSS and JS using the W3C Validator API.\n- 🧠 **Grade deliverables with AI**: Grades the deliverables using the project description, all project files for the deliverable, and the grading criteria. This is optional, and can be run without AI.\n\n## 🚨 Very important to note\n\nThis project is only meant to be a guideline when grading assignments, **not a one-stop shop**. It is important to review the generated feedback and adjust it to fit the student's deliverable. Every single deliverable requires a human eye to evaluate the points given and the feedback provided.\n\n**Please do not use this blindly without reviewing the feedback generated. 🫶🏽**\n\n## Getting started\n\n### Prerequisites\n\nEnsure you have Rust and Cargo installed on your machine. If not, you can install it by following the instructions [here](https://www.rust-lang.org/tools/install). If you are on MacOS or Linux, you can follow the instructions below:\n\n```sh\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n```\n\nIf you're on Windows, you can download the installer from [here](https://forge.rust-lang.org/infra/other-installation-methods.html#other-ways-to-install-rustup).\n\n**If you want to use the `Grade with AI` feature**, ensure you have an OpenAI API key. If not, you can get one by following the instructions [here](https://platform.openai.com/docs/quickstart). Next, create a `.env` file in the root of the project directory and add the following:\n\n```sh\nOPENAI_API_KEY=\u003cyour-openai-api-key\u003e\n```\n\nAlternatively, you can set the `OPENAI_API_KEY` environment variable in your terminal using `export OPENAI_API_KEY=\u003cyour-openai-api-key\u003e`, followed by running the application.\n\n\u003e **I recommend using the `.env` file approach as it is easier to manage across sessions.**\n\nFor instance, if you're grading deliverables in a directory called `webtek`, the directory structure should look like this:\n\n```sh\nwebtek/\n└── .env\n```\n\n### Running the application\n\n```sh\n# Install the application\ncargo install webtek-grader\n\n# Display the help message\nwebtek-grader --help\n\n# Extract and validate without AI\nwebtek-grader without-ai \u003carchive-file\u003e \u003cdestination-directory\u003e\n\n# Extract, validate and grade with AI\nwebtek-grader with-ai \u003carchive-file\u003e \u003cdestination-directory\u003e \u003cdescription-file\u003e \u003ccriteria-file\u003e\n```\n\n## How does grading with AI work?\n\nAs described above, ensure you have an `OPENAI_API_KEY` environment variable set in your terminal or a `.env` file in the root of the project directory.\n\nThe `archive-file` is the path to the compressed file containing the student deliverables.\n\nThe `destination-directory` is the directory where the deliverables will be extracted, e.g. `assignment-1`.\n\nThe `description-file` is the path to a PDF file for the assignment description. **Ensure this is a PDF file, and not any other file extension**.\n\nThe `criteria-file` is the path to the grading criteria for the assignment. **Ensure this is a PDF file, and not any other file extension**.\n\n### The pipeline when grading with AI\n\n1. The script starts by **extracting the deliverables**.\n\n2. Next, it **validates** the HTML, CSS and JS using the W3C Validator API. When running this with AI, the errors and warning from W3C Validator are input to the GPT model, and a `validate.txt` file is generated with the validation feedback for that group.\n\n3. Next, the deliverable is **graded** using the project description, all project files for the deliverable, and the grading criteria. The GPT model outputs feedback and a suggested score for the deliverable in the `feedback.txt` file.\n\n4. **For your convenience, the script creates a `final.txt` which contains the validation feedback and grading feedback for the deliverable in one file.**\n\n## Example of validating with AI\n\nHere is an example of some errors and warnings from W3C Validator, and the respective generated feedback:\n\n### Response from W3C Validator\n\n```json\n{\n  \"messages\": [\n    {\n      \"type\": \"error\",\n      \"message\": \"Bad value “300px” for attribute “width” on element “img”: Expected a digit but saw “p” instead.\"\n    },\n    {\n      \"type\": \"error\",\n      \"message\": \"An “img” element must have an “alt” attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images.\"\n    },\n    {\n      \"type\": \"error\",\n      \"message\": \"No “p” element in scope but a “p” end tag seen.\"\n    },\n    {\n      \"type\": \"info\",\n      \"subType\": \"warning\",\n      \"message\": \"Consider using the “h1” element as a top-level heading only (all “h1” elements are treated as top-level headings by many screen readers and other tools).\"\n    },\n    {\n      \"type\": \"info\",\n      \"subType\": \"warning\",\n      \"message\": \"Consider adding a “lang” attribute to the “html” start tag to declare the language of this document.\"\n    }\n  ]\n}\n```\n\n### Generated feedback for validating\n\n```txt\nTilbakemelding om validering:\n\nVerdien “300px” for attributten “width” på elementet “img” er ugyldig. Attributter for bredde og høyde skal kun spesifiseres med tall, så her skal “300” være brukt uten “px”. Eksempel: `\u003cimg src=\"bilde.jpg\" width=\"300\"\u003e`.\n\nEt “img”-element må ha et “alt”-attributt for å gi tekstalternativer til bilder, noe som er viktig for tilgjengelighet. Eksempel: `\u003cimg src=\"bilde.jpg\" alt=\"Beskrivelse av bildet\"\u003e`.\n\nDet finnes ikke noe “p”-element i scope, men det er funnet en avsluttende “p”-tag. Dette betyr at det er en feil bruk av parantes, og avsluttende tagger bør kun brukes hvis det er et tilhørende åpningstag. Eksempel: Hvis det er en ubrukt “p”-tag, fjern den eller legg til en matchende åpningstag.\n\nDet anbefales å bruke “h1”-elementet kun som et toppnivå overskrift, da skjermlesere og verktøy betrakter alle “h1”-elementer som toppnivå overskrifter. Bruk riktig hierarki, for eksempel: `\u003ch1\u003eTittel\u003c/h1\u003e` for hovedtittelen.\n\nDet kan være nyttig å legge til et “lang”-attributt i “html”-starttaggen for å deklarere språket i dokumentet. Dette forbedrer tilgjengeligheten for brukere som bruker skjermlesere. Eksempel: `\u003chtml lang=\"no\"\u003e`.\n```\n\n## Example of grading with AI\n\nHere is an example of a project description and grading criteria, and the respective generated feedback:\n\n### Excerpt from project description and grading criteria\n\n```md\n# Project Description\n\nCreate a new section element, below your previous, but above the footer.\nAdd a header element to it, and fill it with an h2 tag containing the title \"Questions\".\nThen make a table with 2 columns and seven rows.\nThe first row must be the table header with “Questions” and “Answers”.\nIn each of the remaining six rows add one of the following questions and write their answers:\n\n...\n\n# Grading Criteria\n\nIs the placement of the section correct? 1.5 points\nIs the new header added properly? 1.5 points\nAre the questions answered correctly? 1 point for each correct answer\nIs the table created correctly? 6 points\nIs the table rendering properly? 6 points\nDoes the columns have headings? 2 points for each heading\n```\n\n### Generated feedback for grading\n\n```txt\nDenne delen inkluderer en ny seksjon med overskriften (h2) \"Questions\".\nI denne seksjonen inkluderer studenten en tabell med syv rader og to kolonner.\nKan følge lenken til denne seksjonen ved hjelp av ankeret \"questions\".\nSpørsmål og svar på spørsmålene oppgitt i oppgavebeskrivelsen er inkludert i tabellen.\nDette oppfyller alle kravene i del 3.\n```\n\n## Developer Information\n\nDeveloped by [Magnus Rødseth](https://github.com/magnusrodseth).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmagnusrodseth%2Fwebtek-grader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmagnusrodseth%2Fwebtek-grader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmagnusrodseth%2Fwebtek-grader/lists"}