def get_rooms_conflicts(rooms, start_dt, end_dt, repeat_frequency, repeat_interval, blocked_rooms, nonbookable_periods, unbookable_hours, skip_conflicts_with=None): rooms_conflicts = defaultdict(list) rooms_pre_conflicts = defaultdict(list) skip_conflicts_with = skip_conflicts_with or [] candidates = ReservationOccurrence.create_series(start_dt, end_dt, (repeat_frequency, repeat_interval)) room_ids = [room.id for room in rooms] query = (ReservationOccurrence.query .filter(Reservation.room_id.in_(room_ids), ReservationOccurrence.is_valid, ReservationOccurrence.filter_overlap(candidates)) .join(ReservationOccurrence.reservation) .options(ReservationOccurrence.NO_RESERVATION_USER_STRATEGY, contains_eager(ReservationOccurrence.reservation))) if skip_conflicts_with: query = query.filter(~Reservation.id.in_(skip_conflicts_with)) overlapping_occurrences = group_list(query, key=lambda obj: obj.reservation.room.id) for room_id, occurrences in overlapping_occurrences.iteritems(): rooms_conflicts[room_id], rooms_pre_conflicts[room_id] = get_room_bookings_conflicts(candidates, occurrences, skip_conflicts_with) for room_id, occurrences in blocked_rooms.iteritems(): rooms_conflicts[room_id] += get_room_blockings_conflicts(room_id, candidates, occurrences) # TODO: do proper per-room override checks if not rb_is_admin(session.user): for room_id, occurrences in nonbookable_periods.iteritems(): rooms_conflicts[room_id] += get_room_nonbookable_periods_conflicts(candidates, occurrences) for room_id, occurrences in unbookable_hours.iteritems(): rooms_conflicts[room_id] += get_room_unbookable_hours_conflicts(candidates, occurrences) return rooms_conflicts, rooms_pre_conflicts
def get_rooms_conflicts(rooms, start_dt, end_dt, repeat_frequency, repeat_interval, blocked_rooms, nonbookable_periods, unbookable_hours): rooms_conflicts = defaultdict(list) rooms_pre_conflicts = defaultdict(list) candidates = ReservationOccurrence.create_series( start_dt, end_dt, (repeat_frequency, repeat_interval)) room_ids = [room.id for room in rooms] query = (ReservationOccurrence.query.filter( Reservation.room_id.in_(room_ids), ReservationOccurrence.is_valid, ReservationOccurrence.filter_overlap(candidates)).join( ReservationOccurrence.reservation).options( ReservationOccurrence.NO_RESERVATION_USER_STRATEGY, contains_eager(ReservationOccurrence.reservation))) overlapping_occurrences = group_list( query, key=lambda obj: obj.reservation.room.id) for room_id, occurrences in overlapping_occurrences.iteritems(): rooms_conflicts[room_id], rooms_pre_conflicts[ room_id] = get_room_bookings_conflicts(candidates, occurrences) for room_id, occurrences in blocked_rooms.iteritems(): rooms_conflicts[room_id] += get_room_blockings_conflicts( room_id, candidates, occurrences) for room_id, occurrences in nonbookable_periods.iteritems(): rooms_conflicts[room_id] += get_room_nonbookable_periods_conflicts( candidates, occurrences) for room_id, occurrences in unbookable_hours.iteritems(): rooms_conflicts[room_id] += get_room_unbookable_hours_conflicts( candidates, occurrences) return rooms_conflicts, rooms_pre_conflicts
def get_existing_rooms_occurrences(rooms, start_dt, end_dt, repeat_frequency, repeat_interval, allow_overlapping=False, only_accepted=False): room_ids = [room.id for room in rooms] query = (ReservationOccurrence.query.filter( ReservationOccurrence.is_valid, Reservation.room_id.in_(room_ids)).join( ReservationOccurrence.reservation).options( ReservationOccurrence.NO_RESERVATION_USER_STRATEGY, contains_eager(ReservationOccurrence.reservation))) if allow_overlapping: query = query.filter( db_dates_overlap(ReservationOccurrence, 'start_dt', start_dt, 'end_dt', end_dt)) else: query = query.filter(ReservationOccurrence.start_dt >= start_dt, ReservationOccurrence.end_dt <= end_dt) if only_accepted: query = query.filter(Reservation.is_accepted) if repeat_frequency != RepeatFrequency.NEVER: candidates = ReservationOccurrence.create_series( start_dt, end_dt, (repeat_frequency, repeat_interval)) dates = [candidate.start_dt for candidate in candidates] query = query.filter( db.cast(ReservationOccurrence.start_dt, db.Date).in_(dates)) return group_list(query, key=lambda obj: obj.reservation.room.id, sort_by=lambda obj: (obj.reservation.room_id, obj.start_dt))
def get_rooms_nonbookable_periods(rooms, start_dt, end_dt): room_ids = [room.id for room in rooms] query = (NonBookablePeriod.query .filter(NonBookablePeriod.room_id.in_(room_ids), NonBookablePeriod.start_dt <= end_dt.replace(hour=23, minute=59), NonBookablePeriod.end_dt >= start_dt.replace(hour=0, minute=0))) return group_list(query, key=lambda obj: obj.room_id)
def get_rooms_nonbookable_periods(rooms, start_dt, end_dt): room_ids = [room.id for room in rooms] query = (NonBookablePeriod.query.filter( NonBookablePeriod.room_id.in_(room_ids), NonBookablePeriod.start_dt <= end_dt.replace(hour=23, minute=59), NonBookablePeriod.end_dt >= start_dt.replace(hour=0, minute=0))) return group_list(query, key=lambda obj: obj.room_id)
def get_rooms_conflicts(rooms, start_dt, end_dt, repeat_frequency, repeat_interval, blocked_rooms, nonbookable_periods, unbookable_hours, skip_conflicts_with=None, allow_admin=False): rooms_conflicts = defaultdict(set) rooms_pre_conflicts = defaultdict(set) rooms_conflicting_candidates = defaultdict(set) skip_conflicts_with = skip_conflicts_with or [] candidates = ReservationOccurrence.create_series( start_dt, end_dt, (repeat_frequency, repeat_interval)) room_ids = [room.id for room in rooms] query = (ReservationOccurrence.query.filter( Reservation.room_id.in_(room_ids), ReservationOccurrence.is_valid, ReservationOccurrence.filter_overlap(candidates)).join( ReservationOccurrence.reservation).options( ReservationOccurrence.NO_RESERVATION_USER_STRATEGY, contains_eager(ReservationOccurrence.reservation))) if skip_conflicts_with: query = query.filter(~Reservation.id.in_(skip_conflicts_with)) overlapping_occurrences = group_list( query, key=lambda obj: obj.reservation.room.id) for room_id, occurrences in overlapping_occurrences.iteritems(): conflicts = get_room_bookings_conflicts(candidates, occurrences, room_id, skip_conflicts_with) rooms_conflicts[room_id], rooms_pre_conflicts[ room_id], rooms_conflicting_candidates[room_id] = conflicts for room_id, occurrences in blocked_rooms.iteritems(): conflicts, conflicting_candidates = get_room_blockings_conflicts( room_id, candidates, occurrences) rooms_conflicts[room_id] |= conflicts rooms_conflicting_candidates[room_id] |= conflicting_candidates if not (allow_admin and rb_is_admin(session.user)): for room_id, occurrences in nonbookable_periods.iteritems(): room = Room.get_one(room_id) if not room.can_override(session.user, allow_admin=allow_admin): conflicts, conflicting_candidates = get_room_nonbookable_periods_conflicts( candidates, occurrences) rooms_conflicts[room_id] |= conflicts rooms_conflicting_candidates[room_id] |= conflicting_candidates for room_id, occurrences in unbookable_hours.iteritems(): room = Room.get_one(room_id) if not room.can_override(session.user, allow_admin=allow_admin): conflicts, conflicting_candidates = get_room_unbookable_hours_conflicts( candidates, occurrences) rooms_conflicts[room_id] |= conflicts rooms_conflicting_candidates[room_id] |= conflicting_candidates rooms_conflicting_candidates = defaultdict( list, ((k, list(v)) for k, v in rooms_conflicting_candidates.items())) return rooms_conflicts, rooms_pre_conflicts, rooms_conflicting_candidates
def get_rooms_conflicts(rooms, start_dt, end_dt, repeat_frequency, repeat_interval, blocked_rooms, nonbookable_periods, unbookable_hours): rooms_conflicts = defaultdict(list) rooms_pre_conflicts = defaultdict(list) candidates = ReservationOccurrence.create_series(start_dt, end_dt, (repeat_frequency, repeat_interval)) room_ids = [room.id for room in rooms] query = (ReservationOccurrence.query .filter(Reservation.room_id.in_(room_ids), ReservationOccurrence.is_valid, ReservationOccurrence.filter_overlap(candidates)) .join(ReservationOccurrence.reservation) .options(ReservationOccurrence.NO_RESERVATION_USER_STRATEGY, contains_eager(ReservationOccurrence.reservation))) overlapping_occurrences = group_list(query, key=lambda obj: obj.reservation.room.id) for room_id, occurrences in overlapping_occurrences.iteritems(): rooms_conflicts[room_id], rooms_pre_conflicts[room_id] = get_room_bookings_conflicts(candidates, occurrences) for room_id, occurrences in blocked_rooms.iteritems(): rooms_conflicts[room_id] += get_room_blockings_conflicts(room_id, candidates, occurrences) for room_id, occurrences in nonbookable_periods.iteritems(): rooms_conflicts[room_id] += get_room_nonbookable_periods_conflicts(candidates, occurrences) for room_id, occurrences in unbookable_hours.iteritems(): rooms_conflicts[room_id] += get_room_unbookable_hours_conflicts(candidates, occurrences) return rooms_conflicts, rooms_pre_conflicts
def _process(self): form = RequestListFilterForm(request.args, csrf_enabled=False) results = None if form.validate_on_submit(): reverse = form.direction.data == 'desc' from_dt = as_utc(get_day_start( form.start_date.data)) if form.start_date.data else None to_dt = as_utc(get_day_end( form.end_date.data)) if form.end_date.data else None results = find_requests(from_dt=from_dt, to_dt=to_dt) results = [(req, req.event, req.event.start_dt, contribs, session_blocks) for req, contribs, session_blocks in results] results = group_list(results, lambda x: x[2].date(), itemgetter(2), sort_reverse=reverse) results = OrderedDict( sorted(results.viewitems(), key=itemgetter(0), reverse=reverse)) return WPVCAssistance.render_template( 'request_list.html', form=form, results=results, action=url_for('.request_list'), vc_capable_rooms=get_vc_capable_rooms(), within_working_hours=start_time_within_working_hours)
def _process(self): form = RequestListFilterForm(request.args, csrf_enabled=False) results = None if request.args and form.validate(): reverse = form.direction.data == 'desc' talks = form.granularity.data == 'talks' from_dt = as_utc(get_day_start( form.start_date.data)) if form.start_date.data else None to_dt = as_utc(get_day_end( form.end_date.data)) if form.end_date.data else None states = {form.state.data} if form.state.data is not None else None results = find_requests(talks=talks, from_dt=from_dt, to_dt=to_dt, states=states) if not talks: results = [(req, req.event, req.event.start_dt) for req in results] results = group_list(results, lambda x: x[2].date(), itemgetter(2), sort_reverse=reverse) results = OrderedDict( sorted(results.viewitems(), key=itemgetter(0), reverse=reverse)) return WPAudiovisualManagers.render_template('request_list.html', form=form, results=results)
def get_rooms_blockings(rooms, start_date, end_date): room_ids = [room.id for room in rooms] query = (BlockedRoom.query.filter( BlockedRoom.room_id.in_(room_ids), BlockedRoom.state == BlockedRoomState.accepted, Blocking.start_date <= end_date, Blocking.end_date >= start_date).join( BlockedRoom.blocking).options(contains_eager('blocking'))) return group_list(query, key=lambda obj: obj.room_id)
def build_bars_data(self, show_empty_rooms=True, show_empty_days=True): bars_data = defaultdict(list) day_bars = group_list(self.bars, key=lambda b: b.date) for day in self.iter_days(): bars = day_bars.get(day, []) if not bars and not show_empty_days: continue room_bars = group_list(bars, key=attrgetter('room_id'), sort_by=attrgetter('importance')) for room in self.rooms: bars = room_bars.get(room.id, []) if not bars and not show_empty_rooms: continue room_dict = { 'room': room.to_serializable('__calendar_public__'), 'bars': [bar.to_serializable() for bar in bars] } bars_data[str(day)].append(room_dict) return bars_data
def _process(self): form = RequestListFilterForm(request.args) results = None if form.validate_on_submit(): reverse = form.direction.data == 'desc' from_dt = as_utc(get_day_start(form.start_date.data)) if form.start_date.data else None to_dt = as_utc(get_day_end(form.end_date.data)) if form.end_date.data else None results = _find_requests(from_dt=from_dt, to_dt=to_dt) results = group_list(results, lambda req: dateutil.parser.parse(req['requested_at']).date(), sort_reverse=reverse) results = OrderedDict(sorted(results.viewitems(), reverse=reverse)) return WPRoomAssistance.render_template('request_list.html', form=form, results=results, parse_dt=dateutil.parser.parse)
def _process(self): form = VCRoomListFilterForm(request.args) results = None if request.args and form.validate(): reverse = form.direction.data == 'desc' from_dt = as_utc(get_day_start(form.start_date.data)) if form.start_date.data else None to_dt = as_utc(get_day_end(form.end_date.data)) if form.end_date.data else None results = find_event_vc_rooms(from_dt=from_dt, to_dt=to_dt, distinct=True) results = group_list((r for r in results if r.event), key=lambda r: r.event.getStartDate().date(), sort_by=lambda r: r.event.getStartDate(), sort_reverse=reverse) results = OrderedDict(sorted(results.viewitems(), key=itemgetter(0), reverse=reverse)) return WPVCService.render_template('vc_room_list.html', form=form, results=results, action=url_for('.vc_room_list'))
def _process(self): form = VCRoomListFilterForm(request.args, csrf_enabled=False) results = None if request.args and form.validate(): reverse = form.direction.data == 'desc' from_dt = as_utc(get_day_start(form.start_date.data)) if form.start_date.data else None to_dt = as_utc(get_day_end(form.end_date.data)) if form.end_date.data else None results = find_event_vc_rooms(from_dt=from_dt, to_dt=to_dt, distinct=True) results = group_list((r for r in results if r.event_new), key=lambda r: r.event_new.start_dt.date(), sort_by=lambda r: r.event_new.start_dt, sort_reverse=reverse) results = OrderedDict(sorted(results.viewitems(), key=itemgetter(0), reverse=reverse)) return WPVCService.render_template('vc_room_list.html', form=form, results=results, action=url_for('.vc_room_list'))
def get_rooms_conflicts(rooms, start_dt, end_dt, repeat_frequency, repeat_interval, blocked_rooms, nonbookable_periods, unbookable_hours, skip_conflicts_with=None, allow_admin=False): rooms_conflicts = defaultdict(set) rooms_pre_conflicts = defaultdict(set) rooms_conflicting_candidates = defaultdict(set) skip_conflicts_with = skip_conflicts_with or [] candidates = ReservationOccurrence.create_series(start_dt, end_dt, (repeat_frequency, repeat_interval)) room_ids = [room.id for room in rooms] query = (ReservationOccurrence.query .filter(Reservation.room_id.in_(room_ids), ReservationOccurrence.is_valid, ReservationOccurrence.filter_overlap(candidates)) .join(ReservationOccurrence.reservation) .options(ReservationOccurrence.NO_RESERVATION_USER_STRATEGY, contains_eager(ReservationOccurrence.reservation))) if skip_conflicts_with: query = query.filter(~Reservation.id.in_(skip_conflicts_with)) overlapping_occurrences = group_list(query, key=lambda obj: obj.reservation.room.id) for room_id, occurrences in overlapping_occurrences.iteritems(): conflicts = get_room_bookings_conflicts(candidates, occurrences, room_id, skip_conflicts_with) rooms_conflicts[room_id], rooms_pre_conflicts[room_id], rooms_conflicting_candidates[room_id] = conflicts for room_id, occurrences in blocked_rooms.iteritems(): conflicts, conflicting_candidates = get_room_blockings_conflicts(room_id, candidates, occurrences) rooms_conflicts[room_id] |= conflicts rooms_conflicting_candidates[room_id] |= conflicting_candidates if not (allow_admin and rb_is_admin(session.user)): for room_id, occurrences in nonbookable_periods.iteritems(): room = Room.get_one(room_id) if not room.can_override(session.user, allow_admin=allow_admin): conflicts, conflicting_candidates = get_room_nonbookable_periods_conflicts(candidates, occurrences) rooms_conflicts[room_id] |= conflicts rooms_conflicting_candidates[room_id] |= conflicting_candidates for room_id, occurrences in unbookable_hours.iteritems(): room = Room.get_one(room_id) if not room.can_override(session.user, allow_admin=allow_admin): conflicts, conflicting_candidates = get_room_unbookable_hours_conflicts(candidates, occurrences) rooms_conflicts[room_id] |= conflicts rooms_conflicting_candidates[room_id] |= conflicting_candidates rooms_conflicting_candidates = defaultdict(list, ((k, list(v)) for k, v in rooms_conflicting_candidates.items())) return rooms_conflicts, rooms_pre_conflicts, rooms_conflicting_candidates
def get_rooms_unbookable_hours(rooms): room_ids = [room.id for room in rooms] query = BookableHours.query.filter(BookableHours.room_id.in_(room_ids)) rooms_hours = group_list(query, key=lambda obj: obj.room_id) inverted_rooms_hours = {} for room_id, hours in rooms_hours.iteritems(): hours.sort(key=lambda x: x.start_time) inverted_hours = [] first = BookableHours(start_time=datetime.strptime('00:00', '%H:%M').time(), end_time=hours[0].start_time) inverted_hours.append(first) for i in range(1, len(hours)): hour = BookableHours(start_time=hours[i - 1].end_time, end_time=hours[i].start_time) inverted_hours.append(hour) last = BookableHours(start_time=hours[-1].end_time, end_time=datetime.strptime('23:59', '%H:%M').time()) inverted_hours.append(last) inverted_rooms_hours[room_id] = inverted_hours return inverted_rooms_hours
def get_existing_rooms_occurrences(rooms, start_dt, end_dt, repeat_frequency, repeat_interval, allow_overlapping=False, only_accepted=False): room_ids = [room.id for room in rooms] query = (ReservationOccurrence.query .filter(ReservationOccurrence.is_valid, Reservation.room_id.in_(room_ids)) .join(ReservationOccurrence.reservation) .options(ReservationOccurrence.NO_RESERVATION_USER_STRATEGY, contains_eager(ReservationOccurrence.reservation))) if allow_overlapping: query = query.filter(db_dates_overlap(ReservationOccurrence, 'start_dt', start_dt, 'end_dt', end_dt)) else: query = query.filter(ReservationOccurrence.start_dt >= start_dt, ReservationOccurrence.end_dt <= end_dt) if only_accepted: query = query.filter(Reservation.is_accepted) if repeat_frequency != RepeatFrequency.NEVER: candidates = ReservationOccurrence.create_series(start_dt, end_dt, (repeat_frequency, repeat_interval)) dates = [candidate.start_dt for candidate in candidates] query = query.filter(db.cast(ReservationOccurrence.start_dt, db.Date).in_(dates)) return group_list(query, key=lambda obj: obj.reservation.room.id, sort_by=lambda obj: (obj.reservation.room_id, obj.start_dt))
def group_blocked_rooms(blocked_rooms): return group_list(blocked_rooms, key=attrgetter('room_id'))
def group_by_occurrence_date(occurrences, sort_by=None): key = lambda obj: obj.start_dt.date() if sort_by is None: sort_by = key return group_list(occurrences, key=key, sort_by=sort_by)
def group_by_occurrence_date(occurrences, sort_by=None): return group_list(occurrences, key=lambda obj: obj.start_dt.date(), sort_by=sort_by)
def group(cls, entries): """Returns the given entries grouped by its parent""" return sorted(group_list(entries, key=attrgetter('parent'), sort_by=attrgetter('caption')).items())
def group_by_occurrence_date(occurrences): return group_list(occurrences, key=lambda obj: obj.start_dt.date())