Example #1
0
def rb_merge_users(new_id, old_id):
    """Updates RB data after an Avatar merge

    :param new_id: Target user
    :param old_id: Source user (being deleted in the merge)
    """
    from indico.modules.rb import settings as rb_settings
    from indico.modules.rb.models.blocking_principals import BlockingPrincipal
    from indico.modules.rb.models.blockings import Blocking
    from indico.modules.rb.models.reservations import Reservation
    from indico.modules.rb.models.rooms import Room

    old_user = User.get(int(old_id))
    new_user = User.get(int(new_id))
    for bp in BlockingPrincipal.find():
        if bp.principal == old_user:
            bp.principal = new_user
    Blocking.find(created_by_id=old_id).update({'created_by_id': new_id})
    Reservation.find(created_by_id=old_id).update({'created_by_id': new_id})
    Reservation.find(booked_for_id=old_id).update({'booked_for_id': new_id})
    Room.find(owner_id=old_id).update({'owner_id': new_id})
    for key in ('authorized_principals', 'admin_principals'):
        principals = rb_settings.get(key)
        principals = principals_merge_users(principals, new_id, old_id)
        rb_settings.set(key, principals)
Example #2
0
def _build_digest_window_filter():
    if datetime.now().hour >= rb_settings.get('notification_hour'):
        # Both today and delayed digests
        return Room.is_in_digest_window()
    else:
        # Delayed digests only
        return Room.is_in_digest_window(exclude_first_day=True)
Example #3
0
def _build_notification_window_filter():
    if datetime.now().hour >= rb_settings.get('notification_hour'):
        # Both today and delayed notifications
        return ReservationOccurrence.is_in_notification_window()
    else:
        # Delayed notifications only
        return ReservationOccurrence.is_in_notification_window(exclude_first_day=True)
Example #4
0
def roombooking_occurrences_digest():
    if not Config.getInstance().getIsRoomBookingActive():
        logger.info('Digest not sent because room booking is disabled')
        return
    if not rb_settings.get('notifications_enabled'):
        logger.info('Digest not sent because notifications are globally disabled')
        return

    digest_start = round_up_month(date.today(), from_day=2)
    digest_end = get_month_end(digest_start)

    occurrences = ReservationOccurrence.find(
        Room.notifications_enabled,
        Reservation.is_accepted,
        Reservation.repeat_frequency == RepeatFrequency.WEEK,
        ReservationOccurrence.is_valid,
        ReservationOccurrence.start_dt >= digest_start,
        ReservationOccurrence.start_dt <= digest_end,
        ~ReservationOccurrence.notification_sent,
        _build_digest_window_filter(),
        _join=[Reservation, Room]
    )

    digests = defaultdict(list)
    for occurrence in occurrences:
        digests[occurrence.reservation].append(occurrence)

    try:
        for reservation, occurrences in digests.iteritems():
            notify_reservation_digest(reservation, occurrences)
            for occurrence in occurrences:
                occurrence.notification_sent = True
    finally:
        db.session.commit()
Example #5
0
def roombooking_occurrences():
    if not Config.getInstance().getIsRoomBookingActive():
        logger.info('Notifications not sent because room booking is disabled')
        return
    if not rb_settings.get('notifications_enabled'):
        logger.info('Notifications not sent because they are globally disabled')
        return

    occurrences = ReservationOccurrence.find(
        Room.notifications_enabled,
        Reservation.is_accepted,
        Reservation.repeat_frequency != RepeatFrequency.WEEK,
        ReservationOccurrence.is_valid,
        ReservationOccurrence.start_dt >= datetime.now(),
        ~ReservationOccurrence.notification_sent,
        _build_notification_window_filter(),
        _join=[Reservation, Room]
    )

    try:
        for occ in occurrences:
            notify_upcoming_occurrence(occ)
            occ.notification_sent = True
            if occ.reservation.repeat_frequency == RepeatFrequency.DAY:
                occ.reservation.occurrences.update({'notification_sent': True})
    finally:
        db.session.commit()
Example #6
0
def rb_is_admin(user):
    """Checks if the user is a room booking admin"""
    from indico.modules.rb import settings as rb_settings
    if user.user.is_admin:
        return True
    principals = retrieve_principals(rb_settings.get('admin_principals'))
    return any(principal.containsUser(user) for principal in principals)
