From ea81d185eb8ea2de5ddb7a3334e45cfcbe0d5ade Mon Sep 17 00:00:00 2001 From: vangef Date: Mon, 17 Jul 2023 03:17:43 +0100 Subject: [PATCH] remove favicon --- .gitignore | 8 +- README.md | 109 --------------------------- docs/CHANGELOG.md | 13 ++++ docs/README.md | 54 +++++++++++++ docs/img/favicon.ico | Bin 0 -> 15406 bytes README-inspect.md => docs/inspect.md | 6 +- docs/instructions.md | 70 +++++++++++++++++ docs/stylesheets/extra.css | 5 ++ utils/organiser.py | 7 +- 9 files changed, 153 insertions(+), 119 deletions(-) delete mode 100644 README.md create mode 100644 docs/CHANGELOG.md create mode 100644 docs/README.md create mode 100644 docs/img/favicon.ico rename README-inspect.md => docs/inspect.md (93%) create mode 100644 docs/instructions.md create mode 100644 docs/stylesheets/extra.css diff --git a/.gitignore b/.gitignore index fb8b236..dadee54 100644 --- a/.gitignore +++ b/.gitignore @@ -117,9 +117,6 @@ venv.bak/ # Rope project settings .ropeproject -# mkdocs documentation -/site - # mypy .mypy_cache/ .dmypy.json @@ -136,3 +133,8 @@ csv-inspect/ !BB_gradebooks/README.md !BB_submissions/README.md + +# mkdocs + +mkdocs.yml +/site diff --git a/README.md b/README.md deleted file mode 100644 index eef8c31..0000000 --- a/README.md +++ /dev/null @@ -1,109 +0,0 @@ -# **BBGradebookOrganiser** - -Blackboard Gradebook Organiser - -## **Description** - -**Blackboard Gradebook Organiser** is a tool for organising a downloaded gradebook with assignment submissions from [Blackboard Learn ⧉](https://en.wikipedia.org/wiki/Blackboard_Learn). -The submission files are organised per student, by extracting the student number from the submission file names and creating a directory per student. Compressed files are extracted into the student's directory, and any remaining individually submitted files are also moved into the student's directory. Student comments from the submissions are also extracted into a single text file for convenient access and review. -Optionally, you can inspect the submissions for identical files (by generating and comparing SHA256 hashes) and detect if any files have been submitted by multiple students. See [Inspect by hash](README-inspect.md) for more information. - -## **Features** - -- Extracts, and organises per student, the content of submitted compressed files with extensions: `.zip`, `.rar`, `.7z` - - - Detects invalid/corrupt files - - - Doesn't extract macOS system generated files (ignores directory *__MACOSX* inside the compressed file) - -- Deletes each compressed file after successful extraction into student directory - -- Organises per student any remaining individually submitted files - -- Checks and extracts any comments from the student submission generated text files - -- Checks if any compressed files (from the contents of the submitted compressed files) have been extracted and organised per student - - - The path of any extracted and organised compressed files will be displayed on the terminal - they need to be extracted manually - -- [Inspect by hash](README-inspect.md) generates and compares SHA256 hashes of all the submitted files, and detects files that are identical and have been submitted by multiple students. Two ways to inspect: - - - Inspect gradebook: Before organising a gradebook - for identical files in the files submitted to *Blackboard* - - - Inspect submissions: After organising a gradebook - for identical files in the files extracted from any submitted *compressed* files - -## **Instructions** - -### **Download gradebook** - -1. Go to the course page on Blackboard - -2. Go to *Grade Centre -> Full Grade Centre* - -3. Find the assignment and click on the arrow for more options, and select *Assignment File Download* - -4. Select all (click *Show All* at the bottom first, to display all users) and click submit to generate the gradebook zip file - -5. Wait for the generated download link to appear, and click to download - -### **Extract gradebook** - -Extract the downloaded gradebook in a new directory inside [*BB_gradebooks*](BB_gradebooks). - -- e.g. for `AssignmentX` extract the gradebook in [*BB_gradebooks*](BB_gradebooks)/`AssignmentX` - -### **Organise gradebook** - -Before running the script for the first time, install the required packages (*py7z*, *rarfile*): - -```python -python -m pip install py7zr rarfile -``` - -Note: If running on Linux/Mac, you also need to have `unrar` installed in order to be able to extract *.rar* files. - -- `sudo apt install unrar` for Linux - -- `brew install rar` for Mac - -  -To organise the gradebook run **`organise_gradebook.py`** and provide the name of the directory with the *extracted* gradebook (from section *Extract gradebook* above) as an argument. - -- e.g. for gradebook `AssignmentX` (in [*BB_gradebooks*](BB_gradebooks)/`AssignmentX`) run: - -```python -python organise_gradebook.py AssignmentX -``` - -While running, the script displays on the terminal information and stats about the gradebook submissions and files. - -### **Post-run** - -- All submission files can be found - organised in directories per student number - in directory [*BB_submissions*](BB_submissions), under the sub-directory named after the gradebook name provided when running the script - - - e.g. `organise_gradebook.py AssignmentX` creates the directory `AssignmentX` inside [*BB_submissions*](BB_submissions) - -- Each student directory contains: - - - the extracted files from the submitted `.zip`, `.rar`, `.7z` - - - the individually submitted files - - - the text file generated by Blackboard for the submission (which also contains any comments left by the student) - -- All comments found in the gradebook are extracted in a text file in [*BB_submissions*](BB_submissions), with the gradebook name as prefix - - - e.g. `AssignmentX_comments.txt` will be created for gradebook `AssignmentX` - -- Compressed files are deleted after successfully extracting and organising the contents - - - Any invalid/corrupt compressed files are moved into folder `__BAD__` inside the gradebook directory - -## **Inspect by hash** :mag: - -See [***Inspect by hash***](README-inspect.md) for more information & details. - -## **General notes** - -The Blackboard generated name for submission files must follow the pattern: -> ANYTHING_STUDENTNUMBER_attempt_DATETIME_FILENAME diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md new file mode 100644 index 0000000..5ae0a56 --- /dev/null +++ b/docs/CHANGELOG.md @@ -0,0 +1,13 @@ +# **BBGradebookOrganiser** - *CHANGELOG* + +Blackboard Gradebook Organiser - main (functional) changes and new features log + +## **Notable updates** + +2023-03-16 Hyperlinks for file paths and names listed in generated CSV files by *inspect by hash* + +2023-03-10 Added *inspect gradebook* and merged with *inspect submission* to make [***inspect by hash***](inspect.md) + +2023-03-02 Added *exclude files from hashing* + +2023-02-28 Added *inspect submission files by hash* diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..9c06438 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,54 @@ +# **BBGradebookOrganiser** + +Blackboard Gradebook Organiser + +**Documentation**: [docs.vangef.net/BBGradebookOrganiser](https://docs.vangef.net/BBGradebookOrganiser) + +**Source Code**: [github.com/vangef/BBGradebookOrganiser](https://github.com/vangef/BBGradebookOrganiser) + +## **Description** + +**Blackboard Gradebook Organiser** is a tool for organising a downloaded gradebook with assignment submissions from [Blackboard Learn ⧉](https://en.wikipedia.org/wiki/Blackboard_Learn). +The submission files are organised per student, by extracting the student number from the submission file names and creating a directory per student. Compressed files are extracted into the student's directory, and any remaining individually submitted files are also moved into the student's directory. Student comments from the submissions are also extracted into a single text file for convenient access and review. +Optionally, you can inspect the submissions for identical files (by generating and comparing SHA256 hashes) and detect if any files have been submitted by multiple students. See [Inspect by hash](inspect.md) for more information. + +## **Features** + +- Extracts, and organises per student, the content of submitted compressed files with extensions: `.zip`, `.rar`, `.7z` + + - Detects invalid/corrupt files + + - Doesn't extract macOS system generated files (ignores directory *__MACOSX* inside the compressed file) + +- Deletes each compressed file after successful extraction into student directory + +- Organises per student any remaining individually submitted files + +- Checks and extracts any comments from the student submission generated text files + +- Checks if any compressed files (from the contents of the submitted compressed files) have been extracted and organised per student + + - The path of any extracted and organised compressed files will be displayed on the terminal - they need to be extracted manually + +- [Inspect by hash](inspect.md) generates and compares SHA256 hashes of all the submitted files, and detects files that are identical and have been submitted by multiple students. Two ways to inspect: + + - Inspect gradebook: Before organising a gradebook - for identical files in the files submitted to *Blackboard* + + - Inspect submissions: After organising a gradebook - for identical files in the files extracted from any submitted *compressed* files + +## **Instructions** + +See [***Instructions***](instructions.md) for more information & details. + +## **Inspect by hash** :mag: + +See [***Inspect by hash***](inspect.md) for more information & details. + +## **General notes** + +The Blackboard generated name for submission files must follow the pattern: +> ANYTHING_STUDENTNUMBER_attempt_DATETIME_FILENAME + +## **Changes log** + +See [***Changelog***](CHANGELOG.md) for notable changes and updates. diff --git a/docs/img/favicon.ico b/docs/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..99a0be190682df2f37ef5b76668cb76d2f950085 GIT binary patch literal 15406 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 Full Grade Centre* + +3. Find the assignment and click on the arrow for more options, and select *Assignment File Download* + +4. Select all (click *Show All* at the bottom first, to display all users) and click submit to generate the gradebook zip file + +5. Wait for the generated download link to appear, and click to download + +## **Extract gradebook** + +Extract the downloaded gradebook in a new directory inside *BB_gradebooks*. + +- e.g. for `AssignmentX` extract the gradebook in *BB_gradebooks*/`AssignmentX` + +## **Organise gradebook** + +Before running the script for the first time, install the required packages (*py7z*, *rarfile*): + +```python +python -m pip install py7zr rarfile +``` + +Note: If running on Linux/Mac, you also need to have `unrar` installed in order to be able to extract *.rar* files. + +- `sudo apt install unrar` for Linux + +- `brew install rar` for Mac + +  +To organise the gradebook run **`organise_gradebook.py`** and provide the name of the directory with the *extracted* gradebook (from section *Extract gradebook* above) as an argument. + +- e.g. for gradebook `AssignmentX` (in *BB_gradebooks*/`AssignmentX`) run: + +```python +python organise_gradebook.py AssignmentX +``` + +While running, the script displays on the terminal information and stats about the gradebook submissions and files. + +## **Post-run** + +- All submission files can be found - organised in directories per student number - in directory *BB_submissions*, under the sub-directory named after the gradebook name provided when running the script + + - e.g. `organise_gradebook.py AssignmentX` creates the directory `AssignmentX` inside *BB_submissions* + +- Each student directory contains: + + - the extracted files from the submitted `.zip`, `.rar`, `.7z` + + - the individually submitted files + + - the text file generated by Blackboard for the submission (which also contains any comments left by the student) + +- All comments found in the gradebook are extracted in a text file in *BB_submissions*, with the gradebook name as prefix + + - e.g. `AssignmentX_comments.txt` will be created for gradebook `AssignmentX` + +- Compressed files are deleted after successfully extracting and organising the contents + + - Any invalid/corrupt compressed files are moved into folder `__BAD__` inside the gradebook directory + +## **Inspect by hash** :mag: + +See [***Inspect by hash***](inspect.md) for more information & details. diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 0000000..4f91c8a --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,5 @@ +.md-header__source { + min-width: 12.5rem!important; + + +} \ No newline at end of file diff --git a/utils/organiser.py b/utils/organiser.py index c88249c..f505446 100644 --- a/utils/organiser.py +++ b/utils/organiser.py @@ -25,10 +25,9 @@ def get_comment_from_submission_txt(file_path: str) -> str | None: if not no_comment_regex_compile.findall(file_contents): regular_expression = f'Comments:\n.*' regex_compile = re.compile(regular_expression) - match = regex_compile.findall(file_contents) - match = str(match).replace('\\n', '').replace('[','').replace(']','').replace('"','') - match = str(match).split('Comments:')[-1] - return match + match = regex_compile.findall(file_contents)[0] + comment = match.split('\n')[1] + return comment return None