Esempio n. 1
0
 def validate_occurrences(self, field):
     for req_dt in field.data:
         if not isinstance(req_dt, datetime):
             raise ValidationError(_('You have to explicitly specify the time for the assistance request'))
         is_in_working_hours = WORKING_TIME_PERIOD[0] <= req_dt.time() <= WORKING_TIME_PERIOD[1]
         if not is_in_working_hours:
             raise ValidationError(_('One of the specified times is not within the working hours'))
Esempio n. 2
0
class RoomAssistanceForm(IndicoForm):
    _fieldsets = [
        ('Startup assistance emails', [
            'room_assistance_recipients', 'rooms_with_assistance',
            'room_assistance_support'
        ]),
    ]

    room_assistance_recipients = EmailListField(
        _('Recipients'),
        description=_('Notifications about room assistance requests are sent '
                      'to these email addresses (one per line)'))
    rooms_with_assistance = IndicoQuerySelectMultipleField(
        'Rooms',
        query_factory=lambda: Room.query,
        description=_('Rooms for which users can request startup '
                      'assistance'),
        get_label='full_name',
        collection_class=set,
        render_kw={'size': 20},
        modify_object_list=_order_func)
    room_assistance_support = PrincipalListField(
        _('Room assistance support'),
        groups=True,
        description=_('List of users who can view the list of events with '
                      'room startup assistance.'))
Esempio n. 3
0
    def _on_event_update(self, event, **kwargs):
        changes = kwargs['changes']
        if not changes.viewkeys() & {'location_data', 'start_dt', 'end_dt'}:
            return

        request = Request.find_latest_for_event(event,
                                                RoomAssistanceRequest.name)
        if not request or request.state != RequestState.accepted:
            return

        if 'location_data' in changes and not event_has_room_with_support_attached(
                event):
            request.definition.reject(
                request, {
                    'comment':
                    render_plugin_template('auto_reject_no_supported_room.txt')
                }, User.get_system_user())
            request.data = dict(request.data, occurrences=[])
            flash(
                _("The new event location is not in the list of the rooms supported by the room assistance team. "
                  "Room assistance request has been rejected and support will not be provided."
                  ), 'warning')
        if changes.viewkeys() & {'start_dt', 'end_dt'}:
            tz = pytz.timezone(config.DEFAULT_TIMEZONE)
            occurrences = {
                dateutil.parser.parse(occ).astimezone(tz)
                for occ in request.data['occurrences']
            }
            req_dates = {occ.date() for occ in occurrences}
            event_dates = set(event.iter_days())
            old_dates = req_dates - event_dates
            has_overlapping_dates = req_dates & event_dates

            if not has_overlapping_dates:
                request.definition.reject(
                    request, {
                        'comment':
                        render_plugin_template(
                            'auto_reject_no_overlapping_dates.txt')
                    }, User.get_system_user())
                request.data = dict(request.data, occurrences=[])
                flash(
                    _("The new event dates don't overlap with the existing room assistance request for this event. "
                      "Room assistance request has been rejected and support will not be provided."
                      ), 'warning')
            elif old_dates and has_overlapping_dates:
                new_data = dict(request.data)
                new_data['occurrences'] = [
                    occ.astimezone(pytz.utc).isoformat() for occ in occurrences
                    if occ.date() in req_dates & event_dates
                ]
                request.data = new_data
                flash(
                    _("Room assistance had been requested for days that are not between the updated start/end "
                      "dates. Support will not be provided on these days anymore."
                      ), 'warning')
Esempio n. 4
0
class RoomAssistanceRequestForm(RequestFormBase):
    start_dt = IndicoDateTimeField(
        _('When'),
        [DataRequired(), DateTimeRange(earliest=now_utc())],
        description=_('When do you need the assistance?'))
    reason = TextAreaField(_('Reason'), [DataRequired()],
                           description=_('Why are you requesting assistance?'))

    def validate_start_dt(self, field):
        localized_time = field.data.astimezone(session.tzinfo).time()
        is_in_working_hours = WORKING_TIME_PERIOD[
            0] <= localized_time <= WORKING_TIME_PERIOD[1]
        if not is_in_working_hours:
            raise ValidationError(
                'Specified datetime is not within the working hours')