Example #7
0
def create_user(db):
    """Returns a callable which lets you create dummy users"""
    _users = set()

    def _create_user(id_, name=u'Pig', surname=u'Guinea', rb_admin=False, email=None, groups=None):
        user = User.get(id_)
        if user:
            return user.as_avatar
        user = User()
        user.id = id_
        user.first_name = name
        user.last_name = surname
        user.email = email or u'{}@example.com'.format(id_)
        user.local_groups = {g.group for g in (groups or ())}
        db.session.add(user)
        db.session.flush()
        if rb_admin:
            rb_settings.set('admin_principals', rb_settings.get('admin_principals') + [user.as_principal])
        db.session.flush()
        _users.add(user)
        avatar = user.as_avatar
        avatar.email = user.email
        return avatar

    yield _create_user

    admins = set(map(tuple, rb_settings.get('admin_principals')))
    for user in _users:
        admins.discard(user.as_principal)
        db.session.delete(user)
    rb_settings.set('admin_principals', list(admins))
Example #8
0
 def _getBody(self, params):
     reservation = params["reservation"]
     params["endpoints"] = self.endpoints
     params["assistance_emails"] = rb_settings.get("assistance_emails")
     params["vc_equipment"] = ", ".join(eq.name for eq in reservation.get_vc_equipment())
     params["repetition"] = RepeatMapping.get_message(*reservation.repetition)
     params["edit_logs"] = reservation.edit_logs.order_by(ReservationEditLog.timestamp.desc()).all()
     params["excluded_days"] = reservation.find_excluded_days().all()
     return WTemplated("RoomBookingDetails").getHTML(params)
Example #9
0
def _build_notification_before_days_filter(notification_before_days):
    days_until_occurrence = cast(ReservationOccurrence.start_dt, Date) - cast(func.now(), Date)
    notification_before_days = func.coalesce(Room.notification_before_days, notification_before_days)
    if datetime.now().hour >= settings.get('notification_hour', 6):
        # Notify of today and delayed occurrences (happening in N or less days)
        return days_until_occurrence <= notification_before_days
    else:
        # Notify only of delayed occurrences (happening in less than N days)
        return days_until_occurrence < notification_before_days
Example #10
0
 def is_in_digest_window(self, exclude_first_day=False):
     from indico.modules.rb import settings as rb_settings
     digest_start = round_up_month(date.today(), from_day=2)
     days_until_next_digest = (digest_start - date.today()).days
     digest_window = self.notification_before_days or rb_settings.get('notification_before_days')
     if exclude_first_day:
         return days_until_next_digest < digest_window
     else:
         return days_until_next_digest <= digest_window
Example #11
0
 def is_in_digest_window(self, exclude_first_day=False):
     from indico.modules.rb import settings as rb_settings
     digest_start = round_up_month(date.today(), from_day=2)
     days_until_next_digest = cast(digest_start, Date) - cast(func.now(), Date)
     digest_window = func.coalesce(self.notification_before_days, rb_settings.get('notification_before_days'))
     if exclude_first_day:
         return days_until_next_digest < digest_window
     else:
         return days_until_next_digest <= digest_window
Example #12
0
    def compose_email_to_vc_support(self, **mail_params):
        from indico.modules.rb import settings as rb_settings

        if self.reservation.is_accepted and self.reservation.uses_vc:
            to_list = rb_settings.get('vc_support_emails')
            if to_list:
                subject = self._get_email_subject(**mail_params)
                body = self._make_body(mail_params, reservation=self.reservation)
                return make_email(to_list=to_list, subject=subject, body=body)
Example #13
0
 def _getBody(self, params):
     reservation = params['reservation']
     params['endpoints'] = self.endpoints
     params['assistance_emails'] = rb_settings.get('assistance_emails')
     params['vc_equipment'] = ', '.join(eq.name for eq in reservation.get_vc_equipment())
     params['repetition'] = RepeatMapping.get_message(*reservation.repetition)
     params['edit_logs'] = reservation.edit_logs.order_by(ReservationEditLog.timestamp.desc()).all()
     params['excluded_days'] = reservation.find_excluded_days().all()
     return WTemplated('RoomBookingDetails').getHTML(params)
Example #14
0
def rb_check_user_access(user):
    """Checks if the user has access to the room booking system"""
    from indico.modules.rb import settings

    if user.isRBAdmin():
        return True
    principals = retrieve_principals(settings.get('authorized_principals', []))
    if not principals:  # everyone has access
        return True
    return any(principal.containsUser(user) for principal in principals)
