コード例 #1
0
ファイル: choices.py プロジェクト: indico/indico
 def unprocess_field_data(cls, versioned_data, unversioned_data):
     data = {}
     arrival_date_from = _to_date(unversioned_data['arrival_date_from'])
     arrival_date_to = _to_date(unversioned_data['arrival_date_to'])
     departure_date_from = _to_date(unversioned_data['departure_date_from'])
     departure_date_to = _to_date(unversioned_data['departure_date_to'])
     data['arrival_dates'] = [(dt.date().isoformat(), format_date(dt))
                              for dt in iterdays(arrival_date_from, arrival_date_to)]
     data['departure_dates'] = [(dt.date().isoformat(), format_date(dt))
                                for dt in iterdays(departure_date_from, departure_date_to)]
     items = deepcopy(versioned_data['choices'])
     for item in items:
         item['caption'] = unversioned_data['captions'][item['id']]
     data['choices'] = items
     return data
コード例 #2
0
 def unprocess_field_data(cls, versioned_data, unversioned_data):
     data = {}
     arrival_date_from = _to_date(unversioned_data['arrival_date_from'])
     arrival_date_to = _to_date(unversioned_data['arrival_date_to'])
     departure_date_from = _to_date(unversioned_data['departure_date_from'])
     departure_date_to = _to_date(unversioned_data['departure_date_to'])
     data['arrival_dates'] = [(dt.date().isoformat(), format_date(dt))
                              for dt in iterdays(arrival_date_from, arrival_date_to)]
     data['departure_dates'] = [(dt.date().isoformat(), format_date(dt))
                                for dt in iterdays(departure_date_from, departure_date_to)]
     items = deepcopy(versioned_data['choices'])
     for item in items:
         item['caption'] = unversioned_data['captions'][item['id']]
     data['choices'] = items
     return data
コード例 #3
0
ファイル: bookings.py プロジェクト: pferreir/indico
def get_room_calendar(start_date, end_date, room_ids, **filters):
    start_dt = datetime.combine(start_date, time(hour=0, minute=0))
    end_dt = datetime.combine(end_date, time(hour=23, minute=59))
    query = _bookings_query(dict(filters, **{'start_date': start_dt, 'end_date': end_dt, 'room_ids': room_ids}))
    query = query.order_by(db.func.indico.natsort(Room.full_name))
    rooms = (Room.query
             .filter(Room.is_active, Room.id.in_(room_ids) if room_ids else True)
             .options(joinedload('location'))
             .order_by(db.func.indico.natsort(Room.full_name))
             .all())

    unbookable_hours = get_rooms_unbookable_hours(rooms)
    nonbookable_periods = get_rooms_nonbookable_periods(rooms, start_dt, end_dt)
    occurrences_by_room = groupby(query, attrgetter('reservation.room_id'))
    blocked_rooms = get_rooms_blockings(rooms, start_dt, end_dt)

    dates = [d.date() for d in iterdays(start_dt, end_dt)]

    calendar = OrderedDict((room.id, {
        'room_id': room.id,
        'nonbookable_periods': group_nonbookable_periods(nonbookable_periods.get(room.id, []), dates),
        'unbookable_hours': unbookable_hours.get(room.id, []),
        'blockings': group_blockings(blocked_rooms.get(room.id, []), dates),
    }) for room in rooms)

    for room_id, occurrences in occurrences_by_room:
        occurrences = list(occurrences)
        pre_bookings = [occ for occ in occurrences if not occ.reservation.is_accepted]
        existing_bookings = [occ for occ in occurrences if occ.reservation.is_accepted]

        calendar[room_id].update({
            'bookings': group_by_occurrence_date(existing_bookings),
            'pre_bookings': group_by_occurrence_date(pre_bookings)
        })
    return calendar
コード例 #4
0
ファイル: api.py プロジェクト: stomanin/indico
 def _calculate_occurrences(self, event, from_dt, to_dt, tz):
     start_dt = max(from_dt, event.start_dt) if from_dt else event.start_dt
     end_dt = min(to_dt, event.end_dt) if to_dt else event.end_dt
     for day in iterdays(start_dt, end_dt):
         first_start, last_end = find_event_day_bounds(event, day.date())
         if first_start is not None:
             yield Period(first_start, last_end)
コード例 #5
0
ファイル: backend.py プロジェクト: jazzi/indico
    def _process(self):
        room_details = room_details_schema.dump(self.room).data
        start_dt = date.today()
        end_dt = start_dt + timedelta(days=4)
        last_bookings = group_by_occurrence_date(
            get_existing_room_occurrences(self.room,
                                          start_dt,
                                          end_dt,
                                          only_accepted=True))
        range_bookings = {
            day.date(): last_bookings.get(day.date())
            for day in iterdays(start_dt, end_dt)
        }
        bookings = [{
            'availability': {
                'usage': bookings or []
            },
            'label': dt,
            'conflictIndicator': False,
            'id': dt
        } for dt, bookings in serialize_occurrences(
            range_bookings).iteritems()]

        room_details['bookings'] = sorted(bookings, key=itemgetter('id'))
        return jsonify(room_details)
コード例 #6
0
ファイル: bookings.py プロジェクト: javfg/indico
def get_room_details_availability(room, start_dt, end_dt):
    dates = [d.date() for d in iterdays(start_dt, end_dt)]

    occurrences = get_existing_room_occurrences(room, start_dt, end_dt, RepeatFrequency.DAY, 1)
    pre_bookings = [occ for occ in occurrences if not occ.reservation.is_accepted]
    bookings = [occ for occ in occurrences if occ.reservation.is_accepted]
    blocked_rooms = get_rooms_blockings([room], start_dt.date(), end_dt.date())
    nonoverridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms,
                                                                            nonoverridable_only=True,
                                                                            explicit=True)).get(room.id, [])
    overridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms,
                                                                         overridable_only=True,
                                                                         explicit=True)).get(room.id, [])
    unbookable_hours = get_rooms_unbookable_hours([room]).get(room.id, [])
    nonbookable_periods = get_rooms_nonbookable_periods([room], start_dt, end_dt).get(room.id, [])

    availability = []
    for day in dates:
        iso_day = day.isoformat()
        nb_periods = serialize_nonbookable_periods(group_nonbookable_periods(nonbookable_periods, dates)).get(iso_day)
        availability.append({
            'bookings': serialize_occurrences(group_by_occurrence_date(bookings)).get(iso_day),
            'pre_bookings': serialize_occurrences(group_by_occurrence_date(pre_bookings)).get(iso_day),
            'blockings': serialize_blockings(group_blockings(nonoverridable_blocked_rooms, dates)).get(iso_day),
            'overridable_blockings': (serialize_blockings(group_blockings(overridable_blocked_rooms, dates))
                                      .get(iso_day)),
            'nonbookable_periods': nb_periods,
            'unbookable_hours': serialize_unbookable_hours(unbookable_hours),
            'day': iso_day,
        })
    return sorted(availability, key=itemgetter('day'))
コード例 #7
0
 def _calculate_occurrences(self, event, from_dt, to_dt, tz):
     start_dt = max(from_dt, event.start_dt) if from_dt else event.start_dt
     end_dt = min(to_dt, event.end_dt) if to_dt else event.end_dt
     for day in iterdays(start_dt, end_dt):
         first_start, last_end = find_event_day_bounds(event, day.date())
         if first_start is not None:
             yield Period(first_start, last_end)
