diff --git a/oef/__init__.py b/oef/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/oef/admin.py b/oef/admin.py new file mode 100644 index 00000000..f1c11913 --- /dev/null +++ b/oef/admin.py @@ -0,0 +1,9 @@ +from django.contrib import admin + +# Register your models here. + +from .models import Entry, Formats + + +admin.site.register(Entry) +admin.site.register(Formats) diff --git a/oef/apps.py b/oef/apps.py new file mode 100644 index 00000000..46757cba --- /dev/null +++ b/oef/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class OefConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'oef' diff --git a/oef/filters.py b/oef/filters.py new file mode 100644 index 00000000..a227d78d --- /dev/null +++ b/oef/filters.py @@ -0,0 +1,18 @@ + +import django_filters + +from .models import Entry +from django.contrib.auth.models import User + +from django.db.models import Q + +class EntryFilter(django_filters.FilterSet): + class Meta: + model = Entry + fields = { + "modality": ["icontains"], + "exam_code": ["icontains"], + "exam_name": ["icontains"], + "questions": ["icontains"], + "comments": ["icontains"], + } \ No newline at end of file diff --git a/oef/management/__init__.py b/oef/management/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/oef/management/commands/__init__.py b/oef/management/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/oef/management/commands/importoef.py b/oef/management/commands/importoef.py new file mode 100644 index 00000000..f610a37d --- /dev/null +++ b/oef/management/commands/importoef.py @@ -0,0 +1,70 @@ + +from pathlib import Path +from django.core.management.base import BaseCommand, CommandError +import argparse + +from oef.models import Entry +from bs4 import BeautifulSoup + +class Command(BaseCommand): + help = "Imports the RCR spreadsheet" + + def add_arguments(self, parser): + # parser.add_argument("poll_ids", nargs="+", type=int) + parser.add_argument('--file', type=argparse.FileType('r')) + + + + def handle(self, *args, **options): + #with open(options["file"]) as f: + soup = BeautifulSoup(options["file"], "html.parser") + + Entry.objects.all().delete() + rows = 0 + for row in soup.find_all("tr"): + if rows > 0: + entry.questions = entry.questions + "\n" + row.find_all("td")[0].text + rows = rows - 1 + if rows == 0: + entry.save() + continue + + cells = row.find_all("td") + + if cells[0].text == "Modality": + continue + + + entry = Entry() + entry.modality = cells[0].text + entry.exam_code = cells[1].text + entry.exam_name = cells[2].text + entry.questions = cells[3].text + entry.oef_name = cells[4].text + entry.comments = cells[5].text + + if cells[0].has_attr("rowspan"): + rows = int(cells[0]["rowspan"]) - 1 + else: + entry.save() + + #Entry.objects.all().delete() + + #for row in soup.find_all("tr"): + # cells = row.find_all("td") + # if len(cells) == 6: + # entry = Entry() + # entry.modality = cells[0].text + # entry.exam_code = cells[1].text + # entry.exam_name = cells[2].text + # entry.questions = cells[3].text + # #entry. + # entry.comments = cells[5].text + # entry.save() + # self.stdout.write( + # self.style.SUCCESS(f"Entry added: {entry.pk}/{entry.exam_name}") + # ) + # else: + # self.stdout.write( + # self.style.WARNING(f"Skipping row: {row}") + # ) \ No newline at end of file diff --git a/oef/migrations/0001_initial.py b/oef/migrations/0001_initial.py new file mode 100644 index 00000000..c66f41b9 --- /dev/null +++ b/oef/migrations/0001_initial.py @@ -0,0 +1,36 @@ +# Generated by Django 5.0.2 on 2024-10-07 13:30 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Entry', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('modality', models.CharField(max_length=200)), + ('exam_code', models.CharField(max_length=50)), + ('exam_name', models.CharField(max_length=200)), + ('questions', models.TextField()), + ('questions_original', models.TextField()), + ('comments', models.TextField()), + ], + ), + migrations.CreateModel( + name='Formats', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200)), + ('format', models.TextField()), + ('inherits', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='oef.formats')), + ], + ), + ] diff --git a/oef/migrations/0002_entry_oef_name_alter_entry_comments.py b/oef/migrations/0002_entry_oef_name_alter_entry_comments.py new file mode 100644 index 00000000..1349b54b --- /dev/null +++ b/oef/migrations/0002_entry_oef_name_alter_entry_comments.py @@ -0,0 +1,23 @@ +# Generated by Django 5.0.2 on 2024-10-07 15:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('oef', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='entry', + name='oef_name', + field=models.CharField(blank=True, max_length=200), + ), + migrations.AlterField( + model_name='entry', + name='comments', + field=models.TextField(blank=True), + ), + ] diff --git a/oef/migrations/0003_alter_formats_format.py b/oef/migrations/0003_alter_formats_format.py new file mode 100644 index 00000000..9dcf34d5 --- /dev/null +++ b/oef/migrations/0003_alter_formats_format.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.2 on 2024-10-07 15:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('oef', '0002_entry_oef_name_alter_entry_comments'), + ] + + operations = [ + migrations.AlterField( + model_name='formats', + name='format', + field=models.TextField(blank=True), + ), + ] diff --git a/oef/migrations/__init__.py b/oef/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/oef/models.py b/oef/models.py new file mode 100644 index 00000000..5c69a43c --- /dev/null +++ b/oef/models.py @@ -0,0 +1,61 @@ +from django.db import models +from django.urls import reverse + +# Create your models here. +class Entry(models.Model): + modality = models.CharField(max_length=200) + exam_code = models.CharField(max_length=50) + exam_name = models.CharField(max_length=200) + + questions = models.TextField() + + questions_original = models.TextField() + + oef_name = models.CharField(max_length=200, blank=True) + + comments = models.TextField(blank=True) + + #format = models.ForeignKey('Formats', on_delete=models.CASCADE, null=True, blank=True) + + def __str__(self): + return self.exam_name + + def get_absolute_url(self): + return reverse("oef:entry_update", kwargs={"pk": self.pk}) + + def clean(self) -> None: + self.questions = self.questions.replace("\r\n", "\n") + return super().clean() + + def save(self, *args, **kwargs): + self.questions = self.questions.replace("\r\n", "\n") + return super().save(*args, **kwargs) + +class Formats(models.Model): + name = models.CharField(max_length=200) + format = models.TextField(blank=True) + + inherits = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True) + + def __str__(self): + return self.name + + def get_absolute_url(self): + return reverse("oef:format_update", kwargs={"pk": self.pk}) + + def clean(self) -> None: + self.format = self.format.replace("\r\n", "\n") + return super().clean() + + def save(self, *args, **kwargs): + self.format = self.format.replace("\r\n", "\n") + return super().save(*args, **kwargs) + + def get_format(self): + formats = [self.format] + while self.inherits: + self = self.inherits + formats.append(self.format) + + formats.reverse() + return "\n".join(formats) \ No newline at end of file diff --git a/oef/tables.py b/oef/tables.py new file mode 100755 index 00000000..bee166cc --- /dev/null +++ b/oef/tables.py @@ -0,0 +1,35 @@ +import django_tables2 as tables +from django_tables2.utils import A + +from generic.tables import SeriesImageColumn + +from .models import ( + Entry, + Formats +) + +from django.utils.html import format_html + + + + + +class EntryTable(tables.Table): + edit = tables.LinkColumn( + "oef:entry_update", text="Edit", args=[A("pk")], orderable=False + ) + + class Meta: + model = Entry + template_name = "django_tables2/bootstrap4.html" + fields = ( + "modality", + "exam_code", + "exam_name", + "questions", + "comments", + ) + + + def render_questions(self, value): + return format_html("
{}", value)
diff --git a/oef/templates/oef/base.html b/oef/templates/oef/base.html
new file mode 100644
index 00000000..96f909ec
--- /dev/null
+++ b/oef/templates/oef/base.html
@@ -0,0 +1,9 @@
+{% extends 'base.html' %}
+
+{% block css %}
+{% endblock %}
+
+{% block navigation %}
+ Entries /
+ Formats /
+{% endblock %}
\ No newline at end of file
diff --git a/oef/templates/oef/entry_table.html b/oef/templates/oef/entry_table.html
new file mode 100644
index 00000000..a30707ef
--- /dev/null
+++ b/oef/templates/oef/entry_table.html
@@ -0,0 +1,25 @@
+{% extends 'oef/base.html' %}
+
+{% block css %}
+{% endblock %}
+
+{% block content %}
+
+
+{{ format.get_format}}
+
+
+{{text}}