Example #15
0
    def compose_email_to_assistance(self, **mail_params):
        from indico.modules.rb import settings as rb_settings

        if self.reservation.room.notification_for_assistance:
            if self.reservation.needs_assistance or mail_params.get('assistance_cancelled'):
                to_list = rb_settings.get('assistance_emails')
                if to_list:
                    subject = self._get_email_subject(**mail_params)
                    body = self._make_body(mail_params, reservation=self.reservation)
                    return make_email(to_list=to_list, subject=subject, body=body)
 def is_in_notification_window(self, exclude_first_day=False):
     from indico.modules.rb import settings as rb_settings
     from indico.modules.rb.models.rooms import Room
     in_the_past = cast(self.start_dt, Date) < cast(func.now(), Date)
     days_until_occurrence = cast(self.start_dt, Date) - cast(func.now(), Date)
     notification_window = func.coalesce(Room.notification_before_days,
                                         rb_settings.get('notification_before_days', 1))
     if exclude_first_day:
         return (days_until_occurrence < notification_window) & ~in_the_past
     else:
         return (days_until_occurrence <= notification_window) & ~in_the_past
 def is_in_notification_window(self, exclude_first_day=False):
     from indico.modules.rb import settings as rb_settings
     if self.start_dt.date() < date.today():
         return False
     days_until_occurrence = (self.start_dt.date() - date.today()).days
     notification_window = (self.reservation.room.notification_before_days
                            or rb_settings.get('notification_before_days', 1))
     if exclude_first_day:
         return days_until_occurrence < notification_window
     else:
         return days_until_occurrence <= notification_window
 def is_in_notification_window(self, exclude_first_day=False):
     from indico.modules.rb import settings as rb_settings
     if self.start_dt.date() < date.today():
         return False
     days_until_occurrence = (self.start_dt.date() - date.today()).days
     notification_window = (self.reservation.room.notification_before_days
                            or rb_settings.get('notification_before_days',
                                               1))
     if exclude_first_day:
         return days_until_occurrence < notification_window
     else:
         return days_until_occurrence <= notification_window
Example #19
0
 def is_in_digest_window(self, exclude_first_day=False):
     from indico.modules.rb import settings as rb_settings
     digest_start = round_up_month(date.today(), from_day=2)
     days_until_next_digest = cast(digest_start, Date) - cast(
         func.now(), Date)
     digest_window = func.coalesce(
         self.notification_before_days,
         rb_settings.get('notification_before_days'))
     if exclude_first_day:
         return days_until_next_digest < digest_window
     else:
         return days_until_next_digest <= digest_window
Example #20
0
 def _getBody(self, params):
     reservation = params['reservation']
     params['endpoints'] = self.endpoints
     params['assistance_emails'] = rb_settings.get('assistance_emails')
     params['vc_equipment'] = ', '.join(
         eq.name for eq in reservation.get_vc_equipment())
     params['repetition'] = RepeatMapping.get_message(
         *reservation.repetition)
     params['edit_logs'] = reservation.edit_logs.order_by(
         ReservationEditLog.timestamp.desc()).all()
     params['excluded_days'] = reservation.find_excluded_days().all()
     return WTemplated('RoomBookingDetails').getHTML(params)
 def is_in_notification_window(self, exclude_first_day=False):
     from indico.modules.rb import settings as rb_settings
     from indico.modules.rb.models.rooms import Room
     in_the_past = cast(self.start_dt, Date) < cast(func.now(), Date)
     days_until_occurrence = cast(self.start_dt, Date) - cast(
         func.now(), Date)
     notification_window = func.coalesce(
         Room.notification_before_days,
         rb_settings.get('notification_before_days', 1))
     if exclude_first_day:
         return (days_until_occurrence < notification_window) & ~in_the_past
     else:
         return (days_until_occurrence <=
                 notification_window) & ~in_the_past
Example #22
0
    def compose_email_to_assistance(self, **mail_params):
        from indico.modules.rb import settings as rb_settings

        if self.reservation.room.notification_for_assistance:
            if self.reservation.needs_assistance or mail_params.get(
                    'assistance_cancelled'):
                to_list = rb_settings.get('assistance_emails')
                if to_list:
                    subject = self._get_email_subject(**mail_params)
                    body = self._make_body(mail_params,
                                           reservation=self.reservation)
                    return make_email(to_list=to_list,
                                      subject=subject,
                                      body=body)