コード例 #8
0
ファイル: legacy.py プロジェクト: belokop/indico_bare
 def serialize_timetable(self, event, days=None, hide_weekends=False, hide_empty_days=False):
     timetable = {}
     for day in iterdays(event.start_dt_local, event.end_dt_local, skip_weekends=hide_weekends, day_whitelist=days):
         date_str = day.strftime('%Y%m%d')
         timetable[date_str] = {}
     contributions_strategy = defaultload('contribution')
     contributions_strategy.subqueryload('person_links')
     contributions_strategy.subqueryload('references')
     query_options = (contributions_strategy,
                      defaultload('session_block').subqueryload('person_links'))
     query = (TimetableEntry.query.with_parent(event)
              .options(*query_options)
              .order_by(TimetableEntry.type != TimetableEntryType.SESSION_BLOCK))
     for entry in query:
         day = entry.start_dt.astimezone(event.tzinfo).date()
         date_str = day.strftime('%Y%m%d')
         if date_str not in timetable:
             continue
         if not entry.can_view(session.user):
             continue
         data = self.serialize_timetable_entry(entry, load_children=False)
         key = self._get_entry_key(entry)
         if entry.parent:
             parent_code = 's{}'.format(entry.parent_id)
             timetable[date_str][parent_code]['entries'][key] = data
         else:
             timetable[date_str][key] = data
     if hide_empty_days:
         timetable = self._filter_empty_days(timetable)
     return timetable
コード例 #9
0
 def serialize_session_timetable(self,
                                 session_,
                                 without_blocks=False,
                                 hide_empty_days=False):
     timetable = {}
     for day in iterdays(session_.event_new.start_dt_local,
                         session_.event_new.end_dt_local):
         timetable[day.strftime('%Y%m%d')] = {}
     for block in session_.blocks:
         block_entry = block.timetable_entry
         if not block_entry:
             continue
         date_key = block_entry.start_dt.astimezone(
             session_.event_new.tzinfo).strftime('%Y%m%d')
         entries = block_entry.children if without_blocks else [block_entry]
         for entry in entries:
             if not entry.can_view(session.user):
                 continue
             entry_key = self._get_entry_key(entry)
             timetable[date_key][
                 entry_key] = self.serialize_timetable_entry(
                     entry, load_children=True)
     if hide_empty_days:
         timetable = self._filter_empty_days(timetable)
     return timetable
コード例 #10
0
ファイル: legacy.py プロジェクト: innovexa/IDC-Events
    def serialize_session_timetable(self, session_, without_blocks=False, strip_empty_days=False):
        event_tz = self.event.tzinfo
        timetable = {}
        if session_.blocks:
            start_dt = min(chain((b.start_dt for b in session_.blocks), (self.event.start_dt,))).astimezone(event_tz)
            end_dt = max(chain((b.end_dt for b in session_.blocks), (self.event.end_dt,))).astimezone(event_tz)
        else:
            start_dt = self.event.start_dt_local
            end_dt = self.event.end_dt_local

        for day in iterdays(start_dt, end_dt):
            timetable[day.strftime('%Y%m%d')] = {}
        for block in session_.blocks:
            block_entry = block.timetable_entry
            if not block_entry:
                continue
            date_key = block_entry.start_dt.astimezone(event_tz).strftime('%Y%m%d')
            entries = block_entry.children if without_blocks else [block_entry]
            for entry in entries:
                if not entry.can_view(self.user):
                    continue
                entry_key = self._get_entry_key(entry)
                timetable[date_key][entry_key] = self.serialize_timetable_entry(entry, load_children=True)
        if strip_empty_days:
            timetable = self._strip_empty_days(timetable)
        return timetable
コード例 #11
0
ファイル: bookings.py プロジェクト: indico/indico
def get_room_details_availability(room, start_dt, end_dt):
    dates = [d.date() for d in iterdays(start_dt, end_dt)]

    occurrences = get_existing_room_occurrences(room, start_dt, end_dt, RepeatFrequency.DAY, 1)
    pre_bookings = [occ for occ in occurrences if not occ.reservation.is_accepted]
    bookings = [occ for occ in occurrences if occ.reservation.is_accepted]
    blocked_rooms = get_rooms_blockings([room], start_dt.date(), end_dt.date())
    nonoverridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms,
                                                                            nonoverridable_only=True,
                                                                            explicit=True)).get(room.id, [])
    overridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms,
                                                                         overridable_only=True,
                                                                         explicit=True)).get(room.id, [])
    unbookable_hours = get_rooms_unbookable_hours([room]).get(room.id, [])
    nonbookable_periods = get_rooms_nonbookable_periods([room], start_dt, end_dt).get(room.id, [])

    availability = []
    for day in dates:
        iso_day = day.isoformat()
        nb_periods = serialize_nonbookable_periods(group_nonbookable_periods(nonbookable_periods, dates)).get(iso_day)
        availability.append({
            'bookings': serialize_occurrences(group_by_occurrence_date(bookings)).get(iso_day),
            'pre_bookings': serialize_occurrences(group_by_occurrence_date(pre_bookings)).get(iso_day),
            'blockings': serialize_blockings(group_blockings(nonoverridable_blocked_rooms, dates)).get(iso_day),
            'overridable_blockings': (serialize_blockings(group_blockings(overridable_blocked_rooms, dates))
                                      .get(iso_day)),
            'nonbookable_periods': nb_periods,
            'unbookable_hours': serialize_unbookable_hours(unbookable_hours),
            'day': iso_day,
        })
    return sorted(availability, key=itemgetter('day'))
コード例 #12
0
    def find_with_filters(filters, avatar=None):
        from indico.modules.rb.models.rooms import Room
        from indico.modules.rb.models.reservations import Reservation

        q = ReservationOccurrence.find(Room.is_active, _join=[Reservation, Room],
                                       _eager=ReservationOccurrence.reservation)

        if 'start_dt' in filters and 'end_dt' in filters:
            start_dt = filters['start_dt']
            end_dt = filters['end_dt']
            criteria = []
            # We have to check the time range for EACH DAY
            for day_start_dt in iterdays(start_dt, end_dt):
                # Same date, but the end time
                day_end_dt = datetime.combine(day_start_dt.date(), end_dt.time())
                criteria.append(db_dates_overlap(ReservationOccurrence, 'start_dt', day_start_dt, 'end_dt', day_end_dt))
            q = q.filter(or_(*criteria))

        if filters.get('is_only_mine') and avatar:
            q = q.filter((Reservation.booked_for_id == avatar.id) | (Reservation.created_by_id == avatar.id))
        if filters.get('room_ids'):
            q = q.filter(Room.id.in_(filters['room_ids']))

        if filters.get('is_only_confirmed_bookings') and not filters.get('is_only_pending_bookings'):
            q = q.filter(Reservation.is_accepted)
        elif not filters.get('is_only_confirmed_bookings') and filters.get('is_only_pending_bookings'):
            q = q.filter(~Reservation.is_accepted)

        if filters.get('is_rejected') and filters.get('is_cancelled'):
            q = q.filter(Reservation.is_rejected | ReservationOccurrence.is_rejected
                         | Reservation.is_cancelled | ReservationOccurrence.is_cancelled)
        else:
            if filters.get('is_rejected'):
                q = q.filter(Reservation.is_rejected | ReservationOccurrence.is_rejected)
            else:
                q = q.filter(~Reservation.is_rejected & ~ReservationOccurrence.is_rejected)
            if filters.get('is_cancelled'):
                q = q.filter(Reservation.is_cancelled | ReservationOccurrence.is_cancelled)
            else:
                q = q.filter(~Reservation.is_cancelled & ~ReservationOccurrence.is_cancelled)

        if filters.get('is_archived'):
            q = q.filter(Reservation.is_archived)

        if filters.get('uses_vc'):
            q = q.filter(Reservation.uses_vc)
        if filters.get('needs_vc_assistance'):
            q = q.filter(Reservation.needs_vc_assistance)
        if filters.get('needs_assistance'):
            q = q.filter(Reservation.needs_assistance)

        if filters.get('booked_for_name'):
            qs = u'%{}%'.format(filters['booked_for_name'])
            q = q.filter(Reservation.booked_for_name.ilike(qs))
        if filters.get('reason'):
            qs = u'%{}%'.format(filters['reason'])
            q = q.filter(Reservation.booking_reason.ilike(qs))

        return q.order_by(Room.id)
