Example #1
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 #2
0
def _merge_users(target, source, **kwargs):
    BlockingPrincipal.merge_users(target, source, 'blocking')
    Blocking.find(created_by_id=source.id).update({Blocking.created_by_id: target.id})
    Reservation.find(created_by_id=source.id).update({Reservation.created_by_id: target.id})
    Reservation.find(booked_for_id=source.id).update({Reservation.booked_for_id: target.id})
    Room.find(owner_id=source.id).update({Room.owner_id: target.id})
    rb_settings.acls.merge_users(target, source)
Example #3
0
def assert_is_in_digest_window(room, expected, expected_with_exclude):
    assert room.is_in_digest_window() == expected
    assert room.is_in_digest_window(exclude_first_day=True) == expected_with_exclude
    assert Room.find_first(Room.is_in_digest_window()) == (room if expected else None)
    assert Room.find_first(Room.is_in_digest_window(exclude_first_day=True)) == (
        room if expected_with_exclude else None
    )
Example #4
0
def test_filter_available(
    dummy_room,
    create_reservation,
    create_blocking,
    has_booking,
    has_blocking,
    has_pre_booking,
    include_pre_bookings,
    has_pending_blocking,
    include_pending_blockings,
    filtered,
):
    if has_booking:
        create_reservation(
            start_dt=datetime.combine(date.today(), time(8)), end_dt=datetime.combine(date.today(), time(10))
        )
    if has_pre_booking:
        create_reservation(
            start_dt=datetime.combine(date.today(), time(10)),
            end_dt=datetime.combine(date.today(), time(12)),
            is_accepted=False,
        )
    if has_blocking:
        create_blocking(state=BlockedRoom.State.accepted)
    if has_pending_blocking:
        create_blocking(state=BlockedRoom.State.pending)
    availabilty_filter = Room.filter_available(
        get_day_start(date.today()),
        get_day_end(date.today()),
        (RepeatFrequency.NEVER, 0),
        include_pre_bookings=include_pre_bookings,
        include_pending_blockings=include_pending_blockings,
    )
    assert set(Room.find_all(availabilty_filter)) == (set() if filtered else {dummy_room})
Example #5
0
    def _process(self):
        form = self._form
        if self._is_submitted() and form.validate():
            if form.data.get("is_only_my_rooms"):
                form.room_ids.data = [room.id for room in Room.find_all() if room.is_owned_by(session.user)]

            occurrences = ReservationOccurrence.find_with_filters(form.data, session.user).all()
            rooms = self._filter_displayed_rooms(
                [r for r in self._rooms if r.id in set(form.room_ids.data)], occurrences
            )
            return WPRoomBookingSearchBookingsResults(
                self,
                rooms=rooms,
                occurrences=occurrences,
                show_blockings=self.show_blockings,
                start_dt=form.start_dt.data,
                end_dt=form.end_dt.data,
                form=form,
                form_data=self._form_data,
                menu_item=self.menu_item,
            ).display()

        my_rooms = [r.id for r in Room.get_owned_by(session.user)]
        return WPRoomBookingSearchBookings(
            self, errors=form.error_list, rooms=self._rooms, my_rooms=my_rooms, form=form
        ).display()
Example #6
0
def test_find_with_filters_availability_error():
    with pytest.raises(ValueError):
        filters = {'available': 123,
                   'repeatability': 'None',
                   'start_dt': datetime.now(),
                   'end_dt': datetime.now()}
        Room.find_with_filters(filters, None)
Example #7
0
 def _process(self):
     form = self._form
     if self._is_submitted() and form.validate():
         rooms = Room.find_with_filters(form.data, session.user)
         return WPRoomBookingSearchRoomsResults(self, self.menu_item, rooms=rooms).display()
     return WPRoomBookingSearchRooms(self, form=form, errors=form.error_list,
                                     rooms=Room.find_all(is_active=True)).display()
Example #8
0
def test_find_with_filters_details_cols(db, dummy_room, create_room, col):
    create_room()  # some room we won't find!
    assert set(Room.find_with_filters({}, None)) == set(Room.find_all())
    assert not Room.find_with_filters({'details': u'meow'}, None)
    setattr(dummy_room, col, u'meow')
    db.session.flush()
    assert set(Room.find_with_filters({'details': u'meow'}, None)) == {dummy_room}
Example #9
0
def test_find_with_filters(
    db, dummy_room, create_room, dummy_avatar, create_equipment_type, create_room_attribute, dummy_reservation
):
    # Simple testcase that ensures we find the room when many filters are used
    other_room = create_room()
    assert set(Room.find_with_filters({}, dummy_avatar)) == {dummy_room, other_room}
    create_room_attribute(u"attr")
    eq = create_equipment_type(u"eq")
    dummy_room.capacity = 100
    dummy_room.is_reservable = True
    dummy_room.available_equipment.append(eq)
    dummy_room.set_attribute_value(u"attr", u"meowmeow")
    db.session.flush()
    filters = {
        "available_equipment": {eq},
        "capacity": 90,
        "only_public": True,
        "is_only_my_rooms": True,
        "details": u"meow",
        "available": 0,
        "repeatability": "None",
        "start_dt": dummy_reservation.start_dt,
        "end_dt": dummy_reservation.end_dt,
    }
    assert set(Room.find_with_filters(filters, dummy_avatar)) == {dummy_room}
Example #10
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 #11
0
def test_find_with_filters_only_public(dummy_room, create_room_attribute, is_reservable, booking_group, match):
    create_room_attribute(u"allowed-booking-group")
    dummy_room.is_reservable = is_reservable
    dummy_room.set_attribute_value(u"allowed-booking-group", booking_group)
    if match:
        assert set(Room.find_with_filters({"is_only_public": True}, None)) == {dummy_room}
    else:
        assert not Room.find_with_filters({"is_only_public": True}, None)
Example #12
0
def test_find_with_filters_details_values(db, dummy_room, create_room, value, search_value, other_value):
    other_room = create_room()
    assert set(Room.find_with_filters({}, None)) == set(Room.find_all())
    assert not Room.find_with_filters({'details': search_value}, None)
    dummy_room.comments = value
    other_room.comments = other_value
    db.session.flush()
    assert set(Room.find_with_filters({'details': search_value}, None)) == {dummy_room}
Example #13
0
 def _process(self):
     form = self._form
     if self._is_submitted() and form.validate():
         rooms = Room.find_with_filters(form.data, session.user)
         return WPRoomBookingSearchRoomsResults(self, self.menu_item, rooms=rooms).display()
     equipment_locations = {eq.id: eq.location_id for eq in EquipmentType.find()}
     return WPRoomBookingSearchRooms(
         self, form=form, errors=form.error_list, rooms=Room.find_all(), equipment_locations=equipment_locations
     ).display()
