Beispiel #1
0
 def _process(self):
     new_start_dt = self.event_new.tzinfo.localize(
         dateutil.parser.parse(
             request.form.get('startDate'))).astimezone(utc)
     new_end_dt = self.event_new.tzinfo.localize(
         dateutil.parser.parse(request.form.get('endDate'))).astimezone(utc)
     new_duration = new_end_dt - new_start_dt
     is_session_block = self.entry.type == TimetableEntryType.SESSION_BLOCK
     tzinfo = self.event_new.tzinfo
     if is_session_block and new_end_dt.astimezone(tzinfo).date(
     ) != self.entry.start_dt.astimezone(tzinfo).date():
         raise UserValueError(
             _('Session block cannot span more than one day'))
     with track_time_changes(auto_extend=True,
                             user=session.user) as changes:
         update_timetable_entry_object(self.entry,
                                       {'duration': new_duration})
         if is_session_block:
             self.entry.move(new_start_dt)
         if not is_session_block:
             update_timetable_entry(self.entry, {'start_dt': new_start_dt})
     if is_session_block and self.entry.children:
         if new_end_dt < max(self.entry.children,
                             key=attrgetter('end_dt')).end_dt:
             raise UserValueError(
                 _("Session block cannot be shortened this much because contributions contained "
                   "wouldn't fit."))
     notifications = get_time_changes_notifications(
         changes, tzinfo=self.event_new.tzinfo, entry=self.entry)
     return jsonify_data(flash=False,
                         update=serialize_entry_update(
                             self.entry, session_=self.session),
                         notifications=notifications)
Beispiel #2
0
    def _process(self):
        item = self.entry.object
        entry_dt = self.entry.start_dt.astimezone(self.event.tzinfo)
        form = BaseEntryForm(obj=FormDefaults(item, time=entry_dt.time()), day=entry_dt.date(),
                             event=self.event, entry=self.entry,
                             session_block=self.entry.parent.object if self.entry.parent else None)
        data = form.data
        shift_later = data.pop('shift_later')

        if form.validate_on_submit():
            with track_time_changes(auto_extend=True, user=session.user) as changes:
                if shift_later:
                    new_end_dt = form.start_dt.data + form.duration.data
                    shift = new_end_dt - self.entry.end_dt
                    shift_following_entries(self.entry, shift, session_=self.session)
                if self.entry.contribution:
                    update_timetable_entry(self.entry, {'start_dt': form.start_dt.data})
                    update_contribution(item, {'duration': form.duration.data})
                elif self.entry.break_:
                    update_break_entry(item, data)
                elif self.entry.session_block:
                    update_session_block(item, data)
            notifications = get_time_changes_notifications(changes, tzinfo=self.event.tzinfo, entry=self.entry)
            return jsonify_data(update=serialize_entry_update(self.entry, session_=self.session),
                                notifications=notifications, flash=False)
        self.commit = False
        return jsonify_form(form, back_button=False, disabled_until_change=True)
Beispiel #3
0
    def _process(self):
        item = self.entry.object
        entry_dt = self.entry.start_dt.astimezone(self.event_new.tzinfo)
        form = BaseEntryForm(obj=FormDefaults(item, time=entry_dt.time()), day=entry_dt.date(),
                             event=self.event_new, entry=self.entry,
                             session_block=self.entry.parent.object if self.entry.parent else None)
        data = form.data
        shift_later = data.pop('shift_later')
        updated_entries = []

        if form.validate_on_submit():
            with track_time_changes(auto_extend=True, user=session.user) as changes:
                if shift_later:
                    new_end_dt = form.start_dt.data + form.duration.data
                    shift = new_end_dt - self.entry.end_dt
                    updated_entries += shift_following_entries(self.entry, shift, session_=self.session)
                if self.entry.contribution:
                    update_timetable_entry(self.entry, {'start_dt': form.start_dt.data})
                    update_contribution(item, {'duration': form.duration.data})
                elif self.entry.break_:
                    update_break_entry(item, data)
                elif self.entry.session_block:
                    update_session_block(item, data)
            notifications = get_time_changes_notifications(changes, tzinfo=self.event_new.tzinfo, entry=self.entry)
            updated_entries.append(item.timetable_entry)
            return jsonify_data(entries=[serialize_entry_update(entry) for entry in updated_entries], flash=False,
                                shift_later=shift_later, notifications=notifications)
        self.commit = False
        return jsonify_form(form, back_button=False, disabled_until_change=True)