コード例 #13
0
ファイル: choices.py プロジェクト: mdoucet/indico
 def unprocess_field_data(cls, versioned_data, unversioned_data):
     data = {}
     arrival_date_from = _to_date(unversioned_data["arrival_date_from"])
     arrival_date_to = _to_date(unversioned_data["arrival_date_to"])
     departure_date_from = _to_date(unversioned_data["departure_date_from"])
     departure_date_to = _to_date(unversioned_data["departure_date_to"])
     data["arrival_dates"] = [
         (dt.date().isoformat(), format_date(dt)) for dt in iterdays(arrival_date_from, arrival_date_to)
     ]
     data["departure_dates"] = [
         (dt.date().isoformat(), format_date(dt)) for dt in iterdays(departure_date_from, departure_date_to)
     ]
     items = deepcopy(versioned_data["choices"])
     for item in items:
         item["caption"] = unversioned_data["captions"][item["id"]]
     data["choices"] = items
     return data
コード例 #14
0
ファイル: bookings.py プロジェクト: vincentroman/indico
def get_room_calendar(start_date, end_date, room_ids):
    start_dt = datetime.combine(start_date, time(hour=0, minute=0))
    end_dt = datetime.combine(end_date, time(hour=23, minute=59))
    reservation_strategy = contains_eager('reservation')
    reservation_strategy.noload('room')
    reservation_strategy.noload('booked_for_user')
    reservation_strategy.noload('created_by_user')
    query = (ReservationOccurrence.query.filter(
        ReservationOccurrence.is_valid).filter(
            ReservationOccurrence.start_dt >= start_dt,
            ReservationOccurrence.end_dt <=
            end_dt).join(Reservation).join(Room).filter(
                Room.is_active,
                Room.id.in_(room_ids) if room_ids else True).order_by(
                    db.func.indico.natsort(
                        Room.full_name)).options(reservation_strategy))

    rooms = (Room.query.filter(
        Room.is_active,
        Room.id.in_(room_ids) if room_ids else True).options(
            joinedload('location')).order_by(
                db.func.indico.natsort(Room.full_name)).all())

    unbookable_hours = get_rooms_unbookable_hours(rooms)
    nonbookable_periods = get_rooms_nonbookable_periods(
        rooms, start_dt, end_dt)
    occurrences_by_room = groupby(query, attrgetter('reservation.room_id'))
    blocked_rooms = get_rooms_blockings(rooms, start_dt, end_dt)

    dates = [d.date() for d in iterdays(start_dt, end_dt)]

    calendar = OrderedDict((room.id, {
        'room_id':
        room.id,
        'nonbookable_periods':
        group_nonbookable_periods(nonbookable_periods.get(room.id, []), dates),
        'unbookable_hours':
        unbookable_hours.get(room.id, []),
        'blockings':
        group_blockings(blocked_rooms.get(room.id, []), dates),
    }) for room in rooms)

    for room_id, occurrences in occurrences_by_room:
        occurrences = list(occurrences)
        pre_bookings = [
            occ for occ in occurrences if not occ.reservation.is_accepted
        ]
        existing_bookings = [
            occ for occ in occurrences if occ.reservation.is_accepted
        ]

        calendar[room_id].update({
            'bookings':
            group_by_occurrence_date(existing_bookings),
            'pre_bookings':
            group_by_occurrence_date(pre_bookings)
        })
    return calendar
コード例 #15
0
 def iter_days(self):
     if self.repeat_frequency is None and self.repeat_interval is None:
         for dt in iterdays(self.start_dt, self.end_dt):
             yield dt.date()
     else:
         for dt in ReservationOccurrence.iter_start_time(self.start_dt, self.end_dt,
                                                         (self.repeat_frequency, self.repeat_interval)):
             for offset in xrange(-self.flexible_days, self.flexible_days + 1):
                 yield (dt + timedelta(days=offset)).date()
コード例 #16
0
ファイル: statistics.py プロジェクト: indico/indico
def calculate_rooms_bookable_time(rooms, start_date=None, end_date=None):
    if end_date is None:
        end_date = date.today() - relativedelta(days=1)
    if start_date is None:
        start_date = end_date - relativedelta(days=29)
    working_time_per_day = sum((datetime.combine(date.today(), end) - datetime.combine(date.today(), start)).seconds
                               for start, end in WORKING_TIME_PERIODS)
    working_days = sum(1 for __ in iterdays(start_date, end_date, skip_weekends=True))
    return working_days * working_time_per_day * len(rooms)
コード例 #17
0
ファイル: calendar.py プロジェクト: MichelCordeiro/indico
 def iter_days(self):
     if self.repeat_frequency is None and self.repeat_interval is None:
         for dt in iterdays(self.start_dt, self.end_dt):
             yield dt.date()
     else:
         for dt in ReservationOccurrence.iter_start_time(self.start_dt, self.end_dt,
                                                         (self.repeat_frequency, self.repeat_interval)):
             for offset in xrange(-self.flexible_days, self.flexible_days + 1):
                 yield (dt + timedelta(days=offset)).date()
コード例 #18
0
ファイル: statistics.py プロジェクト: vireshbackup/indico
def calculate_rooms_bookable_time(rooms, start_date=None, end_date=None):
    if end_date is None:
        end_date = date.today() - relativedelta(days=1)
    if start_date is None:
        start_date = end_date - relativedelta(days=29)
    working_time_per_day = sum((datetime.combine(date.today(), end) - datetime.combine(date.today(), start)).seconds
                               for start, end in Location.working_time_periods)
    working_days = sum(1 for __ in iterdays(start_date, end_date, skip_weekends=True))
    return working_days * working_time_per_day * len(rooms)
コード例 #19
0
ファイル: statistics.py プロジェクト: belokop/indico_bare
def calculate_rooms_bookable_time(rooms, start_date=None, end_date=None):
    if end_date is None:
        end_date = date.today() - relativedelta(days=1)
    if start_date is None:
        start_date = end_date - relativedelta(days=29)
    working_time_start = datetime.combine(date.today(), Location.working_time_start)
    working_time_end = datetime.combine(date.today(), Location.working_time_end)
    working_time_per_day = (working_time_end - working_time_start).seconds
    working_days = sum(1 for __ in iterdays(start_date, end_date, skip_weekends=True))
    return working_days * working_time_per_day * len(rooms)
コード例 #20
0
ファイル: bookings.py プロジェクト: javfg/indico
def get_room_calendar(start_date, end_date, room_ids, include_inactive=False, **filters):
    start_dt = datetime.combine(start_date, time(hour=0, minute=0))
    end_dt = datetime.combine(end_date, time(hour=23, minute=59))
    query = _bookings_query(dict(filters, start_dt=start_dt, end_dt=end_dt, room_ids=room_ids,
                                 include_inactive=include_inactive))
    bookings = query.order_by(db.func.indico.natsort(Room.full_name)).all()
    rooms = set()
    if room_ids:
        rooms = set(Room.query
                    .filter(~Room.is_deleted, Room.id.in_(room_ids))
                    .options(joinedload('location')))

    rooms.update(b.reservation.room for b in bookings)
    rooms = sorted(rooms, key=lambda r: natural_sort_key(r.full_name))
    occurrences_by_room = groupby(bookings, attrgetter('reservation.room_id'))
    unbookable_hours = get_rooms_unbookable_hours(rooms)
    nonbookable_periods = get_rooms_nonbookable_periods(rooms, start_dt, end_dt)
    blocked_rooms = get_rooms_blockings(rooms, start_dt, end_dt)
    nonoverridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms,
                                                                            nonoverridable_only=True,
                                                                            explicit=True))
    overridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms,
                                                                         overridable_only=True,
                                                                         explicit=True))
    dates = [d.date() for d in iterdays(start_dt, end_dt)]

    calendar = {room.id: {
        'room_id': room.id,
        'nonbookable_periods': group_nonbookable_periods(nonbookable_periods.get(room.id, []), dates),
        'unbookable_hours': unbookable_hours.get(room.id, []),
        'blockings': group_blockings(nonoverridable_blocked_rooms.get(room.id, []), dates),
        'overridable_blockings': group_blockings(overridable_blocked_rooms.get(room.id, []), dates),
    } for room in rooms}

    for room_id, occurrences in occurrences_by_room:
        occurrences = list(occurrences)
        pre_bookings = [occ for occ in occurrences if occ.reservation.is_pending]
        existing_bookings = [occ for occ in occurrences if not occ.reservation.is_pending and occ.is_valid]
        concurrent_pre_bookings = get_concurrent_pre_bookings(pre_bookings)

        additional_data = {
            'bookings': group_by_occurrence_date(existing_bookings),
            'pre_bookings': group_by_occurrence_date(pre_bookings),
            'concurrent_pre_bookings': group_by_occurrence_date(concurrent_pre_bookings)
        }

        if include_inactive:
            additional_data.update({
                'cancellations': group_by_occurrence_date(occ for occ in occurrences if occ.is_cancelled),
                'rejections': group_by_occurrence_date(occ for occ in occurrences if occ.is_rejected)
            })

        calendar[room_id].update(additional_data)
    return calendar
