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/sphinxcontrib-apidoc-0.x
  • renovate/tzdata-2025.x
  • renovate/uwsgi-2.x
9 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
  • komasolver
  • main
  • renovate/django-5.x
  • renovate/django-debug-toolbar-5.x
  • renovate/django_csp-4.x
  • renovate/djangorestframework-3.x
  • renovate/sphinxcontrib-apidoc-0.x
  • renovate/tzdata-2025.x
  • renovate/uwsgi-2.x
9 results
Show changes
Commits on Source (4)
...@@ -293,7 +293,7 @@ class Availability(models.Model): ...@@ -293,7 +293,7 @@ class Availability(models.Model):
# event end + 1 day # event end + 1 day
full_event = Availability(event=event, start=event.start, end=event.end) full_event = Availability(event=event, start=event.start, end=event.end)
avail_union = Availability.union(availabilities) avail_union = Availability.union(availabilities)
return not avail_union or avail_union[0].contains(full_event) return any(avail.contains(full_event) for avail in avail_union)
class Meta: class Meta:
verbose_name = _('Availability') verbose_name = _('Availability')
......
...@@ -274,7 +274,7 @@ class RoomFormWithAvailabilities(AvailabilitiesFormMixin, RoomForm): ...@@ -274,7 +274,7 @@ class RoomFormWithAvailabilities(AvailabilitiesFormMixin, RoomForm):
self.fields["properties"].queryset = AKRequirement.objects.filter(event=self.instance.event) self.fields["properties"].queryset = AKRequirement.objects.filter(event=self.instance.event)
class JSONImportForm(AdminIntermediateForm): class JSONScheduleImportForm(AdminIntermediateForm):
"""Form to import an AK schedule from a json file.""" """Form to import an AK schedule from a json file."""
json_data = forms.CharField( json_data = forms.CharField(
required=True, required=True,
......
...@@ -1262,8 +1262,8 @@ msgstr "" ...@@ -1262,8 +1262,8 @@ msgstr ""
"{u} Slot(s) aktualisiert, {c} Slot(s) hinzugefügt und {d} Slot(s) gelöscht" "{u} Slot(s) aktualisiert, {c} Slot(s) hinzugefügt und {d} Slot(s) gelöscht"
#: AKModel/views/manage.py:257 #: AKModel/views/manage.py:257
msgid "AK JSON Import" msgid "AK Schedule JSON Import"
msgstr "AK-JSON-Import" msgstr "AK-Plan JSON-Import"
#: AKModel/views/room.py:37 #: AKModel/views/room.py:37
#, python-format #, python-format
......
...@@ -2,7 +2,7 @@ import itertools ...@@ -2,7 +2,7 @@ import itertools
import json import json
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Iterable from typing import Iterable, Generator
from django.db import models from django.db import models
from django.apps import apps from django.apps import apps
...@@ -17,10 +17,15 @@ from timezone_field import TimeZoneField ...@@ -17,10 +17,15 @@ from timezone_field import TimeZoneField
@dataclass @dataclass
class OptimizerTimeslot: class OptimizerTimeslot:
"""Class describing a timeslot. Used to interface with an optimizer.""" """Class describing a discrete timeslot. Used to interface with an optimizer."""
"""The availability object corresponding to this timeslot."""
avail: "Availability" avail: "Availability"
"""The unique index of this optimizer timeslot."""
idx: int idx: int
"""The set of time constraints fulfilled by this object."""
constraints: set[str] constraints: set[str]
def merge(self, other: "OptimizerTimeslot") -> "OptimizerTimeslot": def merge(self, other: "OptimizerTimeslot") -> "OptimizerTimeslot":
...@@ -33,7 +38,6 @@ class OptimizerTimeslot: ...@@ -33,7 +38,6 @@ class OptimizerTimeslot:
""" """
avail = self.avail.merge_with(other.avail) avail = self.avail.merge_with(other.avail)
constraints = self.constraints.union(other.constraints) constraints = self.constraints.union(other.constraints)
# we simply use the index of result[-1]
return OptimizerTimeslot( return OptimizerTimeslot(
avail=avail, idx=self.idx, constraints=constraints avail=avail, idx=self.idx, constraints=constraints
) )
...@@ -200,10 +204,10 @@ class Event(models.Model): ...@@ -200,10 +204,10 @@ class Event(models.Model):
slot_duration: timedelta, slot_duration: timedelta,
slot_index: int = 0, slot_index: int = 0,
constraints: set[str] | None = None, constraints: set[str] | None = None,
) -> Iterable[TimeslotBlock]: ) -> Generator[TimeslotBlock, None, int]:
"""Discretize a time range into timeslots. """Discretize a time range into timeslots.
Uses a uniform discretization into blocks of length `slot_duration`, Uses a uniform discretization into discrete slots of length `slot_duration`,
starting at `start`. No incomplete timeslots are generated, i.e. starting at `start`. No incomplete timeslots are generated, i.e.
if (`end` - `start`) is not a whole number multiple of `slot_duration` if (`end` - `start`) is not a whole number multiple of `slot_duration`
then the last incomplete timeslot is dropped. then the last incomplete timeslot is dropped.
...@@ -214,7 +218,11 @@ class Event(models.Model): ...@@ -214,7 +218,11 @@ class Event(models.Model):
:param slot_index: index of the first timeslot. Defaults to 0. :param slot_index: index of the first timeslot. Defaults to 0.
:yield: Block of optimizer timeslots as the discretization result. :yield: Block of optimizer timeslots as the discretization result.
:ytype: list of TimeslotBlock :ytype: list of OptimizerTimeslot
:return: The first slot index after the yielded blocks, i.e.
`slot_index` + total # generated timeslots
:rtype: int
""" """
# local import to prevent cyclic import # local import to prevent cyclic import
# pylint: disable=import-outside-toplevel # pylint: disable=import-outside-toplevel
...@@ -264,12 +272,15 @@ class Event(models.Model): ...@@ -264,12 +272,15 @@ class Event(models.Model):
return slot_index return slot_index
def uniform_time_slots(self, *, slots_in_an_hour: float = 1.0) -> Iterable[TimeslotBlock]: def uniform_time_slots(self, *, slots_in_an_hour: float = 1.0) -> Iterable[TimeslotBlock]:
"""Uniformly discretize the entire event into a single block of timeslots. """Uniformly discretize the entire event into blocks of timeslots.
Discretizes entire event uniformly. May not necessarily result in a single block
as slots with no room availability are dropped.
:param slots_in_an_hour: The percentage of an hour covered by a single slot. :param slots_in_an_hour: The percentage of an hour covered by a single slot.
Determines the discretization granularity. Determines the discretization granularity.
:yield: Block of optimizer timeslots as the discretization result. :yield: Block of optimizer timeslots as the discretization result.
:ytype: a single list of TimeslotBlock :ytype: list of OptimizerTimeslot
""" """
all_category_constraints = AKCategory.create_category_constraints( all_category_constraints = AKCategory.create_category_constraints(
AKCategory.objects.filter(event=self).all() AKCategory.objects.filter(event=self).all()
...@@ -631,7 +642,7 @@ class AK(models.Model): ...@@ -631,7 +642,7 @@ class AK(models.Model):
availabilities = ', \n'.join(f'{a.simplified}' for a in Availability.objects.select_related('event') availabilities = ', \n'.join(f'{a.simplified}' for a in Availability.objects.select_related('event')
.filter(ak=self)) .filter(ak=self))
detail_string = f"""{self.name}{" (R)" if self.reso else ""}: detail_string = f"""{self.name}{" (R)" if self.reso else ""}:
{self.owners_list} {self.owners_list}
{_('Interest')}: {self.interest}""" {_('Interest')}: {self.interest}"""
...@@ -925,7 +936,7 @@ class AKSlot(models.Model): ...@@ -925,7 +936,7 @@ class AKSlot(models.Model):
# self.slots_in_an_hour is set in AKJSONExportView # self.slots_in_an_hour is set in AKJSONExportView
data = { data = {
"id": str(self.pk), "id": str(self.pk),
"duration": int(self.duration * self.slots_in_an_hour), "duration": round(self.duration * self.slots_in_an_hour),
"properties": {}, "properties": {},
"room_constraints": [constraint.name "room_constraints": [constraint.name
for constraint in self.ak.requirements.all()], for constraint in self.ak.requirements.all()],
......
...@@ -5,7 +5,7 @@ from rest_framework.routers import DefaultRouter ...@@ -5,7 +5,7 @@ from rest_framework.routers import DefaultRouter
import AKModel.views.api import AKModel.views.api
from AKModel.views.manage import ExportSlidesView, PlanPublishView, PlanUnpublishView, DefaultSlotEditorView, \ from AKModel.views.manage import ExportSlidesView, PlanPublishView, PlanUnpublishView, DefaultSlotEditorView, \
AKsByUserView, AKJSONImportView AKsByUserView, AKScheduleJSONImportView
from AKModel.views.ak import AKRequirementOverview, AKCSVExportView, AKJSONExportView, AKWikiExportView, \ from AKModel.views.ak import AKRequirementOverview, AKCSVExportView, AKJSONExportView, AKWikiExportView, \
AKMessageDeleteView AKMessageDeleteView
from AKModel.views.event_wizard import NewEventWizardStartView, NewEventWizardPrepareImportView, \ from AKModel.views.event_wizard import NewEventWizardStartView, NewEventWizardPrepareImportView, \
...@@ -99,8 +99,8 @@ def get_admin_urls_event(admin_site): ...@@ -99,8 +99,8 @@ def get_admin_urls_event(admin_site):
name="ak_csv_export"), name="ak_csv_export"),
path('<slug:event_slug>/ak-json-export/', admin_site.admin_view(AKJSONExportView.as_view()), path('<slug:event_slug>/ak-json-export/', admin_site.admin_view(AKJSONExportView.as_view()),
name="ak_json_export"), name="ak_json_export"),
path('<slug:event_slug>/ak-json-import/', admin_site.admin_view(AKJSONImportView.as_view()), path('<slug:event_slug>/ak-schedule-json-import/', admin_site.admin_view(AKScheduleJSONImportView.as_view()),
name="ak_json_import"), name="ak_schedule_json_import"),
path('<slug:slug>/ak-wiki-export/', admin_site.admin_view(AKWikiExportView.as_view()), path('<slug:slug>/ak-wiki-export/', admin_site.admin_view(AKWikiExportView.as_view()),
name="ak_wiki_export"), name="ak_wiki_export"),
path('<slug:event_slug>/delete-orga-messages/', admin_site.admin_view(AKMessageDeleteView.as_view()), path('<slug:event_slug>/delete-orga-messages/', admin_site.admin_view(AKMessageDeleteView.as_view()),
......
...@@ -14,7 +14,7 @@ from django.views.generic import TemplateView, DetailView ...@@ -14,7 +14,7 @@ from django.views.generic import TemplateView, DetailView
from django_tex.core import render_template_with_context, run_tex_in_directory from django_tex.core import render_template_with_context, run_tex_in_directory
from django_tex.response import PDFResponse from django_tex.response import PDFResponse
from AKModel.forms import SlideExportForm, DefaultSlotEditorForm, JSONImportForm from AKModel.forms import SlideExportForm, DefaultSlotEditorForm, JSONScheduleImportForm
from AKModel.metaviews.admin import EventSlugMixin, IntermediateAdminView, IntermediateAdminActionView, AdminViewMixin from AKModel.metaviews.admin import EventSlugMixin, IntermediateAdminView, IntermediateAdminActionView, AdminViewMixin
from AKModel.models import ConstraintViolation, Event, DefaultSlot, AKOwner from AKModel.models import ConstraintViolation, Event, DefaultSlot, AKOwner
...@@ -249,12 +249,12 @@ class AKsByUserView(AdminViewMixin, EventSlugMixin, DetailView): ...@@ -249,12 +249,12 @@ class AKsByUserView(AdminViewMixin, EventSlugMixin, DetailView):
template_name = "admin/AKModel/aks_by_user.html" template_name = "admin/AKModel/aks_by_user.html"
class AKJSONImportView(EventSlugMixin, IntermediateAdminView): class AKScheduleJSONImportView(EventSlugMixin, IntermediateAdminView):
""" """
View: Import an AK schedule from a json file that can be pasted into this view. View: Import an AK schedule from a json file that can be pasted into this view.
""" """
form_class = JSONImportForm form_class = JSONScheduleImportForm
title = _("AK JSON Import") title = _("AK Schedule JSON Import")
def form_valid(self, form): def form_valid(self, form):
self.event.schedule_from_json(form.data["json_data"]) self.event.schedule_from_json(form.data["json_data"])
......
...@@ -135,7 +135,7 @@ class EventAKsWidget(TemplateStatusWidget): ...@@ -135,7 +135,7 @@ class EventAKsWidget(TemplateStatusWidget):
}, },
{ {
"text": _("Import AK schedule from JSON"), "text": _("Import AK schedule from JSON"),
"url": reverse_lazy("admin:ak_json_import", kwargs={"event_slug": context["event"].slug}), "url": reverse_lazy("admin:ak_schedule_json_import", kwargs={"event_slug": context["event"].slug}),
}, },
{ {
"text": _("Export AKs as CSV"), "text": _("Export AKs as CSV"),
......