Esempio n. 5
0
class RoomAssistanceRequestForm(RequestFormBase):
    occurrences = _RequestOccurrencesField(_('When'), [DataRequired()],
                                           description=_('When do you need the assistance?'))
    reason = TextAreaField(_('Reason'), [DataRequired()], description=_('Why are you requesting assistance?'))

    def __init__(self, *args, **kwargs):
        super(RoomAssistanceRequestForm, self).__init__(*args, **kwargs)
        self.occurrences.event = kwargs['event']

    def validate_occurrences(self, field):
        for req_dt in field.data:
            if not isinstance(req_dt, datetime):
                raise ValidationError(_('You have to explicitly specify the time for the assistance request'))
            is_in_working_hours = WORKING_TIME_PERIOD[0] <= req_dt.time() <= WORKING_TIME_PERIOD[1]
            if not is_in_working_hours:
                raise ValidationError(_('One of the specified times is not within the working hours'))
Esempio n. 6
0
    def _extend_services_menu(self, reservation, **kwargs):
        if not session.user or not is_room_assistance_support(session.user):
            return

        return TopMenuItem('services-cern-room-assistance',
                           _('Room assistance'),
                           url_for_plugin('room_assistance.request_list'),
                           section='services')
Esempio n. 7
0
 def validate_occurrences(self, field):
     for req_dt in field.data:
         is_in_working_hours = WORKING_TIME_PERIOD[0] <= req_dt.time(
         ) <= WORKING_TIME_PERIOD[1]
         if not is_in_working_hours:
             raise ValidationError(
                 _('One of the specified times is not within the working hours'
                   ))
Esempio n. 8
0
class RequestListFilterForm(IndicoForm):
    direction = SelectField(_('Sort direction'), [DataRequired()],
                            choices=[('asc', _('Ascending')),
                                     ('desc', _('Descending'))])
    abs_start_date = IndicoDateField(
        _('Start Date'), [Optional(), Exclusive('rel_start_date')])
    abs_end_date = IndicoDateField(
        _('End Date'), [Optional(), Exclusive('rel_end_date')])
    rel_start_date = IntegerField(
        _('Days in the past'),
        [Optional(),
         Exclusive('abs_start_date'),
         NumberRange(min=0)])
    rel_end_date = IntegerField(
        _('Days in the future'),
        [Optional(), Exclusive('abs_end_date'),
         NumberRange(min=0)])

    def is_submitted(self):
        return bool(request.args)

    @generated_data
    def start_date(self):
        if self.abs_start_date.data is None and self.rel_start_date.data is None:
            return None
        return self.abs_start_date.data or (
            date.today() - timedelta(days=self.rel_start_date.data))

    @generated_data
    def end_date(self):
        if self.abs_end_date.data is None and self.rel_end_date.data is None:
            return None
        return self.abs_end_date.data or (
            date.today() + timedelta(days=self.rel_end_date.data))