Example #14
0
    def testGetVerboseEquipment(self):
        e1 = RoomEquipment(name='eq1')
        e2 = RoomEquipment(name='eq2')

        room = Room.get(5)
        room.equipments.extend([e1, e2])
        db.session.add(room)
        db.session.commit()

        assert ','.join(['eq1', 'eq2']) == Room.get(5).getVerboseEquipment()
Example #15
0
def test_find_with_filters_details_attrs(dummy_room, create_room, create_room_attribute,
                                         value, search_value, other_value):
    other_room = create_room()
    assert set(Room.find_with_filters({}, None)) == set(Room.find_all())
    assert not Room.find_with_filters({'details': search_value}, None)
    create_room_attribute(u'foo')
    assert not Room.find_with_filters({'details': search_value}, None)
    dummy_room.set_attribute_value(u'foo', value)
    other_room.set_attribute_value(u'foo', other_value)
    assert set(Room.find_with_filters({'details': search_value}, None)) == {dummy_room}
Example #16
0
def test_find_with_attribute(dummy_room, create_room, create_room_attribute):
    assert Room.find_all() == [dummy_room]  # one room without the attribute
    assert not Room.find_with_attribute(u'foo')
    create_room_attribute(u'foo')
    assert not Room.find_with_attribute(u'foo')
    expected = set()
    for room in [create_room(), create_room()]:
        value = u'bar-{}'.format(room.id)
        room.set_attribute_value(u'foo', value)
        expected.add((room, value))
    assert set(Room.find_with_attribute(u'foo')) == expected
Example #17
0
def test_ownership_functions(dummy_room, create_user, create_room_attribute, is_owner, has_group, in_group, expected):
    user = create_user(u'user')
    create_room_attribute(u'manager-group')
    if is_owner:
        dummy_room.owner = user
    if has_group:
        dummy_room.set_attribute_value(u'manager-group', u'managers')
    if in_group:
        user.groups.add(u'managers')
    assert dummy_room.is_owned_by(user) == expected
    assert Room.user_owns_rooms(user) == expected
    assert set(Room.get_owned_by(user)) == ({dummy_room} if expected else set())
Example #18
0
 def _create_room(**params):
     params.setdefault('building', u'1')
     params.setdefault('floor', u'2')
     params.setdefault('number', u'3')
     params.setdefault('name', '')
     params.setdefault('owner', dummy_avatar.user)
     params.setdefault('location', dummy_location)
     room = Room(**params)
     room.update_name()
     db.session.add(room)
     db.session.flush()
     return room
Example #19
0
def test_ownership_functions(dummy_room, create_user, create_room_attribute, create_group,
                             is_owner, has_group, in_group, expected):
    other_user = create_user(123)
    create_room_attribute(u'manager-group')
    if is_owner:
        dummy_room.owner = other_user
    if has_group:
        dummy_room.set_attribute_value(u'manager-group', u'123')
    if in_group:
        other_user.local_groups.add(create_group(123).group)
    assert dummy_room.is_owned_by(other_user) == expected
    assert Room.user_owns_rooms(other_user) == expected
    assert set(Room.get_owned_by(other_user)) == ({dummy_room} if expected else set())
Example #20
0
def test_find_with_filters_capacity(db, dummy_room, create_room,
                                    capacity, other_capacity, search_capacity, match, match_other):
    other_room = create_room()
    assert set(Room.find_with_filters({}, None)) == set(Room.find_all())
    dummy_room.capacity = capacity
    other_room.capacity = other_capacity
    db.session.flush()
    expected = set()
    if match:
        expected.add(dummy_room)
    if match_other:
        expected.add(other_room)
    assert set(Room.find_with_filters({'capacity': search_capacity}, None)) == expected
Example #21
0
def _merge_users(target, source, **kwargs):
    source_principals = set(source.in_blocking_acls.options(joinedload(BlockingPrincipal.blocking)))
    target_blockings = {x.blocking for x in target.in_blocking_acls.options(joinedload(BlockingPrincipal.blocking))}
    for principal in source_principals:
        if principal.blocking not in target_blockings:
            principal.user_id = target.id
        else:
            db.session.delete(principal)
    Blocking.find(created_by_id=source.id).update({Blocking.created_by_id: target.id})
    Reservation.find(created_by_id=source.id).update({Reservation.created_by_id: target.id})
    Reservation.find(booked_for_id=source.id).update({Reservation.booked_for_id: target.id})
    Room.find(owner_id=source.id).update({Room.owner_id: target.id})
    settings.acls.merge_users(target, source)
Example #22
0
def _main(args):
    yesterday = date.today() - relativedelta(days=1)
    past_month = yesterday - relativedelta(days=29)
    past_year = yesterday - relativedelta(years=1)

    if not args.locations:
        rooms = Room.find_all()
    else:
        rooms = Room.find_all(Location.name.in_(args.locations), _join=Location)

    print 'Month\tYear\tRoom'
    for room in rooms:
        print '{1:.3f}\t{2:.3f}\t{0}'.format(room.full_name,
                                             calculate_rooms_occupancy([room], past_month, yesterday) * 100,
                                             calculate_rooms_occupancy([room], past_year, yesterday) * 100)
Example #23
0
 def _make_select_room_form(self):
     # Step 1
     self._rooms = sorted(Room.find_all(is_active=True), key=lambda r: natural_sort_key(r.full_name))
     form_obj, self.date_changed = self._get_select_room_form_defaults()
     form = NewBookingCriteriaForm(obj=form_obj)
     form.room_ids.choices = [(r.id, None) for r in self._rooms]
     return form
Example #24
0
    def _process_select_room(self):
        # Step 1: Room(s), dates, repetition selection
        form = self._make_select_room_form()
        if form.validate_on_submit():
            flexible_days = form.flexible_dates_range.data
            day_start_dt = datetime.combine(form.start_dt.data.date(), time())
            day_end_dt = datetime.combine(form.end_dt.data.date(), time(23, 59))

            selected_rooms = [r for r in self._rooms if r.id in form.room_ids.data]
            occurrences, candidates = self._get_all_occurrences(form.room_ids.data, form, flexible_days)

            period_form_defaults = FormDefaults(repeat_interval=form.repeat_interval.data,
                                                repeat_frequency=form.repeat_frequency.data)
            period_form = self._make_select_period_form(period_form_defaults)

            # Show step 2 page
            return self._get_view('select_period', rooms=selected_rooms, occurrences=occurrences, candidates=candidates,
                                  start_dt=day_start_dt, end_dt=day_end_dt, period_form=period_form, form=form,
                                  repeat_frequency=form.repeat_frequency.data,
                                  repeat_interval=form.repeat_interval.data, flexible_days=flexible_days).display()

        # GET or form errors => show step 1 page
        return self._get_view('select_room', errors=form.error_list, rooms=self._rooms, form=form,
                              my_rooms=[r.id for r in Room.get_owned_by(session.user)],
                              max_room_capacity=Room.max_capacity, can_override=rb_is_admin(session.user),
                              date_changed=not form.is_submitted() and self.date_changed, ).display()