コード例 #21
0
ファイル: event.py プロジェクト: pferreir/indico-backup
 def _eventDaysIterator(conf):
     """
     Iterates over the daily times of an event
     """
     sched = conf.getSchedule()
     for day in iterdays(conf.getStartDate(), conf.getEndDate()):
         # ignore days that have no occurrences
         if sched.getEntriesOnDay(day):
             startDT = sched.calculateDayStartDate(day)
             endDT = sched.calculateDayEndDate(day)
             if startDT != endDT:
                 yield Period(startDT, endDT)
コード例 #22
0
def calculate_rooms_bookable_time(rooms, start_date=None, end_date=None):
    if end_date is None:
        end_date = date.today() - relativedelta(days=1)
    if start_date is None:
        start_date = end_date - relativedelta(days=29)
    working_time_start = datetime.combine(date.today(),
                                          Location.working_time_start)
    working_time_end = datetime.combine(date.today(),
                                        Location.working_time_end)
    working_time_per_day = (working_time_end - working_time_start).seconds
    working_days = iterdays(start_date, end_date, skip_weekends=True).count()
    return working_days * working_time_per_day * len(rooms)
コード例 #23
0
ファイル: event.py プロジェクト: NIIF/indico
 def _eventDaysIterator(conf):
     """
     Iterates over the daily times of an event
     """
     sched = conf.getSchedule()
     for day in iterdays(conf.getStartDate(), conf.getEndDate()):
         # ignore days that have no occurrences
         if sched.getEntriesOnDay(day):
             startDT = sched.calculateDayStartDate(day)
             endDT = sched.calculateDayEndDate(day)
             if startDT != endDT:
                 yield Period(startDT, endDT)
コード例 #24
0
ファイル: bookings.py プロジェクト: indico/indico
def get_room_calendar(start_date, end_date, room_ids, include_inactive=False, **filters):
    start_dt = datetime.combine(start_date, time(hour=0, minute=0))
    end_dt = datetime.combine(end_date, time(hour=23, minute=59))
    query = _bookings_query(dict(filters, start_dt=start_dt, end_dt=end_dt, room_ids=room_ids,
                                 include_inactive=include_inactive))
    query = query.order_by(db.func.indico.natsort(Room.full_name))
    rooms = (Room.query
             .filter(~Room.is_deleted, Room.id.in_(room_ids) if room_ids else True)
             .options(joinedload('location'))
             .order_by(db.func.indico.natsort(Room.full_name))
             .all())

    unbookable_hours = get_rooms_unbookable_hours(rooms)
    nonbookable_periods = get_rooms_nonbookable_periods(rooms, start_dt, end_dt)
    occurrences_by_room = groupby(query, attrgetter('reservation.room_id'))
    blocked_rooms = get_rooms_blockings(rooms, start_dt, end_dt)
    nonoverridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms,
                                                                            nonoverridable_only=True,
                                                                            explicit=True))
    overridable_blocked_rooms = group_blocked_rooms(filter_blocked_rooms(blocked_rooms,
                                                                         overridable_only=True,
                                                                         explicit=True))
    dates = [d.date() for d in iterdays(start_dt, end_dt)]

    calendar = OrderedDict((room.id, {
        'room_id': room.id,
        'nonbookable_periods': group_nonbookable_periods(nonbookable_periods.get(room.id, []), dates),
        'unbookable_hours': unbookable_hours.get(room.id, []),
        'blockings': group_blockings(nonoverridable_blocked_rooms.get(room.id, []), dates),
        'overridable_blockings': group_blockings(overridable_blocked_rooms.get(room.id, []), dates),
    }) for room in rooms)

    for room_id, occurrences in occurrences_by_room:
        occurrences = list(occurrences)
        pre_bookings = [occ for occ in occurrences if occ.reservation.is_pending]
        existing_bookings = [occ for occ in occurrences if not occ.reservation.is_pending and occ.is_valid]

        additional_data = {
            'bookings': group_by_occurrence_date(existing_bookings),
            'pre_bookings': group_by_occurrence_date(pre_bookings)
        }

        if include_inactive:
            additional_data.update({
                'cancellations': group_by_occurrence_date(occ for occ in occurrences if occ.is_cancelled),
                'rejections': group_by_occurrence_date(occ for occ in occurrences if occ.is_rejected)
            })

        calendar[room_id].update(additional_data)
    return calendar
コード例 #25
0
ファイル: bookings.py プロジェクト: jas01/indico
def get_room_calendar(day, room_ids):
    start_dt = datetime.combine(day, time(hour=0, minute=0))
    end_dt = datetime.combine(day, time(hour=23, minute=59))
    reservation_strategy = contains_eager('reservation')
    reservation_strategy.noload('room')
    reservation_strategy.noload('booked_for_user')
    reservation_strategy.noload('created_by_user')
    query = (ReservationOccurrence.query
             .filter(ReservationOccurrence.is_valid)
             .filter(ReservationOccurrence.start_dt >= start_dt, ReservationOccurrence.end_dt <= end_dt)
             .join(Reservation)
             .join(Room)
             .filter(Room.is_active, Room.id.in_(room_ids) if room_ids else True)
             .order_by(db.func.indico.natsort(Room.full_name))
             .options(reservation_strategy))

    rooms = (Room.query
             .filter(Room.is_active, Room.id.in_(room_ids) if room_ids else True)
             .options(joinedload('location'))
             .order_by(db.func.indico.natsort(Room.full_name))
             .all())

    unbookable_hours = get_rooms_unbookable_hours(rooms)
    nonbookable_periods = get_rooms_nonbookable_periods(rooms, start_dt, end_dt)
    occurrences_by_room = groupby(query, attrgetter('reservation.room_id'))
    blocked_rooms = get_rooms_blockings(rooms, start_dt, end_dt)

    dates = [d.date() for d in iterdays(start_dt, end_dt)]

    calendar = OrderedDict((room.id, {
        'room_id': room.id,
        'nonbookable_periods': group_nonbookable_periods(nonbookable_periods.get(room.id, []), dates),
        'unbookable_hours': unbookable_hours.get(room.id, []),
        'blockings': group_blockings(blocked_rooms.get(room.id, []), dates),
    }) for room in rooms)

    for room_id, occurrences in occurrences_by_room:
        occurrences = list(occurrences)
        pre_bookings = [occ for occ in occurrences if not occ.reservation.is_accepted]
        existing_bookings = [occ for occ in occurrences if occ.reservation.is_accepted]

        calendar[room_id].update({
            'bookings': group_by_occurrence_date(existing_bookings),
            'pre_bookings': group_by_occurrence_date(pre_bookings)
        })
    return calendar
