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)
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)
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 )
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})
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()
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)
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()
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}
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}
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)
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)
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}
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()
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()
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}
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
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())
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
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())
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
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)
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)
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
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()
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')
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)
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')
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')
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()
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')
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()
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]
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
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
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)}
def _process_args(self): self._room = Room() self._form = self._make_form()
def _process_args(self): self.room = None if 'room_id' in request.view_args: self.room = Room.get_one(request.view_args['room_id'])
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))
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)
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
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
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()
def _process_args(self): self.room = Room.get_one(request.view_args['room_id'], is_deleted=False)
def _process_args(self): self._room = Room.get(request.view_args['roomID']) self._target = self._room
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')
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
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'])
def _checkParams(self): self._room = Room.get(int(request.view_args['roomID'])) if self._room is None: raise NotFoundError('This room does not exist')
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)
def _checkParams(self): self._room = Room.get(request.view_args['roomID']) self._target = self._room
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()
def _checkParams(self): self._room = Room() self._form = self._make_form()
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]
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
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
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)
def test_get_with_data_errors(): with pytest.raises(ValueError): Room.get_with_data(foo='bar')
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)
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
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