Example #25
0
File: api.py Project: OmeGak/indico
    def _getParams(self):
        super(BookRoomHook, self)._getParams()
        self._fromDT = utc_to_server(self._fromDT.astimezone(pytz.utc)).replace(tzinfo=None) if self._fromDT else None
        self._toDT = utc_to_server(self._toDT.astimezone(pytz.utc)).replace(tzinfo=None) if self._toDT else None
        if not self._fromDT or not self._toDT or self._fromDT.date() != self._toDT.date():
            raise HTTPAPIError('from/to must be on the same day')
        elif self._fromDT >= self._toDT:
            raise HTTPAPIError('to must be after from')
        elif self._fromDT < datetime.now():
            raise HTTPAPIError('You cannot make bookings in the past')

        username = get_query_parameter(self._queryParams, 'username')
        if not username:
            raise HTTPAPIError('No username provided')
        users = User.find_all(~User.is_deleted, Identity.identifier == username)
        if not users:
            raise HTTPAPIError('Username does not exist')
        elif len(users) != 1:
            raise HTTPAPIError('Ambiguous username ({} users found)'.format(len(users)))
        user = users[0]

        self._params = {
            'room_id': get_query_parameter(self._queryParams, 'roomid'),
            'reason': get_query_parameter(self._queryParams, 'reason'),
            'booked_for': user,
            'from': self._fromDT,
            'to': self._toDT
        }
        missing = [key for key, val in self._params.iteritems() if not val]
        if missing:
            raise HTTPAPIError('Required params missing: {}'.format(', '.join(missing)))
        self._room = Room.get(self._params['room_id'])
        if not self._room:
            raise HTTPAPIError('A room with this ID does not exist')
Example #26
0
    def validate_blocked_rooms(self, field):
        try:
            field.data = map(int, field.data)
        except Exception as e:
            # In case someone sent crappy data
            raise ValidationError(str(e))

        # Make sure all room ids are valid
        if len(field.data) != Room.find(Room.id.in_(field.data)).count():
            raise ValidationError('Invalid rooms')

        if hasattr(self, '_blocking'):
            start_date = self._blocking.start_date
            end_date = self._blocking.end_date
            blocking_id = self._blocking.id
        else:
            start_date = self.start_date.data
            end_date = self.end_date.data
            blocking_id = None

        overlap = BlockedRoom.find_first(
            BlockedRoom.room_id.in_(field.data),
            BlockedRoom.state != BlockedRoom.State.rejected,
            Blocking.start_date <= end_date,
            Blocking.end_date >= start_date,
            Blocking.id != blocking_id,
            _join=Blocking
        )
        if overlap:
            msg = 'Your blocking for {} is overlapping with another blocking.'.format(overlap.room.full_name)
            raise ValidationError(msg)
Example #27
0
def _sidemenu_items(sender, **kwargs):
    user_is_admin = session.user is not None and rb_is_admin(session.user)
    user_has_rooms = session.user is not None and Room.user_owns_rooms(session.user)
    map_available = Location.default_location is not None and Location.default_location.is_map_available

    yield SideMenuItem('book_room', _('Book a Room'), url_for('rooms.book'), 80, icon='checkmark')
    if map_available:
        yield SideMenuItem('map', _('Map of Rooms'), url_for('rooms.roomBooking-mapOfRooms'), 70, icon='location')
    yield SideMenuItem('calendar', _('Calendar'), url_for('rooms.calendar'), 60, icon='calendar')
    yield SideMenuItem('my_bookings', _('My Bookings'), url_for('rooms.my_bookings'), 50, icon='time')
    yield SideMenuItem('search_bookings', _('Search bookings'), url_for('rooms.roomBooking-search4Bookings'),
                       section='search')
    yield SideMenuItem('search_rooms', _('Search rooms'), url_for('rooms.search_rooms'),
                       section='search')
    if user_has_rooms:
        yield SideMenuItem('bookings_in_my_rooms', _('Bookings in my rooms'), url_for('rooms.bookings_my_rooms'),
                           section='my_rooms')
        yield SideMenuItem('prebookings_in_my_rooms', _('Pre-bookings in my rooms'),
                           url_for('rooms.pending_bookings_my_rooms'),
                           section='my_rooms')
        yield SideMenuItem('room_list', _('Room list'), url_for('rooms.search_my_rooms'),
                           section='my_rooms')
    yield SideMenuItem('my_blockings', _('My Blockings'),
                       url_for('rooms.blocking_list', only_mine=True, timeframe='recent'),
                       section='blocking')
    if user_has_rooms:
        yield SideMenuItem('blockings_my_rooms', _('Blockings for my rooms'), url_for('rooms.blocking_my_rooms'),
                           section='blocking')
    yield SideMenuItem('blocking_create', _('Block rooms'), url_for('rooms.create_blocking'), section='blocking')
    if user_is_admin:
        yield SideMenuItem('admin', _('Administration'), url_for('rooms_admin.roomBooking-admin'), 10,
                           icon='user-chairperson')
Example #28
0
def _sidemenu_sections(sender, **kwargs):
    user_has_rooms = session.user is not None and Room.user_owns_rooms(session.user)

    yield SideMenuSection('search', _("Search"), 40, icon='search', active=True)
    if user_has_rooms:
        yield SideMenuSection('my_rooms', _("My Rooms"), 30, icon='user')
    yield SideMenuSection('blocking', _("Room Blocking"), 20, icon='lock')
Example #29
0
    def _process(self):
        room = self._reservation.room
        form = ModifyBookingForm(obj=self._reservation, old_start_date=self._reservation.start_dt.date())
        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

        if form.is_submitted() and not form.validate():
            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:
                self._reservation.modify(form.data, session.user)
                flash(_(u'Booking updated'), 'success')
            except NoReportError as e:
                transaction.abort()
                return jsonify(success=False, msg=unicode(e))
            return jsonify(success=True, url=self._get_success_url())

        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 #30