Beispiel #4
0
 def _process(self):
     form = ContributionStartDateForm(obj=FormDefaults(start_dt=self.contrib.start_dt), contrib=self.contrib)
     if form.validate_on_submit():
         with track_time_changes():
             update_timetable_entry(self.contrib.timetable_entry, {'start_dt': form.start_dt.data})
         return jsonify_data(new_value=format_datetime(self.contrib.start_dt, 'short'))
     return jsonify_form(form, back_button=False, disabled_until_change=True)
Beispiel #5
0
 def _process_PATCH(self):
     """Update a timetable entry"""
     data = request.json
     # TODO: support breaks
     if set(data.viewkeys()) > {'start_dt'}:
         raise BadRequest('Invalid keys found')
     updates = {}
     if 'start_dt' in data:
         updates['start_dt'] = dateutil.parser.parse(data['start_dt'])
     if updates:
         with track_time_changes():
             update_timetable_entry(self.entry, updates)
     return jsonify()
Beispiel #6
0
 def _process_PATCH(self):
     """Update a timetable entry"""
     data = request.json
     # TODO: support breaks
     if set(data.viewkeys()) > {'start_dt'}:
         raise BadRequest('Invalid keys found')
     updates = {}
     if 'start_dt' in data:
         updates['start_dt'] = dateutil.parser.parse(data['start_dt'])
     if updates:
         with track_time_changes():
             update_timetable_entry(self.entry, updates)
     return jsonify()
Beispiel #7
0
def update_session_block(session_block, data):
    """Update a session block with data passed in the `data` argument"""
    from indico.modules.events.timetable.operations import update_timetable_entry

    start_dt = data.pop('start_dt', None)
    if start_dt is not None:
        session_block.timetable_entry.move(start_dt)
        update_timetable_entry(session_block.timetable_entry, {'start_dt': start_dt})
    session_block.populate_from_dict(data)
    db.session.flush()
    session_block.event_new.log(EventLogRealm.management, EventLogKind.change, 'Sessions',
                                'Session block "{}" has been updated'.format(session_block.title), session.user)
    logger.info('Session block %s modified by %s', session_block, session.user)
Beispiel #8
0
def update_session_block(session_block, data):
    """Update a session block with data passed in the `data` argument"""
    from indico.modules.events.timetable.operations import update_timetable_entry

    start_dt = data.pop('start_dt', None)
    if start_dt is not None:
        session_block.timetable_entry.move(start_dt)
        update_timetable_entry(session_block.timetable_entry, {'start_dt': start_dt})
    session_block.populate_from_dict(data)
    db.session.flush()
    session_block.event_new.log(EventLogRealm.management, EventLogKind.change, 'Sessions',
                                'Session block "{}" has been updated'.format(session_block.title), session.user)
    logger.info('Session block %s modified by %s', session_block, session.user)
Beispiel #9
0
def update_contribution(contrib, contrib_data, custom_fields_data=None):
    """Update a contribution.

    :param contrib: The `Contribution` to update
    :param contrib_data: A dict containing the data to update
    :param custom_fields_data: A dict containing the data for custom
                               fields.
    :return: A dictionary containing information related to the
             update.  `unscheduled` will be true if the modification
             resulted in the contribution being unscheduled.  In this
             case `undo_unschedule` contains the necessary data to
             re-schedule it (undoing the session change causing it to
             be unscheduled)
    """
    rv = {'unscheduled': False, 'undo_unschedule': None}
    current_session_block = contrib.session_block
    start_dt = contrib_data.pop('start_dt', None)
    if start_dt is not None:
        update_timetable_entry(contrib.timetable_entry, {'start_dt': start_dt})
    with track_location_changes():
        changes = contrib.populate_from_dict(contrib_data)
    if custom_fields_data:
        changes.update(set_custom_fields(contrib, custom_fields_data))
    if 'session' in contrib_data:
        timetable_entry = contrib.timetable_entry
        if timetable_entry is not None and _ensure_consistency(contrib):
            rv['unscheduled'] = True
            rv['undo_unschedule'] = {
                'start_dt':
                timetable_entry.start_dt.isoformat(),
                'contribution_id':
                contrib.id,
                'session_block_id':
                current_session_block.id if current_session_block else None,
                'force':
                True
            }
    db.session.flush()
    if changes:
        signals.event.contribution_updated.send(contrib, changes=changes)
        logger.info('Contribution %s updated by %s', contrib, session.user)
        contrib.log(EventLogRealm.management, EventLogKind.change,
                    'Contributions',
                    f'Contribution "{contrib.title}" has been updated',
                    session.user)
    return rv