コード例 #26
0
 def serialize_timetable(self,
                         event,
                         days=None,
                         hide_weekends=False,
                         strip_empty_days=False):
     tzinfo = event.tzinfo if self.management else event.display_tzinfo
     event.preload_all_acl_entries()
     timetable = {}
     for day in iterdays(event.start_dt.astimezone(tzinfo),
                         event.end_dt.astimezone(tzinfo),
                         skip_weekends=hide_weekends,
                         day_whitelist=days):
         date_str = day.strftime('%Y%m%d')
         timetable[date_str] = {}
     contributions_strategy = defaultload('contribution')
     contributions_strategy.subqueryload('person_links')
     contributions_strategy.subqueryload('references')
     query_options = (
         contributions_strategy,
         defaultload('session_block').subqueryload('person_links'))
     query = (TimetableEntry.query.with_parent(event).options(
         *query_options).order_by(
             TimetableEntry.type != TimetableEntryType.SESSION_BLOCK))
     for entry in query:
         day = entry.start_dt.astimezone(tzinfo).date()
         date_str = day.strftime('%Y%m%d')
         if date_str not in timetable:
             continue
         if not entry.can_view(session.user):
             continue
         data = self.serialize_timetable_entry(entry, load_children=False)
         key = self._get_entry_key(entry)
         if entry.parent:
             parent_code = 's{}'.format(entry.parent_id)
             timetable[date_str][parent_code]['entries'][key] = data
         else:
             if (entry.type == TimetableEntryType.SESSION_BLOCK
                     and entry.start_dt.astimezone(tzinfo).date() !=
                     entry.end_dt.astimezone(tzinfo).date()):
                 # If a session block lasts into another day we need to add it to that day, too
                 timetable[entry.end_dt.astimezone(tzinfo).date().strftime(
                     '%Y%m%d')][key] = data
             timetable[date_str][key] = data
     if strip_empty_days:
         timetable = self._strip_empty_days(timetable)
     return timetable
コード例 #27
0
ファイル: legacy.py プロジェクト: belokop/indico_bare
 def serialize_session_timetable(self, session_, without_blocks=False, hide_empty_days=False):
     timetable = {}
     for day in iterdays(session_.event_new.start_dt_local, session_.event_new.end_dt_local):
         timetable[day.strftime('%Y%m%d')] = {}
     for block in session_.blocks:
         block_entry = block.timetable_entry
         if not block_entry:
             continue
         date_key = block_entry.start_dt.astimezone(session_.event_new.tzinfo).strftime('%Y%m%d')
         entries = block_entry.children if without_blocks else [block_entry]
         for entry in entries:
             if not entry.can_view(session.user):
                 continue
             entry_key = self._get_entry_key(entry)
             timetable[date_key][entry_key] = self.serialize_timetable_entry(entry, load_children=True)
     if hide_empty_days:
         timetable = self._filter_empty_days(timetable)
     return timetable
コード例 #28
0
    def index_booking(self, bk):
        conf = bk.getConference()
        contribs = bk.getTalkSelectionList()
        choose = bk.isChooseTalkSelected()

        # if contributions chosen individually
        if choose and contribs:
            for contrib_id in contribs:
                # check that contrib is in valid room
                if CollaborationTools.isAbleToBeWebcastOrRecorded(conf.getContributionById(contrib_id), bk.getType()):
                    self.index_obj(CSBookingInstanceWrapper(bk, conf.getContributionById(contrib_id)))
        # We need to check if it is a lecture with a correct room
        elif CollaborationTools.isAbleToBeWebcastOrRecorded(conf, bk.getType()) or conf.getType() !="simple_event":
            for day in iterdays(conf.getStartDate(), conf.getEndDate()):
                bkw = CSBookingInstanceWrapper(bk, conf,
                                               day.replace(hour=0, minute=0, second=0),
                                               day.replace(hour=23, minute=59, second=59))
                self.index_obj(bkw)
コード例 #29
0
def get_room_details_availability(room, start_dt, end_dt):
    dates = [d.date() for d in iterdays(start_dt, end_dt)]

    bookings = get_existing_room_occurrences(room, start_dt, end_dt, RepeatFrequency.DAY, 1, only_accepted=True)
    blockings = get_rooms_blockings([room], start_dt.date(), end_dt.date()).get(room.id, [])
    unbookable_hours = get_rooms_unbookable_hours([room]).get(room.id, [])
    nonbookable_periods = get_rooms_nonbookable_periods([room], start_dt, end_dt).get(room.id, [])

    availability = []
    for day in dates:
        iso_day = day.isoformat()
        availability.append({
            'bookings': serialize_occurrences(group_by_occurrence_date(bookings)).get(iso_day),
            'blockings': serialize_blockings(group_blockings(blockings, dates)).get(iso_day),
            'nonbookable_periods': serialize_nonbookable_periods(
                group_nonbookable_periods(nonbookable_periods, dates)).get(iso_day),
            'unbookable_hours': serialize_unbookable_hours(unbookable_hours),
            'day': iso_day,
        })
    return sorted(availability, key=itemgetter('day'))
コード例 #30
0
ファイル: bookings.py プロジェクト: pferreir/indico
def get_room_details_availability(room, start_dt, end_dt):
    dates = [d.date() for d in iterdays(start_dt, end_dt)]

    bookings = get_existing_room_occurrences(room, start_dt, end_dt, RepeatFrequency.DAY, 1, only_accepted=True)
    blockings = get_rooms_blockings([room], start_dt.date(), end_dt.date()).get(room.id, [])
    unbookable_hours = get_rooms_unbookable_hours([room]).get(room.id, [])
    nonbookable_periods = get_rooms_nonbookable_periods([room], start_dt, end_dt).get(room.id, [])

    availability = []
    for day in dates:
        iso_day = day.isoformat()
        nb_periods = serialize_nonbookable_periods(group_nonbookable_periods(nonbookable_periods, dates)).get(iso_day)
        availability.append({
            'bookings': serialize_occurrences(group_by_occurrence_date(bookings)).get(iso_day),
            'blockings': serialize_blockings(group_blockings(blockings, dates)).get(iso_day),
            'nonbookable_periods': nb_periods,
            'unbookable_hours': serialize_unbookable_hours(unbookable_hours),
            'day': iso_day,
        })
    return sorted(availability, key=itemgetter('day'))
コード例 #31
0
 def serialize_timetable(self,
                         event,
                         days=None,
                         hide_weekends=False,
                         hide_empty_days=False):
     timetable = {}
     for day in iterdays(event.start_dt_local,
                         event.end_dt_local,
                         skip_weekends=hide_weekends,
                         day_whitelist=days):
         date_str = day.strftime('%Y%m%d')
         timetable[date_str] = {}
     contributions_strategy = defaultload('contribution')
     contributions_strategy.subqueryload('person_links')
     contributions_strategy.subqueryload('references')
     query_options = (
         contributions_strategy,
         defaultload('session_block').subqueryload('person_links'))
     query = (TimetableEntry.query.with_parent(event).options(
         *query_options).order_by(
             TimetableEntry.type != TimetableEntryType.SESSION_BLOCK))
     for entry in query:
         day = entry.start_dt.astimezone(event.tzinfo).date()
         date_str = day.strftime('%Y%m%d')
         if date_str not in timetable:
             continue
         if not entry.can_view(session.user):
             continue
         data = self.serialize_timetable_entry(entry, load_children=False)
         key = self._get_entry_key(entry)
         if entry.parent:
             parent_code = 's{}'.format(entry.parent_id)
             timetable[date_str][parent_code]['entries'][key] = data
         else:
             timetable[date_str][key] = data
     if hide_empty_days:
         timetable = self._filter_empty_days(timetable)
     return timetable