Example #23
0
    def run(self):
        occurrences = ReservationOccurrence.find(
            Reservation.is_accepted,
            ~ReservationOccurrence.notification_sent,
            ReservationOccurrence.is_valid,
            ReservationOccurrence.start_dt >= func.now(),
            _build_notification_before_days_filter(settings.get('notification_before_days', 0)),
            _join=[Reservation, Room]
        )

        for occ in occurrences:
            occ.notification_sent = True
            if occ.reservation.repeat_frequency == RepeatFrequency.DAY:
                occ.reservation.occurrences.update({'notification_sent': True})
            notify_upcoming_occurrence(occ)
Example #24
0
 def _getBody(self, params):
     params['endpoints'] = self.endpoints
     calendar = RoomBookingCalendarWidget(
         params['occurrences'],
         params['start_dt'],
         params['end_dt'],
         candidates=params['candidates'],
         specific_room=params['room'],
         repeat_frequency=params['repeat_frequency'],
         repeat_interval=params['repeat_interval'])
     params['calendar'] = calendar.render(show_navbar=False,
                                          details_in_new_tab=True)
     params['serializable_room'] = Room.get(
         params['room'].id).to_serializable('__public_exhaustive__')
     params['booking_limit'] = rb_settings.get('booking_limit')
     return WTemplated('RoomBookingBookingForm').getHTML(params)
Example #25
0
    def run(self):
        occurrences = ReservationOccurrence.find(
            Reservation.is_accepted,
            ~ReservationOccurrence.notification_sent,
            ReservationOccurrence.is_valid,
            ReservationOccurrence.start_dt >= func.now(),
            _build_notification_before_days_filter(
                settings.get('notification_before_days', 0)),
            _join=[Reservation, Room])

        try:
            for occ in occurrences:
                notify_upcoming_occurrence(occ)
                occ.notification_sent = True
                if occ.reservation.repeat_frequency == RepeatFrequency.DAY:
                    occ.reservation.occurrences.update(
                        {'notification_sent': True})
        finally:
            db.session.commit()
Example #26
0
    def _process(self):
        room = self._reservation.room
        form = ModifyBookingForm(obj=self._reservation,
                                 old_start_dt=self._reservation.start_dt, old_end_dt=self._reservation.end_dt)
        form.used_equipment.query = room.find_available_vc_equipment()

        if not room.notification_for_assistance and not self._reservation.needs_assistance:
            del form.needs_assistance

        invalid_form = form.is_submitted() and not form.validate()
        if invalid_form:
            occurrences = {}
            candidates = {}
            conflicts = {}
            pre_conflicts = {}
        else:
            occurrences, candidates = self._get_all_occurrences([room.id], form, reservation_id=self._reservation.id)
            conflicts, pre_conflicts = self._get_all_conflicts(room, form, self._reservation.id)

        if form.validate_on_submit() and not form.submit_check.data:
            try:
                booking_limit_days = room.booking_limit_days or rb_settings.get('booking_limit')
                if not self._validate_room_booking_limit(form, booking_limit_days):
                    msg = (_(u'Bookings for the room "{}" may not be longer than {} days')
                           .format(room.name, booking_limit_days))
                    return jsonify(success=False, url=url_for('rooms.roomBooking-modifyBookingForm', self._reservation),
                                   msg=msg)
                self._reservation.modify(form.data, session.user)
                flash(_(u'Booking updated'), 'success')
            except NoReportError as e:
                db.session.rollback()
                return jsonify(success=False, msg=unicode(e))
            return jsonify(success=True, url=self._get_success_url())

        elif invalid_form and not form.submit_check.data and request.is_xhr:
            return jsonify(success=False, msg='\n'.join(form.error_list))

        return self._get_view(form=form, room=room, rooms=Room.find_all(), occurrences=occurrences,
                              candidates=candidates, conflicts=conflicts, pre_conflicts=pre_conflicts,
                              start_dt=form.start_dt.data, end_dt=form.end_dt.data, only_conflicts=False,
                              repeat_frequency=form.repeat_frequency.data, repeat_interval=form.repeat_interval.data,
                              reservation=self._reservation,
                              can_override=room.can_be_overridden(session.user)).display()
Example #27
0
 def _create_user(id_, name=u'Pig', surname=u'Guinea', rb_admin=False, email=None, groups=None):
     user = User.get(id_)
     if user:
         return user.as_avatar
     user = User()
     user.id = id_
     user.first_name = name
     user.last_name = surname
     user.email = email or u'{}@example.com'.format(id_)
     user.local_groups = {g.group for g in (groups or ())}
     db.session.add(user)
     db.session.flush()
     if rb_admin:
         rb_settings.set('admin_principals', rb_settings.get('admin_principals') + [user.as_principal])
     db.session.flush()
     _users.add(user)
     avatar = user.as_avatar
     avatar.email = user.email
     return avatar
