bornhack-website/src/camps/models.py

285 lines
10 KiB
Python
Raw Normal View History

import logging
from datetime import timedelta
SpeakerAvailability, EventSession, autoscheduler, and other goodies (#497) * fix old bug where the get_days() method would return the wrong number of days, this was not discovered because our bootstrap script has been creating 9 day camps instead of 8 day camps (this has been fixed in a different commit) * remove stray debug print * output camp days in local timezone (CEST usually), not UTC * speakeravailability commit of doom, originally intended for #385 but goes a bit further than that. Adds SpeakerAvailability and EventSession models, and models for the new autoscheduler. Update bootstrap script and more. New conference_autoscheduler dependency. Work in progress, but ready for playing around! * add conference-scheduler to requirements * rework migrations, work at bit with postgres range fields and bounds, change how speakeravailability is saved (continuous ranges instead of 1 hour chunks), add tests for utils/range_fields.py including adding hypothesis to requirements/dev.txt, add a test which runs our bootstrap script * catch name collision in the right place, and load missing postgres extension in the migration * add some verbosity to see what the travis issue might be * manually create btree_gist extension in postgres, not sure why the BtreeGistExtension() operation in program/migrations/0085... isn't working in travis? * create extension in the right database maybe * lets try this then * ok so the problem is not that the btree_gist extension isn't getting loaded, the problem is that GIST indexes do not work with uuid fields in postgres 9.6, lets take another stab at getting pg10 with postgis to work with in travis * lets try normal socket connection * add SPEAKER_AVAILABILITY_DAYCHUNK_HOURS=3 to travis environment_settings.py * rework migrations, change so an autoschedule can work with multiple eventtypes, change AutoSlot model to use a DateTimeRangeField so we can use the database for more efficient lookups, add 'conflicts' self m2m for EventLocation to indicate when a room conflicts with another room, add a support_autoscheduling bool to EventType, add workshops to bootstrap script, add timing output to bootstrap script * update README a bit, move some functionality to model methods, update jquery and jquery.datatables, include datatables in base.html instead of in each page, start adding backoffice schedule management views (unfinished), yolo commit so I can show valberg something * Switch to a more simple way of using the autoscheduler, meaning we can remove the whole autoscheduler app and all models. All autoscheduler code is now in program/autoscheduler.py and a bit in backoffice views. Add more backoffice CRUD views for schedule management. Add datatables moment.js plugin to help table sorting of dates. Add Speaker{Proposal}EventConflict model to allow speakers to inform us which events they want to attend so we dont schedule them at the same time. Add EventTag model. New models not hooked up to anything yet. * handle cases where there is no solution without failing, also dont return anything here * wrong block kiddo * switch from EventInstance to EventSlot as the way we schedule events. Finish backoffice content team views (mostly). Many small changes. Prod will need data migration of EventInstances -> EventSlots when the time comes. * keep speakeravailability stuff a bit more DRY by using the AvailabilityMatrixViewMixin everywhere, add event_duration_minutes to EventSession create/update form, reverse the order we delete/create EventSlot objects when updating an EventSession * go through all views, fix various little bugs here and there * add missing migration * add django-taggit, add tags for Events, add tags in bootstrap script, make AutoScheduler use tags. Add tags in forms and templates. * fix taggit entry in requirements * Fix our iCal view: Add uuid field to Event, add uuid property to EventSlot which calculates a consitent UUID for an event at a start time at a location. Use this as the schedule uuid. While here fix so our iCal export is valid, a few fields were missing, the iCal file now validates 100% OK. * fix our FRAB xml export view * comment the EventSlot.uuid property better * typo in comment * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * Update src/backoffice/templates/autoschedule_debug_events.html Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * add a field to make this form look less weird. No difference in functionality. * remove stray print and refactor this form init a bit * fix ScheduleView * only show slots where all speakers are available when scheduling events manually in backoffice * make event list sortable by video recording column * update description on {speaker|event}proposal models reason field * remove badge showing number of scheduled slots for each event in backoffice eventlist. it was unclear what the number meant and it doesn't really fit * remember to consider events in the same location when deciding whether a slot is available or not * add is_available() method to EventLocation, add clean_location() method to EventSlot, call it from EventSlot.clean(), update a bit of text in eventslotunschedule template * fix EventSession.get_available_slots() so it doesnt return busy slots as available, and since this means we can no longer schedule stuff in the lunchbreak lower the number of talks in the bootstrap script a bit so we have a better chance of having a solvable problem * fix the excludefilter in EventSession.get_available_slots() for real this time, also fix an icon and add link in event schedule template in backoffice * show message when no slots are available for manual scheduling in backoffice * add event_conflicts to SpeakerUpdateView form in backoffice * fix link to speaker object in speakerproposal list in backoffice * allow blank tags * make duration validation depend on the eventtype event_duration_minutes if we have one. fix help_text and label and placeholder for all duration fields * allow music acts up to 180 mins in the bootstrap data * fix wrong eventtype name for recreational events in speakerproposalform * stretch the colspan one cell more * save event_conflicts m2m when submitting speaker and event together * form not self, and add succes message * move js function toggleclass() to bornhack.js and rename to toggle_sa_form_class(), function is used in several templates and was missing when submitting combined proposals * move the no-js removal to the top of ready() function This will allow other javascript initialization (eg. DataTable) to see the elements and initialize accordingly (eg. column width for tables) * Fixed problem with event feedback detail view * Fixed problem with event feedback list view * introduce a get_tzrange_days() function and use that to get the relevant days for the matrix instead of camp.get_days(), thereby fixing some display issues when eventsessions cross dates * show submitting user and link to proposal on backoffice event detail page, change User to Submitter in backoffice speaker list table * show warning by the buttons when a proposal cannot be approved, and show better text on approve/reject buttons * disable js schedule, save m2m, prefetch some stuff * fix broken date header in table * remove use of djangos regular slugify function, use the new utils.slugs.unique_slugify() instead Co-authored-by: Thomas Steen Rasmussen <tykling@bornhack.org> Co-authored-by: Benjamin Balder Bach <benjamin@overtag.dk> Co-authored-by: Thomas Flummer <tf@flummer.net>
2020-06-03 19:18:06 +00:00
from django.apps import apps
from django.contrib.postgres.fields import DateTimeRangeField
from django.core.exceptions import ValidationError
from django.db import models
2017-02-19 20:20:19 +00:00
from django.urls import reverse
SpeakerAvailability, EventSession, autoscheduler, and other goodies (#497) * fix old bug where the get_days() method would return the wrong number of days, this was not discovered because our bootstrap script has been creating 9 day camps instead of 8 day camps (this has been fixed in a different commit) * remove stray debug print * output camp days in local timezone (CEST usually), not UTC * speakeravailability commit of doom, originally intended for #385 but goes a bit further than that. Adds SpeakerAvailability and EventSession models, and models for the new autoscheduler. Update bootstrap script and more. New conference_autoscheduler dependency. Work in progress, but ready for playing around! * add conference-scheduler to requirements * rework migrations, work at bit with postgres range fields and bounds, change how speakeravailability is saved (continuous ranges instead of 1 hour chunks), add tests for utils/range_fields.py including adding hypothesis to requirements/dev.txt, add a test which runs our bootstrap script * catch name collision in the right place, and load missing postgres extension in the migration * add some verbosity to see what the travis issue might be * manually create btree_gist extension in postgres, not sure why the BtreeGistExtension() operation in program/migrations/0085... isn't working in travis? * create extension in the right database maybe * lets try this then * ok so the problem is not that the btree_gist extension isn't getting loaded, the problem is that GIST indexes do not work with uuid fields in postgres 9.6, lets take another stab at getting pg10 with postgis to work with in travis * lets try normal socket connection * add SPEAKER_AVAILABILITY_DAYCHUNK_HOURS=3 to travis environment_settings.py * rework migrations, change so an autoschedule can work with multiple eventtypes, change AutoSlot model to use a DateTimeRangeField so we can use the database for more efficient lookups, add 'conflicts' self m2m for EventLocation to indicate when a room conflicts with another room, add a support_autoscheduling bool to EventType, add workshops to bootstrap script, add timing output to bootstrap script * update README a bit, move some functionality to model methods, update jquery and jquery.datatables, include datatables in base.html instead of in each page, start adding backoffice schedule management views (unfinished), yolo commit so I can show valberg something * Switch to a more simple way of using the autoscheduler, meaning we can remove the whole autoscheduler app and all models. All autoscheduler code is now in program/autoscheduler.py and a bit in backoffice views. Add more backoffice CRUD views for schedule management. Add datatables moment.js plugin to help table sorting of dates. Add Speaker{Proposal}EventConflict model to allow speakers to inform us which events they want to attend so we dont schedule them at the same time. Add EventTag model. New models not hooked up to anything yet. * handle cases where there is no solution without failing, also dont return anything here * wrong block kiddo * switch from EventInstance to EventSlot as the way we schedule events. Finish backoffice content team views (mostly). Many small changes. Prod will need data migration of EventInstances -> EventSlots when the time comes. * keep speakeravailability stuff a bit more DRY by using the AvailabilityMatrixViewMixin everywhere, add event_duration_minutes to EventSession create/update form, reverse the order we delete/create EventSlot objects when updating an EventSession * go through all views, fix various little bugs here and there * add missing migration * add django-taggit, add tags for Events, add tags in bootstrap script, make AutoScheduler use tags. Add tags in forms and templates. * fix taggit entry in requirements * Fix our iCal view: Add uuid field to Event, add uuid property to EventSlot which calculates a consitent UUID for an event at a start time at a location. Use this as the schedule uuid. While here fix so our iCal export is valid, a few fields were missing, the iCal file now validates 100% OK. * fix our FRAB xml export view * comment the EventSlot.uuid property better * typo in comment * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * Update src/backoffice/templates/autoschedule_debug_events.html Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * add a field to make this form look less weird. No difference in functionality. * remove stray print and refactor this form init a bit * fix ScheduleView * only show slots where all speakers are available when scheduling events manually in backoffice * make event list sortable by video recording column * update description on {speaker|event}proposal models reason field * remove badge showing number of scheduled slots for each event in backoffice eventlist. it was unclear what the number meant and it doesn't really fit * remember to consider events in the same location when deciding whether a slot is available or not * add is_available() method to EventLocation, add clean_location() method to EventSlot, call it from EventSlot.clean(), update a bit of text in eventslotunschedule template * fix EventSession.get_available_slots() so it doesnt return busy slots as available, and since this means we can no longer schedule stuff in the lunchbreak lower the number of talks in the bootstrap script a bit so we have a better chance of having a solvable problem * fix the excludefilter in EventSession.get_available_slots() for real this time, also fix an icon and add link in event schedule template in backoffice * show message when no slots are available for manual scheduling in backoffice * add event_conflicts to SpeakerUpdateView form in backoffice * fix link to speaker object in speakerproposal list in backoffice * allow blank tags * make duration validation depend on the eventtype event_duration_minutes if we have one. fix help_text and label and placeholder for all duration fields * allow music acts up to 180 mins in the bootstrap data * fix wrong eventtype name for recreational events in speakerproposalform * stretch the colspan one cell more * save event_conflicts m2m when submitting speaker and event together * form not self, and add succes message * move js function toggleclass() to bornhack.js and rename to toggle_sa_form_class(), function is used in several templates and was missing when submitting combined proposals * move the no-js removal to the top of ready() function This will allow other javascript initialization (eg. DataTable) to see the elements and initialize accordingly (eg. column width for tables) * Fixed problem with event feedback detail view * Fixed problem with event feedback list view * introduce a get_tzrange_days() function and use that to get the relevant days for the matrix instead of camp.get_days(), thereby fixing some display issues when eventsessions cross dates * show submitting user and link to proposal on backoffice event detail page, change User to Submitter in backoffice speaker list table * show warning by the buttons when a proposal cannot be approved, and show better text on approve/reject buttons * disable js schedule, save m2m, prefetch some stuff * fix broken date header in table * remove use of djangos regular slugify function, use the new utils.slugs.unique_slugify() instead Co-authored-by: Thomas Steen Rasmussen <tykling@bornhack.org> Co-authored-by: Benjamin Balder Bach <benjamin@overtag.dk> Co-authored-by: Thomas Flummer <tf@flummer.net>
2020-06-03 19:18:06 +00:00
from django.utils import timezone
from psycopg2.extras import DateTimeTZRange
from utils.models import CreatedUpdatedModel, UUIDModel
2019-06-16 12:32:24 +00:00
2017-03-23 17:32:13 +00:00
logger = logging.getLogger("bornhack.%s" % __name__)
2015-10-03 01:07:05 +00:00
class Permission(models.Model):
"""
An unmanaged field-less model which holds our non-model permissions (such as team permission sets)
"""
2019-06-16 12:32:24 +00:00
class Meta:
managed = False
2019-06-16 12:32:24 +00:00
default_permissions = ()
permissions = (
("backoffice_permission", "BackOffice access"),
("badgeteam_permission", "Badge Team permissions set"),
("barteam_permission", "Bar Team permissions set"),
("certteam_permission", "CERT Team permissions set"),
("constructionteam_permission", "Construction Team permissions set"),
("contentteam_permission", "Content Team permissions set"),
("economyteam_permission", "Economy Team permissions set"),
("foodareateam_permission", "Foodarea Team permissions set"),
("infoteam_permission", "Info Team permissions set"),
("lightteam_permission", "Light Team permissions set"),
("logisticsteam_permission", "Logistics Team permissions set"),
("metricsteam_permission", "Metrics Team permissions set"),
("nocteam_permission", "NOC Team permissions set"),
("orgateam_permission", "Orga Team permissions set"),
("pocteam_permission", "POC Team permissions set"),
("prteam_permission", "PR Team permissions set"),
("phototeam_permission", "Photo Team permissions set"),
("powerteam_permission", "Power Team permissions set"),
("rocteam_permission", "ROC Team permissions set"),
("sanitationteam_permission", "Sanitation Team permissions set"),
("shuttleteam_permission", "Shuttle Team permissions set"),
("sponsorsteam_permission", "Sponsors Team permissions set"),
("sysadminteam_permission", "Sysadmin Team permissions set"),
("videoteam_permission", "Video Team permissions set"),
("websiteteam_permission", "Website Team permissions set"),
("wellnessteam_permission", "Wellness Team permissions set"),
("expense_create_permission", "Expense Create permission"),
("revenue_create_permission", "Revenue Create permission"),
)
2015-10-03 01:07:05 +00:00
class Camp(CreatedUpdatedModel, UUIDModel):
class Meta:
2019-06-16 12:32:24 +00:00
verbose_name = "Camp"
verbose_name_plural = "Camps"
ordering = ["-title"]
2015-10-03 01:07:05 +00:00
title = models.CharField(
2019-06-16 12:32:24 +00:00
verbose_name="Title",
help_text="Title of the camp, ie. Bornhack 2016.",
2015-10-03 01:07:05 +00:00
max_length=255,
)
tagline = models.CharField(
2019-06-16 12:32:24 +00:00
verbose_name="Tagline",
help_text='Tagline of the camp, ie. "Initial Commit"',
max_length=255,
2015-10-03 01:07:05 +00:00
)
slug = models.SlugField(
2019-06-16 12:32:24 +00:00
verbose_name="Url Slug", help_text="The url slug to use for this camp"
2015-10-03 01:07:05 +00:00
)
Merge teamcomms branch. Refactor team app and add events app. * Primary commit towards improved team communications. Add new events app to handle team notifications when various events happen, with a Type model which contain event types and a Routing model which controls routing of events to teams. Add shortslug for Camp and Team models. events.handler.py contains the code for sending irc and email notifications for teams. The first two eventtypes have been added in datamigrations, 'ticket_created' and 'public_credit_name_changed', and the tickets and profile apps have been adjusted accordingly. Team IRC channels can be marked as managed and if so the IRC bot will register the team channel with ChanServ if possible. Team IRC channels can be marked as private and the bot will set invite only and maintain an ACL with team members. Users can set their NickServ username in their profile to get on the ACL. Rework all team views and templates. Remove TeamArea model and make Team have an FK to Camp directly. Add docstrings a whole bunch of places. Move signal handlers to apps.py and signal_handlers.py in a few apps. Add basic team mailing list handling, more work to be done. Update bootstrap-devsite script to add more teammembers and add some team event routing for the two eventtypes we have. * default to the console backend for email unless we specifically ask for realworld email * fix signal for public_credit_name approval irc message * fix name display on /people/ page * fix the text on people pages when all non-responsible team members are anonymous * handle cases where we fallback to the area responsible properly * readd removed property, it is used in team_detail view * make it possible to filter profiles by public_credit_name_approved * add method for sending IRC messages in ircbot.utils.add_irc_message(), extend periodic bot method to do more than check for outgoing messages so rename it, refactor chanserv and nickserv handling code, create methods to check and join/part IRC channels as needed, maintain channel ACLs for private channels, do not autojoin any channels when instatiating the bot instead rely on the new check_irc_channels() method to join them, rename profile presave signal, add checking for changed nickserv usernames for acl handling, add teammember.irc_channel_acl_ok boolean to track ACL state, add missing help_text properties to TeamMember fields, rename teammember postsave signal, add teammember deleted signal, readd wrongly deleted EnsureTeamMemberResponsibleMixin * add a few missing early returns
2018-04-09 21:11:05 +00:00
shortslug = models.SlugField(
2019-06-16 12:32:24 +00:00
verbose_name="Short Slug",
help_text="Abbreviated version of the slug. Used in IRC channel names and other places with restricted name length.",
Merge teamcomms branch. Refactor team app and add events app. * Primary commit towards improved team communications. Add new events app to handle team notifications when various events happen, with a Type model which contain event types and a Routing model which controls routing of events to teams. Add shortslug for Camp and Team models. events.handler.py contains the code for sending irc and email notifications for teams. The first two eventtypes have been added in datamigrations, 'ticket_created' and 'public_credit_name_changed', and the tickets and profile apps have been adjusted accordingly. Team IRC channels can be marked as managed and if so the IRC bot will register the team channel with ChanServ if possible. Team IRC channels can be marked as private and the bot will set invite only and maintain an ACL with team members. Users can set their NickServ username in their profile to get on the ACL. Rework all team views and templates. Remove TeamArea model and make Team have an FK to Camp directly. Add docstrings a whole bunch of places. Move signal handlers to apps.py and signal_handlers.py in a few apps. Add basic team mailing list handling, more work to be done. Update bootstrap-devsite script to add more teammembers and add some team event routing for the two eventtypes we have. * default to the console backend for email unless we specifically ask for realworld email * fix signal for public_credit_name approval irc message * fix name display on /people/ page * fix the text on people pages when all non-responsible team members are anonymous * handle cases where we fallback to the area responsible properly * readd removed property, it is used in team_detail view * make it possible to filter profiles by public_credit_name_approved * add method for sending IRC messages in ircbot.utils.add_irc_message(), extend periodic bot method to do more than check for outgoing messages so rename it, refactor chanserv and nickserv handling code, create methods to check and join/part IRC channels as needed, maintain channel ACLs for private channels, do not autojoin any channels when instatiating the bot instead rely on the new check_irc_channels() method to join them, rename profile presave signal, add checking for changed nickserv usernames for acl handling, add teammember.irc_channel_acl_ok boolean to track ACL state, add missing help_text properties to TeamMember fields, rename teammember postsave signal, add teammember deleted signal, readd wrongly deleted EnsureTeamMemberResponsibleMixin * add a few missing early returns
2018-04-09 21:11:05 +00:00
)
buildup = DateTimeRangeField(
2019-06-16 12:32:24 +00:00
verbose_name="Buildup Period", help_text="The camp buildup period."
2016-05-06 20:33:59 +00:00
)
2019-06-16 12:32:24 +00:00
camp = DateTimeRangeField(verbose_name="Camp Period", help_text="The camp period.")
teardown = DateTimeRangeField(
2019-06-16 12:32:24 +00:00
verbose_name="Teardown period", help_text="The camp teardown period."
)
read_only = models.BooleanField(
2019-06-16 12:32:24 +00:00
help_text="Whether the camp is read only (i.e. in the past)", default=False
)
2017-08-14 17:10:58 +00:00
colour = models.CharField(
2019-06-16 12:32:24 +00:00
verbose_name="Colour",
help_text="The primary colour for the camp in hex",
max_length=7,
2017-08-14 17:10:58 +00:00
)
light_text = models.BooleanField(
default=True,
2019-06-16 12:32:24 +00:00
help_text="Check if this camps colour requires white text, uncheck if black text is better",
)
call_for_participation_open = models.BooleanField(
2019-06-16 12:32:24 +00:00
help_text="Check if the Call for Participation is open for this camp",
default=False,
)
call_for_participation = models.TextField(
blank=True,
2019-06-16 12:32:24 +00:00
help_text="The CFP markdown for this Camp",
default="The Call For Participation for this Camp has not been written yet",
)
call_for_sponsors_open = models.BooleanField(
2019-06-16 12:32:24 +00:00
help_text="Check if the Call for Sponsors is open for this camp", default=False
)
call_for_sponsors = models.TextField(
blank=True,
2019-06-16 12:32:24 +00:00
help_text="The CFS markdown for this Camp",
default="The Call For Sponsors for this Camp has not been written yet",
)
show_schedule = models.BooleanField(
help_text="Check if the schedule should be shown.", default=True
)
2017-02-19 20:20:19 +00:00
def get_absolute_url(self):
2019-06-16 12:32:24 +00:00
return reverse("camp_detail", kwargs={"camp_slug": self.slug})
2017-02-19 20:20:19 +00:00
def clean(self):
2019-06-16 12:32:24 +00:00
""" Make sure the dates make sense - meaning no overlaps and buildup before camp before teardown """
errors = []
# check for overlaps buildup vs. camp
if self.buildup.upper > self.camp.lower:
msg = "End of buildup must not be after camp start"
2019-06-16 12:32:24 +00:00
errors.append(ValidationError({"buildup", msg}))
errors.append(ValidationError({"camp", msg}))
# check for overlaps camp vs. teardown
if self.camp.upper > self.teardown.lower:
msg = "End of camp must not be after teardown start"
2019-06-16 12:32:24 +00:00
errors.append(ValidationError({"camp", msg}))
errors.append(ValidationError({"teardown", msg}))
if errors:
raise ValidationError(errors)
def __str__(self):
return "%s - %s" % (self.title, self.tagline)
2016-07-13 19:44:09 +00:00
@property
def logo_small(self):
2019-06-16 12:32:24 +00:00
return "img/%(slug)s/logo/%(slug)s-logo-s.png" % {"slug": self.slug}
2015-10-03 01:07:05 +00:00
@property
def logo_small_svg(self):
2019-06-16 12:32:24 +00:00
return "img/%(slug)s/logo/%(slug)s-logo-small.svg" % {"slug": self.slug}
@property
def logo_large(self):
2019-06-16 12:32:24 +00:00
return "img/%(slug)s/logo/%(slug)s-logo-l.png" % {"slug": self.slug}
@property
def logo_large_svg(self):
2019-06-16 12:32:24 +00:00
return "img/%(slug)s/logo/%(slug)s-logo-large.svg" % {"slug": self.slug}
def get_days(self, camppart):
2019-06-16 12:32:24 +00:00
"""
Returns a list of DateTimeTZRanges representing the days during the specified part of the camp.
2019-06-16 12:32:24 +00:00
"""
if not hasattr(self, camppart):
2017-03-23 17:32:13 +00:00
logger.error("nonexistant field/attribute")
return False
field = getattr(self, camppart)
2019-06-16 12:32:24 +00:00
if (
not hasattr(field, "__class__")
or not hasattr(field.__class__, "__name__")
or not field.__class__.__name__ == "DateTimeTZRange"
):
2017-03-23 17:32:13 +00:00
logger.error("this attribute is not a datetimetzrange field: %s" % field)
return False
SpeakerAvailability, EventSession, autoscheduler, and other goodies (#497) * fix old bug where the get_days() method would return the wrong number of days, this was not discovered because our bootstrap script has been creating 9 day camps instead of 8 day camps (this has been fixed in a different commit) * remove stray debug print * output camp days in local timezone (CEST usually), not UTC * speakeravailability commit of doom, originally intended for #385 but goes a bit further than that. Adds SpeakerAvailability and EventSession models, and models for the new autoscheduler. Update bootstrap script and more. New conference_autoscheduler dependency. Work in progress, but ready for playing around! * add conference-scheduler to requirements * rework migrations, work at bit with postgres range fields and bounds, change how speakeravailability is saved (continuous ranges instead of 1 hour chunks), add tests for utils/range_fields.py including adding hypothesis to requirements/dev.txt, add a test which runs our bootstrap script * catch name collision in the right place, and load missing postgres extension in the migration * add some verbosity to see what the travis issue might be * manually create btree_gist extension in postgres, not sure why the BtreeGistExtension() operation in program/migrations/0085... isn't working in travis? * create extension in the right database maybe * lets try this then * ok so the problem is not that the btree_gist extension isn't getting loaded, the problem is that GIST indexes do not work with uuid fields in postgres 9.6, lets take another stab at getting pg10 with postgis to work with in travis * lets try normal socket connection * add SPEAKER_AVAILABILITY_DAYCHUNK_HOURS=3 to travis environment_settings.py * rework migrations, change so an autoschedule can work with multiple eventtypes, change AutoSlot model to use a DateTimeRangeField so we can use the database for more efficient lookups, add 'conflicts' self m2m for EventLocation to indicate when a room conflicts with another room, add a support_autoscheduling bool to EventType, add workshops to bootstrap script, add timing output to bootstrap script * update README a bit, move some functionality to model methods, update jquery and jquery.datatables, include datatables in base.html instead of in each page, start adding backoffice schedule management views (unfinished), yolo commit so I can show valberg something * Switch to a more simple way of using the autoscheduler, meaning we can remove the whole autoscheduler app and all models. All autoscheduler code is now in program/autoscheduler.py and a bit in backoffice views. Add more backoffice CRUD views for schedule management. Add datatables moment.js plugin to help table sorting of dates. Add Speaker{Proposal}EventConflict model to allow speakers to inform us which events they want to attend so we dont schedule them at the same time. Add EventTag model. New models not hooked up to anything yet. * handle cases where there is no solution without failing, also dont return anything here * wrong block kiddo * switch from EventInstance to EventSlot as the way we schedule events. Finish backoffice content team views (mostly). Many small changes. Prod will need data migration of EventInstances -> EventSlots when the time comes. * keep speakeravailability stuff a bit more DRY by using the AvailabilityMatrixViewMixin everywhere, add event_duration_minutes to EventSession create/update form, reverse the order we delete/create EventSlot objects when updating an EventSession * go through all views, fix various little bugs here and there * add missing migration * add django-taggit, add tags for Events, add tags in bootstrap script, make AutoScheduler use tags. Add tags in forms and templates. * fix taggit entry in requirements * Fix our iCal view: Add uuid field to Event, add uuid property to EventSlot which calculates a consitent UUID for an event at a start time at a location. Use this as the schedule uuid. While here fix so our iCal export is valid, a few fields were missing, the iCal file now validates 100% OK. * fix our FRAB xml export view * comment the EventSlot.uuid property better * typo in comment * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * Update src/backoffice/templates/autoschedule_debug_events.html Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * add a field to make this form look less weird. No difference in functionality. * remove stray print and refactor this form init a bit * fix ScheduleView * only show slots where all speakers are available when scheduling events manually in backoffice * make event list sortable by video recording column * update description on {speaker|event}proposal models reason field * remove badge showing number of scheduled slots for each event in backoffice eventlist. it was unclear what the number meant and it doesn't really fit * remember to consider events in the same location when deciding whether a slot is available or not * add is_available() method to EventLocation, add clean_location() method to EventSlot, call it from EventSlot.clean(), update a bit of text in eventslotunschedule template * fix EventSession.get_available_slots() so it doesnt return busy slots as available, and since this means we can no longer schedule stuff in the lunchbreak lower the number of talks in the bootstrap script a bit so we have a better chance of having a solvable problem * fix the excludefilter in EventSession.get_available_slots() for real this time, also fix an icon and add link in event schedule template in backoffice * show message when no slots are available for manual scheduling in backoffice * add event_conflicts to SpeakerUpdateView form in backoffice * fix link to speaker object in speakerproposal list in backoffice * allow blank tags * make duration validation depend on the eventtype event_duration_minutes if we have one. fix help_text and label and placeholder for all duration fields * allow music acts up to 180 mins in the bootstrap data * fix wrong eventtype name for recreational events in speakerproposalform * stretch the colspan one cell more * save event_conflicts m2m when submitting speaker and event together * form not self, and add succes message * move js function toggleclass() to bornhack.js and rename to toggle_sa_form_class(), function is used in several templates and was missing when submitting combined proposals * move the no-js removal to the top of ready() function This will allow other javascript initialization (eg. DataTable) to see the elements and initialize accordingly (eg. column width for tables) * Fixed problem with event feedback detail view * Fixed problem with event feedback list view * introduce a get_tzrange_days() function and use that to get the relevant days for the matrix instead of camp.get_days(), thereby fixing some display issues when eventsessions cross dates * show submitting user and link to proposal on backoffice event detail page, change User to Submitter in backoffice speaker list table * show warning by the buttons when a proposal cannot be approved, and show better text on approve/reject buttons * disable js schedule, save m2m, prefetch some stuff * fix broken date header in table * remove use of djangos regular slugify function, use the new utils.slugs.unique_slugify() instead Co-authored-by: Thomas Steen Rasmussen <tykling@bornhack.org> Co-authored-by: Benjamin Balder Bach <benjamin@overtag.dk> Co-authored-by: Thomas Flummer <tf@flummer.net>
2020-06-03 19:18:06 +00:00
# count how many unique dates we have in this range
daycount = 1
while True:
if field.lower.date() + timedelta(days=daycount) > field.upper.date():
break
daycount += 1
# loop through the required number of days, append to list as we go
days = []
for i in range(0, daycount):
if i == 0:
SpeakerAvailability, EventSession, autoscheduler, and other goodies (#497) * fix old bug where the get_days() method would return the wrong number of days, this was not discovered because our bootstrap script has been creating 9 day camps instead of 8 day camps (this has been fixed in a different commit) * remove stray debug print * output camp days in local timezone (CEST usually), not UTC * speakeravailability commit of doom, originally intended for #385 but goes a bit further than that. Adds SpeakerAvailability and EventSession models, and models for the new autoscheduler. Update bootstrap script and more. New conference_autoscheduler dependency. Work in progress, but ready for playing around! * add conference-scheduler to requirements * rework migrations, work at bit with postgres range fields and bounds, change how speakeravailability is saved (continuous ranges instead of 1 hour chunks), add tests for utils/range_fields.py including adding hypothesis to requirements/dev.txt, add a test which runs our bootstrap script * catch name collision in the right place, and load missing postgres extension in the migration * add some verbosity to see what the travis issue might be * manually create btree_gist extension in postgres, not sure why the BtreeGistExtension() operation in program/migrations/0085... isn't working in travis? * create extension in the right database maybe * lets try this then * ok so the problem is not that the btree_gist extension isn't getting loaded, the problem is that GIST indexes do not work with uuid fields in postgres 9.6, lets take another stab at getting pg10 with postgis to work with in travis * lets try normal socket connection * add SPEAKER_AVAILABILITY_DAYCHUNK_HOURS=3 to travis environment_settings.py * rework migrations, change so an autoschedule can work with multiple eventtypes, change AutoSlot model to use a DateTimeRangeField so we can use the database for more efficient lookups, add 'conflicts' self m2m for EventLocation to indicate when a room conflicts with another room, add a support_autoscheduling bool to EventType, add workshops to bootstrap script, add timing output to bootstrap script * update README a bit, move some functionality to model methods, update jquery and jquery.datatables, include datatables in base.html instead of in each page, start adding backoffice schedule management views (unfinished), yolo commit so I can show valberg something * Switch to a more simple way of using the autoscheduler, meaning we can remove the whole autoscheduler app and all models. All autoscheduler code is now in program/autoscheduler.py and a bit in backoffice views. Add more backoffice CRUD views for schedule management. Add datatables moment.js plugin to help table sorting of dates. Add Speaker{Proposal}EventConflict model to allow speakers to inform us which events they want to attend so we dont schedule them at the same time. Add EventTag model. New models not hooked up to anything yet. * handle cases where there is no solution without failing, also dont return anything here * wrong block kiddo * switch from EventInstance to EventSlot as the way we schedule events. Finish backoffice content team views (mostly). Many small changes. Prod will need data migration of EventInstances -> EventSlots when the time comes. * keep speakeravailability stuff a bit more DRY by using the AvailabilityMatrixViewMixin everywhere, add event_duration_minutes to EventSession create/update form, reverse the order we delete/create EventSlot objects when updating an EventSession * go through all views, fix various little bugs here and there * add missing migration * add django-taggit, add tags for Events, add tags in bootstrap script, make AutoScheduler use tags. Add tags in forms and templates. * fix taggit entry in requirements * Fix our iCal view: Add uuid field to Event, add uuid property to EventSlot which calculates a consitent UUID for an event at a start time at a location. Use this as the schedule uuid. While here fix so our iCal export is valid, a few fields were missing, the iCal file now validates 100% OK. * fix our FRAB xml export view * comment the EventSlot.uuid property better * typo in comment * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * Update src/backoffice/templates/autoschedule_debug_events.html Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * add a field to make this form look less weird. No difference in functionality. * remove stray print and refactor this form init a bit * fix ScheduleView * only show slots where all speakers are available when scheduling events manually in backoffice * make event list sortable by video recording column * update description on {speaker|event}proposal models reason field * remove badge showing number of scheduled slots for each event in backoffice eventlist. it was unclear what the number meant and it doesn't really fit * remember to consider events in the same location when deciding whether a slot is available or not * add is_available() method to EventLocation, add clean_location() method to EventSlot, call it from EventSlot.clean(), update a bit of text in eventslotunschedule template * fix EventSession.get_available_slots() so it doesnt return busy slots as available, and since this means we can no longer schedule stuff in the lunchbreak lower the number of talks in the bootstrap script a bit so we have a better chance of having a solvable problem * fix the excludefilter in EventSession.get_available_slots() for real this time, also fix an icon and add link in event schedule template in backoffice * show message when no slots are available for manual scheduling in backoffice * add event_conflicts to SpeakerUpdateView form in backoffice * fix link to speaker object in speakerproposal list in backoffice * allow blank tags * make duration validation depend on the eventtype event_duration_minutes if we have one. fix help_text and label and placeholder for all duration fields * allow music acts up to 180 mins in the bootstrap data * fix wrong eventtype name for recreational events in speakerproposalform * stretch the colspan one cell more * save event_conflicts m2m when submitting speaker and event together * form not self, and add succes message * move js function toggleclass() to bornhack.js and rename to toggle_sa_form_class(), function is used in several templates and was missing when submitting combined proposals * move the no-js removal to the top of ready() function This will allow other javascript initialization (eg. DataTable) to see the elements and initialize accordingly (eg. column width for tables) * Fixed problem with event feedback detail view * Fixed problem with event feedback list view * introduce a get_tzrange_days() function and use that to get the relevant days for the matrix instead of camp.get_days(), thereby fixing some display issues when eventsessions cross dates * show submitting user and link to proposal on backoffice event detail page, change User to Submitter in backoffice speaker list table * show warning by the buttons when a proposal cannot be approved, and show better text on approve/reject buttons * disable js schedule, save m2m, prefetch some stuff * fix broken date header in table * remove use of djangos regular slugify function, use the new utils.slugs.unique_slugify() instead Co-authored-by: Thomas Steen Rasmussen <tykling@bornhack.org> Co-authored-by: Benjamin Balder Bach <benjamin@overtag.dk> Co-authored-by: Thomas Flummer <tf@flummer.net>
2020-06-03 19:18:06 +00:00
# on the first day use actual start time instead of midnight (local time)
days.append(
DateTimeTZRange(
SpeakerAvailability, EventSession, autoscheduler, and other goodies (#497) * fix old bug where the get_days() method would return the wrong number of days, this was not discovered because our bootstrap script has been creating 9 day camps instead of 8 day camps (this has been fixed in a different commit) * remove stray debug print * output camp days in local timezone (CEST usually), not UTC * speakeravailability commit of doom, originally intended for #385 but goes a bit further than that. Adds SpeakerAvailability and EventSession models, and models for the new autoscheduler. Update bootstrap script and more. New conference_autoscheduler dependency. Work in progress, but ready for playing around! * add conference-scheduler to requirements * rework migrations, work at bit with postgres range fields and bounds, change how speakeravailability is saved (continuous ranges instead of 1 hour chunks), add tests for utils/range_fields.py including adding hypothesis to requirements/dev.txt, add a test which runs our bootstrap script * catch name collision in the right place, and load missing postgres extension in the migration * add some verbosity to see what the travis issue might be * manually create btree_gist extension in postgres, not sure why the BtreeGistExtension() operation in program/migrations/0085... isn't working in travis? * create extension in the right database maybe * lets try this then * ok so the problem is not that the btree_gist extension isn't getting loaded, the problem is that GIST indexes do not work with uuid fields in postgres 9.6, lets take another stab at getting pg10 with postgis to work with in travis * lets try normal socket connection * add SPEAKER_AVAILABILITY_DAYCHUNK_HOURS=3 to travis environment_settings.py * rework migrations, change so an autoschedule can work with multiple eventtypes, change AutoSlot model to use a DateTimeRangeField so we can use the database for more efficient lookups, add 'conflicts' self m2m for EventLocation to indicate when a room conflicts with another room, add a support_autoscheduling bool to EventType, add workshops to bootstrap script, add timing output to bootstrap script * update README a bit, move some functionality to model methods, update jquery and jquery.datatables, include datatables in base.html instead of in each page, start adding backoffice schedule management views (unfinished), yolo commit so I can show valberg something * Switch to a more simple way of using the autoscheduler, meaning we can remove the whole autoscheduler app and all models. All autoscheduler code is now in program/autoscheduler.py and a bit in backoffice views. Add more backoffice CRUD views for schedule management. Add datatables moment.js plugin to help table sorting of dates. Add Speaker{Proposal}EventConflict model to allow speakers to inform us which events they want to attend so we dont schedule them at the same time. Add EventTag model. New models not hooked up to anything yet. * handle cases where there is no solution without failing, also dont return anything here * wrong block kiddo * switch from EventInstance to EventSlot as the way we schedule events. Finish backoffice content team views (mostly). Many small changes. Prod will need data migration of EventInstances -> EventSlots when the time comes. * keep speakeravailability stuff a bit more DRY by using the AvailabilityMatrixViewMixin everywhere, add event_duration_minutes to EventSession create/update form, reverse the order we delete/create EventSlot objects when updating an EventSession * go through all views, fix various little bugs here and there * add missing migration * add django-taggit, add tags for Events, add tags in bootstrap script, make AutoScheduler use tags. Add tags in forms and templates. * fix taggit entry in requirements * Fix our iCal view: Add uuid field to Event, add uuid property to EventSlot which calculates a consitent UUID for an event at a start time at a location. Use this as the schedule uuid. While here fix so our iCal export is valid, a few fields were missing, the iCal file now validates 100% OK. * fix our FRAB xml export view * comment the EventSlot.uuid property better * typo in comment * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * Update src/backoffice/templates/autoschedule_debug_events.html Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * add a field to make this form look less weird. No difference in functionality. * remove stray print and refactor this form init a bit * fix ScheduleView * only show slots where all speakers are available when scheduling events manually in backoffice * make event list sortable by video recording column * update description on {speaker|event}proposal models reason field * remove badge showing number of scheduled slots for each event in backoffice eventlist. it was unclear what the number meant and it doesn't really fit * remember to consider events in the same location when deciding whether a slot is available or not * add is_available() method to EventLocation, add clean_location() method to EventSlot, call it from EventSlot.clean(), update a bit of text in eventslotunschedule template * fix EventSession.get_available_slots() so it doesnt return busy slots as available, and since this means we can no longer schedule stuff in the lunchbreak lower the number of talks in the bootstrap script a bit so we have a better chance of having a solvable problem * fix the excludefilter in EventSession.get_available_slots() for real this time, also fix an icon and add link in event schedule template in backoffice * show message when no slots are available for manual scheduling in backoffice * add event_conflicts to SpeakerUpdateView form in backoffice * fix link to speaker object in speakerproposal list in backoffice * allow blank tags * make duration validation depend on the eventtype event_duration_minutes if we have one. fix help_text and label and placeholder for all duration fields * allow music acts up to 180 mins in the bootstrap data * fix wrong eventtype name for recreational events in speakerproposalform * stretch the colspan one cell more * save event_conflicts m2m when submitting speaker and event together * form not self, and add succes message * move js function toggleclass() to bornhack.js and rename to toggle_sa_form_class(), function is used in several templates and was missing when submitting combined proposals * move the no-js removal to the top of ready() function This will allow other javascript initialization (eg. DataTable) to see the elements and initialize accordingly (eg. column width for tables) * Fixed problem with event feedback detail view * Fixed problem with event feedback list view * introduce a get_tzrange_days() function and use that to get the relevant days for the matrix instead of camp.get_days(), thereby fixing some display issues when eventsessions cross dates * show submitting user and link to proposal on backoffice event detail page, change User to Submitter in backoffice speaker list table * show warning by the buttons when a proposal cannot be approved, and show better text on approve/reject buttons * disable js schedule, save m2m, prefetch some stuff * fix broken date header in table * remove use of djangos regular slugify function, use the new utils.slugs.unique_slugify() instead Co-authored-by: Thomas Steen Rasmussen <tykling@bornhack.org> Co-authored-by: Benjamin Balder Bach <benjamin@overtag.dk> Co-authored-by: Thomas Flummer <tf@flummer.net>
2020-06-03 19:18:06 +00:00
timezone.localtime(field.lower),
timezone.localtime(
(field.lower + timedelta(days=i + 1))
).replace(hour=0),
)
)
2019-06-16 12:32:24 +00:00
elif i == daycount - 1:
SpeakerAvailability, EventSession, autoscheduler, and other goodies (#497) * fix old bug where the get_days() method would return the wrong number of days, this was not discovered because our bootstrap script has been creating 9 day camps instead of 8 day camps (this has been fixed in a different commit) * remove stray debug print * output camp days in local timezone (CEST usually), not UTC * speakeravailability commit of doom, originally intended for #385 but goes a bit further than that. Adds SpeakerAvailability and EventSession models, and models for the new autoscheduler. Update bootstrap script and more. New conference_autoscheduler dependency. Work in progress, but ready for playing around! * add conference-scheduler to requirements * rework migrations, work at bit with postgres range fields and bounds, change how speakeravailability is saved (continuous ranges instead of 1 hour chunks), add tests for utils/range_fields.py including adding hypothesis to requirements/dev.txt, add a test which runs our bootstrap script * catch name collision in the right place, and load missing postgres extension in the migration * add some verbosity to see what the travis issue might be * manually create btree_gist extension in postgres, not sure why the BtreeGistExtension() operation in program/migrations/0085... isn't working in travis? * create extension in the right database maybe * lets try this then * ok so the problem is not that the btree_gist extension isn't getting loaded, the problem is that GIST indexes do not work with uuid fields in postgres 9.6, lets take another stab at getting pg10 with postgis to work with in travis * lets try normal socket connection * add SPEAKER_AVAILABILITY_DAYCHUNK_HOURS=3 to travis environment_settings.py * rework migrations, change so an autoschedule can work with multiple eventtypes, change AutoSlot model to use a DateTimeRangeField so we can use the database for more efficient lookups, add 'conflicts' self m2m for EventLocation to indicate when a room conflicts with another room, add a support_autoscheduling bool to EventType, add workshops to bootstrap script, add timing output to bootstrap script * update README a bit, move some functionality to model methods, update jquery and jquery.datatables, include datatables in base.html instead of in each page, start adding backoffice schedule management views (unfinished), yolo commit so I can show valberg something * Switch to a more simple way of using the autoscheduler, meaning we can remove the whole autoscheduler app and all models. All autoscheduler code is now in program/autoscheduler.py and a bit in backoffice views. Add more backoffice CRUD views for schedule management. Add datatables moment.js plugin to help table sorting of dates. Add Speaker{Proposal}EventConflict model to allow speakers to inform us which events they want to attend so we dont schedule them at the same time. Add EventTag model. New models not hooked up to anything yet. * handle cases where there is no solution without failing, also dont return anything here * wrong block kiddo * switch from EventInstance to EventSlot as the way we schedule events. Finish backoffice content team views (mostly). Many small changes. Prod will need data migration of EventInstances -> EventSlots when the time comes. * keep speakeravailability stuff a bit more DRY by using the AvailabilityMatrixViewMixin everywhere, add event_duration_minutes to EventSession create/update form, reverse the order we delete/create EventSlot objects when updating an EventSession * go through all views, fix various little bugs here and there * add missing migration * add django-taggit, add tags for Events, add tags in bootstrap script, make AutoScheduler use tags. Add tags in forms and templates. * fix taggit entry in requirements * Fix our iCal view: Add uuid field to Event, add uuid property to EventSlot which calculates a consitent UUID for an event at a start time at a location. Use this as the schedule uuid. While here fix so our iCal export is valid, a few fields were missing, the iCal file now validates 100% OK. * fix our FRAB xml export view * comment the EventSlot.uuid property better * typo in comment * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * Update src/backoffice/templates/autoschedule_debug_events.html Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * add a field to make this form look less weird. No difference in functionality. * remove stray print and refactor this form init a bit * fix ScheduleView * only show slots where all speakers are available when scheduling events manually in backoffice * make event list sortable by video recording column * update description on {speaker|event}proposal models reason field * remove badge showing number of scheduled slots for each event in backoffice eventlist. it was unclear what the number meant and it doesn't really fit * remember to consider events in the same location when deciding whether a slot is available or not * add is_available() method to EventLocation, add clean_location() method to EventSlot, call it from EventSlot.clean(), update a bit of text in eventslotunschedule template * fix EventSession.get_available_slots() so it doesnt return busy slots as available, and since this means we can no longer schedule stuff in the lunchbreak lower the number of talks in the bootstrap script a bit so we have a better chance of having a solvable problem * fix the excludefilter in EventSession.get_available_slots() for real this time, also fix an icon and add link in event schedule template in backoffice * show message when no slots are available for manual scheduling in backoffice * add event_conflicts to SpeakerUpdateView form in backoffice * fix link to speaker object in speakerproposal list in backoffice * allow blank tags * make duration validation depend on the eventtype event_duration_minutes if we have one. fix help_text and label and placeholder for all duration fields * allow music acts up to 180 mins in the bootstrap data * fix wrong eventtype name for recreational events in speakerproposalform * stretch the colspan one cell more * save event_conflicts m2m when submitting speaker and event together * form not self, and add succes message * move js function toggleclass() to bornhack.js and rename to toggle_sa_form_class(), function is used in several templates and was missing when submitting combined proposals * move the no-js removal to the top of ready() function This will allow other javascript initialization (eg. DataTable) to see the elements and initialize accordingly (eg. column width for tables) * Fixed problem with event feedback detail view * Fixed problem with event feedback list view * introduce a get_tzrange_days() function and use that to get the relevant days for the matrix instead of camp.get_days(), thereby fixing some display issues when eventsessions cross dates * show submitting user and link to proposal on backoffice event detail page, change User to Submitter in backoffice speaker list table * show warning by the buttons when a proposal cannot be approved, and show better text on approve/reject buttons * disable js schedule, save m2m, prefetch some stuff * fix broken date header in table * remove use of djangos regular slugify function, use the new utils.slugs.unique_slugify() instead Co-authored-by: Thomas Steen Rasmussen <tykling@bornhack.org> Co-authored-by: Benjamin Balder Bach <benjamin@overtag.dk> Co-authored-by: Thomas Flummer <tf@flummer.net>
2020-06-03 19:18:06 +00:00
# on the last day use actual end time instead of midnight (local time)
days.append(
DateTimeTZRange(
SpeakerAvailability, EventSession, autoscheduler, and other goodies (#497) * fix old bug where the get_days() method would return the wrong number of days, this was not discovered because our bootstrap script has been creating 9 day camps instead of 8 day camps (this has been fixed in a different commit) * remove stray debug print * output camp days in local timezone (CEST usually), not UTC * speakeravailability commit of doom, originally intended for #385 but goes a bit further than that. Adds SpeakerAvailability and EventSession models, and models for the new autoscheduler. Update bootstrap script and more. New conference_autoscheduler dependency. Work in progress, but ready for playing around! * add conference-scheduler to requirements * rework migrations, work at bit with postgres range fields and bounds, change how speakeravailability is saved (continuous ranges instead of 1 hour chunks), add tests for utils/range_fields.py including adding hypothesis to requirements/dev.txt, add a test which runs our bootstrap script * catch name collision in the right place, and load missing postgres extension in the migration * add some verbosity to see what the travis issue might be * manually create btree_gist extension in postgres, not sure why the BtreeGistExtension() operation in program/migrations/0085... isn't working in travis? * create extension in the right database maybe * lets try this then * ok so the problem is not that the btree_gist extension isn't getting loaded, the problem is that GIST indexes do not work with uuid fields in postgres 9.6, lets take another stab at getting pg10 with postgis to work with in travis * lets try normal socket connection * add SPEAKER_AVAILABILITY_DAYCHUNK_HOURS=3 to travis environment_settings.py * rework migrations, change so an autoschedule can work with multiple eventtypes, change AutoSlot model to use a DateTimeRangeField so we can use the database for more efficient lookups, add 'conflicts' self m2m for EventLocation to indicate when a room conflicts with another room, add a support_autoscheduling bool to EventType, add workshops to bootstrap script, add timing output to bootstrap script * update README a bit, move some functionality to model methods, update jquery and jquery.datatables, include datatables in base.html instead of in each page, start adding backoffice schedule management views (unfinished), yolo commit so I can show valberg something * Switch to a more simple way of using the autoscheduler, meaning we can remove the whole autoscheduler app and all models. All autoscheduler code is now in program/autoscheduler.py and a bit in backoffice views. Add more backoffice CRUD views for schedule management. Add datatables moment.js plugin to help table sorting of dates. Add Speaker{Proposal}EventConflict model to allow speakers to inform us which events they want to attend so we dont schedule them at the same time. Add EventTag model. New models not hooked up to anything yet. * handle cases where there is no solution without failing, also dont return anything here * wrong block kiddo * switch from EventInstance to EventSlot as the way we schedule events. Finish backoffice content team views (mostly). Many small changes. Prod will need data migration of EventInstances -> EventSlots when the time comes. * keep speakeravailability stuff a bit more DRY by using the AvailabilityMatrixViewMixin everywhere, add event_duration_minutes to EventSession create/update form, reverse the order we delete/create EventSlot objects when updating an EventSession * go through all views, fix various little bugs here and there * add missing migration * add django-taggit, add tags for Events, add tags in bootstrap script, make AutoScheduler use tags. Add tags in forms and templates. * fix taggit entry in requirements * Fix our iCal view: Add uuid field to Event, add uuid property to EventSlot which calculates a consitent UUID for an event at a start time at a location. Use this as the schedule uuid. While here fix so our iCal export is valid, a few fields were missing, the iCal file now validates 100% OK. * fix our FRAB xml export view * comment the EventSlot.uuid property better * typo in comment * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * Update src/backoffice/templates/autoschedule_debug_events.html Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * add a field to make this form look less weird. No difference in functionality. * remove stray print and refactor this form init a bit * fix ScheduleView * only show slots where all speakers are available when scheduling events manually in backoffice * make event list sortable by video recording column * update description on {speaker|event}proposal models reason field * remove badge showing number of scheduled slots for each event in backoffice eventlist. it was unclear what the number meant and it doesn't really fit * remember to consider events in the same location when deciding whether a slot is available or not * add is_available() method to EventLocation, add clean_location() method to EventSlot, call it from EventSlot.clean(), update a bit of text in eventslotunschedule template * fix EventSession.get_available_slots() so it doesnt return busy slots as available, and since this means we can no longer schedule stuff in the lunchbreak lower the number of talks in the bootstrap script a bit so we have a better chance of having a solvable problem * fix the excludefilter in EventSession.get_available_slots() for real this time, also fix an icon and add link in event schedule template in backoffice * show message when no slots are available for manual scheduling in backoffice * add event_conflicts to SpeakerUpdateView form in backoffice * fix link to speaker object in speakerproposal list in backoffice * allow blank tags * make duration validation depend on the eventtype event_duration_minutes if we have one. fix help_text and label and placeholder for all duration fields * allow music acts up to 180 mins in the bootstrap data * fix wrong eventtype name for recreational events in speakerproposalform * stretch the colspan one cell more * save event_conflicts m2m when submitting speaker and event together * form not self, and add succes message * move js function toggleclass() to bornhack.js and rename to toggle_sa_form_class(), function is used in several templates and was missing when submitting combined proposals * move the no-js removal to the top of ready() function This will allow other javascript initialization (eg. DataTable) to see the elements and initialize accordingly (eg. column width for tables) * Fixed problem with event feedback detail view * Fixed problem with event feedback list view * introduce a get_tzrange_days() function and use that to get the relevant days for the matrix instead of camp.get_days(), thereby fixing some display issues when eventsessions cross dates * show submitting user and link to proposal on backoffice event detail page, change User to Submitter in backoffice speaker list table * show warning by the buttons when a proposal cannot be approved, and show better text on approve/reject buttons * disable js schedule, save m2m, prefetch some stuff * fix broken date header in table * remove use of djangos regular slugify function, use the new utils.slugs.unique_slugify() instead Co-authored-by: Thomas Steen Rasmussen <tykling@bornhack.org> Co-authored-by: Benjamin Balder Bach <benjamin@overtag.dk> Co-authored-by: Thomas Flummer <tf@flummer.net>
2020-06-03 19:18:06 +00:00
timezone.localtime((field.lower + timedelta(days=i))).replace(
hour=0
),
timezone.localtime(field.lower + timedelta(days=i)),
)
)
else:
SpeakerAvailability, EventSession, autoscheduler, and other goodies (#497) * fix old bug where the get_days() method would return the wrong number of days, this was not discovered because our bootstrap script has been creating 9 day camps instead of 8 day camps (this has been fixed in a different commit) * remove stray debug print * output camp days in local timezone (CEST usually), not UTC * speakeravailability commit of doom, originally intended for #385 but goes a bit further than that. Adds SpeakerAvailability and EventSession models, and models for the new autoscheduler. Update bootstrap script and more. New conference_autoscheduler dependency. Work in progress, but ready for playing around! * add conference-scheduler to requirements * rework migrations, work at bit with postgres range fields and bounds, change how speakeravailability is saved (continuous ranges instead of 1 hour chunks), add tests for utils/range_fields.py including adding hypothesis to requirements/dev.txt, add a test which runs our bootstrap script * catch name collision in the right place, and load missing postgres extension in the migration * add some verbosity to see what the travis issue might be * manually create btree_gist extension in postgres, not sure why the BtreeGistExtension() operation in program/migrations/0085... isn't working in travis? * create extension in the right database maybe * lets try this then * ok so the problem is not that the btree_gist extension isn't getting loaded, the problem is that GIST indexes do not work with uuid fields in postgres 9.6, lets take another stab at getting pg10 with postgis to work with in travis * lets try normal socket connection * add SPEAKER_AVAILABILITY_DAYCHUNK_HOURS=3 to travis environment_settings.py * rework migrations, change so an autoschedule can work with multiple eventtypes, change AutoSlot model to use a DateTimeRangeField so we can use the database for more efficient lookups, add 'conflicts' self m2m for EventLocation to indicate when a room conflicts with another room, add a support_autoscheduling bool to EventType, add workshops to bootstrap script, add timing output to bootstrap script * update README a bit, move some functionality to model methods, update jquery and jquery.datatables, include datatables in base.html instead of in each page, start adding backoffice schedule management views (unfinished), yolo commit so I can show valberg something * Switch to a more simple way of using the autoscheduler, meaning we can remove the whole autoscheduler app and all models. All autoscheduler code is now in program/autoscheduler.py and a bit in backoffice views. Add more backoffice CRUD views for schedule management. Add datatables moment.js plugin to help table sorting of dates. Add Speaker{Proposal}EventConflict model to allow speakers to inform us which events they want to attend so we dont schedule them at the same time. Add EventTag model. New models not hooked up to anything yet. * handle cases where there is no solution without failing, also dont return anything here * wrong block kiddo * switch from EventInstance to EventSlot as the way we schedule events. Finish backoffice content team views (mostly). Many small changes. Prod will need data migration of EventInstances -> EventSlots when the time comes. * keep speakeravailability stuff a bit more DRY by using the AvailabilityMatrixViewMixin everywhere, add event_duration_minutes to EventSession create/update form, reverse the order we delete/create EventSlot objects when updating an EventSession * go through all views, fix various little bugs here and there * add missing migration * add django-taggit, add tags for Events, add tags in bootstrap script, make AutoScheduler use tags. Add tags in forms and templates. * fix taggit entry in requirements * Fix our iCal view: Add uuid field to Event, add uuid property to EventSlot which calculates a consitent UUID for an event at a start time at a location. Use this as the schedule uuid. While here fix so our iCal export is valid, a few fields were missing, the iCal file now validates 100% OK. * fix our FRAB xml export view * comment the EventSlot.uuid property better * typo in comment * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * Update src/backoffice/templates/autoschedule_debug_events.html Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * add a field to make this form look less weird. No difference in functionality. * remove stray print and refactor this form init a bit * fix ScheduleView * only show slots where all speakers are available when scheduling events manually in backoffice * make event list sortable by video recording column * update description on {speaker|event}proposal models reason field * remove badge showing number of scheduled slots for each event in backoffice eventlist. it was unclear what the number meant and it doesn't really fit * remember to consider events in the same location when deciding whether a slot is available or not * add is_available() method to EventLocation, add clean_location() method to EventSlot, call it from EventSlot.clean(), update a bit of text in eventslotunschedule template * fix EventSession.get_available_slots() so it doesnt return busy slots as available, and since this means we can no longer schedule stuff in the lunchbreak lower the number of talks in the bootstrap script a bit so we have a better chance of having a solvable problem * fix the excludefilter in EventSession.get_available_slots() for real this time, also fix an icon and add link in event schedule template in backoffice * show message when no slots are available for manual scheduling in backoffice * add event_conflicts to SpeakerUpdateView form in backoffice * fix link to speaker object in speakerproposal list in backoffice * allow blank tags * make duration validation depend on the eventtype event_duration_minutes if we have one. fix help_text and label and placeholder for all duration fields * allow music acts up to 180 mins in the bootstrap data * fix wrong eventtype name for recreational events in speakerproposalform * stretch the colspan one cell more * save event_conflicts m2m when submitting speaker and event together * form not self, and add succes message * move js function toggleclass() to bornhack.js and rename to toggle_sa_form_class(), function is used in several templates and was missing when submitting combined proposals * move the no-js removal to the top of ready() function This will allow other javascript initialization (eg. DataTable) to see the elements and initialize accordingly (eg. column width for tables) * Fixed problem with event feedback detail view * Fixed problem with event feedback list view * introduce a get_tzrange_days() function and use that to get the relevant days for the matrix instead of camp.get_days(), thereby fixing some display issues when eventsessions cross dates * show submitting user and link to proposal on backoffice event detail page, change User to Submitter in backoffice speaker list table * show warning by the buttons when a proposal cannot be approved, and show better text on approve/reject buttons * disable js schedule, save m2m, prefetch some stuff * fix broken date header in table * remove use of djangos regular slugify function, use the new utils.slugs.unique_slugify() instead Co-authored-by: Thomas Steen Rasmussen <tykling@bornhack.org> Co-authored-by: Benjamin Balder Bach <benjamin@overtag.dk> Co-authored-by: Thomas Flummer <tf@flummer.net>
2020-06-03 19:18:06 +00:00
# neither first nor last day, goes from midnight to midnight (local time)
days.append(
DateTimeTZRange(
SpeakerAvailability, EventSession, autoscheduler, and other goodies (#497) * fix old bug where the get_days() method would return the wrong number of days, this was not discovered because our bootstrap script has been creating 9 day camps instead of 8 day camps (this has been fixed in a different commit) * remove stray debug print * output camp days in local timezone (CEST usually), not UTC * speakeravailability commit of doom, originally intended for #385 but goes a bit further than that. Adds SpeakerAvailability and EventSession models, and models for the new autoscheduler. Update bootstrap script and more. New conference_autoscheduler dependency. Work in progress, but ready for playing around! * add conference-scheduler to requirements * rework migrations, work at bit with postgres range fields and bounds, change how speakeravailability is saved (continuous ranges instead of 1 hour chunks), add tests for utils/range_fields.py including adding hypothesis to requirements/dev.txt, add a test which runs our bootstrap script * catch name collision in the right place, and load missing postgres extension in the migration * add some verbosity to see what the travis issue might be * manually create btree_gist extension in postgres, not sure why the BtreeGistExtension() operation in program/migrations/0085... isn't working in travis? * create extension in the right database maybe * lets try this then * ok so the problem is not that the btree_gist extension isn't getting loaded, the problem is that GIST indexes do not work with uuid fields in postgres 9.6, lets take another stab at getting pg10 with postgis to work with in travis * lets try normal socket connection * add SPEAKER_AVAILABILITY_DAYCHUNK_HOURS=3 to travis environment_settings.py * rework migrations, change so an autoschedule can work with multiple eventtypes, change AutoSlot model to use a DateTimeRangeField so we can use the database for more efficient lookups, add 'conflicts' self m2m for EventLocation to indicate when a room conflicts with another room, add a support_autoscheduling bool to EventType, add workshops to bootstrap script, add timing output to bootstrap script * update README a bit, move some functionality to model methods, update jquery and jquery.datatables, include datatables in base.html instead of in each page, start adding backoffice schedule management views (unfinished), yolo commit so I can show valberg something * Switch to a more simple way of using the autoscheduler, meaning we can remove the whole autoscheduler app and all models. All autoscheduler code is now in program/autoscheduler.py and a bit in backoffice views. Add more backoffice CRUD views for schedule management. Add datatables moment.js plugin to help table sorting of dates. Add Speaker{Proposal}EventConflict model to allow speakers to inform us which events they want to attend so we dont schedule them at the same time. Add EventTag model. New models not hooked up to anything yet. * handle cases where there is no solution without failing, also dont return anything here * wrong block kiddo * switch from EventInstance to EventSlot as the way we schedule events. Finish backoffice content team views (mostly). Many small changes. Prod will need data migration of EventInstances -> EventSlots when the time comes. * keep speakeravailability stuff a bit more DRY by using the AvailabilityMatrixViewMixin everywhere, add event_duration_minutes to EventSession create/update form, reverse the order we delete/create EventSlot objects when updating an EventSession * go through all views, fix various little bugs here and there * add missing migration * add django-taggit, add tags for Events, add tags in bootstrap script, make AutoScheduler use tags. Add tags in forms and templates. * fix taggit entry in requirements * Fix our iCal view: Add uuid field to Event, add uuid property to EventSlot which calculates a consitent UUID for an event at a start time at a location. Use this as the schedule uuid. While here fix so our iCal export is valid, a few fields were missing, the iCal file now validates 100% OK. * fix our FRAB xml export view * comment the EventSlot.uuid property better * typo in comment * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * Update src/backoffice/templates/autoschedule_debug_events.html Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * add a field to make this form look less weird. No difference in functionality. * remove stray print and refactor this form init a bit * fix ScheduleView * only show slots where all speakers are available when scheduling events manually in backoffice * make event list sortable by video recording column * update description on {speaker|event}proposal models reason field * remove badge showing number of scheduled slots for each event in backoffice eventlist. it was unclear what the number meant and it doesn't really fit * remember to consider events in the same location when deciding whether a slot is available or not * add is_available() method to EventLocation, add clean_location() method to EventSlot, call it from EventSlot.clean(), update a bit of text in eventslotunschedule template * fix EventSession.get_available_slots() so it doesnt return busy slots as available, and since this means we can no longer schedule stuff in the lunchbreak lower the number of talks in the bootstrap script a bit so we have a better chance of having a solvable problem * fix the excludefilter in EventSession.get_available_slots() for real this time, also fix an icon and add link in event schedule template in backoffice * show message when no slots are available for manual scheduling in backoffice * add event_conflicts to SpeakerUpdateView form in backoffice * fix link to speaker object in speakerproposal list in backoffice * allow blank tags * make duration validation depend on the eventtype event_duration_minutes if we have one. fix help_text and label and placeholder for all duration fields * allow music acts up to 180 mins in the bootstrap data * fix wrong eventtype name for recreational events in speakerproposalform * stretch the colspan one cell more * save event_conflicts m2m when submitting speaker and event together * form not self, and add succes message * move js function toggleclass() to bornhack.js and rename to toggle_sa_form_class(), function is used in several templates and was missing when submitting combined proposals * move the no-js removal to the top of ready() function This will allow other javascript initialization (eg. DataTable) to see the elements and initialize accordingly (eg. column width for tables) * Fixed problem with event feedback detail view * Fixed problem with event feedback list view * introduce a get_tzrange_days() function and use that to get the relevant days for the matrix instead of camp.get_days(), thereby fixing some display issues when eventsessions cross dates * show submitting user and link to proposal on backoffice event detail page, change User to Submitter in backoffice speaker list table * show warning by the buttons when a proposal cannot be approved, and show better text on approve/reject buttons * disable js schedule, save m2m, prefetch some stuff * fix broken date header in table * remove use of djangos regular slugify function, use the new utils.slugs.unique_slugify() instead Co-authored-by: Thomas Steen Rasmussen <tykling@bornhack.org> Co-authored-by: Benjamin Balder Bach <benjamin@overtag.dk> Co-authored-by: Thomas Flummer <tf@flummer.net>
2020-06-03 19:18:06 +00:00
timezone.localtime((field.lower + timedelta(days=i))).replace(
hour=0
),
timezone.localtime(
(field.lower + timedelta(days=i + 1))
).replace(hour=0),
)
)
return days
@property
def buildup_days(self):
2019-06-16 12:32:24 +00:00
"""
Returns a list of DateTimeTZRanges representing the days during the buildup.
2019-06-16 12:32:24 +00:00
"""
return self.get_days("buildup")
@property
def camp_days(self):
2019-06-16 12:32:24 +00:00
"""
Returns a list of DateTimeTZRanges representing the days during the camp.
2019-06-16 12:32:24 +00:00
"""
return self.get_days("camp")
@property
def teardown_days(self):
2019-06-16 12:32:24 +00:00
"""
Returns a list of DateTimeTZRanges representing the days during the buildup.
2019-06-16 12:32:24 +00:00
"""
return self.get_days("teardown")
SpeakerAvailability, EventSession, autoscheduler, and other goodies (#497) * fix old bug where the get_days() method would return the wrong number of days, this was not discovered because our bootstrap script has been creating 9 day camps instead of 8 day camps (this has been fixed in a different commit) * remove stray debug print * output camp days in local timezone (CEST usually), not UTC * speakeravailability commit of doom, originally intended for #385 but goes a bit further than that. Adds SpeakerAvailability and EventSession models, and models for the new autoscheduler. Update bootstrap script and more. New conference_autoscheduler dependency. Work in progress, but ready for playing around! * add conference-scheduler to requirements * rework migrations, work at bit with postgres range fields and bounds, change how speakeravailability is saved (continuous ranges instead of 1 hour chunks), add tests for utils/range_fields.py including adding hypothesis to requirements/dev.txt, add a test which runs our bootstrap script * catch name collision in the right place, and load missing postgres extension in the migration * add some verbosity to see what the travis issue might be * manually create btree_gist extension in postgres, not sure why the BtreeGistExtension() operation in program/migrations/0085... isn't working in travis? * create extension in the right database maybe * lets try this then * ok so the problem is not that the btree_gist extension isn't getting loaded, the problem is that GIST indexes do not work with uuid fields in postgres 9.6, lets take another stab at getting pg10 with postgis to work with in travis * lets try normal socket connection * add SPEAKER_AVAILABILITY_DAYCHUNK_HOURS=3 to travis environment_settings.py * rework migrations, change so an autoschedule can work with multiple eventtypes, change AutoSlot model to use a DateTimeRangeField so we can use the database for more efficient lookups, add 'conflicts' self m2m for EventLocation to indicate when a room conflicts with another room, add a support_autoscheduling bool to EventType, add workshops to bootstrap script, add timing output to bootstrap script * update README a bit, move some functionality to model methods, update jquery and jquery.datatables, include datatables in base.html instead of in each page, start adding backoffice schedule management views (unfinished), yolo commit so I can show valberg something * Switch to a more simple way of using the autoscheduler, meaning we can remove the whole autoscheduler app and all models. All autoscheduler code is now in program/autoscheduler.py and a bit in backoffice views. Add more backoffice CRUD views for schedule management. Add datatables moment.js plugin to help table sorting of dates. Add Speaker{Proposal}EventConflict model to allow speakers to inform us which events they want to attend so we dont schedule them at the same time. Add EventTag model. New models not hooked up to anything yet. * handle cases where there is no solution without failing, also dont return anything here * wrong block kiddo * switch from EventInstance to EventSlot as the way we schedule events. Finish backoffice content team views (mostly). Many small changes. Prod will need data migration of EventInstances -> EventSlots when the time comes. * keep speakeravailability stuff a bit more DRY by using the AvailabilityMatrixViewMixin everywhere, add event_duration_minutes to EventSession create/update form, reverse the order we delete/create EventSlot objects when updating an EventSession * go through all views, fix various little bugs here and there * add missing migration * add django-taggit, add tags for Events, add tags in bootstrap script, make AutoScheduler use tags. Add tags in forms and templates. * fix taggit entry in requirements * Fix our iCal view: Add uuid field to Event, add uuid property to EventSlot which calculates a consitent UUID for an event at a start time at a location. Use this as the schedule uuid. While here fix so our iCal export is valid, a few fields were missing, the iCal file now validates 100% OK. * fix our FRAB xml export view * comment the EventSlot.uuid property better * typo in comment * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * language Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * Update src/backoffice/templates/autoschedule_debug_events.html Co-Authored-By: Benjamin Balder Bach <benjamin@overtag.dk> * add a field to make this form look less weird. No difference in functionality. * remove stray print and refactor this form init a bit * fix ScheduleView * only show slots where all speakers are available when scheduling events manually in backoffice * make event list sortable by video recording column * update description on {speaker|event}proposal models reason field * remove badge showing number of scheduled slots for each event in backoffice eventlist. it was unclear what the number meant and it doesn't really fit * remember to consider events in the same location when deciding whether a slot is available or not * add is_available() method to EventLocation, add clean_location() method to EventSlot, call it from EventSlot.clean(), update a bit of text in eventslotunschedule template * fix EventSession.get_available_slots() so it doesnt return busy slots as available, and since this means we can no longer schedule stuff in the lunchbreak lower the number of talks in the bootstrap script a bit so we have a better chance of having a solvable problem * fix the excludefilter in EventSession.get_available_slots() for real this time, also fix an icon and add link in event schedule template in backoffice * show message when no slots are available for manual scheduling in backoffice * add event_conflicts to SpeakerUpdateView form in backoffice * fix link to speaker object in speakerproposal list in backoffice * allow blank tags * make duration validation depend on the eventtype event_duration_minutes if we have one. fix help_text and label and placeholder for all duration fields * allow music acts up to 180 mins in the bootstrap data * fix wrong eventtype name for recreational events in speakerproposalform * stretch the colspan one cell more * save event_conflicts m2m when submitting speaker and event together * form not self, and add succes message * move js function toggleclass() to bornhack.js and rename to toggle_sa_form_class(), function is used in several templates and was missing when submitting combined proposals * move the no-js removal to the top of ready() function This will allow other javascript initialization (eg. DataTable) to see the elements and initialize accordingly (eg. column width for tables) * Fixed problem with event feedback detail view * Fixed problem with event feedback list view * introduce a get_tzrange_days() function and use that to get the relevant days for the matrix instead of camp.get_days(), thereby fixing some display issues when eventsessions cross dates * show submitting user and link to proposal on backoffice event detail page, change User to Submitter in backoffice speaker list table * show warning by the buttons when a proposal cannot be approved, and show better text on approve/reject buttons * disable js schedule, save m2m, prefetch some stuff * fix broken date header in table * remove use of djangos regular slugify function, use the new utils.slugs.unique_slugify() instead Co-authored-by: Thomas Steen Rasmussen <tykling@bornhack.org> Co-authored-by: Benjamin Balder Bach <benjamin@overtag.dk> Co-authored-by: Thomas Flummer <tf@flummer.net>
2020-06-03 19:18:06 +00:00
# convenience properties to access Camp-related stuff easily from the Camp object
@property
def event_types(self):
""" Return all event types with at least one event in this camp """
EventType = apps.get_model("program", "EventType")
return EventType.objects.filter(
events__isnull=False, event__track__camp=self
).distinct()
@property
def event_proposals(self):
EventProposal = apps.get_model("program", "EventProposal")
return EventProposal.objects.filter(track__camp=self)
@property
def events(self):
Event = apps.get_model("program", "Event")
return Event.objects.filter(track__camp=self)
@property
def event_sessions(self):
EventSession = apps.get_model("program", "EventSession")
return EventSession.objects.filter(camp=self)
@property
def event_slots(self):
EventSlot = apps.get_model("program", "EventSlot")
return EventSlot.objects.filter(event_session__in=self.event_sessions.all())