diff --git a/personalni/templates/personalni/profil/orgorozcestnik.html b/personalni/templates/personalni/profil/orgorozcestnik.html
index 338857ba..320d84b9 100644
--- a/personalni/templates/personalni/profil/orgorozcestnik.html
+++ b/personalni/templates/personalni/profil/orgorozcestnik.html
@@ -55,6 +55,7 @@
Úlohy
{% for u in ulohy %}
+ r
- {{ u }}
{% endfor %}
diff --git a/seminar/migrations/0117_auto_20240312_2125.py b/seminar/migrations/0117_auto_20240312_2125.py
index 0134534a..47dd1bca 100644
--- a/seminar/migrations/0117_auto_20240312_2125.py
+++ b/seminar/migrations/0117_auto_20240312_2125.py
@@ -10,7 +10,6 @@ class Migration(migrations.Migration):
('various', '0003_fix_permissions'), # Zapomenutá post-split migrace, suplujeme tady.
('personalni', '0001_skupiny'), # Mělo být spíš 0002_auto_20240312_2118, ale to je no-op, tak je to jedno.
('korektury', '0021_auto_20240312_2124'),
- ('sifrovacka', '0004_auto_20240312_2124'),
('prednasky', '0013_auto_20240312_2124'),
]
diff --git a/seminar/migrations/0120_remove_osoba_user_remove_prijemce_osoba_and_more.py b/seminar/migrations/0120_remove_osoba_user_remove_prijemce_osoba_and_more.py
index 1bbfcff0..ab47e455 100644
--- a/seminar/migrations/0120_remove_osoba_user_remove_prijemce_osoba_and_more.py
+++ b/seminar/migrations/0120_remove_osoba_user_remove_prijemce_osoba_and_more.py
@@ -10,7 +10,6 @@ class Migration(migrations.Migration):
('personalni', '0003_initial'),
('korektury', '0022_alter_komentar_autor_alter_korekturovanepdf_org_and_more'),
('prednasky', '0014_alter_prednaska_org'),
- ('sifrovacka', '0005_alter_odpoveducastnika_resitel'),
]
operations = [
diff --git a/seminar/migrations/0144_post_odstrel_vseho.py b/seminar/migrations/0144_post_odstrel_vseho.py
index 2a5d10f2..bc7a8242 100644
--- a/seminar/migrations/0144_post_odstrel_vseho.py
+++ b/seminar/migrations/0144_post_odstrel_vseho.py
@@ -28,7 +28,6 @@ class Migration(migrations.Migration):
('reversion', '0002_add_index_on_version_for_content_type_and_db'),
('seminar', '0143_odstrel_treenode_post'),
('sessions', '0001_initial'),
- ('sifrovacka', '0006_personalni_post_migrate'),
('sites', '0002_alter_domain_unique'),
('sitetree', '0002_alter_treeitem_parent_alter_treeitem_tree'),
('soustredeni', '0010_tvorba_post'),
diff --git a/sifrovacka/admin.py b/sifrovacka/admin.py
index ec159726..2a843494 100644
--- a/sifrovacka/admin.py
+++ b/sifrovacka/admin.py
@@ -1,9 +1,36 @@
from django.contrib import admin
-from .models import OdpovedUcastnika, SpravnaOdpoved, NapovezenoUcastnikovi, Napoveda, SeznamSifer
+from .models import Sifrovacka, Sifra, Tajenka, Napoveda, OdpovedUcastnika, NapovezenoUcastnikovi
-admin.site.register(OdpovedUcastnika)
-admin.site.register(SpravnaOdpoved)
+
+class SifryInline(admin.TabularInline):
+ fields = ('cislo', 'nazev', 'preskocitelna')
+ show_change_link=True
+ model = Sifra
+ extra = 0
+
+
+@admin.register(Sifrovacka)
+class SifrovackaAdmin(admin.ModelAdmin):
+ inline_type = 'tabular'
+ inlines = [SifryInline]
+
+class TajenkaInline(admin.TabularInline):
+ model = Tajenka
+ extra = 0
+
+class NapovedaInline(admin.TabularInline):
+ model = Napoveda
+ extra = 0
+
+
+@admin.register(Sifra)
+class SifraAdmin(admin.ModelAdmin):
+ inline_type = 'tabular'
+ inlines = [TajenkaInline, NapovedaInline]
+
+
+admin.site.register(Tajenka)
admin.site.register(Napoveda)
+admin.site.register(OdpovedUcastnika)
admin.site.register(NapovezenoUcastnikovi)
-admin.site.register(SeznamSifer)
diff --git a/sifrovacka/forms.py b/sifrovacka/forms.py
index 1267848b..9f4fbcfc 100644
--- a/sifrovacka/forms.py
+++ b/sifrovacka/forms.py
@@ -1,30 +1,30 @@
-from django.core.exceptions import ValidationError
-from django.forms import ModelForm, Textarea
-from .models import OdpovedUcastnika, SpravnaOdpoved, NapovezenoUcastnikovi, Napoveda
-
-
-class SifrovackaForm(ModelForm):
- class Meta:
- model = OdpovedUcastnika
- fields = ["sifra", "odpoved", ]
- widgets = {
- "odpoved": Textarea(attrs={'rows': 1, 'cols': 30}),
- }
-
- def clean_sifra(self):
- sifra = self.cleaned_data.get('sifra')
- if SpravnaOdpoved.objects.filter(sifra__iexact=sifra).count() == 0:
- raise ValidationError("Tuhle šifru v databázi nemáme. Zkontrolujte si, že jste zadali název správně.")
- return sifra
-
-
-class NapovedaForm(ModelForm):
- class Meta:
- model = NapovezenoUcastnikovi
- fields = ["sifra",]
-
- def clean_sifra(self):
- sifra = self.cleaned_data.get('sifra')
- if Napoveda.objects.filter(sifra__iexact=sifra).count() == 0:
- raise ValidationError("K této šifře nemáme nápovědu. Zkontrolujte si, že jste zadali název správně.")
- return sifra
+# from django.core.exceptions import ValidationError
+# from django.forms import ModelForm, Textarea
+# from .models import OdpovedUcastnika, SpravnaOdpoved, NapovezenoUcastnikovi, Napoveda
+#
+#
+# class SifrovackaForm(ModelForm):
+# class Meta:
+# model = OdpovedUcastnika
+# fields = ["sifra", "odpoved", ]
+# widgets = {
+# "odpoved": Textarea(attrs={'rows': 1, 'cols': 30}),
+# }
+#
+# def clean_sifra(self):
+# sifra = self.cleaned_data.get('sifra')
+# if SpravnaOdpoved.objects.filter(sifra__iexact=sifra).count() == 0:
+# raise ValidationError("Tuhle šifru v databázi nemáme. Zkontrolujte si, že jste zadali název správně.")
+# return sifra
+#
+#
+# class NapovedaForm(ModelForm):
+# class Meta:
+# model = NapovezenoUcastnikovi
+# fields = ["sifra",]
+#
+# def clean_sifra(self):
+# sifra = self.cleaned_data.get('sifra')
+# if Napoveda.objects.filter(sifra__iexact=sifra).count() == 0:
+# raise ValidationError("K této šifře nemáme nápovědu. Zkontrolujte si, že jste zadali název správně.")
+# return sifra
diff --git a/sifrovacka/migrations/0001_initial.py b/sifrovacka/migrations/0001_initial.py
index 742461ef..12b4ab45 100644
--- a/sifrovacka/migrations/0001_initial.py
+++ b/sifrovacka/migrations/0001_initial.py
@@ -1,7 +1,8 @@
-# Generated by Django 3.2.22 on 2023-10-14 09:20
+# Generated by Django 4.2.20 on 2025-04-23 20:08
from django.db import migrations, models
import django.db.models.deletion
+import django.utils.timezone
class Migration(migrations.Migration):
@@ -9,26 +10,104 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
- ('seminar', '0113_resitel_zasilat_cislo_papirove'),
+ ('personalni', '0019_rename_upozorneni_resitel_upozornovat_na_opravy_reseni'),
]
operations = [
migrations.CreateModel(
- name='SpravnaOdpoved',
+ name='Napoveda',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('odpoved', models.TextField()),
- ('sifra', models.IntegerField()),
- ('skryty_text', models.TextField()),
+ ('text', models.TextField(verbose_name='Text nápovědy (zobrazený, když si účastník vezme nápovědu)')),
+ ('uroven', models.IntegerField(default=1, verbose_name='Úroveň jak moc (nebo který krok) nápověda napoví, nejvýše jedna nápověda dané úrovně k dané šifře!')),
],
+ options={
+ 'verbose_name': 'Nápověda',
+ 'verbose_name_plural': 'Nápovědy',
+ 'ordering': ['sifra', 'uroven'],
+ },
+ ),
+ migrations.CreateModel(
+ name='Sifra',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('cislo', models.IntegerField(blank=True, null=True, verbose_name='Číslo šifry')),
+ ('nazev', models.CharField(blank=True, max_length=255, null=True, verbose_name='Název šifry')),
+ ('preskocitelna', models.BooleanField(default=False)),
+ ('skryty_text', models.TextField(blank=True, null=True, verbose_name='Text zobrazený při přeskočení (pokud prázdný, pak se zobrazují skryté texty všech tajenek k této šifře)')),
+ ],
+ options={
+ 'verbose_name': 'Šifra',
+ 'verbose_name_plural': 'Šifry',
+ 'ordering': ['sifrovacka', 'cislo', 'nazev'],
+ },
+ ),
+ migrations.CreateModel(
+ name='Sifrovacka',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('jmeno', models.CharField(max_length=255, verbose_name='Jméno seznamu')),
+ ('aktivni', models.BooleanField(default=True, verbose_name='Lze odevzdávat šifry z tohoto seznamu?')),
+ ('oznameni_spatne', models.TextField(default='Bohužel vám hvězdy nebyly nakloněny. Rozumějte máte to blbě.
', verbose_name='Oznámení při špatné odpovědi')),
+ ],
+ options={
+ 'verbose_name': 'Šifrovačka',
+ 'verbose_name_plural': 'Šifrovačky',
+ 'ordering': ['aktivni', 'jmeno'],
+ },
+ ),
+ migrations.CreateModel(
+ name='Tajenka',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('tajenka', models.TextField(verbose_name='Tajenka bez diakritiky')),
+ ('skryty_text', models.TextField(verbose_name='Text zobrazený po zadání tajenky')),
+ ('sifra', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tajenky', to='sifrovacka.sifra')),
+ ],
+ options={
+ 'verbose_name': 'Tajenka',
+ 'verbose_name_plural': 'Tajenky',
+ 'ordering': ['sifra'],
+ },
+ ),
+ migrations.AddField(
+ model_name='sifra',
+ name='sifrovacka',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sifry', to='sifrovacka.sifrovacka'),
),
migrations.CreateModel(
name='OdpovedUcastnika',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('odpoved', models.TextField(verbose_name='Tajenka')),
- ('sifra', models.IntegerField(verbose_name='Číslo šifry')),
- ('resitel', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='seminar.resitel')),
+ ('timestamp', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Timestamp')),
+ ('odpoved', models.TextField(verbose_name='Tajenka bez diakritiky')),
+ ('uspech', models.BooleanField(default=False, verbose_name='Zda byla odpověď správná')),
+ ('resitel', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='personalni.resitel')),
+ ('sifra', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='odpovedi', to='sifrovacka.sifra')),
],
+ options={
+ 'verbose_name': 'Odpověď účastníka',
+ 'verbose_name_plural': 'Odpovědi účastníků',
+ 'ordering': ['-timestamp'],
+ },
+ ),
+ migrations.CreateModel(
+ name='NapovezenoUcastnikovi',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('timestamp', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Timestamp')),
+ ('napoveda', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='napovezeno', to='sifrovacka.napoveda')),
+ ('resitel', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='personalni.resitel')),
+ ],
+ options={
+ 'verbose_name': 'Napovězeno účastníkovi',
+ 'verbose_name_plural': 'Napovězeno účastníkům',
+ 'ordering': ['-timestamp'],
+ },
+ ),
+ migrations.AddField(
+ model_name='napoveda',
+ name='sifra',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='napovedy', to='sifrovacka.sifra'),
),
]
diff --git a/sifrovacka/migrations/0002_auto_20231015_1944.py b/sifrovacka/migrations/0002_auto_20231015_1944.py
deleted file mode 100644
index dea42891..00000000
--- a/sifrovacka/migrations/0002_auto_20231015_1944.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Generated by Django 3.2.22 on 2023-10-15 17:44
-
-from django.db import migrations, models
-import django.utils.timezone
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('sifrovacka', '0001_initial'),
- ]
-
- operations = [
- migrations.AlterModelOptions(
- name='odpoveducastnika',
- options={'ordering': ['-timestamp']},
- ),
- migrations.AddField(
- model_name='odpoveducastnika',
- name='timestamp',
- field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='Timestamp'),
- ),
- migrations.AlterField(
- model_name='odpoveducastnika',
- name='odpoved',
- field=models.TextField(verbose_name='Tajenka bez diakritiky'),
- ),
- ]
diff --git a/sifrovacka/migrations/0003_odpoveducastnika_uspech.py b/sifrovacka/migrations/0003_odpoveducastnika_uspech.py
deleted file mode 100644
index 1d61dd8c..00000000
--- a/sifrovacka/migrations/0003_odpoveducastnika_uspech.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 3.2.22 on 2023-10-16 17:51
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('sifrovacka', '0002_auto_20231015_1944'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='odpoveducastnika',
- name='uspech',
- field=models.BooleanField(default=False, verbose_name='Úspěch'),
- ),
- ]
diff --git a/sifrovacka/migrations/0004_auto_20240312_2124.py b/sifrovacka/migrations/0004_auto_20240312_2124.py
deleted file mode 100644
index 252268a6..00000000
--- a/sifrovacka/migrations/0004_auto_20240312_2124.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Generated by Django 4.2.8 on 2024-03-12 20:24
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('sifrovacka', '0004_napoveda_napovezenoucastnikovi'),
- ]
-
- operations = [
- ]
diff --git a/sifrovacka/migrations/0004_napoveda_napovezenoucastnikovi.py b/sifrovacka/migrations/0004_napoveda_napovezenoucastnikovi.py
deleted file mode 100644
index cba7ae8f..00000000
--- a/sifrovacka/migrations/0004_napoveda_napovezenoucastnikovi.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Generated by Django 4.2.8 on 2024-04-14 12:57
-
-from django.db import migrations, models
-import django.db.models.deletion
-import django.utils.timezone
-
-
-class Migration(migrations.Migration):
- dependencies = [
- (
- "seminar",
- "0114_related_name_se_zmenilo_a_django_chce_migraci_tak_dostane_migraci",
- ),
- ("sifrovacka", "0003_odpoveducastnika_uspech"),
- ]
-
- operations = [
- migrations.CreateModel(
- name="Napoveda",
- fields=[
- (
- "id",
- models.AutoField(
- auto_created=True,
- primary_key=True,
- serialize=False,
- verbose_name="ID",
- ),
- ),
- ("text", models.TextField()),
- ("sifra", models.IntegerField()),
- ],
- ),
- migrations.CreateModel(
- name="NapovezenoUcastnikovi",
- fields=[
- (
- "id",
- models.AutoField(
- auto_created=True,
- primary_key=True,
- serialize=False,
- verbose_name="ID",
- ),
- ),
- ("sifra", models.IntegerField(verbose_name="Číslo šifry")),
- (
- "timestamp",
- models.DateTimeField(
- default=django.utils.timezone.now, verbose_name="Timestamp"
- ),
- ),
- (
- "resitel",
- models.ForeignKey(
- on_delete=django.db.models.deletion.CASCADE,
- to="seminar.resitel",
- ),
- ),
- ],
- options={
- "ordering": ["-timestamp"],
- },
- ),
- ]
diff --git a/sifrovacka/migrations/0005_alter_odpoveducastnika_resitel.py b/sifrovacka/migrations/0005_alter_odpoveducastnika_resitel.py
deleted file mode 100644
index d21d65d6..00000000
--- a/sifrovacka/migrations/0005_alter_odpoveducastnika_resitel.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Generated by Django 4.2.11 on 2024-03-19 21:35
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('personalni', '0003_initial'),
- ('sifrovacka', '0004_auto_20240312_2124'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='odpoveducastnika',
- name='resitel',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='personalni.resitel'),
- ),
- migrations.AlterField(
- model_name='napovezenoucastnikovi',
- name='resitel',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='personalni.resitel'),
- ),
- ]
diff --git a/sifrovacka/migrations/0006_personalni_post_migrate.py b/sifrovacka/migrations/0006_personalni_post_migrate.py
deleted file mode 100644
index cf2c8ad5..00000000
--- a/sifrovacka/migrations/0006_personalni_post_migrate.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Generated by Django 4.2.11 on 2024-03-26 21:25
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('sifrovacka', '0005_alter_odpoveducastnika_resitel'),
- ('personalni', '0005_personalni_post_migrate'),
- ]
-
- operations = [
- ]
diff --git a/sifrovacka/migrations/0007_alter_napoveda_sifra_and_more.py b/sifrovacka/migrations/0007_alter_napoveda_sifra_and_more.py
deleted file mode 100644
index 0212e3c4..00000000
--- a/sifrovacka/migrations/0007_alter_napoveda_sifra_and_more.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Generated by Django 4.2.18 on 2025-03-19 20:12
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('sifrovacka', '0006_personalni_post_migrate'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='napoveda',
- name='sifra',
- field=models.CharField(max_length=255),
- ),
- migrations.AlterField(
- model_name='napovezenoucastnikovi',
- name='sifra',
- field=models.CharField(max_length=255, verbose_name='Šifra'),
- ),
- migrations.AlterField(
- model_name='odpoveducastnika',
- name='sifra',
- field=models.CharField(max_length=255, verbose_name='Šifra'),
- ),
- migrations.AlterField(
- model_name='spravnaodpoved',
- name='sifra',
- field=models.CharField(max_length=255),
- ),
- ]
diff --git a/sifrovacka/migrations/0008_seznamsifer.py b/sifrovacka/migrations/0008_seznamsifer.py
deleted file mode 100644
index ea211afe..00000000
--- a/sifrovacka/migrations/0008_seznamsifer.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Generated by Django 4.2.20 on 2025-03-19 21:39
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('sifrovacka', '0007_alter_napoveda_sifra_and_more'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='SeznamSifer',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('jmeno', models.CharField(help_text='něco co jde zadat do adresy', max_length=255, verbose_name='Jméno seznamu')),
- ('sifry', models.ManyToManyField(to='sifrovacka.spravnaodpoved')),
- ],
- ),
- ]
diff --git a/sifrovacka/models.py b/sifrovacka/models.py
index e96a6d99..b0922ebc 100644
--- a/sifrovacka/models.py
+++ b/sifrovacka/models.py
@@ -3,46 +3,95 @@ from django.utils import timezone
from personalni.models import Resitel
+class Sifrovacka(models.Model):
+ class Meta:
+ verbose_name = 'Šifrovačka'
+ verbose_name_plural = 'Šifrovačky'
+ ordering = ['aktivni', 'jmeno']
+
+ jmeno = models.CharField("Jméno seznamu", max_length=255, blank=False, null=False)
+ aktivni = models.BooleanField("Lze odevzdávat šifry z tohoto seznamu?", default=True, blank=False, null=False)
+ oznameni_spatne = models.TextField("Oznámení při špatné odpovědi", default="Bohužel vám hvězdy nebyly nakloněny. Rozumějte máte to blbě.
", blank=False, null=False)
+
+ def __str__(self): return f"{'☢' if self.aktivni else '🗑'} {self.jmeno}"
+
+class Sifra(models.Model):
+ """
+ Reprezentuje jednu šifru, která:
+ - má :py:class:`Tajenku/y `
+ - má :py:class:`Nápovědu/y `
+ - může být v :py:class:`SeznamechŠifer `
+ - a lze ji řešit:
+ :py:class:`OdpověďÚčastníka `
+ :py:class:`NapovezenoUcastnikovi `
+ """
+ class Meta:
+ verbose_name = 'Šifra'
+ verbose_name_plural = 'Šifry'
+ ordering = ['sifrovacka', 'cislo', 'nazev']
+
+ sifrovacka = models.ForeignKey(Sifrovacka, related_name="sifry", on_delete=models.CASCADE, blank=False, null=False)
+ cislo = models.IntegerField("Číslo šifry", blank=True, null=True)
+ nazev = models.CharField("Název šifry", max_length=255, blank=True, null=True)
+ preskocitelna = models.BooleanField(default=False, blank=False, null=False)
+ skryty_text = models.TextField("Text zobrazený při přeskočení (pokud prázdný, pak se zobrazují skryté texty všech tajenek k této šifře)", blank=True, null=True)
+
+ def __str__(self): return f"{self.cislo}. {self.nazev}"
+
+ def clean(self):
+ if self.cislo is None and self.nazev is None:
+ raise models.exceptions.ValidationError()
+
+
+class Tajenka(models.Model):
+ class Meta:
+ verbose_name = 'Tajenka'
+ verbose_name_plural = 'Tajenky'
+ ordering = ['sifra']
+
+ sifra = models.ForeignKey(Sifra, related_name="tajenky", on_delete=models.CASCADE, blank=False, null=False)
+ tajenka = models.TextField("Tajenka bez diakritiky", blank=False, null=False)
+ skryty_text = models.TextField("Text zobrazený po zadání tajenky", blank=False, null=False)
+
+ def __str__(self): return f"{self.sifra}: {self.tajenka}"
+
+
+class Napoveda(models.Model):
+ class Meta:
+ verbose_name = 'Nápověda'
+ verbose_name_plural = 'Nápovědy'
+ ordering = ["sifra", "uroven"]
+
+ sifra = models.ForeignKey(Sifra, related_name="napovedy", on_delete=models.CASCADE, blank=False, null=False)
+ text = models.TextField("Text nápovědy (zobrazený, když si účastník vezme nápovědu)", blank=False, null=False)
+ uroven = models.IntegerField("Úroveň jak moc (nebo který krok) nápověda napoví, nejvýše jedna nápověda dané úrovně k dané šifře!", default=1, blank=False, null=False)
+
+ def __str__(self): return f"{self.sifra} ({self.uroven}): {self.text}"
+
class OdpovedUcastnika(models.Model):
class Meta:
+ verbose_name = 'Odpověď účastníka'
+ verbose_name_plural = 'Odpovědi účastníků'
ordering = ["-timestamp"]
- resitel = models.ForeignKey(Resitel, blank=False, null=False, on_delete=models.CASCADE)
+ sifra = models.ForeignKey(Sifra, related_name="odpovedi", on_delete=models.CASCADE, blank=False, null=False)
+ timestamp = models.DateTimeField("Timestamp", default=timezone.now, blank=False, null=False)
odpoved = models.TextField("Tajenka bez diakritiky", blank=False, null=False,)
- sifra = models.CharField("Šifra", max_length=255, blank=False, null=False,)
- timestamp = models.DateTimeField("Timestamp", blank=False, null=False, default=timezone.now)
- uspech = models.BooleanField("Úspěch", blank=False, null=False, default=False)
+ uspech = models.BooleanField("Zda byla odpověď správná", default=False, blank=False, null=False)
+ resitel = models.ForeignKey(Resitel, blank=False, null=False, on_delete=models.CASCADE)
-
-class SpravnaOdpoved(models.Model):
- odpoved = models.TextField(blank=False, null=False,)
- sifra = models.CharField(max_length=255, blank=False, null=False,)
- skryty_text = models.TextField(blank=False, null=False,)
-
- def __str__(self):
- return f"{self.sifra}: {self.odpoved}"
+ def __str__(self): return f"{self.timestamp}: {'✓' if self.uspech else '❌'} {self.resitel} praví {self.odpoved} na {self.sifra}"
class NapovezenoUcastnikovi(models.Model):
class Meta:
+ verbose_name = 'Napovězeno účastníkovi'
+ verbose_name_plural = 'Napovězeno účastníkům'
ordering = ["-timestamp"]
+ napoveda = models.ForeignKey(Napoveda, related_name="napovezeno", on_delete=models.CASCADE, blank=False, null=False)
resitel = models.ForeignKey(Resitel, blank=False, null=False, on_delete=models.CASCADE)
- sifra = models.CharField("Šifra", max_length=255, blank=False, null=False,)
timestamp = models.DateTimeField("Timestamp", blank=False, null=False, default=timezone.now)
-
-class Napoveda(models.Model):
- text = models.TextField(blank=False, null=False,)
- sifra = models.CharField(max_length=255, blank=False, null=False,)
-
- def __str__(self):
- return f"{self.sifra}: {self.text}"
-
-class SeznamSifer(models.Model):
- jmeno = models.CharField("Jméno seznamu", max_length=255, blank=False, null=False, help_text="něco co jde zadat do adresy")
- sifry = models.ManyToManyField(SpravnaOdpoved)
-
- def __str__(self):
- return f"{self.jmeno}"
+ def __str__(self): return f"{self.timestamp}: {self.resitel} bere {self.napoveda}"
diff --git a/sifrovacka/urls.py b/sifrovacka/urls.py
index 63e9a5c2..e95a61ce 100644
--- a/sifrovacka/urls.py
+++ b/sifrovacka/urls.py
@@ -1,37 +1,38 @@
-from django.urls import path
-
-from personalni.utils import org_required, resitel_or_org_required
-from .views import SifrovackaView, SifrovackaListView, SifrovackaNektereListView, NapovedaView, NapovedaListView, PreskoceniView
-
-urlpatterns = [
- path(
- '',
- resitel_or_org_required(SifrovackaView.as_view()),
- name='sifrovacka'
- ),
- path(
- 'odpovedi/',
- org_required(SifrovackaListView.as_view()),
- name='sifrovacka_odpovedi'
- ),
- path(
- 'odpovedi//',
- org_required(SifrovackaNektereListView.as_view()),
- name='sifrovacka_odpovedi_nektere'
- ),
- path(
- 'napoveda/',
- resitel_or_org_required(NapovedaView.as_view()),
- name='sifrovacka_napoveda'
- ),
- path(
- 'napovedy/',
- org_required(NapovedaListView.as_view()),
- name='sifrovacka_napovedy'
- ),
- path(
- 'preskoceni/',
- resitel_or_org_required(PreskoceniView.as_view()),
- name='sifrovacka_preskoceni'
- ),
-]
+urlpatterns = []
+# from django.urls import path
+#
+# from personalni.utils import org_required, resitel_or_org_required
+# from .views import SifrovackaView, SifrovackaListView, SifrovackaNektereListView, NapovedaView, NapovedaListView, PreskoceniView
+#
+# urlpatterns = [
+# path(
+# '',
+# resitel_or_org_required(SifrovackaView.as_view()),
+# name='sifrovacka'
+# ),
+# path(
+# 'odpovedi/',
+# org_required(SifrovackaListView.as_view()),
+# name='sifrovacka_odpovedi'
+# ),
+# path(
+# 'odpovedi//',
+# org_required(SifrovackaNektereListView.as_view()),
+# name='sifrovacka_odpovedi_nektere'
+# ),
+# path(
+# 'napoveda/',
+# resitel_or_org_required(NapovedaView.as_view()),
+# name='sifrovacka_napoveda'
+# ),
+# path(
+# 'napovedy/',
+# org_required(NapovedaListView.as_view()),
+# name='sifrovacka_napovedy'
+# ),
+# path(
+# 'preskoceni/',
+# resitel_or_org_required(PreskoceniView.as_view()),
+# name='sifrovacka_preskoceni'
+# ),
+# ]
diff --git a/sifrovacka/views.py b/sifrovacka/views.py
index a525131a..37f3d186 100644
--- a/sifrovacka/views.py
+++ b/sifrovacka/views.py
@@ -1,75 +1,75 @@
-from django.shortcuts import get_object_or_404
-from django.urls import reverse
-from django.views.generic import FormView, ListView
-
-from various.views.pomocne import formularOKView
-from .forms import SifrovackaForm, NapovedaForm
-from .models import OdpovedUcastnika, SpravnaOdpoved, Napoveda, NapovezenoUcastnikovi, SeznamSifer
-from personalni.models import Resitel
-
-
-class SifrovackaView(FormView):
- template_name = 'sifrovacka/sifrovacka.html'
- form_class = SifrovackaForm
-
- def form_valid(self, form):
- instance = form.save(commit=False)
- resitel = Resitel.objects.get(osoba__user=self.request.user)
- instance.resitel = resitel
- instance.save()
- sifra = SpravnaOdpoved.objects.filter(sifra__iexact=instance.sifra, odpoved__iexact=instance.odpoved.strip()).first()
- if sifra is None:
- return formularOKView(self.request, f'Bohužel vám hvězdy nebyly nakloněny. Rozumějte máte to blbě.
Zkusit znovu.
')
-
- instance.uspech = True
- instance.save()
-
- return formularOKView(self.request, f'{sifra.skryty_text}
Odevzdat další.
')
-
-
-class SifrovackaListView(ListView):
- template_name = 'sifrovacka/odpovedi_list.html'
- model = OdpovedUcastnika
-
-class SifrovackaNektereListView(SifrovackaListView):
- def get_queryset(self):
- seznam = get_object_or_404(SeznamSifer, jmeno=self.kwargs['seznam'])
- orig = super().get_queryset()
- return orig.filter(sifra__in=seznam.sifry.all().values('sifra')) # poslední je kvůli tomu, že máme odkaz na celý objekt a ne jen na jméno šifry.
-
-
-class NapovedaView(FormView):
- template_name = 'sifrovacka/napoveda.html'
- form_class = NapovedaForm
-
- def form_valid(self, form):
- instance = form.save(commit=False)
- resitel = Resitel.objects.get(osoba__user=self.request.user)
- instance.resitel = resitel
-
- if NapovezenoUcastnikovi.objects.filter(resitel=resitel, sifra__iexact=instance.sifra).first() is None:
- instance.save()
-
- napoveda = Napoveda.objects.filter(sifra__iexact=instance.sifra).first()
- return formularOKView(self.request, f'Nápověda k šifře číslo {instance.sifra} je:
{napoveda.text}
Odevzdat řešení.
')
-
-
-class NapovedaListView(ListView):
- template_name = 'sifrovacka/napovedy_list.html'
- model = NapovezenoUcastnikovi
-
-
-class PreskoceniView(FormView):
- template_name = 'sifrovacka/preskoceni.html'
- form_class = SifrovackaForm
- initial = {"odpoved": "=======PŘESKOČENO======="}
-
- def form_valid(self, form):
- instance = form.save(commit=False)
- instance.odpoved = "=======PŘESKOČENO======="
- resitel = Resitel.objects.get(osoba__user=self.request.user)
- instance.resitel = resitel
- instance.save()
- sifra = SpravnaOdpoved.objects.filter(sifra__iexact=instance.sifra).first() # FIXME co když je více "správných" odpovědí?
-
- return formularOKView(self.request, f'{sifra.skryty_text}
Zpět na odevzdávátko.
')
+# from django.shortcuts import get_object_or_404
+# from django.urls import reverse
+# from django.views.generic import FormView, ListView
+#
+# from various.views.pomocne import formularOKView
+# from .forms import SifrovackaForm, NapovedaForm
+# from .models import OdpovedUcastnika, SpravnaOdpoved, Napoveda, NapovezenoUcastnikovi, Sifrovacka
+# from personalni.models import Resitel
+#
+#
+# class SifrovackaView(FormView):
+# template_name = 'sifrovacka/sifrovacka.html'
+# form_class = SifrovackaForm
+#
+# def form_valid(self, form):
+# instance = form.save(commit=False)
+# resitel = Resitel.objects.get(osoba__user=self.request.user)
+# instance.resitel = resitel
+# instance.save()
+# sifra = SpravnaOdpoved.objects.filter(sifra__iexact=instance.sifra, odpoved__iexact=instance.odpoved.strip()).first()
+# if sifra is None:
+# return formularOKView(self.request, f'Bohužel vám hvězdy nebyly nakloněny. Rozumějte máte to blbě.
Zkusit znovu.
')
+#
+# instance.uspech = True
+# instance.save()
+#
+# return formularOKView(self.request, f'{sifra.skryty_text}
Odevzdat další.
')
+#
+#
+# class SifrovackaListView(ListView):
+# template_name = 'sifrovacka/odpovedi_list.html'
+# model = OdpovedUcastnika
+#
+# class SifrovackaNektereListView(SifrovackaListView):
+# def get_queryset(self):
+# seznam = get_object_or_404(Sifrovacka, jmeno=self.kwargs['seznam'])
+# orig = super().get_queryset()
+# return orig.filter(sifra__in=seznam.sifry.all().values('sifra')) # poslední je kvůli tomu, že máme odkaz na celý objekt a ne jen na jméno šifry.
+#
+#
+# class NapovedaView(FormView):
+# template_name = 'sifrovacka/napoveda.html'
+# form_class = NapovedaForm
+#
+# def form_valid(self, form):
+# instance = form.save(commit=False)
+# resitel = Resitel.objects.get(osoba__user=self.request.user)
+# instance.resitel = resitel
+#
+# if NapovezenoUcastnikovi.objects.filter(resitel=resitel, sifra__iexact=instance.sifra).first() is None:
+# instance.save()
+#
+# napoveda = Napoveda.objects.filter(sifra__iexact=instance.sifra).first()
+# return formularOKView(self.request, f'Nápověda k šifře číslo {instance.sifra} je:
{napoveda.text}
Odevzdat řešení.
')
+#
+#
+# class NapovedaListView(ListView):
+# template_name = 'sifrovacka/napovedy_list.html'
+# model = NapovezenoUcastnikovi
+#
+#
+# class PreskoceniView(FormView):
+# template_name = 'sifrovacka/preskoceni.html'
+# form_class = SifrovackaForm
+# initial = {"odpoved": "=======PŘESKOČENO======="}
+#
+# def form_valid(self, form):
+# instance = form.save(commit=False)
+# instance.odpoved = "=======PŘESKOČENO======="
+# resitel = Resitel.objects.get(osoba__user=self.request.user)
+# instance.resitel = resitel
+# instance.save()
+# sifra = SpravnaOdpoved.objects.filter(sifra__iexact=instance.sifra).first() # FIXME co když je více "správných" odpovědí?
+#
+# return formularOKView(self.request, f'{sifra.skryty_text}
Zpět na odevzdávátko.
')