vault backup: 2025-12-21 20:21:58
All checks were successful
Deploy Quartz site to GitHub Pages / build (push) Successful in 2m30s
All checks were successful
Deploy Quartz site to GitHub Pages / build (push) Successful in 2m30s
This commit is contained in:
143
quiz/IMPLEMENTATION_SUMMARY.md
Normal file
143
quiz/IMPLEMENTATION_SUMMARY.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# Auto-Import Implementation Summary
|
||||
|
||||
## What was implemented:
|
||||
|
||||
### 1. Dependencies (pyproject.toml)
|
||||
- Created `pyproject.toml` in `quiz/` directory
|
||||
- Added Django and watchdog dependencies
|
||||
- Configured for `uv` package manager
|
||||
|
||||
### 2. Question Importer (quiz/utils/importer.py)
|
||||
- `ImportStats` class: Tracks import statistics including:
|
||||
- Total files found
|
||||
- MCQ vs non-MCQ questions
|
||||
- Questions with answers vs TODO placeholders
|
||||
- Created vs updated counts
|
||||
- Per-folder completion statistics
|
||||
- `parse_markdown_question()`: Parses markdown files to extract:
|
||||
- Question text
|
||||
- Options (supports both `- A:` and `- A` formats)
|
||||
- Correct answer from spoiler blocks
|
||||
- Skips questions with "TODO" answers
|
||||
- `import_question_file()`: Imports a single question file
|
||||
- `import_questions()`: Bulk import with statistics
|
||||
- `delete_question_by_path()`: Removes deleted questions from database
|
||||
|
||||
### 3. File System Watcher (quiz/utils/watcher.py)
|
||||
- `QuestionFileHandler`: Handles file system events with:
|
||||
- 2-second debounce for file changes
|
||||
- Auto-import on file create/modify
|
||||
- Auto-delete on file removal
|
||||
- Real-time console feedback
|
||||
- `QuestionWatcher`: Main watcher class using watchdog Observer
|
||||
- `start_watcher_thread()`: Starts watcher in background daemon thread
|
||||
- Performs initial full import on startup
|
||||
- Displays comprehensive statistics
|
||||
- Continues watching for changes
|
||||
|
||||
### 4. Django Integration
|
||||
- Updated `QuizAppConfig.ready()` in `apps.py`:
|
||||
- Automatically starts watcher thread on Django startup
|
||||
- Runs in daemon thread (doesn't block shutdown)
|
||||
- Only runs in main process (not reloader)
|
||||
- Updated `import_questions` management command:
|
||||
- Uses refactored importer
|
||||
- Shows detailed statistics output
|
||||
- Added `QUESTION_WATCH_PATH` setting to `settings.py`
|
||||
|
||||
## Current Statistics:
|
||||
```
|
||||
Total .md files found: 312
|
||||
MCQ questions found: 162
|
||||
Non-MCQ skipped: 152
|
||||
Questions with answers: 6
|
||||
Questions with TODO: 154
|
||||
Overall completion: 3.7%
|
||||
|
||||
Completion by Exam Folder:
|
||||
2022-01-15 2/ 25 MCQ ( 8.0%)
|
||||
2022-06-01 4/ 19 MCQ ( 21.1%)
|
||||
2023-01-11 0/ 17 MCQ ( 0.0%)
|
||||
2023-05-31 0/ 10 MCQ ( 0.0%)
|
||||
2024-01-10 0/ 14 MCQ ( 0.0%)
|
||||
2024-05-29 0/ 14 MCQ ( 0.0%)
|
||||
2025-01-15 0/ 16 MCQ ( 0.0%)
|
||||
2025-02-08 0/ 16 MCQ ( 0.0%)
|
||||
2025-06-03 0/ 16 MCQ ( 0.0%)
|
||||
2025-08-08 0/ 15 MCQ ( 0.0%)
|
||||
```
|
||||
|
||||
## How it works:
|
||||
|
||||
1. **On Django startup**:
|
||||
- Background thread starts automatically
|
||||
- Performs initial import of all questions
|
||||
- Displays comprehensive statistics
|
||||
- Begins watching for file changes
|
||||
|
||||
2. **When you edit a question in Obsidian**:
|
||||
- Watcher detects file change
|
||||
- Waits 2 seconds (debounce multiple saves)
|
||||
- Automatically imports/updates the question
|
||||
- Shows console feedback
|
||||
|
||||
3. **When you delete a question file**:
|
||||
- Watcher detects deletion
|
||||
- Removes question from database
|
||||
|
||||
4. **Manual import**:
|
||||
- Run: `python3 manage.py import_questions`
|
||||
- Shows same detailed statistics
|
||||
|
||||
## Future considerations:
|
||||
|
||||
### Multi-select questions support:
|
||||
Currently the `Question.correct_answer` field is `max_length=1`, which only supports single answers. Many questions have "Välj två alternativ" and answers like "B och D" or "B, D".
|
||||
|
||||
To support multi-select:
|
||||
1. Update `Question.correct_answer` to `max_length=50`
|
||||
2. Create Django migration
|
||||
3. Update `parse_markdown_question()` to extract multiple letters (e.g., "B och D" → "B,D")
|
||||
4. Update `views.py` answer validation to compare sorted comma-separated values
|
||||
5. Update quiz UI to allow selecting multiple options
|
||||
|
||||
### Answer format normalization:
|
||||
Need to standardize multi-select answer format in Obsidian:
|
||||
- Current: "B och D", "B, D", "BD"
|
||||
- Recommended: "B,D" (sorted, comma-separated, no spaces)
|
||||
|
||||
### Question types not yet supported:
|
||||
- `frågetyp/hotspot`: Image-based clickable questions
|
||||
- `frågetyp/dnd-text`: Drag-and-drop text matching
|
||||
- `frågetyp/textfält`: Free text input questions
|
||||
- `frågetyp/sammansatt`: Multi-part questions
|
||||
|
||||
These are currently skipped during import.
|
||||
|
||||
## Testing the implementation:
|
||||
|
||||
1. **Start Django server**:
|
||||
```bash
|
||||
cd /Users/johandahlin/dev/medical-notes/quiz
|
||||
python3 manage.py runserver
|
||||
```
|
||||
You'll see the initial import statistics on startup.
|
||||
|
||||
2. **Test auto-import**:
|
||||
- Open a question in Obsidian with "TODO" in spoiler block
|
||||
- Replace "TODO" with a letter (e.g., "B")
|
||||
- Save the file
|
||||
- Check Django console for auto-import message
|
||||
|
||||
3. **Test manual import**:
|
||||
```bash
|
||||
python3 manage.py import_questions
|
||||
```
|
||||
|
||||
4. **Check database**:
|
||||
```bash
|
||||
python3 manage.py shell
|
||||
>>> from quiz.models import Question
|
||||
>>> Question.objects.count()
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user