コード例 #32
0
ファイル: legacy.py プロジェクト: bkolobara/indico
 def serialize_timetable(self, days=None, hide_weekends=False, strip_empty_days=False):
     tzinfo = self.event.tzinfo if self.management else self.event.display_tzinfo
     self.event.preload_all_acl_entries()
     timetable = {}
     for day in iterdays(self.event.start_dt.astimezone(tzinfo), self.event.end_dt.astimezone(tzinfo),
                         skip_weekends=hide_weekends, day_whitelist=days):
         date_str = day.strftime('%Y%m%d')
         timetable[date_str] = {}
     contributions_strategy = defaultload('contribution')
     contributions_strategy.subqueryload('person_links')
     contributions_strategy.subqueryload('references')
     query_options = (contributions_strategy,
                      defaultload('session_block').subqueryload('person_links'))
     query = (TimetableEntry.query.with_parent(self.event)
              .options(*query_options)
              .order_by(TimetableEntry.type != TimetableEntryType.SESSION_BLOCK))
     for entry in query:
         day = entry.start_dt.astimezone(tzinfo).date()
         date_str = day.strftime('%Y%m%d')
         if date_str not in timetable:
             continue
         if not entry.can_view(self.user):
             continue
         data = self.serialize_timetable_entry(entry, load_children=False)
         key = self._get_entry_key(entry)
         if entry.parent:
             parent_code = 's{}'.format(entry.parent_id)
             timetable[date_str][parent_code]['entries'][key] = data
         else:
             if (entry.type == TimetableEntryType.SESSION_BLOCK and
                     entry.start_dt.astimezone(tzinfo).date() != entry.end_dt.astimezone(tzinfo).date()):
                 # If a session block lasts into another day we need to add it to that day, too
                 timetable[entry.end_dt.astimezone(tzinfo).date().strftime('%Y%m%d')][key] = data
             timetable[date_str][key] = data
     if strip_empty_days:
         timetable = self._strip_empty_days(timetable)
     return timetable
コード例 #33
0
ファイル: date_time_test.py プロジェクト: bkolobara/indico
def test_iterdays(from_, to, skip_weekends, day_whitelist, day_blacklist, expected):
    assert len(list(iterdays(from_, to, skip_weekends, day_whitelist, day_blacklist))) == expected
コード例 #34
0
    def find_with_filters(cls, filters, user=None):
        from indico.modules.rb.models.rooms import Room
        from indico.modules.rb.models.reservations import Reservation

        q = (ReservationOccurrence.find(
            Room.is_active,
            _join=[ReservationOccurrence.reservation, Room],
            _eager=ReservationOccurrence.reservation).options(
                cls.NO_RESERVATION_USER_STRATEGY))

        if 'start_dt' in filters and 'end_dt' in filters:
            start_dt = filters['start_dt']
            end_dt = filters['end_dt']
            criteria = []
            # We have to check the time range for EACH DAY
            for day_start_dt in iterdays(start_dt, end_dt):
                # Same date, but the end time
                day_end_dt = datetime.combine(day_start_dt.date(),
                                              end_dt.time())
                criteria.append(
                    db_dates_overlap(ReservationOccurrence, 'start_dt',
                                     day_start_dt, 'end_dt', day_end_dt))
            q = q.filter(or_(*criteria))

        if filters.get('is_only_mine') and user:
            q = q.filter((Reservation.booked_for_id == user.id)
                         | (Reservation.created_by_id == user.id))
        if filters.get('room_ids'):
            q = q.filter(Room.id.in_(filters['room_ids']))

        if filters.get('is_only_confirmed_bookings'
                       ) and not filters.get('is_only_pending_bookings'):
            q = q.filter(Reservation.is_accepted)
        elif not filters.get('is_only_confirmed_bookings') and filters.get(
                'is_only_pending_bookings'):
            q = q.filter(~Reservation.is_accepted)

        if filters.get('is_rejected') and filters.get('is_cancelled'):
            q = q.filter(Reservation.is_rejected
                         | ReservationOccurrence.is_rejected
                         | Reservation.is_cancelled
                         | ReservationOccurrence.is_cancelled)
        else:
            if filters.get('is_rejected'):
                q = q.filter(Reservation.is_rejected
                             | ReservationOccurrence.is_rejected)
            else:
                q = q.filter(~Reservation.is_rejected
                             & ~ReservationOccurrence.is_rejected)
            if filters.get('is_cancelled'):
                q = q.filter(Reservation.is_cancelled
                             | ReservationOccurrence.is_cancelled)
            else:
                q = q.filter(~Reservation.is_cancelled
                             & ~ReservationOccurrence.is_cancelled)

        if filters.get('is_archived'):
            q = q.filter(Reservation.is_archived)

        if filters.get('uses_vc'):
            q = q.filter(Reservation.uses_vc)
        if filters.get('needs_vc_assistance'):
            q = q.filter(Reservation.needs_vc_assistance)
        if filters.get('needs_assistance'):
            q = q.filter(Reservation.needs_assistance)

        if filters.get('booked_for_name'):
            qs = u'%{}%'.format(filters['booked_for_name'])
            q = q.filter(Reservation.booked_for_name.ilike(qs))
        if filters.get('reason'):
            qs = u'%{}%'.format(filters['reason'])
            q = q.filter(Reservation.booking_reason.ilike(qs))

        return q.order_by(Room.id)
コード例 #35
0
 def _get_session_timetable_entries(self):
     entries = {}
     for day in iterdays(self.event_new.start_dt, self.event_new.end_dt):
         entries[day.date()] = get_session_block_entries(
             self.event_new, day)
     return entries
コード例 #36
0
ファイル: date_time_test.py プロジェクト: imfht/flaskapps
def test_iterdays(from_, to, skip_weekends, day_whitelist, day_blacklist, expected):
    assert len(list(iterdays(from_, to, skip_weekends, day_whitelist, day_blacklist))) == expected
コード例 #37
0
ファイル: legacy.py プロジェクト: belokop/indico_bare
 def _get_session_timetable_entries(self):
     entries = {}
     for day in iterdays(self.event_new.start_dt, self.event_new.end_dt):
         entries[day.date()] = get_session_block_entries(self.event_new, day)
     return entries
コード例 #38
0
ファイル: weeks.py プロジェクト: javfg/indico
def inject_week_timetable(event,
                          days,
                          tz_name,
                          tpl='events/timetable/display/_weeks.html'):
    first_week_day = layout_settings.get(
        event, 'timetable_theme_settings').get('start_day')
    sunday_first = (first_week_day == 'sunday')
    show_end_times = request.args.get('showEndTimes') == '1'

    tz = timezone(tz_name)

    day_dict = defaultdict(list, days)
    sorted_dates = [
        d.date() for d in iterdays(event.start_dt.astimezone(tz),
                                   event.end_dt.astimezone(tz))
    ]
    first_day, last_day = sorted_dates[0], sorted_dates[-1]
    has_weekends = any(d.weekday() in (5, 6) for d in sorted_dates)

    # Calculate the actual starting day, based on the selected first day of the week
    if first_week_day != 'event':
        week_start = 6 if sunday_first else 0
        if first_day.weekday() != week_start:
            first_day -= timedelta(days=first_day.weekday()) + timedelta(
                days=int(has_weekends and sunday_first))
    week_table_shallow = []
    skipped_days = 0
    for i, dt in enumerate(iterdays(first_day, last_day)):
        day = dt.date()
        if day > last_day:
            # the loop doesn't account for skipped days so we might have to break early
            break
        if not has_weekends and day.weekday() == 5:
            day += timedelta(days=2)
            skipped_days += 2
        if i % (7 if has_weekends else 5) == 0:
            week_table_shallow.append([])
        week_table_shallow[-1].append((day, day_dict[day]))

    # build a new week table that contains placeholders
    week_table = []
    for week in week_table_shallow:
        # Build list of time slots that are used this week
        time_slots = set()
        for day, entries in week:
            time_slots.update(_localized_time(x.start_dt, tz) for x in entries)

        # Build each day with its contributions and placeholders
        tmp = []
        for day, entries in week:
            day_tmp = defaultdict(list)
            for entry in entries:
                day_tmp[_localized_time(entry.start_dt, tz)].append(entry)

            for slot in sorted(time_slots):
                day_tmp.setdefault(slot, [])

            # We've got a dict with a {slot: [entry, entry, ...]} mapping (for a single day)
            # We'll run over it and make some additional calculations
            day_tmp_sorted = sorted(day_tmp.items())
            day_entries = {}
            for n, (slot, slot_entries) in enumerate(day_tmp_sorted):
                tmp_slot_entries = []
                for entry in slot_entries:
                    # Check how many empty slots which intersect this one exist
                    count = sum(1 for x in takewhile(
                        lambda x: not x[1], iter(day_tmp_sorted[n + 1:]))
                                if x[0] < _localized_time(entry.end_dt, tz))
                    tmp_slot_entries.append((entry, count))
                day_entries[slot] = tmp_slot_entries
            tmp.append((day, day_entries))
        week_table.append(tmp)

    timetable_settings = layout_settings.get(event, 'timetable_theme_settings')
    return render_template(tpl,
                           event=event,
                           week_table=week_table,
                           timetable_settings=timetable_settings,
                           has_weekends=has_weekends,
                           timezone=tz_name,
                           tz_object=tz,
                           show_end_times=show_end_times)