0
    def _getParams(self):
        super(BookRoomHook, self)._getParams()
        self._fromDT = utc_to_server(self._fromDT.astimezone(pytz.utc)).replace(tzinfo=None) if self._fromDT else None
        self._toDT = utc_to_server(self._toDT.astimezone(pytz.utc)).replace(tzinfo=None) if self._toDT else None
        if not self._fromDT or not self._toDT or self._fromDT.date() != self._toDT.date():
            raise HTTPAPIError('from/to must be on the same day')
        elif self._fromDT >= self._toDT:
            raise HTTPAPIError('to must be after from')
        elif self._fromDT < datetime.now():
            raise HTTPAPIError('You cannot make bookings in the past')

        username = get_query_parameter(self._queryParams, 'username')
        avatars = username and filter(None, AuthenticatorMgr().getAvatarByLogin(username).itervalues())
        if not avatars:
            raise HTTPAPIError('Username does not exist')
        elif len(avatars) != 1:
            raise HTTPAPIError('Ambiguous username ({} users found)'.format(len(avatars)))
        avatar = avatars[0]

        self._params = {
            'room_id': get_query_parameter(self._queryParams, 'roomid'),
            'reason': get_query_parameter(self._queryParams, 'reason'),
            'booked_for': avatar,
            'from': self._fromDT,
            'to': self._toDT
        }
        missing = [key for key, val in self._params.iteritems() if not val]
        if missing:
            raise HTTPAPIError('Required params missing: {}'.format(', '.join(missing)))
        self._room = Room.get(self._params['room_id'])
        if not self._room:
            raise HTTPAPIError('A room with this ID does not exist')
Example #31
0
    def migrate_reservations(self):
        print cformat('%{white!}migrating reservations')
        i = 1
        for rid, v in self.rb_root['Reservations'].iteritems():
            room = Room.get(v.room.id)
            if room is None:
                print cformat(
                    '  %{red!}skipping resv for dead room {0.room.id}: {0.id} ({0._utcCreatedDT})'
                ).format(v)
                continue

            repeat_frequency, repeat_interval = RepeatMapping.convert_legacy_repeatability(
                v.repeatability)
            booked_for_id = getattr(v, 'bookedForId', None)

            r = Reservation(
                id=v.id,
                created_dt=as_utc(v._utcCreatedDT),
                start_dt=utc_to_local(v._utcStartDT),
                end_dt=utc_to_local(v._utcEndDT),
                booked_for_id=self.merged_avatars.get(booked_for_id,
                                                      booked_for_id) or None,
                booked_for_name=convert_to_unicode(v.bookedForName),
                contact_email=convert_to_unicode(v.contactEmail),
                contact_phone=convert_to_unicode(
                    getattr(v, 'contactPhone', None)),
                created_by_id=self.merged_avatars.get(v.createdBy, v.createdBy)
                or None,
                is_cancelled=v.isCancelled,
                is_accepted=v.isConfirmed,
                is_rejected=v.isRejected,
                booking_reason=convert_to_unicode(v.reason),
                rejection_reason=convert_to_unicode(
                    getattr(v, 'rejectionReason', None)),
                repeat_frequency=repeat_frequency,
                repeat_interval=repeat_interval,
                uses_vc=getattr(v, 'usesAVC', False),
                needs_vc_assistance=getattr(v, 'needsAVCSupport', False),
                needs_assistance=getattr(v, 'needsAssistance', False))

            for eq_name in getattr(v, 'useVC', []):
                eq = room.location.get_equipment_by_name(eq_name)
                if eq:
                    r.used_equipment.append(eq)

            occurrence_rejection_reasons = {}
            if getattr(v, 'resvHistory', None):
                for h in reversed(v.resvHistory._entries):
                    ts = as_utc(parse_dt_string(h._timestamp))

                    if len(h._info) == 2:
                        possible_rejection_date, possible_rejection_reason = h._info
                        m = re.match(
                            r'Booking occurrence of the (\d{1,2} \w{3} \d{4}) rejected',
                            possible_rejection_reason)
                        if m:
                            d = datetime.strptime(m.group(1), '%d %b %Y')
                            occurrence_rejection_reasons[
                                d] = possible_rejection_reason[9:].strip('\'')

                    el = ReservationEditLog(timestamp=ts,
                                            user_name=h._responsibleUser,
                                            info=map(convert_to_unicode,
                                                     h._info))
                    r.edit_logs.append(el)

            notifications = getattr(v, 'startEndNotification', []) or []
            excluded_days = getattr(v, '_excludedDays', []) or []
            ReservationOccurrence.create_series_for_reservation(r)
            for occ in r.occurrences:
                occ.notification_sent = occ.date in notifications
                occ.is_rejected = r.is_rejected
                occ.is_cancelled = r.is_cancelled or occ.date in excluded_days
                occ.rejection_reason = (
                    convert_to_unicode(occurrence_rejection_reasons[occ.date])
                    if occ.date in occurrence_rejection_reasons else None)

            event_id = getattr(v, '_ReservationBase__owner', None)
            if hasattr(event_id, '_Impersistant__obj'):  # Impersistant object
                event_id = event_id._Impersistant__obj
            if event_id is not None:
                event = self.zodb_root['conferences'].get(event_id)
                if event:
                    # For some stupid reason there are bookings in the database which have a completely unrelated parent
                    guids = getattr(event, '_Conference__roomBookingGuids', [])
                    if any(
                            int(x.id) == v.id for x in guids
                            if x.id is not None):
                        r.event_id = int(event_id)
                    else:
                        print cformat(
                            '  %{red}event {} does not contain booking {}'
                        ).format(event_id, v.id)

            print cformat(
                '- [%{cyan}{}%{reset}/%{green!}{}%{reset}]  %{grey!}{}%{reset}  {}'
            ).format(room.location_name, room.name, r.id, r.created_dt.date())

            room.reservations.append(r)
            db.session.add(room)
            i = (i + 1) % 1000
            if not i:
                db.session.commit()
        db.session.commit()
Example #32
0
 def _checkParams(self):
     self._rooms = sorted(Room.find_all(is_active=True),
                          key=lambda r: natural_sort_key(r.full_name))
     self._form_data = self._get_form_data()
     self._form = BookingSearchForm(self._form_data, csrf_enabled=False)
     self._form.room_ids.choices = [(r.id, None) for r in self._rooms]
Example #33
0
 def _process_args(self):
     self.room = None
     if 'room_id' in request.view_args:
         self.room = Room.get_one(request.view_args['room_id'])
         if not self.room.is_active:
             raise NotFound
Example #34
0
 def _checkParams(self):
     blocking_id = self._params.get('blocking_id')
     self._room = Room.get(self._params['room_id'])
     self._blocking = Blocking.get(blocking_id) if blocking_id else None
Example #35
0
def get_managed_room_ids(user):
    if _can_get_all_groups(user):
        return {id_ for id_, in _query_managed_rooms(user).with_entities(Room.id)}
    else:
        return {r.id for r in Room.get_owned_by(user)}
Example #36
0
 def _process_args(self):
     self._room = Room()
     self._form = self._make_form()
Example #37
0
 def _process_args(self):
     self.room = None
     if 'room_id' in request.view_args:
         self.room = Room.get_one(request.view_args['room_id'])
Example #38
0
 def _jsonify_user_permissions(user):
     permissions = Room.get_permissions_for_user(user, allow_admin=False)
     return jsonify(user=permissions,
                    admin=(Room.get_permissions_for_user(user)
                           if rb_is_admin(user) else None))
