1
0

vault backup: 2025-12-26 02:09:22
All checks were successful
Deploy Quartz site to GitHub Pages / build (push) Successful in 2m29s

This commit is contained in:
2025-12-26 02:09:22 +01:00
parent 3fddadfe50
commit 50366b9b9c
288 changed files with 58893 additions and 750 deletions

View File

@@ -0,0 +1,2 @@
# Management commands

View File

@@ -0,0 +1,46 @@
from django.core.management.base import BaseCommand
from django.conf import settings
from quiz.utils.importer import import_questions
class Command(BaseCommand):
help = 'Import questions from Markdown files'
def add_arguments(self, parser):
parser.add_argument(
'--folder',
type=str,
default='content/Anatomi & Histologi 2/Gamla tentor',
help='Folder to import questions from (relative to project root)'
)
parser.add_argument(
'--force',
action='store_true',
help='Force import even if files have not changed'
)
def handle(self, *args, **options):
import_folder = options['folder']
folder = settings.BASE_DIR.parent / import_folder
if not folder.exists():
self.stdout.write(self.style.ERROR(f'Import folder {folder} does not exist'))
return
self.stdout.write(self.style.SUCCESS(f'Importing questions from {folder}...'))
stats = import_questions(folder, folder, force=options['force'])
# Only show full statistics if there were changes
output = stats.format_output(show_if_no_changes=False)
if output:
self.stdout.write(output)
if stats.errors > 0:
self.stdout.write(self.style.WARNING(f'Completed with {stats.errors} errors'))
else:
self.stdout.write(self.style.SUCCESS('Import completed successfully!'))
else:
# No changes, show brief message
self.stdout.write(self.style.SUCCESS(f'✓ All {stats.total_files} files up to date, no changes needed'))

View File

@@ -0,0 +1,87 @@
"""
Management command to populate Course and Exam models from existing questions.
"""
from django.core.management.base import BaseCommand
from django.conf import settings
from quiz.models import Course, Exam, Question
from datetime import datetime
from pathlib import Path
class Command(BaseCommand):
help = 'Populate Course and Exam models from existing question file paths'
def handle(self, *args, **options):
# Create default course
course, created = Course.objects.get_or_create(
name="Anatomi & Histologi 2",
defaults={'code': 'AH2', 'description': 'Anatomy and Histology course'}
)
if created:
self.stdout.write(self.style.SUCCESS(f'Created course: {course.name}'))
else:
self.stdout.write(f'Course exists: {course.name}')
# Analyze existing questions and create exams
questions = Question.objects.all()
exam_folders = {}
for question in questions:
# Extract exam date from file path
# Expected: content/Anatomi & Histologi 2/Gamla tentor/2022-01-15/1.md
path_parts = Path(question.file_path).parts
if len(path_parts) >= 2:
# Try to find a date-like folder
for part in path_parts:
if '-' in part and len(part) == 10: # Looks like YYYY-MM-DD
try:
exam_date = datetime.strptime(part, '%Y-%m-%d').date()
folder_path = '/'.join(path_parts[:-1])
if part not in exam_folders:
exam_folders[part] = {
'date': exam_date,
'folder': folder_path,
'questions': []
}
exam_folders[part]['questions'].append(question)
break
except ValueError:
continue
# Create exams and assign questions
exams_created = 0
questions_assigned = 0
for folder_name, data in sorted(exam_folders.items()):
exam, created = Exam.objects.get_or_create(
course=course,
date=data['date'],
defaults={
'name': folder_name,
'folder_path': data['folder']
}
)
if created:
exams_created += 1
self.stdout.write(self.style.SUCCESS(f' Created exam: {exam.date}'))
# Assign questions to this exam
for question in data['questions']:
if question.exam != exam:
question.exam = exam
question.save(update_fields=['exam'])
questions_assigned += 1
self.stdout.write(self.style.SUCCESS(
f'\nSummary:\n'
f' Exams created: {exams_created}\n'
f' Questions assigned: {questions_assigned}\n'
f' Total exams: {Exam.objects.count()}\n'
f' Questions with exams: {Question.objects.filter(exam__isnull=False).count()}\n'
f' Questions without exams: {Question.objects.filter(exam__isnull=True).count()}'
))