Esempio n. 9
0
class RoomAssistanceRequest(RequestDefinitionBase):
    name = 'room-assistance'
    title = _('Room assistance')
    form = RoomAssistanceRequestForm

    @classmethod
    def render_form(cls, event, **kwargs):
        kwargs['event_has_room_attached'] = event.room is not None
        kwargs['room_allows_assistance'] = event.room in cls.plugin.settings.get('rooms_with_assistance')
        return super(RoomAssistanceRequest, cls).render_form(event, **kwargs)

    @classmethod
    def create_form(cls, event, existing_request=None):
        form_data = {'occurrences': None}
        if existing_request:
            tz = pytz.timezone(config.DEFAULT_TIMEZONE)
            form_data = dict(existing_request.data)
            form_data['occurrences'] = [dateutil.parser.parse(occ).astimezone(tz) for occ in form_data['occurrences']]
        with plugin_context(cls.plugin):
            return cls.form(prefix='request-', obj=FormDefaults(form_data), event=event, request=existing_request)

    @classmethod
    def can_be_managed(cls, user):
        return False

    @classmethod
    def send(cls, req, data):
        room = req.event.room
        if room is None or room not in cls.plugin.settings.get('rooms_with_assistance'):
            raise Forbidden

        is_new = req.id is None
        req.state = RequestState.accepted
        old_data = {} if is_new else req.data
        data['occurrences'] = [occ.astimezone(pytz.utc).isoformat() for occ in data['occurrences']]

        super(RoomAssistanceRequest, cls).send(req, data)
        with plugin_context(cls.plugin):
            if is_new:
                notify_about_new_request(req)
            else:
                changes = {}
                if data['reason'] != old_data['reason']:
                    changes['reason'] = {'old': old_data['reason'], 'new': data['reason']}
                if data['occurrences'] != old_data['occurrences']:
                    changes['occurrences'] = [dateutil.parser.parse(occ) for occ in data['occurrences']]
                if changes:
                    notify_about_request_modification(req, changes)

    @classmethod
    def withdraw(cls, req, notify_event_managers=True):
        super(RoomAssistanceRequest, cls).withdraw(req, notify_event_managers)
        with plugin_context(cls.plugin):
            notify_about_withdrawn_request(req)
Esempio n. 10
0
class RoomAssistanceRequest(RequestDefinitionBase):
    name = 'room-assistance'
    title = _('Room assistance')
    form = RoomAssistanceRequestForm

    @classmethod
    def render_form(cls, event, **kwargs):
        kwargs['event_has_room_attached'] = event.room is not None
        kwargs[
            'room_allows_assistance'] = event.room in cls.plugin.settings.get(
                'rooms_with_assistance')
        return super(RoomAssistanceRequest, cls).render_form(event, **kwargs)

    @classmethod
    def create_form(cls, event, existing_request=None):
        form_data = {'start_dt': event.start_dt_local - timedelta(minutes=30)}
        if existing_request:
            form_data = dict(existing_request.data)
            if form_data['start_dt']:
                form_data['start_dt'] = dateutil.parser.parse(
                    form_data['start_dt'])
        with plugin_context(cls.plugin):
            return cls.form(prefix='request-',
                            obj=FormDefaults(form_data),
                            event=event,
                            request=existing_request)

    @classmethod
    def can_be_managed(cls, user):
        return False

    @classmethod
    def send(cls, req, data):
        room = req.event.room
        if room is None or room not in cls.plugin.settings.get(
                'rooms_with_assistance'):
            raise Forbidden

        data['start_dt'] = data['start_dt'].isoformat()
        is_new = req.id is None
        req.state = RequestState.accepted
        old_data = {} if is_new else req.data

        super(RoomAssistanceRequest, cls).send(req, data)
        with plugin_context(cls.plugin):
            if is_new:
                notify_about_new_request(req)
            else:
                changes = {}
                if data['reason'] != old_data['reason']:
                    changes['reason'] = {
                        'old': old_data['reason'],
                        'new': data['reason']
                    }
                if data['start_dt'] != old_data['start_dt']:
                    changes['start_dt'] = {
                        'old': dateutil.parser.parse(old_data['start_dt']),
                        'new': dateutil.parser.parse(data['start_dt'])
                    }
                if changes:
                    notify_about_request_modification(req, changes)

    @classmethod
    def withdraw(cls, req, notify_event_managers=True):
        super(RoomAssistanceRequest, cls).withdraw(req, notify_event_managers)
        with plugin_context(cls.plugin):
            notify_about_withdrawn_request(req)
Esempio n. 11
0
 def _get_breadcrumbs(self):
     return render_breadcrumbs(_('Room assistance'))