Beispiel #10
0
def update_session_block(session_block, data):
    """Update a session block with data passed in the `data` argument."""
    from indico.modules.events.timetable.operations import update_timetable_entry

    start_dt = data.pop('start_dt', None)
    if start_dt is not None:
        session_block.timetable_entry.move(start_dt)
        update_timetable_entry(session_block.timetable_entry,
                               {'start_dt': start_dt})
    with track_location_changes():
        session_block.populate_from_dict(data)
    db.session.flush()
    signals.event.session_block_updated.send(session_block)
    session_block.event.log(
        EventLogRealm.management,
        EventLogKind.change,
        'Sessions',
        f'Session block "{session_block.title}" has been updated',
        session.user,
        meta={'session_block_id': session_block.id})
    logger.info('Session block %s modified by %s', session_block, session.user)
Beispiel #11
0
 def _process(self):
     new_start_dt = self.event_new.tzinfo.localize(
         dateutil.parser.parse(request.form.get('startDate'))).astimezone(utc)
     new_end_dt = self.event_new.tzinfo.localize(dateutil.parser.parse(request.form.get('endDate'))).astimezone(utc)
     new_duration = new_end_dt - new_start_dt
     is_session_block = self.entry.type == TimetableEntryType.SESSION_BLOCK
     tzinfo = self.event_new.tzinfo
     if is_session_block and new_end_dt.astimezone(tzinfo).date() != self.entry.start_dt.astimezone(tzinfo).date():
         raise UserValueError(_('Session block cannot span more than one day'))
     with track_time_changes(auto_extend=True, user=session.user) as changes:
         update_timetable_entry_object(self.entry, {'duration': new_duration})
         if is_session_block:
             self.entry.move(new_start_dt)
         if not is_session_block:
             update_timetable_entry(self.entry, {'start_dt': new_start_dt})
     if is_session_block and self.entry.children:
         if new_end_dt < max(self.entry.children, key=attrgetter('end_dt')).end_dt:
             raise UserValueError(_("Session block cannot be shortened this much because contributions contained "
                                    "wouldn't fit."))
     notifications = get_time_changes_notifications(changes, tzinfo=self.event_new.tzinfo, entry=self.entry)
     return jsonify_data(flash=False, entry=serialize_entry_update(self.entry), notifications=notifications)
Beispiel #12
0
def update_contribution(contrib, contrib_data, custom_fields_data=None):
    """Update a contribution

    :param contrib: The `Contribution` to update
    :param contrib_data: A dict containing the data to update
    :param custom_fields_data: A dict containing the data for custom
                               fields.
    :return: A dictionary containing information related to the
             update.  `unscheduled` will be true if the modification
             resulted in the contribution being unscheduled.  In this
             case `undo_unschedule` contains the necessary data to
             re-schedule it (undoing the session change causing it to
             be unscheduled)
    """
    rv = {'unscheduled': False, 'undo_unschedule': None}
    current_session_block = contrib.session_block
    start_dt = contrib_data.pop('start_dt', None)
    if start_dt is not None:
        update_timetable_entry(contrib.timetable_entry, {'start_dt': start_dt})
    changes = contrib.populate_from_dict(contrib_data)
    if custom_fields_data:
        changes.update(set_custom_fields(contrib, custom_fields_data))
    if 'session' in contrib_data:
        timetable_entry = contrib.timetable_entry
        if timetable_entry is not None and _ensure_consistency(contrib):
            rv['unscheduled'] = True
            rv['undo_unschedule'] = {'start_dt': timetable_entry.start_dt.isoformat(),
                                     'contribution_id': contrib.id,
                                     'session_block_id': current_session_block.id if current_session_block else None,
                                     'force': True}
    db.session.flush()
    if changes:
        signals.event.contribution_updated.send(contrib, changes=changes)
        logger.info('Contribution %s updated by %s', contrib, session.user)
        contrib.event_new.log(EventLogRealm.management, EventLogKind.change, 'Contributions',
                              'Contribution "{}" has been updated'.format(contrib.title), session.user)
    return rv