Example #1
0
 def _process(self):
     if not request.is_xhr:
         return WPCategoryCalendar.render_template(
             'display/calendar.html',
             self.category,
             start_dt=request.args.get('start_dt'))
     tz = self.category.display_tzinfo
     start = tz.localize(dateutil.parser.parse(
         request.args['start'])).astimezone(utc)
     end = tz.localize(dateutil.parser.parse(
         request.args['end'])).astimezone(utc)
     query = (Event.query.filter(Event.starts_between(start, end),
                                 Event.is_visible_in(self.category.id),
                                 ~Event.is_deleted).options(
                                     load_only('id', 'title', 'start_dt',
                                               'end_dt', 'category_id')))
     events = self._get_event_data(query)
     ongoing_events = (Event.query.filter(
         Event.is_visible_in(self.category.id), Event.start_dt < start,
         Event.end_dt > end).options(
             load_only('id', 'title', 'start_dt', 'end_dt',
                       'timezone')).order_by(Event.title).all())
     return jsonify_data(
         flash=False,
         events=events,
         ongoing_event_count=len(ongoing_events),
         ongoing_events_html=self._render_ongoing_events(ongoing_events))
Example #2
0
 def _process(self):
     query = (Event.query
              .filter(Event.starts_between(self.start_dt, self.end_dt),
                      Event.is_visible_in(self.category.id),
                      ~Event.is_deleted)
              .options(load_only('id', 'title', 'start_dt', 'end_dt', 'category_id')))
     events = self._get_event_data(query)
     ongoing_events = (Event.query
                       .filter(Event.is_visible_in(self.category.id),
                               ~Event.is_deleted,
                               Event.start_dt < self.start_dt,
                               Event.end_dt > self.end_dt)
                       .options(load_only('id', 'title', 'start_dt', 'end_dt', 'timezone'))
                       .order_by(Event.title)
                       .all())
     return jsonify_data(flash=False, events=events, ongoing_event_count=len(ongoing_events),
                         ongoing_events_html=self._render_ongoing_events(ongoing_events))
Example #3
0
 def _get_upcoming_event(self):
     query = (Event.query
              .filter(Event.is_visible_in(self.category.id),
                      Event.start_dt > now_utc(),
                      ~Event.is_deleted)
              .options(subqueryload('acl_entries'))
              .order_by(Event.start_dt, Event.id))
     res = get_n_matching(query, 1, lambda event: event.can_access(session.user))
     if res:
         return res[0]
Example #4
0
 def _get_upcoming_event(self):
     query = (Event.query
              .filter(Event.is_visible_in(self.category),
                      Event.start_dt > now_utc(),
                      ~Event.is_deleted)
              .options(subqueryload('acl_entries'))
              .order_by(Event.start_dt, Event.id))
     res = get_n_matching(query, 1, lambda event: event.can_access(session.user))
     if res:
         return res[0]
Example #5
0
 def _process(self):
     if not request.is_xhr:
         return WPCategory.render_template('display/calendar.html', self.category,
                                           start_dt=request.args.get('start_dt'))
     tz = self.category.display_tzinfo
     start = tz.localize(dateutil.parser.parse(request.args['start'])).astimezone(utc)
     end = tz.localize(dateutil.parser.parse(request.args['end'])).astimezone(utc)
     query = (Event.query
              .filter(Event.starts_between(start, end),
                      Event.is_visible_in(self.category),
                      ~Event.is_deleted)
              .options(load_only('id', 'title', 'start_dt', 'end_dt', 'category_id')))
     events = self._get_event_data(query)
     ongoing_events = (Event.query
                       .filter(Event.is_visible_in(self.category),
                               Event.start_dt < start,
                               Event.end_dt > end)
                       .options(load_only('id', 'title', 'start_dt', 'end_dt', 'timezone'))
                       .order_by(Event.title)
                       .all())
     return jsonify_data(flash=False, events=events, ongoing_event_count=len(ongoing_events),
                         ongoing_events_html=self._render_ongoing_events(ongoing_events))
Example #6
0
File: util.py Project: javfg/indico
def get_event_query_filter(category, is_flat=False, hidden_event_ids=None):
    criteria = [~Event.is_deleted]
    if is_flat:
        # Hidden events (visibility == 0) are excluded here, but we can't include an OR criterion
        # checking for a direct category id match as this completely destroys the performance of
        # the query.
        # This should be OK though since showing hidden events in the flattened event list isn't
        # important - they would only be shown to category managers and when using the non-flat
        # view they still see them anyway.
        criteria.append(Event.is_visible_in(category.id))
    else:
        criteria.append(Event.category_id == category.id)
    if hidden_event_ids:
        criteria.append(Event.id.notin_(hidden_event_ids))
    return db.and_(*criteria)
Example #7
0
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
Example #8
0
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