diff --git a/oioioi/base/tests/tests.py b/oioioi/base/tests/tests.py index f3948eecf..2f5d68a6e 100644 --- a/oioioi/base/tests/tests.py +++ b/oioioi/base/tests/tests.py @@ -61,6 +61,7 @@ from oioioi.contests.models import Contest from oioioi.contests.utils import is_contest_admin from oioioi.szkopul.views import main_page_view as szkopul_main_page +from oioioi.welcomepage.views import welcome_page_view if not getattr(settings, 'TESTS', False): print( @@ -163,6 +164,7 @@ class TestIndexNoContest(TestCase): @override_settings(DEFAULT_GLOBAL_PORTAL_AS_MAIN_PAGE=False) def test_no_contest(self): + unregister_main_page_view(welcome_page_view) unregister_main_page_view(szkopul_main_page) with self.assertNumQueriesLessThan(50): response = self.client.get('/') diff --git a/oioioi/deployment/settings.py.template b/oioioi/deployment/settings.py.template index 4a28b1f9c..8e20cea92 100755 --- a/oioioi/deployment/settings.py.template +++ b/oioioi/deployment/settings.py.template @@ -196,6 +196,7 @@ INSTALLED_APPS = ( # 'oioioi.problemsharing', # 'oioioi.usergroups', # 'oioioi.usercontests', + # 'oioioi.welcomepage', ) + INSTALLED_APPS # If set to locations of flite and sox executables, enables audio playback @@ -580,5 +581,3 @@ ZEUS_INSTANCES = { # Experimental # USE_ACE_EDITOR = False - - diff --git a/oioioi/szkopul/tests.py b/oioioi/szkopul/tests.py index c81eb2ea6..87c96aa4e 100644 --- a/oioioi/szkopul/tests.py +++ b/oioioi/szkopul/tests.py @@ -7,10 +7,12 @@ from django.test.utils import override_settings from django.urls import NoReverseMatch, reverse +from oioioi.base.main_page import unregister_main_page_view from oioioi.base.tests import TestCase from oioioi.contests.current_contest import ContestMode from oioioi.contests.models import ProblemInstance, Submission from oioioi.problems.models import Problem +from oioioi.welcomepage.views import welcome_page_view class TestMainPageView(TestCase): @@ -23,6 +25,10 @@ class TestMainPageView(TestCase): 'test_submission', ] + def setUp(self): + super(TestMainPageView, self).setUp() + unregister_main_page_view(welcome_page_view) + @override_settings(CONTEST_MODE=ContestMode.neutral) def test_navbar_links(self): try: diff --git a/oioioi/test_settings.py b/oioioi/test_settings.py index 9ae674474..cdcc6999e 100644 --- a/oioioi/test_settings.py +++ b/oioioi/test_settings.py @@ -61,6 +61,7 @@ 'oioioi.problemsharing', 'oioioi.usercontests', 'oioioi.mp', + 'oioioi.welcomepage', ) + INSTALLED_APPS TEMPLATES[0]['OPTIONS']['context_processors'] += [ diff --git a/oioioi/welcomepage/README.rst b/oioioi/welcomepage/README.rst new file mode 100644 index 000000000..a2e292a95 --- /dev/null +++ b/oioioi/welcomepage/README.rst @@ -0,0 +1 @@ +Welcome page with custom message which is the default page if the app is enabled. diff --git a/oioioi/welcomepage/__init__.py b/oioioi/welcomepage/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/oioioi/welcomepage/apps.py b/oioioi/welcomepage/apps.py new file mode 100644 index 000000000..7b3958de8 --- /dev/null +++ b/oioioi/welcomepage/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class WelcomePageAppConfig(AppConfig): + default_auto_field = 'django.db.models.AutoField' + name = "oioioi.welcomepage" diff --git a/oioioi/welcomepage/forms.py b/oioioi/welcomepage/forms.py new file mode 100644 index 000000000..4ba10cbf2 --- /dev/null +++ b/oioioi/welcomepage/forms.py @@ -0,0 +1,37 @@ +from django import forms +from django.conf import settings +from django.forms import modelformset_factory + +from oioioi.welcomepage.models import WelcomePageMessage + + +class WelcomePageMessageForm(forms.ModelForm): + class Meta(object): + model = WelcomePageMessage + fields = ['content', 'language'] + + language = forms.ChoiceField( + label="Language", + choices=settings.LANGUAGES, + widget=forms.HiddenInput(), + ) + + content = forms.CharField( + label="Content", + widget=forms.Textarea(attrs={ + 'rows': 10, + 'style': 'white-space: pre;', + 'class': 'monospace', + }), + ) + +WelcomePageMessageFormset = modelformset_factory( + WelcomePageMessage, + form=WelcomePageMessageForm, + extra=len(settings.LANGUAGES), + min_num=1, + max_num=len(settings.LANGUAGES), + validate_min=True, + validate_max=True, + can_delete=True, +) diff --git a/oioioi/welcomepage/migrations/0001_initial.py b/oioioi/welcomepage/migrations/0001_initial.py new file mode 100644 index 000000000..3f136780a --- /dev/null +++ b/oioioi/welcomepage/migrations/0001_initial.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.16 on 2024-09-06 09:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='WelcomePageMessage', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content', models.TextField(blank=True, verbose_name='message')), + ('language', models.CharField(max_length=6, verbose_name='language code')), + ], + options={ + 'verbose_name': 'welcome page message', + 'verbose_name_plural': 'welcome page messages', + }, + ), + ] diff --git a/oioioi/welcomepage/migrations/__init__.py b/oioioi/welcomepage/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/oioioi/welcomepage/models.py b/oioioi/welcomepage/models.py new file mode 100644 index 000000000..164ae12d8 --- /dev/null +++ b/oioioi/welcomepage/models.py @@ -0,0 +1,15 @@ +from django.db import models +from django.utils.safestring import mark_safe +from django.utils.translation import gettext_lazy as _ + + +class WelcomePageMessage(models.Model): + content = models.TextField(verbose_name=_("message"), blank=True) + language = models.CharField(max_length=6, verbose_name=_("language code")) + + class Meta: + verbose_name = _("welcome page message") + verbose_name_plural = _("welcome page messages") + + def render_content(self): + return mark_safe(self.content) diff --git a/oioioi/welcomepage/static/welcomepage/textfield-tab.js b/oioioi/welcomepage/static/welcomepage/textfield-tab.js new file mode 100644 index 000000000..e61d62060 --- /dev/null +++ b/oioioi/welcomepage/static/welcomepage/textfield-tab.js @@ -0,0 +1,9 @@ +$('textarea').on('keydown', function (e) { + if (e.key === 'Tab') { + e.preventDefault(); + const start = this.selectionStart; + const end = this.selectionEnd; + this.value = this.value.substring(0, start) + '\t' + this.value.substring(end); + this.selectionStart = this.selectionEnd = start + 1; + } +}); diff --git a/oioioi/welcomepage/templates/welcomepage/welcome-page-edit.html b/oioioi/welcomepage/templates/welcomepage/welcome-page-edit.html new file mode 100644 index 000000000..e8f8fe0a9 --- /dev/null +++ b/oioioi/welcomepage/templates/welcomepage/welcome-page-edit.html @@ -0,0 +1,31 @@ +{% extends "base-with-menu.html" %} +{% load i18n static %} + +{% block title %}Edit welcome page content{% endblock %} + +{% block main-content %} +