Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Limit schedule generator by session purpose #5055

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions ietf/meeting/management/commands/generate_schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
from ietf.person.models import Person
from ietf.meeting import models
from ietf.meeting.helpers import get_person_by_email
from ietf.name.models import SessionPurposeName


# 40 runs of the optimiser for IETF 106 with cycles=160 resulted in 16
# zero-violation invocations, with a mean number of runs of 91 and
Expand Down Expand Up @@ -72,18 +74,31 @@ def add_arguments(self, parser):
'Base schedule for generated schedule, specified as "[owner/]name"'
' (default is no base schedule; owner not required if name is unique)'
))
parser.add_argument('-p', '--purpose',
dest='purposes',
action='append',
choices=[
spn.slug for spn in SessionPurposeName.objects.all()
if 'regular' in spn.timeslot_types # scheduler only works with "regular" timeslots
],
default=None,
help=(
'Limit scheduling to specified purpose '
'(use option multiple times to specify more than one purpose; default is all purposes)'
))

def handle(self, meeting, name, max_cycles, verbosity, base_id, *args, **kwargs):
ScheduleHandler(self.stdout, meeting, name, max_cycles, verbosity, base_id).run()
def handle(self, meeting, name, max_cycles, verbosity, base_id, purposes, *args, **kwargs):
ScheduleHandler(self.stdout, meeting, name, max_cycles, verbosity, base_id, purposes).run()


class ScheduleHandler(object):
def __init__(self, stdout, meeting_number, name=None, max_cycles=OPTIMISER_MAX_CYCLES,
verbosity=1, base_id=None):
verbosity=1, base_id=None, session_purposes=None):
self.stdout = stdout
self.verbosity = verbosity
self.name = name
self.max_cycles = max_cycles
self.session_purposes = session_purposes
if meeting_number:
try:
self.meeting = models.Meeting.objects.get(type="ietf", number=meeting_number)
Expand Down Expand Up @@ -114,6 +129,10 @@ def __init__(self, stdout, meeting_number, name=None, max_cycles=OPTIMISER_MAX_C
msgs.append('Applying schedule {} as base schedule'.format(ScheduleId.from_schedule(self.base_schedule)))
self.stdout.write('\n{}\n\n'.format('\n'.join(msgs)))
self._load_meeting()
if len(self.schedule.sessions) == 0:
raise CommandError('No sessions found to schedule')
if len(self.schedule.timeslots) == 0:
raise CommandError('No timeslots found for schedule')

def run(self):
"""Schedule all sessions"""
Expand Down Expand Up @@ -194,6 +213,8 @@ def _sessions_to_schedule(self, *args, **kwargs):
Extra arguments are passed to the Session constructor.
"""
sessions_db = self.meeting.session_set.that_can_be_scheduled().filter(type_id='regular')
if self.session_purposes is not None:
sessions_db = sessions_db.filter(purpose__slug__in=self.session_purposes)
if self.base_schedule is None:
fixed_sessions = models.Session.objects.none()
else:
Expand Down