Example #28
0
    def _process(self):
        room = self._room
        rooms = Room.find_all()
        form = self._make_form()

        if form.is_submitted() and not form.validate():
            occurrences = {}
            candidates = {}
            conflicts = {}
            pre_conflicts = {}
            only_conflicts = False
        else:
            occurrences, candidates = self._get_all_occurrences([self._room.id], form)
            conflicts, pre_conflicts = self._get_all_conflicts(self._room, form)
            candidate_days = {occ.date for candidate in candidates.itervalues() for occ in candidate}
            conflicting_days = {occ.date for occ in conflicts.iterkeys()}
            only_conflicts = candidate_days <= conflicting_days

        if form.validate_on_submit() and not form.submit_check.data:
            booking_limit_days = room.booking_limit_days or rb_settings.get('booking_limit')
            if not self._validate_room_booking_limit(form, booking_limit_days):
                msg = (_(u'Bookings for the room "{}" may not be longer than {} days')
                       .format(room.name, booking_limit_days))
                return jsonify(success=False, url=url_for('rooms.room_book', room), msg=msg)
            return self._create_booking_response(form, room)

        can_override = room.can_be_overridden(session.user)
        return self._get_view(form=form,
                              room=room,
                              rooms=rooms,
                              occurrences=occurrences,
                              candidates=candidates,
                              conflicts=conflicts,
                              only_conflicts=only_conflicts,
                              pre_conflicts=pre_conflicts,
                              start_dt=form.start_dt.data,
                              end_dt=form.end_dt.data,
                              repeat_frequency=form.repeat_frequency.data,
                              repeat_interval=form.repeat_interval.data,
                              can_override=can_override,
                              past_date=not form.is_submitted() and self.past_date,
                              date_changed=not form.is_submitted() and self.date_changed).display()
Example #29
0
def rb_merge_users(new_id, old_id):
    """Updates RB data after an Avatar merge

    :param new_id: Target user
    :param old_id: Source user (being deleted in the merge)
    """
    from indico.modules.rb import settings
    from indico.modules.rb.models.blocking_principals import BlockingPrincipal
    from indico.modules.rb.models.blockings import Blocking
    from indico.modules.rb.models.reservations import Reservation
    from indico.modules.rb.models.rooms import Room

    BlockingPrincipal.find(entity_type='Avatar', entity_id=old_id).update({'entity_id': new_id})
    Blocking.find(created_by_id=old_id).update({'created_by_id': new_id})
    Reservation.find(created_by_id=old_id).update({'created_by_id': new_id})
    Reservation.find(booked_for_id=old_id).update({'booked_for_id': new_id})
    Room.find(owner_id=old_id).update({'owner_id': new_id})
    for key in ('authorized_principals', 'admin_principals'):
        principals = settings.get(key, [])
        principals = principals_merge_users(principals, new_id, old_id)
        settings.set(key, principals)
Example #30
0
def rb_merge_users(new_id, old_id):
    """Updates RB data after an Avatar merge

    :param new_id: Target user
    :param old_id: Source user (being deleted in the merge)
    """
    from indico.modules.rb import settings
    from indico.modules.rb.models.blocking_principals import BlockingPrincipal
    from indico.modules.rb.models.blockings import Blocking
    from indico.modules.rb.models.reservations import Reservation
    from indico.modules.rb.models.rooms import Room

    BlockingPrincipal.find(entity_type='Avatar',
                           entity_id=old_id).update({'entity_id': new_id})
    Blocking.find(created_by_id=old_id).update({'created_by_id': new_id})
    Reservation.find(created_by_id=old_id).update({'created_by_id': new_id})
    Reservation.find(booked_for_id=old_id).update({'booked_for_id': new_id})
    Room.find(owner_id=old_id).update({'owner_id': new_id})
    for key in ('authorized_principals', 'admin_principals'):
        principals = settings.get(key, [])
        principals = principals_merge_users(principals, new_id, old_id)
        settings.set(key, principals)
Example #31
0
 def _getBody(self, params):
     params['serializable_rooms'] = _get_serializable_rooms(
         [r.id for r in params['rooms']])
     params['booking_limit'] = rb_settings.get('booking_limit')
     return WTemplated('RoomBookingNewBookingSelectRoom').getHTML(params)