Example #39
0
 def _process_args(self, args):
     self.args = args
     self.prebook = args.pop('is_prebooking')
     self.room = Room.get_or_404(self.args.pop('room_id'), is_deleted=False)
Example #40
0
def test_urls_transient_object():
    room = Room()
    assert room.booking_url is None
    assert room.details_url is None
    assert room.large_photo_url is None
Example #41
0
 def _process_args(self, args):
     self.args = args
     self.prebook = args.pop('is_prebooking')
     self.room = Room.get_one(self.args.pop('room_id'))
     if not self.room.is_active:
         raise BadRequest
Example #42
0
    def migrate_rooms(self):
        eq = defaultdict(set)
        vc = defaultdict(set)
        for old_room_id, old_room in self.rb_root['Rooms'].iteritems():
            eq[old_room._locationName].update(
                e for e in old_room._equipment.split('`') if e)
            vc[old_room._locationName].update(
                e for e in getattr(old_room, 'avaibleVC', []) if e)

        print cformat('%{white!}migrating equipment')
        for name, eqs in eq.iteritems():
            l = Location.find_first(name=name)

            if l is None:
                print cformat('%{yellow!}*** WARNING')
                print cformat(
                    "%{{yellow!}}***%{{reset}} Location '{}' does not exist. Skipped equipment: {}"
                    .format(name, eqs))
                continue

            l.equipment_types.extend(EquipmentType(name=x) for x in eqs)
            print cformat('- [%{cyan}{}%{reset}] {}').format(name, eqs)
            db.session.add(l)
        db.session.commit()
        print

        print cformat('%{white!}migrating vc equipment')
        for name, vcs in vc.iteritems():
            l = Location.find_first(name=name)

            if l is None:
                print cformat('%{yellow!}*** WARNING')
                print cformat(
                    "%{{yellow!}}***%{{reset}} Location '{}' does not exist. Skipped VC equipment: {}"
                    .format(name, vcs))
                continue

            pvc = l.get_equipment_by_name('Video conference')
            for vc_name in vcs:
                req = EquipmentType(name=vc_name)
                req.parent = pvc
                l.equipment_types.append(req)
                print cformat('- [%{cyan}{}%{reset}] {}').format(
                    name, req.name)
            db.session.add(l)
        db.session.commit()
        print

        print cformat('%{white!}migrating rooms')

        for old_room_id, old_room in self.rb_root['Rooms'].iteritems():
            l = Location.find_first(name=old_room._locationName)

            if l is None:
                print cformat('%{yellow!}*** WARNING')
                print cformat(
                    "%{{yellow!}}***%{{reset}} Location '{}' does not exist. Skipped room '{}'"
                    .format(old_room._locationName, old_room.id))
                continue

            r = Room(
                id=old_room_id,
                name=convert_to_unicode((old_room._name or '').strip()
                                        or generate_name(old_room)),
                site=convert_to_unicode(old_room.site),
                division=convert_to_unicode(old_room.division),
                building=convert_to_unicode(old_room.building),
                floor=convert_to_unicode(old_room.floor),
                number=convert_to_unicode(old_room.roomNr),
                notification_before_days=((
                    old_room.resvStartNotificationBefore or None) if getattr(
                        old_room, 'resvStartNotification', False) else None),
                notification_for_responsible=getattr(
                    old_room, 'resvNotificationToResponsible', False),
                notification_for_assistance=getattr(
                    old_room, 'resvNotificationAssistance', False),
                reservations_need_confirmation=old_room.resvsNeedConfirmation,
                telephone=convert_to_unicode(
                    getattr(old_room, 'telephone', None)),
                key_location=convert_to_unicode(
                    getattr(old_room, 'whereIsKey', None)),
                capacity=getattr(old_room, 'capacity', None),
                surface_area=getattr(old_room, 'surfaceArea', None),
                latitude=getattr(old_room, 'latitude', None),
                longitude=getattr(old_room, 'longitude', None),
                comments=convert_to_unicode(getattr(old_room, 'comments',
                                                    None)),
                owner_id=self.merged_avatars.get(old_room.responsibleId,
                                                 old_room.responsibleId),
                is_active=old_room.isActive,
                is_reservable=old_room.isReservable,
                max_advance_days=int(old_room.maxAdvanceDays) if getattr(
                    old_room, 'maxAdvanceDays', None) else None)

            print cformat(
                '- [%{cyan}{}%{reset}] %{grey!}{:4}%{reset}  %{green!}{}%{reset}'
            ).format(l.name, r.id, r.name)

            for old_bookable_time in getattr(old_room, '_dailyBookablePeriods',
                                             []):
                r.bookable_hours.append(
                    BookableHours(start_time=old_bookable_time._startTime,
                                  end_time=old_bookable_time._endTime))
                print cformat('  %{blue!}Bookable:%{reset} {}').format(
                    r.bookable_hours[-1])

            for old_nonbookable_date in getattr(old_room, '_nonBookableDates',
                                                []):
                r.nonbookable_periods.append(
                    NonBookablePeriod(start_dt=old_nonbookable_date._startDate,
                                      end_dt=old_nonbookable_date._endDate))
                print cformat('  %{blue!}Nonbookable:%{reset} {}').format(
                    r.nonbookable_periods[-1])

            if self.photo_path:
                try:
                    with open(
                            os.path.join(
                                self.photo_path, 'large_photos',
                                get_canonical_name_of(old_room) + '.jpg'),
                            'rb') as f:
                        large_photo = f.read()
                except Exception:
                    large_photo = None

                try:
                    with open(
                            os.path.join(
                                self.photo_path, 'small_photos',
                                get_canonical_name_of(old_room) + '.jpg'),
                            'rb') as f:
                        small_photo = f.read()
                except Exception:
                    small_photo = None

                if large_photo and small_photo:
                    r.photo = Photo(data=large_photo, thumbnail=small_photo)
                    print cformat('  %{blue!}Photos')

            new_eq = []
            for old_equipment in ifilter(
                    None,
                    old_room._equipment.split('`') + old_room.avaibleVC):
                room_eq = l.get_equipment_by_name(old_equipment)
                new_eq.append(room_eq)
                r.available_equipment.append(room_eq)
            if new_eq:
                print cformat('  %{blue!}Equipment:%{reset} {}').format(
                    ', '.join(sorted(x.name for x in new_eq)))

            for attr_name, value in getattr(old_room, 'customAtts',
                                            {}).iteritems():
                value = convert_to_unicode(value)
                if not value or ('Simba' in attr_name
                                 and value == u'Error: unknown mailing list'):
                    continue
                attr_name = attribute_map.get(attr_name,
                                              attr_name).replace(' ',
                                                                 '-').lower()
                ca = l.get_attribute_by_name(attr_name)
                if not ca:
                    print cformat(
                        '  %{blue!}Attribute:%{reset} {} %{red!}not found'
                    ).format(attr_name)
                    continue
                attr = RoomAttributeAssociation()
                attr.value = value
                attr.attribute = ca
                r.attributes.append(attr)
                print cformat('  %{blue!}Attribute:%{reset} {} = {}').format(
                    attr.attribute.title, attr.value)

            l.rooms.append(r)
            db.session.add(l)
            print
        db.session.commit()
