# 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() ```