コード例 #39
0
ファイル: weeks.py プロジェクト: indico/indico
def inject_week_timetable(event, days, tz_name, tpl='events/timetable/display/_weeks.html'):
    first_week_day = layout_settings.get(event, 'timetable_theme_settings').get('start_day')
    sunday_first = (first_week_day == 'sunday')
    show_end_times = request.args.get('showEndTimes') == '1'

    tz = timezone(tz_name)

    day_dict = defaultdict(list, days)
    sorted_dates = [d.date() for d in iterdays(event.start_dt.astimezone(tz), event.end_dt.astimezone(tz))]
    first_day, last_day = sorted_dates[0], sorted_dates[-1]
    has_weekends = any(d.weekday() in (5, 6) for d in sorted_dates)

    # Calculate the actual starting day, based on the selected first day of the week
    if first_week_day != 'event':
        week_start = 6 if sunday_first else 0
        if first_day.weekday() != week_start:
            first_day -= timedelta(days=first_day.weekday()) + timedelta(days=int(has_weekends and sunday_first))
    week_table_shallow = []
    skipped_days = 0
    for i, dt in enumerate(iterdays(first_day, last_day)):
        day = dt.date()
        if day > last_day:
            # the loop doesn't account for skipped days so we might have to break early
            break
        if not has_weekends and day.weekday() == 5:
            day += timedelta(days=2)
            skipped_days += 2
        if i % (7 if has_weekends else 5) == 0:
            week_table_shallow.append([])
        week_table_shallow[-1].append((day, day_dict[day]))

    # build a new week table that contains placeholders
    week_table = []
    for week in week_table_shallow:
        # Build list of time slots that are used this week
        time_slots = set()
        for day, entries in week:
            time_slots.update(_localized_time(x.start_dt, tz) for x in entries)

        # Build each day with its contributions and placeholders
        tmp = []
        for day, entries in week:
            day_tmp = defaultdict(list)
            for entry in entries:
                day_tmp[_localized_time(entry.start_dt, tz)].append(entry)

            for slot in sorted(time_slots):
                day_tmp.setdefault(slot, [])

            # We've got a dict with a {slot: [entry, entry, ...]} mapping (for a single day)
            # We'll run over it and make some additional calculations
            day_tmp_sorted = sorted(day_tmp.viewitems())
            day_entries = OrderedDict()
            for n, (slot, slot_entries) in enumerate(day_tmp_sorted):
                tmp_slot_entries = []
                for entry in slot_entries:
                    # Check how many empty slots which intersect this one exist
                    count = sum(1 for x in takewhile(lambda x: not x[1], iter(day_tmp_sorted[n + 1:]))
                                if x[0] < _localized_time(entry.end_dt, tz))
                    tmp_slot_entries.append((entry, count))
                day_entries[slot] = tmp_slot_entries
            tmp.append((day, day_entries))
        week_table.append(tmp)

    timetable_settings = layout_settings.get(event, 'timetable_theme_settings')
    return render_template(tpl, event=event, week_table=week_table, timetable_settings=timetable_settings,
                           has_weekends=has_weekends, timezone=tz_name, tz_object=tz, show_end_times=show_end_times)
コード例 #40
0
ファイル: bookings.py プロジェクト: prostokak/indico
def get_room_calendar(start_date,
                      end_date,
                      room_ids,
                      include_inactive=False,
                      **filters):
    start_dt = datetime.combine(start_date, time(hour=0, minute=0))
    end_dt = datetime.combine(end_date, time(hour=23, minute=59))
    query = _bookings_query(
        dict(filters,
             start_dt=start_dt,
             end_dt=end_dt,
             room_ids=room_ids,
             include_inactive=include_inactive))
    query = query.order_by(db.func.indico.natsort(Room.full_name))
    rooms = (Room.query.filter(
        Room.is_active,
        Room.id.in_(room_ids) if room_ids else True).options(
            joinedload('location')).order_by(
                db.func.indico.natsort(Room.full_name)).all())

    unbookable_hours = get_rooms_unbookable_hours(rooms)
    nonbookable_periods = get_rooms_nonbookable_periods(
        rooms, start_dt, end_dt)
    occurrences_by_room = groupby(query, attrgetter('reservation.room_id'))
    blocked_rooms = get_rooms_blockings(rooms, start_dt, end_dt)

    dates = [d.date() for d in iterdays(start_dt, end_dt)]

    calendar = OrderedDict((room.id, {
        'room_id':
        room.id,
        'nonbookable_periods':
        group_nonbookable_periods(nonbookable_periods.get(room.id, []), dates),
        'unbookable_hours':
        unbookable_hours.get(room.id, []),
        'blockings':
        group_blockings(blocked_rooms.get(room.id, []), dates),
    }) for room in rooms)

    for room_id, occurrences in occurrences_by_room:
        occurrences = list(occurrences)
        pre_bookings = [
            occ for occ in occurrences if occ.reservation.is_pending
        ]
        existing_bookings = [
            occ for occ in occurrences
            if not occ.reservation.is_pending and occ.is_valid
        ]

        additional_data = {
            'bookings': group_by_occurrence_date(existing_bookings),
            'pre_bookings': group_by_occurrence_date(pre_bookings)
        }

        if include_inactive:
            additional_data.update({
                'cancellations':
                group_by_occurrence_date(occ for occ in occurrences
                                         if occ.is_cancelled),
                'rejections':
                group_by_occurrence_date(occ for occ in occurrences
                                         if occ.is_rejected)
            })

        calendar[room_id].update(additional_data)
    return calendar