Example #43
0
 def _process_args(self):
     self.room = Room.get_one(request.view_args['room_id'],
                              is_deleted=False)
Example #44
0
 def _process_args(self):
     self._room = Room.get(request.view_args['roomID'])
     self._target = self._room
Example #45
0
def _sidemenu_items(sender, **kwargs):
    user_is_admin = session.user is not None and rb_is_admin(session.user)
    user_has_rooms = session.user is not None and Room.user_owns_rooms(
        session.user)
    map_available = Location.default_location is not None and Location.default_location.is_map_available

    yield SideMenuItem('book_room',
                       _('Book a Room'),
                       url_for('rooms.book'),
                       80,
                       icon='checkmark')
    if map_available:
        yield SideMenuItem('map',
                           _('Map of Rooms'),
                           url_for('rooms.roomBooking-mapOfRooms'),
                           70,
                           icon='location')
    yield SideMenuItem('calendar',
                       _('Calendar'),
                       url_for('rooms.calendar'),
                       60,
                       icon='calendar')
    yield SideMenuItem('my_bookings',
                       _('My Bookings'),
                       url_for('rooms.my_bookings'),
                       50,
                       icon='time')
    yield SideMenuItem('search_bookings',
                       _('Search bookings'),
                       url_for('rooms.roomBooking-search4Bookings'),
                       section='search')
    yield SideMenuItem('search_rooms',
                       _('Search rooms'),
                       url_for('rooms.search_rooms'),
                       section='search')
    if user_has_rooms:
        yield SideMenuItem('bookings_in_my_rooms',
                           _('Bookings in my rooms'),
                           url_for('rooms.bookings_my_rooms'),
                           section='my_rooms')
        yield SideMenuItem('prebookings_in_my_rooms',
                           _('Pre-bookings in my rooms'),
                           url_for('rooms.pending_bookings_my_rooms'),
                           section='my_rooms')
        yield SideMenuItem('room_list',
                           _('Room list'),
                           url_for('rooms.search_my_rooms'),
                           section='my_rooms')
    yield SideMenuItem('my_blockings',
                       _('My Blockings'),
                       url_for('rooms.blocking_list',
                               only_mine=True,
                               timeframe='recent'),
                       section='blocking')
    if user_has_rooms:
        yield SideMenuItem('blockings_my_rooms',
                           _('Blockings for my rooms'),
                           url_for('rooms.blocking_my_rooms'),
                           section='blocking')
    yield SideMenuItem('blocking_create',
                       _('Block rooms'),
                       url_for('rooms.create_blocking'),
                       section='blocking')
    if user_is_admin:
        yield SideMenuItem('admin',
                           _('Administration'),
                           url_for('rooms_admin.roomBooking-admin'),
                           10,
                           icon='user-chairperson')
Example #46
0
def get_room(room_id):
    room = Room.get(room_id)
    if not room:
        print(cformat("%{yellow}! Desk with ID {} not found.").format(room_id))
    return room
Example #47
0
    def fetch_rooms(self, connection, room_name=None):
        self._logger.debug("Fetching AIS Role information...")
        room_role_map = _get_room_role_map(connection, self._logger)

        self._logger.debug("Fetching room information...")

        counter = Counter()
        foundation_rooms = []

        coordinates = self.fetch_buildings_coordinates(connection)
        cursor = connection.cursor()

        if room_name:
            cursor.execute('SELECT * FROM foundation_pub.meeting_rooms WHERE ID = :room_name', room_name=room_name)
        else:
            cursor.execute('SELECT * FROM foundation_pub.meeting_rooms ORDER BY ID')

        for row in cursor:
            counter['found'] += 1
            data = self._prepare_row(row, cursor)
            room_id = data['ID']

            try:
                room_data, email_warning = self._parse_room_data(data, coordinates, room_id)
                self._logger.debug("Fetched data for room with id='%s'", room_id)
            except SkipRoom as e:
                counter['skipped'] += 1
                self._logger.info("Skipped room %s: %s", room_id, e)
                continue

            room = Room.query.filter_by(building=room_data['building'], floor=room_data['floor'],
                                        number=room_data['number'], location=self._location).first()

            if room_data['owner'] is None:
                del room_data['owner']
                if room is None:
                    counter['skipped'] += 1
                    self._logger.info("Skipped room %s: %s", room_id, email_warning)
                    continue
                elif not room.is_deleted:
                    self._logger.warning("Problem with room %s: %s", room_id, email_warning)

            # Insert new room
            new_room = False
            if room is None:
                new_room = True
                room = Room()
                self._location.rooms.append(room)
                counter['inserted'] += 1
                self._logger.info("Created new room '%s'", room_id)

            changes = []
            # Update room data
            self._update_room(room, room_data, changes)
            # Update managers
            self._update_managers(room, room_role_map, changes)

            if changes and not new_room:
                counter['updated'] += 1
                for change in changes:
                    self._logger.info("Updated room %s: %s", room_id, change)
            foundation_rooms.append(room)

        # Deactivate rooms not found in Foundation
        if room_name:
            query = Room.query.filter_by(name=room_name)
        else:
            query = Room.query.filter_by(location=self._location)
        rooms_to_deactivate = (room for room in query if room not in foundation_rooms and not room.is_deleted)
        for room in rooms_to_deactivate:
            self._logger.info("Deactivated room '%s'", room.full_name)
            room.is_deleted = True
            counter['deactivated'] += 1
        self._logger.info("Deactivated %d rooms not found in Foundation", counter['deactivated'])

        self._logger.info("Rooms summary: %d in Foundation - %d skipped - %d inserted - %d updated - %d deactivated",
                          counter['found'], counter['skipped'], counter['inserted'], counter['updated'],
                          counter['deactivated'])
Example #48
0
 def _checkParams(self):
     self._room = Room.get(int(request.view_args['roomID']))
     if self._room is None:
         raise NotFoundError('This room does not exist')
