Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • komasolver
  • main
  • renovate/django-5.x
  • renovate/django-debug-toolbar-5.x
  • renovate/django_csp-4.x
  • renovate/djangorestframework-3.x
  • renovate/tzdata-2025.x
  • renovate/uwsgi-2.x
8 results

Target

Select target project
  • konstantin/akplanning
  • matedealer/akplanning
  • kif/akplanning
  • mirco/akplanning
  • lordofthevoid/akplanning
  • voidptr/akplanning
  • xayomer/akplanning-fork
  • mollux/akplanning
  • neumantm/akplanning
  • mmarx/akplanning
  • nerf/akplanning
  • felix_bonn/akplanning
  • sebastian.uschmann/akplanning
13 results
Select Git revision
  • ak-import
  • feature/clear-schedule-button
  • feature/json-export-via-rest-framework
  • feature/json-schedule-import-tests
  • feature/preference-polling
  • feature/preference-polling-form
  • feature/preference-polling-form-rebased
  • feature/preference-polling-rebased
  • fix/add-room-import-only-once
  • main
  • merge-to-upstream
  • renovate/django-5.x
  • renovate/django-debug-toolbar-4.x
  • renovate/django-simple-history-3.x
  • renovate/mysqlclient-2.x
15 results
Show changes
......@@ -213,6 +213,16 @@
{% category_linked_badge ak.category ak.event.slug %}
</td>
</tr>
{% if ak.types.count > 0 %}
<tr>
<td>{% trans "Types" %}</td>
<td>
{% for type in ak.types.all %}
<span class="badge bg-info">{{ type }}</span>
{% endfor %}
</td>
</tr>
{% endif %}
{% if ak.track %}
<tr>
<td>{% trans 'Track' %}</td>
......
......@@ -9,6 +9,9 @@
<th>{% trans "Name" %}</th>
<th>{% trans "Who?" %}</th>
<th>{% trans 'Category' %}</th>
{% if show_types %}
<th>{% trans 'Types' %}</th>
{% endif %}
<th></th>
</tr>
</thead>
......@@ -37,6 +40,13 @@
{% endif %}
</td>
<td>{% category_linked_badge ak.category event.slug %}</td>
{% if show_types %}
<td>
{% for aktype in ak.types.all %}
<span class="badge bg-info">{{ aktype }}</span>
{% endfor %}
</td>
{% endif %}
<td class="text-end" style="white-space: nowrap;">
<a href="{{ ak.detail_url }}" data-bs-toggle="tooltip"
title="{% trans 'Details' %}"
......
......@@ -23,6 +23,13 @@
);
});
</script>
<style>
#id_present_helptext::after {
content: " ({% trans "only relevant for KIF-AKs - determines whether the AK appears in the slides for the closing plenary session" %})";
color: #6c757d;
}
</style>
{% endblock %}
{% block breadcrumbs %}
......
from datetime import timedelta
from datetime import datetime, timedelta
from django.test import TestCase
from django.urls import reverse_lazy
from django.utils.datetime_safe import datetime
from AKModel.models import AK, AKSlot, Event
from AKModel.tests import BasicViewTests
from AKSubmission.forms import AKSubmissionForm
class ModelViewTests(BasicViewTests, TestCase):
......@@ -46,8 +46,8 @@ class ModelViewTests(BasicViewTests, TestCase):
'expected_message': "AK successfully updated"},
{'view': 'akslot_edit', 'target_view': 'ak_detail', 'kwargs': {'event_slug': 'kif42', 'pk': 5},
'target_kwargs': {'event_slug': 'kif42', 'pk': 1}, 'expected_message': "AK Slot successfully updated"},
{'view': 'akowner_edit', 'target_view': 'submission_overview', 'kwargs': {'event_slug': 'kif42', 'slug': 'a'},
'target_kwargs': {'event_slug': 'kif42'}, 'expected_message': "Person Info successfully updated"},
{'view': 'akowner_edit', 'target_view': 'submission_overview', 'kwargs': {'event_slug': 'kif42', 'slug': 'a'},
'target_kwargs': {'event_slug': 'kif42'}, 'expected_message': "Person Info successfully updated"},
]
def test_akslot_edit_delete_prevention(self):
......@@ -146,7 +146,8 @@ class ModelViewTests(BasicViewTests, TestCase):
add_redirect_url = reverse_lazy(f"{self.APP_NAME}:submit_ak", kwargs={'event_slug': 'kif42', 'owner_slug': 'a'})
response = self.client.post(select_url, {'owner_id': 1})
self.assertRedirects(response, add_redirect_url, status_code=302, target_status_code=200,
msg_prefix=f"Dispatch redirect to ak submission page failed (should go to {add_redirect_url})")
msg_prefix=f"Dispatch redirect to ak submission page failed "
f"(should go to {add_redirect_url})")
def test_orga_message_submission(self):
"""
......@@ -200,7 +201,8 @@ class ModelViewTests(BasicViewTests, TestCase):
# Test indication outside of indication window -> HTTP 403, counter not increased
response = self.client.post(interest_api_url)
self.assertEqual(response.status_code, 403,
"API end point still reachable even though interest indication window ended ({interest_api_url})")
"API end point still reachable even though interest indication window ended "
"({interest_api_url})")
self.assertEqual(AK.objects.get(pk=1).interest_counter, ak_interest_counter + 1,
"Counter was increased even though interest indication window ended")
......@@ -236,3 +238,39 @@ class ModelViewTests(BasicViewTests, TestCase):
msg_prefix=f"No correct redirect: {add_new_user_to_ak_url} (POST) -> {detail_url}")
self._assert_message(response, "Added 'New test owner' as new owner of 'Test AK Inhalt'")
self.assertEqual(AK.objects.get(pk=1).owners.count(), 2)
def test_visibility_requirements_in_submission_form(self):
"""
Test visibility of requirements field in submission form
"""
event = Event.get_by_slug('kif42')
form = AKSubmissionForm(data={'name': 'Test AK', 'event': event}, instance=None, initial={"event": event})
self.assertIn('requirements', form.fields,
msg="Requirements field not present in form even though event has requirements")
event2 = Event.objects.create(name='Event without requirements',
slug='no_req',
start=datetime.now().astimezone(event.timezone),
end=datetime.now().astimezone(event.timezone),
active=True)
form2 = AKSubmissionForm(data={'name': 'Test AK', 'event': event2}, instance=None, initial={"event": event2})
self.assertNotIn('requirements', form2.fields,
msg="Requirements field should not be present for events without requirements")
def test_visibility_types_in_submission_form(self):
"""
Test visibility of types field in submission form
"""
event = Event.get_by_slug('kif42')
form = AKSubmissionForm(data={'name': 'Test AK', 'event': event}, instance=None, initial={"event": event})
self.assertIn('types', form.fields,
msg="Requirements field not present in form even though event has requirements")
event2 = Event.objects.create(name='Event without types',
slug='no_types',
start=datetime.now().astimezone(event.timezone),
end=datetime.now().astimezone(event.timezone),
active=True)
form2 = AKSubmissionForm(data={'name': 'Test AK', 'event': event2}, instance=None, initial={"event": event2})
self.assertNotIn('types', form2.fields,
msg="Requirements field should not be present for events without types")
from datetime import timedelta
from math import floor
from abc import ABC, abstractmethod
from datetime import datetime, timedelta
from math import floor
from django.apps import apps
from django.conf import settings
......@@ -8,19 +8,17 @@ from django.contrib import messages
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse_lazy
from django.utils.datetime_safe import datetime
from django.utils.translation import gettext_lazy as _
from django.views import View
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView, TemplateView
from django.views.generic import CreateView, DeleteView, DetailView, ListView, TemplateView, UpdateView
from AKModel.availability.models import Availability
from AKModel.metaviews import status_manager
from AKModel.metaviews.status import TemplateStatusWidget
from AKModel.models import AK, AKCategory, AKOwner, AKSlot, AKTrack, AKOrgaMessage
from AKModel.metaviews.admin import EventSlugMixin, FilterByEventSlugMixin
from AKModel.metaviews.status import TemplateStatusWidget
from AKModel.models import AK, AKCategory, AKOrgaMessage, AKOwner, AKSlot, AKTrack
from AKSubmission.api import ak_interest_indication_active
from AKSubmission.forms import AKWishForm, AKOwnerForm, AKSubmissionForm, AKDurationForm, AKOrgaMessageForm, \
AKForm
from AKSubmission.forms import AKDurationForm, AKForm, AKOrgaMessageForm, AKOwnerForm, AKSubmissionForm, AKWishForm
class SubmissionErrorNotConfiguredView(EventSlugMixin, TemplateView):
......@@ -47,7 +45,7 @@ class AKOverviewView(FilterByEventSlugMixin, ListView):
template_name = "AKSubmission/ak_overview.html"
wishes_as_category = False
def filter_aks(self, context, category): # pylint: disable=unused-argument
def filter_aks(self, context, category): # pylint: disable=unused-argument
"""
Filter which AKs to display based on the given context and category
......@@ -59,7 +57,7 @@ class AKOverviewView(FilterByEventSlugMixin, ListView):
:rtype: QuerySet[AK]
"""
# Use prefetching and relation selection/joining to reduce the amount of necessary queries
return category.ak_set.select_related('event').prefetch_related('owners').all()
return category.ak_set.select_related('event').prefetch_related('owners').prefetch_related('types').all()
def get_active_category_name(self, context):
"""
......@@ -73,7 +71,7 @@ class AKOverviewView(FilterByEventSlugMixin, ListView):
"""
return context["categories_with_aks"][0][0].name
def get_table_title(self, context): # pylint: disable=unused-argument
def get_table_title(self, context): # pylint: disable=unused-argument
"""
Specify the title above the AK list/table in this view
......@@ -91,7 +89,7 @@ class AKOverviewView(FilterByEventSlugMixin, ListView):
redirect to error page if necessary (see :class:`SubmissionErrorNotConfiguredView`)
"""
self._load_event()
self.object_list = self.get_queryset() # pylint: disable=attribute-defined-outside-init
self.object_list = self.get_queryset() # pylint: disable=attribute-defined-outside-init
# No categories yet? Redirect to configuration error page
if self.object_list.count() == 0:
......@@ -124,12 +122,14 @@ class AKOverviewView(FilterByEventSlugMixin, ListView):
if self.wishes_as_category:
categories_with_aks.append(
(AKCategory(name=_("Wishes"), pk=0, description=_("AKs one would like to have")), ak_wishes))
(AKCategory(name=_("Wishes"), pk=0, description=_("AKs one would like to have")), ak_wishes))
context["categories_with_aks"] = categories_with_aks
context["active_category"] = self.get_active_category_name(context)
context['table_title'] = self.get_table_title(context)
context['show_types'] = self.event.aktype_set.count() > 0
# ==========================================================
# Display interest indication button?
# ==========================================================
......@@ -181,10 +181,13 @@ class AKListByCategoryView(AKOverviewView):
This view inherits from :class:`AKOverviewView`, but produces only one list instead of a tabbed one.
"""
def dispatch(self, request, *args, **kwargs):
# Override dispatching
# Needed to handle the checking whether the category exists
self.category = get_object_or_404(AKCategory, pk=kwargs['category_pk']) # pylint: disable=attribute-defined-outside-init,line-too-long
# noinspection PyAttributeOutsideInit
# pylint: disable=attribute-defined-outside-init
self.category = get_object_or_404(AKCategory, pk=kwargs['category_pk'])
return super().dispatch(request, *args, **kwargs)
def get_active_category_name(self, context):
......@@ -207,11 +210,12 @@ class AKListByTrackView(AKOverviewView):
This view inherits from :class:`AKOverviewView` and there will be one list per category
-- but only AKs of a certain given track will be included in them.
"""
def dispatch(self, request, *args, **kwargs):
# Override dispatching
# Needed to handle the checking whether the track exists
self.track = get_object_or_404(AKTrack, pk=kwargs['track_pk']) # pylint: disable=attribute-defined-outside-init
self.track = get_object_or_404(AKTrack, pk=kwargs['track_pk']) # pylint: disable=attribute-defined-outside-init
return super().dispatch(request, *args, **kwargs)
def filter_aks(self, context, category):
......@@ -290,6 +294,7 @@ class EventInactiveRedirectMixin:
Will add a message explaining why the action was not performed to the user
and then redirect to start page of the submission component
"""
def get_error_message(self):
"""
Error message to display after redirect (can be adjusted by this method)
......@@ -349,6 +354,7 @@ class AKSubmissionView(AKAndAKWishSubmissionView):
Extends :class:`AKAndAKWishSubmissionView`
"""
def get_initial(self):
# Load initial values for the form
# Used to directly add the first owner and the event this AK will belong to
......@@ -498,7 +504,6 @@ class AKOwnerDispatchView(ABC, EventSlugMixin, View):
:rtype: HttpResponseRedirect
"""
def post(self, request, *args, **kwargs):
# This view is solely meant to handle POST requests
# Perform dispatching based on the submitted owner_id
......
......@@ -10,7 +10,7 @@ setup.
### System Requirements
* Python 3.8+ incl. development tools
* Python3.11+ incl. development tools
* Virtualenv
* pdflatex & beamer
class (`texlive-latex-base texlive-latex-recommended texlive-latex-extra texlive-fonts-extra texlive-luatex`)
......
......@@ -8,14 +8,21 @@ if [ -z ${VIRTUAL_ENV+x} ]; then
fi
# enable really all warnings, some of them are silenced by default
if [[ "$@" == *"--all"* ]]; then
export PYTHONWARNINGS=all
fi
for arg in "$@"; do
if [[ "$arg" == "--all" ]]; then
export PYTHONWARNINGS=all
fi
done
# in case of checking production setup
if [[ "$@" == *"--prod"* ]]; then
export DJANGO_SETTINGS_MODULE=AKPlanning.settings_production
./manage.py check --deploy
fi
for arg in "$@"; do
if [[ "$arg" == "--prod" ]]; then
export DJANGO_SETTINGS_MODULE=AKPlanning.settings_production
./manage.py check --deploy
./manage.py makemigrations --dry-run --check
fi
done
# check the setup
./manage.py check
./manage.py makemigrations --dry-run --check
......@@ -10,7 +10,7 @@ rm -rf venv/
# Setup Python Environment
# Requires: Virtualenv, appropriate Python installation
virtualenv venv -p python3.9
virtualenv venv -p python3.11
source venv/bin/activate
pip install --upgrade setuptools pip wheel
pip install -r requirements.txt
......
#!/usr/bin/env bash
# Test the AKPlanning setup
# execute as Utils/test.sh
# activate virtualenv when necessary
if [ -z ${VIRTUAL_ENV+x} ]; then
source venv/bin/activate
fi
# enable really all warnings, some of them are silenced by default
for arg in "$@"; do
if [[ "$arg" == "--all" ]]; then
export PYTHONWARNINGS=all
fi
done
# in case of checking production setup
for arg in "$@"; do
if [[ "$arg" == "--prod" ]]; then
export DJANGO_SETTINGS_MODULE=AKPlanning.settings_production
./manage.py test --deploy
fi
done
# run tests
./manage.py test
Django==4.2.13
django-bootstrap5==24.2
fontawesomefree==6.5.1 # Makes static files (css, fonts) available locally
django-fontawesome-6==1.0.0.0 # Provides an icon field for models and forms as well as handy shortcuts to render icons
django-split-settings==1.3.1
django-timezone-field==6.1.0
djangorestframework==3.15.1
django-simple-history==3.5.0
django-registration-redux==2.13
django-debug-toolbar==4.3.0
Django==5.1.6
django-betterforms==2.0.0
django-bootstrap-datepicker-plus==5.0.5
django-tex==1.1.10
django-csp==3.8
django-compressor==4.4
django-bootstrap5==25.1
django-compressor==4.5.1
django-debug-toolbar==5.0.1
django-fontawesome-6==1.0.0.0 # Provides an icon field for models and forms as well as handy shortcuts to render icons
django-libsass==0.9
django-betterforms==2.0.0
mysqlclient==2.2.0 # for production deployment
tzdata==2024.1
django-registration-redux==2.13
django-simple-history==3.8.0
django-split-settings==1.3.2
django-tex==1.1.10
django-timezone-field==7.1
django_csp==3.8
djangorestframework==3.15.2
fontawesomefree==6.6.0 # Makes static files (css, fonts) available locally
mysqlclient==2.2.7 # for production deployment
tzdata==2025.1
# Documentation
sphinxcontrib-django==2.5
Sphinx==8.2.3
sphinx-rtd-theme==3.0.2
sphinxcontrib-apidoc==0.5.0
sphinxcontrib-django==2.5.0
recommonmark==0.7.1
django-docs==0.3.3
sphinx-rtd-theme==2.0.0
sphinx==7.3.7