コード例 #41
0
ファイル: util.py プロジェクト: vireshbackup/indico
def get_category_timetable(categ_ids, start_dt, end_dt, detail_level='event', tz=utc, from_categ=None, grouped=True):
    """Retrieve time blocks that fall within a specific time interval
       for a given set of categories.

       :param categ_ids: iterable containing list of category IDs
       :param start_dt: start of search interval (``datetime``, expected
                        to be in display timezone)
       :param end_dt: end of search interval (``datetime`` in expected
                      to be in display timezone)
       :param detail_level: the level of detail of information
                            (``event|session|contribution``)
       :param tz: the ``timezone`` information should be displayed in
       :param from_categ: ``Category`` that will be taken into account to calculate
                          visibility
       :param grouped: Whether to group results by start date
       :returns: a dictionary containing timetable information in a
                 structured way. See source code for examples.
    """
    day_start = start_dt.astimezone(utc)
    day_end = end_dt.astimezone(utc)
    dates_overlap = lambda t: (t.start_dt >= day_start) & (t.start_dt <= day_end)

    items = defaultdict(lambda: defaultdict(list))

    # first of all, query TimetableEntries/events that fall within
    # specified range of dates (and category set)
    events = _query_events(categ_ids, day_start, day_end)
    if from_categ:
        events = events.filter(Event.is_visible_in(from_categ))
    for eid, tt_start_dt in events:
        if tt_start_dt:
            items[eid][tt_start_dt.astimezone(tz).date()].append(tt_start_dt)
        else:
            items[eid] = None

    # then, retrieve detailed information about the events
    event_ids = set(items)
    query = (Event.find(Event.id.in_(event_ids))
             .options(subqueryload(Event.person_links).joinedload(EventPersonLink.person),
                      joinedload(Event.own_room).noload('owner'),
                      joinedload(Event.own_venue),
                      joinedload(Event.category).undefer('effective_icon_data'),
                      undefer('effective_protection_mode')))
    scheduled_events = defaultdict(list)
    ongoing_events = []
    events = []
    for e in query:
        if grouped:
            local_start_dt = e.start_dt.astimezone(tz).date()
            local_end_dt = e.end_dt.astimezone(tz).date()
            if items[e.id] is None:
                # if there is no TimetableEntry, this means the event has not timetable on that interval
                for day in iterdays(max(start_dt.date(), local_start_dt), min(end_dt.date(), local_end_dt)):
                    # if the event starts on this date, we've got a time slot
                    if day.date() == local_start_dt:
                        scheduled_events[day.date()].append((e.start_dt, e))
                    else:
                        ongoing_events.append(e)
            else:
                for start_d, start_dts in items[e.id].viewitems():
                    scheduled_events[start_d].append((start_dts[0], e))
        else:
            events.append(e)

    # result['events'][date(...)] -> [(datetime(....), Event(...))]
    # result[event_id]['contribs'][date(...)] -> [(TimetableEntry(...), Contribution(...))]
    # result['ongoing_events'] = [Event(...)]
    if grouped:
        result = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
    else:
        result = defaultdict(lambda: defaultdict(list))

    result.update({
        'events': scheduled_events if grouped else events,
        'ongoing_events': ongoing_events
    })

    # according to detail level, ask for extra information from the DB
    if detail_level != 'event':
        query = _query_blocks(event_ids, dates_overlap, detail_level)
        if grouped:
            for b in query:
                start_date = b.timetable_entry.start_dt.astimezone(tz).date()
                result[b.session.event_id]['blocks'][start_date].append((b.timetable_entry, b))
        else:
            for b in query:
                result[b.session.event_id]['blocks'].append(b)

    if detail_level == 'contribution':
        query = (Contribution.find(Contribution.event_id.in_(event_ids),
                                   dates_overlap(TimetableEntry),
                                   ~Contribution.is_deleted)
                 .options(contains_eager(Contribution.timetable_entry),
                          joinedload(Contribution.person_links))
                 .join(TimetableEntry))
        if grouped:
            for c in query:
                start_date = c.timetable_entry.start_dt.astimezone(tz).date()
                result[c.event_id]['contribs'][start_date].append((c.timetable_entry, c))
        else:
            for c in query:
                result[c.event_id]['contributions'].append(c)

        query = (Break.find(TimetableEntry.event_id.in_(event_ids), dates_overlap(TimetableEntry))
                 .options(contains_eager(Break.timetable_entry))
                 .join(TimetableEntry))
        if grouped:
            for b in query:
                start_date = b.timetable_entry.start_dt.astimezone(tz).date()
                result[b.timetable_entry.event_id]['breaks'][start_date].append((b.timetable_entry, b))
        else:
            for b in query:
                result[b.timetable_entry.event_id]['breaks'].append(b)
    return result
コード例 #42
0
ファイル: util.py プロジェクト: OmeGak/indico
def get_category_timetable(categ_ids, start_dt, end_dt, detail_level='event', tz=utc, from_categ=None, grouped=True):
    """Retrieve time blocks that fall within a specific time interval
       for a given set of categories.

       :param categ_ids: iterable containing list of category IDs
       :param start_dt: start of search interval (``datetime``, expected
                        to be in display timezone)
       :param end_dt: end of search interval (``datetime`` in expected
                      to be in display timezone)
       :param detail_level: the level of detail of information
                            (``event|session|contribution``)
       :param tz: the ``timezone`` information should be displayed in
       :param from_categ: ``Category`` that will be taken into account to calculate
                          visibility
       :param grouped: Whether to group results by start date
       :returns: a dictionary containing timetable information in a
                 structured way. See source code for examples.
    """
    day_start = start_dt.astimezone(utc)
    day_end = end_dt.astimezone(utc)
    dates_overlap = lambda t: (t.start_dt >= day_start) & (t.start_dt <= day_end)

    items = defaultdict(lambda: defaultdict(list))

    # first of all, query TimetableEntries/events that fall within
    # specified range of dates (and category set)
    events = _query_events(categ_ids, day_start, day_end)
    if from_categ:
        events = events.filter(Event.is_visible_in(from_categ))
    for eid, tt_start_dt in events:
        if tt_start_dt:
            items[eid][tt_start_dt.astimezone(tz).date()].append(tt_start_dt)
        else:
            items[eid] = None

    # then, retrieve detailed information about the events
    event_ids = set(items)
    query = (Event.find(Event.id.in_(event_ids))
             .options(subqueryload(Event.person_links).joinedload(EventPersonLink.person),
                      joinedload(Event.own_room).noload('owner'),
                      joinedload(Event.own_venue),
                      joinedload(Event.category).undefer('effective_icon_data'),
                      undefer('effective_protection_mode')))
    scheduled_events = defaultdict(list)
    ongoing_events = []
    events = []
    for e in query:
        if grouped:
            local_start_dt = e.start_dt.astimezone(tz).date()
            local_end_dt = e.end_dt.astimezone(tz).date()
            if items[e.id] is None:
                # if there is no TimetableEntry, this means the event has not timetable on that interval
                for day in iterdays(max(start_dt.date(), local_start_dt), min(end_dt.date(), local_end_dt)):
                    # if the event starts on this date, we've got a time slot
                    if day.date() == local_start_dt:
                        scheduled_events[day.date()].append((e.start_dt, e))
                    else:
                        ongoing_events.append(e)
            else:
                for start_d, start_dts in items[e.id].viewitems():
                    scheduled_events[start_d].append((start_dts[0], e))
        else:
            events.append(e)

    # result['events'][date(...)] -> [(datetime(....), Event(...))]
    # result[event_id]['contribs'][date(...)] -> [(TimetableEntry(...), Contribution(...))]
    # result['ongoing_events'] = [Event(...)]
    if grouped:
        result = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
    else:
        result = defaultdict(lambda: defaultdict(list))

    result.update({
        'events': scheduled_events if grouped else events,
        'ongoing_events': ongoing_events
    })

    # according to detail level, ask for extra information from the DB
    if detail_level != 'event':
        query = _query_blocks(event_ids, dates_overlap, detail_level)
        if grouped:
            for b in query:
                start_date = b.timetable_entry.start_dt.astimezone(tz).date()
                result[b.session.event_id]['blocks'][start_date].append((b.timetable_entry, b))
        else:
            for b in query:
                result[b.session.event_id]['blocks'].append(b)

    if detail_level == 'contribution':
        query = (Contribution.find(Contribution.event_id.in_(event_ids),
                                   dates_overlap(TimetableEntry),
                                   ~Contribution.is_deleted)
                 .options(contains_eager(Contribution.timetable_entry),
                          joinedload(Contribution.person_links))
                 .join(TimetableEntry))
        if grouped:
            for c in query:
                start_date = c.timetable_entry.start_dt.astimezone(tz).date()
                result[c.event_id]['contribs'][start_date].append((c.timetable_entry, c))
        else:
            for c in query:
                result[c.event_id]['contributions'].append(c)

        query = (Break.find(TimetableEntry.event_id.in_(event_ids), dates_overlap(TimetableEntry))
                 .options(contains_eager(Break.timetable_entry))
                 .join(TimetableEntry))
        if grouped:
            for b in query:
                start_date = b.timetable_entry.start_dt.astimezone(tz).date()
                result[b.timetable_entry.event_id]['breaks'][start_date].append((b.timetable_entry, b))
        else:
            for b in query:
                result[b.timetable_entry.event_id]['breaks'].append(b)
    return result