Example #49
0
def search_for_rooms(filters, allow_admin=False, availability=None):
    """Search for a room, using the provided filters.

    :param filters: The filters, provided as a dictionary
    :param allow_admin: A boolean specifying whether admins have override privileges
    :param availability: A boolean specifying whether (un)available rooms should be provided,
                         or `None` in case all rooms should be returned.
    """
    query = (Room.query
             .outerjoin(favorite_room_table, db.and_(favorite_room_table.c.user_id == session.user.id,
                                                     favorite_room_table.c.room_id == Room.id))
             .reset_joinpoint()  # otherwise filter_by() would apply to the favorite table
             .filter(~Room.is_deleted)
             .order_by(favorite_room_table.c.user_id.is_(None), db.func.indico.natsort(Room.full_name)))

    criteria = {}
    if 'capacity' in filters:
        query = query.filter(Room.capacity >= filters['capacity'])
    if 'building' in filters:
        criteria['building'] = filters['building']
    if 'division' in filters:
        criteria['division'] = filters['division']
    query = query.filter_by(**criteria)
    if 'text' in filters:
        text = ' '.join(filters['text'].strip().split())
        if text.startswith('#') and text[1:].isdigit():
            query = query.filter(Room.id == int(text[1:]))
        else:
            query = query.filter(_make_room_text_filter(text))
    if filters.get('equipment'):
        subquery = (db.session.query(RoomEquipmentAssociation)
                    .with_entities(db.func.count(RoomEquipmentAssociation.c.room_id))
                    .filter(RoomEquipmentAssociation.c.room_id == Room.id,
                            EquipmentType.name.in_(filters['equipment']))
                    .join(EquipmentType, RoomEquipmentAssociation.c.equipment_id == EquipmentType.id)
                    .correlate(Room)
                    .scalar_subquery())
        query = query.filter(subquery == len(filters['equipment']))
    if filters.get('features'):
        for feature in filters['features']:
            query = query.filter(Room.available_equipment.any(EquipmentType.features.any(RoomFeature.name == feature)))
    if filters.get('favorite'):
        query = query.filter(favorite_room_table.c.user_id.isnot(None))
    if filters.get('mine'):
        ids = get_managed_room_ids(session.user)
        query = query.filter(Room.id.in_(ids))
    query = _filter_coordinates(query, filters)

    if availability is None:
        return query

    start_dt, end_dt = filters['start_dt'], filters['end_dt']
    repeatability = (filters['repeat_frequency'], filters['repeat_interval'])
    availability_filters = [Room.filter_available(start_dt, end_dt, repeatability, include_blockings=False,
                                                  include_pre_bookings=False)]
    if not (allow_admin and rb_is_admin(session.user)):
        selected_period_days = (filters['end_dt'] - filters['start_dt']).days
        booking_limit_days = db.func.coalesce(Room.booking_limit_days, rb_settings.get('booking_limit'))

        criterion = db.and_(Room.filter_bookable_hours(start_dt.time(), end_dt.time()),
                            Room.filter_nonbookable_periods(start_dt, end_dt),
                            db.or_(booking_limit_days.is_(None),
                            selected_period_days <= booking_limit_days))
        unbookable_ids = [room.id
                          for room in query.filter(db.and_(*availability_filters), ~criterion)
                          if not room.can_override(session.user, allow_admin=False)]
        availability_filters.append(~Room.id.in_(unbookable_ids))
    availability_criterion = db.and_(*availability_filters)
    if availability is False:
        availability_criterion = ~availability_criterion
    return query.filter(availability_criterion)
Example #50
0
 def _checkParams(self):
     self._room = Room.get(request.view_args['roomID'])
     self._target = self._room
Example #51
0
def update(csv_file, add_missing, dry_run):
    """Update the Burotels from a CSV file."""
    num_changes = 0
    num_adds = 0
    num_removes = 0
    r = csv.reader(csv_file)

    valid_ids = {id_ for id_, in db.session.query(Room.id)}
    for room_id, division, building, floor, number, verbose_name, owner_email, acl_row, action in r:
        owner = get_user(owner_email)
        acl = {get_principal(principal)
               for principal in acl_row.split(';')} if acl_row else None

        data = {
            'id': int(room_id.decode('utf-8-sig')) if room_id else None,
            'division': division,
            'building': building,
            'floor': floor,
            'number': number,
            'verbose_name': verbose_name,
            'owner': owner,
            'acl_entries': ({owner} | acl) if acl else {owner},
            'action': action or 'UPDATE'
        }
        if not data['id'] and action != 'ADD':
            print(
                cformat(
                    '%{yellow}! Only ADD lines can have an empty Desk ID. Ignoring line.'
                ))
            continue

        if add_missing and data['action'] == 'UPDATE' and data[
                'id'] not in valid_ids:
            data['action'] = 'ADD'
            print(
                cformat('%{yellow}! Desk with ID {} not found; adding it.').
                format(room_id))

        if data['action'] == 'UPDATE':
            room = get_room(room_id)
            if not room:
                continue
            changes = check_changed_fields(room, data)
            if changes:
                num_changes += 1
                _print_changes(room, changes)
                if not dry_run:
                    change_room(room, changes)
        elif data['action'] == 'ADD':
            existing_room = Room.query.filter(
                Room.building == building, Room.floor == floor,
                Room.number == number,
                Room.verbose_name == verbose_name).first()
            if existing_room:
                # a room with the exact same designation already exists
                print(
                    cformat(
                        "%{yellow}!%{reset} A desk with the name %{cyan}{}%{reset} already exists"
                    ).format(existing_room.full_name))
                continue
            print(
                cformat(
                    "%{green!}+%{reset} New desk %{cyan}{}/{}-{} {}").format(
                        building, floor, number, verbose_name))
            num_adds += 1
            if not dry_run:
                room = Room(building=building,
                            floor=floor,
                            number=number,
                            division=division,
                            verbose_name=verbose_name,
                            owner=owner,
                            location=get_location(building),
                            protection_mode=ProtectionMode.protected,
                            reservations_need_confirmation=True)
                room.update_principal(owner, full_access=True)
                if acl:
                    for principal in acl:
                        room.update_principal(principal, full_access=True)
                db.session.add(room)
        elif data['action'] == 'REMOVE':
            room = get_room(room_id)
            if not room:
                continue
            print(cformat('%{red}-%{reset} {}').format(room.full_name))
            if not dry_run:
                room.is_deleted = True
            num_removes += 1

    print((cformat(
        '\n%{cyan}Total:%{reset} %{green}+%{reset}{}  %{yellow}\u00b1%{reset}{}  %{red}-%{reset}{} '
    ).format(num_adds, num_changes, num_removes)))

    if not dry_run:
        db.session.commit()
Example #52
0
 def _checkParams(self):
     self._room = Room()
     self._form = self._make_form()
Example #53
0
 def _getAnswer(self):
     rooms = Room.find_all(
         Room.filter_available(self._start_dt, self._end_dt,
                               self._repetition))
     return [room.id for room in rooms]
Example #54
0
def search_for_rooms(filters, only_available=False):
    query = (
        Room.query.outerjoin(
            favorite_room_table,
            db.and_(
                favorite_room_table.c.user_id == session.user.id,
                favorite_room_table.c.room_id == Room.id)).reset_joinpoint(
                )  # otherwise filter_by() would apply to the favorite table
        .options(raiseload('owner')).filter(Room.is_active).order_by(
            favorite_room_table.c.user_id.is_(None),
            db.func.indico.natsort(Room.full_name)))

    criteria = {}
    if 'capacity' in filters:
        query = query.filter(Room.capacity >= filters['capacity'])
    if 'building' in filters:
        criteria['building'] = filters['building']
    if 'floor' in filters:
        criteria['floor'] = filters['floor']
    query = query.filter_by(**criteria)
    if 'text' in filters:
        query = query.filter(_make_room_text_filter(filters['text']))
    if filters.get('equipment'):
        subquery = (db.session.query(RoomEquipmentAssociation).with_entities(
            db.func.count(RoomEquipmentAssociation.c.room_id)).filter(
                RoomEquipmentAssociation.c.room_id == Room.id,
                EquipmentType.name.in_(filters['equipment'])).join(
                    EquipmentType, RoomEquipmentAssociation.c.equipment_id ==
                    EquipmentType.id).correlate(Room).as_scalar())
        query = query.filter(subquery == len(filters['equipment']))
    if filters.get('favorite'):
        query = query.filter(favorite_room_table.c.user_id.isnot(None))
    if filters.get('mine'):
        ids = get_managed_room_ids(session.user)
        if ids:
            query = query.filter(Room.id.in_(ids))
    query = _filter_coordinates(query, filters)

    if not only_available:
        return query

    start_dt, end_dt = filters['start_dt'], filters['end_dt']
    repeatability = (filters['repeat_frequency'], filters['repeat_interval'])
    query = query.filter(
        Room.filter_available(start_dt,
                              end_dt,
                              repeatability,
                              include_pre_bookings=True,
                              include_pending_blockings=True))
    if not rb_is_admin(session.user):
        selected_period_days = (filters['end_dt'] - filters['start_dt']).days
        booking_limit_days = db.func.coalesce(Room.booking_limit_days,
                                              rb_settings.get('booking_limit'))

        own_rooms = [r.id for r in Room.get_owned_by(session.user)]
        query = query.filter(
            db.or_(
                Room.id.in_(own_rooms) if own_rooms else False,
                db.and_(
                    Room.filter_bookable_hours(start_dt.time(), end_dt.time()),
                    Room.filter_nonbookable_periods(start_dt, end_dt),
                    db.or_(booking_limit_days.is_(None),
                           selected_period_days <= booking_limit_days))))
    return query
Example #55
0
def search_for_rooms(filters, availability=None):
    """Search for a room, using the provided filters.

    :param filters: The filters, provided as a dictionary
    :param availability: A boolean specifying whether (un)available rooms should be provided,
                         or `None` in case all rooms should be returned.
    """
    query = (
        Room.query.outerjoin(
            favorite_room_table,
            db.and_(
                favorite_room_table.c.user_id == session.user.id,
                favorite_room_table.c.room_id == Room.id)).reset_joinpoint(
                )  # otherwise filter_by() would apply to the favorite table
        .options(raiseload('owner')).filter(Room.is_active).order_by(
            favorite_room_table.c.user_id.is_(None),
            db.func.indico.natsort(Room.full_name)))

    criteria = {}
    if 'capacity' in filters:
        query = query.filter(Room.capacity >= filters['capacity'])
    if 'building' in filters:
        criteria['building'] = filters['building']
    if 'division' in filters:
        criteria['division'] = filters['division']
    query = query.filter_by(**criteria)
    if 'text' in filters:
        query = query.filter(_make_room_text_filter(filters['text']))
    if filters.get('equipment'):
        subquery = (db.session.query(RoomEquipmentAssociation).with_entities(
            db.func.count(RoomEquipmentAssociation.c.room_id)).filter(
                RoomEquipmentAssociation.c.room_id == Room.id,
                EquipmentType.name.in_(filters['equipment'])).join(
                    EquipmentType, RoomEquipmentAssociation.c.equipment_id ==
                    EquipmentType.id).correlate(Room).as_scalar())
        query = query.filter(subquery == len(filters['equipment']))
    if filters.get('features'):
        for feature in filters['features']:
            query = query.filter(
                Room.available_equipment.any(
                    EquipmentType.features.any(RoomFeature.name == feature)))
    if filters.get('favorite'):
        query = query.filter(favorite_room_table.c.user_id.isnot(None))
    if filters.get('mine'):
        ids = get_managed_room_ids(session.user)
        query = query.filter(Room.id.in_(ids))
    query = _filter_coordinates(query, filters)

    if availability is None:
        return query

    start_dt, end_dt = filters['start_dt'], filters['end_dt']
    repeatability = (filters['repeat_frequency'], filters['repeat_interval'])
    availability_query = Room.filter_available(start_dt,
                                               end_dt,
                                               repeatability,
                                               include_pre_bookings=True,
                                               include_pending_blockings=True)

    if availability is False:
        availability_query = ~availability_query

    query = query.filter(availability_query)

    if not rb_is_admin(session.user):
        selected_period_days = (filters['end_dt'] - filters['start_dt']).days
        booking_limit_days = db.func.coalesce(Room.booking_limit_days,
                                              rb_settings.get('booking_limit'))

        own_rooms = [r.id for r in Room.get_owned_by(session.user)]
        query = query.filter(
            db.or_(
                Room.id.in_(own_rooms) if own_rooms else False,
                db.and_(
                    Room.filter_bookable_hours(start_dt.time(), end_dt.time()),
                    Room.filter_nonbookable_periods(start_dt, end_dt),
                    db.or_(booking_limit_days.is_(None),
                           selected_period_days <= booking_limit_days))))
    return query
Example #56
0
def has_managed_rooms(user):
    if _can_get_all_groups(user):
        return _query_managed_rooms(user).has_rows()
    else:
        return Room.user_owns_rooms(user)
Example #57
0
def test_get_with_data_errors():
    with pytest.raises(ValueError):
        Room.get_with_data(foo='bar')
Example #58
0
 def _process_args(self):
     self.room = None
     if 'room_id' in request.view_args:
         self.room = Room.get_or_404(request.view_args['room_id'],
                                     is_deleted=False)
Example #59
0
def test_is_auto_confirm(create_room, need_confirmation):
    room = create_room(reservations_need_confirmation=need_confirmation)
    assert room.is_auto_confirm != need_confirmation
    assert Room.find_first(is_auto_confirm=need_confirmation) is None
    assert Room.find_first(is_auto_confirm=not need_confirmation) == room
Example #60
0
 def process_formdata(self, valuelist):
     super(IndicoLocationField, self).process_formdata(valuelist)
     self.data['room'] = Room.get(int(
         self.data['room_id'])) if self.data.get('room_id') else None
     self.data['venue'] = Location.get(int(
         self.data['venue_id'])) if self.data.get('venue_id') else None