Пример #1
0
    def events(self):
        context = aq_inner(self.context)
        data = self.data

        query = {}
        if data.state:
            query['review_state'] = data.state

        events = []
        query.update(self.request.get('contentFilter', {}))
        search_base = self.search_base
        if ICollection and ICollection.providedBy(search_base):
            # Whatever sorting is defined, we're overriding it.
            query = queryparser.parseFormquery(
                search_base, search_base.query,
                sort_on='start', sort_order=None
            )

            start = None
            if 'start' in query:
                start = query['start']
            else:
                start = localized_now(context)

            end = None
            if 'end' in query:
                end = query['end']

            start, end = _prepare_range(search_base, start, end)
            query.update(start_end_query(start, end))
            events = search_base.results(
                batch=False, brains=True, custom_query=query,
                limit=data.count
            )
            events = expand_events(
                events, ret_mode=RET_MODE_ACCESSORS,
                start=start, end=end,
                sort='start', sort_reverse=False
            )
            events = events[:data.count]  # limit expanded
        else:
            search_base_path = self.search_base_path
            if search_base_path:
                query['path'] = {'query': search_base_path}
            events = get_events(
                context, start=localized_now(context),
                ret_mode=RET_MODE_ACCESSORS,
                expand=True, limit=data.count, **query
            )
            eventlist=[]
            for ev in events:
                hasimage = bool(getattr(ev.context, 'image', None))
                eventlist.append((ev, hasimage))
        return eventlist
Пример #2
0
    def events(self):
        context = aq_inner(self.context)
        data = self.data

        query = {}
        if data.state:
            query['review_state'] = data.state

        events = []
        query.update(self.request.get('contentFilter', {}))
        search_base = self.search_base
        if ICollection and ICollection.providedBy(search_base):
            # Whatever sorting is defined, we're overriding it.
            query = queryparser.parseFormquery(search_base,
                                               search_base.query,
                                               sort_on='start',
                                               sort_order=None)

            start = None
            if 'start' in query:
                start = query['start']
            else:
                start = localized_now(context)

            end = None
            if 'end' in query:
                end = query['end']

            start, end = _prepare_range(search_base, start, end)
            query.update(start_end_query(start, end))
            events = search_base.results(batch=False,
                                         brains=True,
                                         custom_query=query,
                                         limit=data.count)
            events = expand_events(events,
                                   ret_mode=RET_MODE_ACCESSORS,
                                   start=start,
                                   end=end,
                                   sort='start',
                                   sort_reverse=False)
            events = events[:data.count]  # limit expanded
        else:
            search_base_path = self.search_base_path
            if search_base_path:
                query['path'] = {'query': search_base_path}
            events = get_events(context,
                                start=localized_now(context),
                                ret_mode=RET_MODE_ACCESSORS,
                                expand=True,
                                limit=data.count,
                                **query)

        return events
 def events(self, ret_mode=RET_MODE_ACCESSORS, expand=True, batch=True):
     res = []
     if self.is_collection:
         ctx = self.default_context
         # Whatever sorting is defined, we're overriding it.
         sort_on = 'start'
         sort_order = None
         if self.mode in ('past', 'all'):
             sort_order = 'reverse'
         query = queryparser.parseFormquery(
             ctx, ctx.query, sort_on=sort_on, sort_order=sort_order)
         custom_query = self.request.get('contentFilter', {})
         if 'start' not in query or 'end' not in query:
             # ... else don't show the navigation bar
             start, end = self._start_end
             start, end = _prepare_range(ctx, start, end)
             custom_query.update(start_end_query(start, end))
         # BAM ... inject our filter viewlet values
         fc_adapter = ICollectionFilter(ctx)
         res = fc_adapter.filtered_result(pquery=query, batch=False,
             custom_query=custom_query)
         if res is None:
             # ORIGINAL
             res = ctx.results(batch=False, brains=True,
                 custom_query=custom_query)
         if expand:
             # get start and end values from the query to ensure limited
             # listing for occurrences
             _filter_start = self.request.get('_filter_start')
             if _filter_start:
                 # check for pickadate day filtering
                 fs = DateTime(_filter_start).earliestTime()
                 fe = DateTime(_filter_start).latestTime()
                 start, end = self._expand_events_start_end(
                     dict(query=[fs, fe], range='minmax'), None)
             else:
                 start, end = self._expand_events_start_end(
                     query.get('start') or custom_query.get('start'),
                     query.get('end') or custom_query.get('end'))
             res = expand_events(
                 res, ret_mode,
                 start=start, end=end,
                 sort=sort_on, sort_reverse=True if sort_order else False)
     else:
         res = self._get_events(ret_mode, expand=expand)
     if batch:
         b_start = self.b_start
         b_size = self.b_size
         res = Batch(res, size=b_size, start=b_start, orphan=self.orphan)
     return res
Пример #4
0
    def results(self, custom_query, request_params):

        # Support for the Event Listing view from plone.app.event
        collection_layout = self.context.getLayout()
        default_view = self.context.restrictedTraverse(collection_layout)
        if isinstance(default_view, EventListing):
            mode = request_params.get("mode", "future")
            date = request_params.get("date", None)
            date = guess_date_from(date) if date else None
            start, end = start_end_from_mode(mode, date, self.collection)
            start, end = _prepare_range(self.collection, start, end)
            custom_query.update(start_end_query(start, end))
            # TODO: expand events. better yet, let collection.results
            #        do that

        return self.collection.results(
            batch=False, brains=True, custom_query=custom_query
        )
Пример #5
0
 def events(self, ret_mode=RET_MODE_ACCESSORS, expand=False, batch=True):
     res = []
     if self.is_collection:
         ctx = self.default_context
         # Whatever sorting is defined, we're overriding it.
         sort_on = 'start'
         sort_order = None
         if self.mode in ('past', 'all'):
             sort_order = 'reverse'
         query = queryparser.parseFormquery(ctx,
                                            ctx.query,
                                            sort_on=sort_on,
                                            sort_order=sort_order)
         custom_query = self.request.get('contentFilter', {})
         if 'start' not in query or 'end' not in query:
             # ... else don't show the navigation bar
             start, end = self._start_end
             start, end = _prepare_range(ctx, start, end)
             custom_query.update(start_end_query(start, end))
         res = ctx.results(batch=False,
                           brains=True,
                           custom_query=custom_query)
         if expand:
             # get start and end values from the query to ensure limited
             # listing for occurrences
             start, end = self._expand_events_start_end(
                 query.get('start') or custom_query.get('start'),
                 query.get('end') or custom_query.get('end'))
             # import pdb; pdb.set_trace()
             res = expand_events(res,
                                 ret_mode,
                                 start=start,
                                 end=end,
                                 sort=sort_on,
                                 sort_reverse=True if sort_order else False)
     else:
         res = self._get_events(ret_mode, expand=expand)
     if batch:
         b_start = self.b_start
         b_size = self.b_size
         res = Batch(res, size=b_size, start=b_start, orphan=self.orphan)
     return res
 def events(self, ret_mode=RET_MODE_ACCESSORS, expand=False, batch=True):
     res = []
     if self.is_collection:
         ctx = self.default_context
         # Whatever sorting is defined, we're overriding it.
         sort_on = 'start'
         sort_order = None
         if self.mode in ('past', 'all'):
             sort_order = 'reverse'
         query = queryparser.parseFormquery(
             ctx, ctx.query, sort_on=sort_on, sort_order=sort_order
         )
         custom_query = self.request.get('contentFilter', {})
         if 'start' not in query or 'end' not in query:
             # ... else don't show the navigation bar
             start, end = self._start_end
             start, end = _prepare_range(ctx, start, end)
             custom_query.update(start_end_query(start, end))
         res = ctx.results(
             batch=False, brains=True, custom_query=custom_query
         )
         if expand:
             # get start and end values from the query to ensure limited
             # listing for occurrences
             start, end = self._expand_events_start_end(
                 query.get('start') or custom_query.get('start'),
                 query.get('end') or custom_query.get('end')
             )
             # import pdb; pdb.set_trace()
             res = expand_events(
                 res, ret_mode,
                 start=start, end=end,
                 sort=sort_on, sort_reverse=True if sort_order else False
             )
     else:
         res = self._get_events(ret_mode, expand=expand)
     if batch:
         b_start = self.b_start
         b_size = self.b_size
         res = Batch(res, size=b_size, start=b_start, orphan=self.orphan)
     return res
    def cal_data(self):
        """Calendar iterator over weeks and days of the month to display.
        """
        context = aq_inner(self.context)
        today = localized_today(context)
        year, month = self.year_month_display()
        monthdates = [dat for dat in self.cal.itermonthdates(year, month)]

        start = monthdates[0]
        end = monthdates[-1]

        data = self.data
        query = {}
        if data.state:
            query['review_state'] = data.state

        events = []
        query.update(self.request.get('contentFilter', {}))
        search_base = self.search_base
        if ICollection and ICollection.providedBy(search_base):
            # Whatever sorting is defined, we're overriding it.
            query = queryparser.parseFormquery(
                search_base, search_base.query,
                sort_on='start', sort_order=None
            )

            # restrict start/end with those from query, if given.
            if 'start' in query and query['start'] > start:
                start = query['start']
            if 'end' in query and query['end'] < end:
                end = query['end']

            start, end = _prepare_range(search_base, start, end)
            query.update(start_end_query(start, end))
            events = search_base.results(
                batch=False, brains=True, custom_query=query
            )
            events = expand_events(
                events, ret_mode=RET_MODE_OBJECTS,
                start=start, end=end,
                sort='start', sort_reverse=False
            )
        else:
            search_base_path = self.search_base_path
            if search_base_path:
                query['path'] = {'query': search_base_path}
            events = get_events(context, start=start, end=end,
                                ret_mode=RET_MODE_OBJECTS,
                                expand=True, **query)

        #today += datetime.timedelta(days=1)
        cal_dict = construct_calendar(events, start=today, end=end)

        # [[day1week1, day2week1, ... day7week1], [day1week2, ...]]
        caldata = [[]]
        for dat in monthdates:
            if len(caldata[-1]) == 7:
                caldata.append([])
            date_events = None
            isodat = dat.isoformat()
            if isodat in cal_dict:
                date_events = cal_dict[isodat]

            events_string_list = []
            if date_events:
                for occ in date_events:
                    accessor = IEventAccessor(occ)
                    location = accessor.location
                    whole_day = accessor.whole_day

                    time = accessor.start.time().strftime('%H:%M')
                    # TODO: make 24/12 hr format configurable
                    events_string_list.append(
                        u'{0}{1}{2}{3}'.format(
                            accessor.title,
                            u' {0}'.format(time) if not whole_day else u'',
                            u', ' if not whole_day and location else u'',
                            u' {0}'.format(location) if location else u''
                        )
                    )
            caldata[-1].append(
                {'date': dat,
                 'day': dat.day,
                 'prev_month': dat.month < month,
                 'next_month': dat.month > month,
                 'today':
                    dat.year == today.year and
                    dat.month == today.month and
                    dat.day == today.day,
                 'date_string': u"%s-%s-%s" % (dat.year, dat.month, dat.day),
                 'events_string': u' | '.join(events_string_list),
                 'events': date_events})
        return caldata
    def cal_data(self):
        """Calendar iterator over weeks and days of the month to display.
        """
        context = aq_inner(self.context)
        today = localized_today(context)
        year, month = self.year_month_display()
        monthdates = [dat for dat in self.cal.itermonthdates(year, month)]

        start = monthdates[0]
        end = monthdates[-1]

        data = self.data
        query = {}
        if data.state:
            query['review_state'] = data.state

        events = []
        query.update(self.request.get('contentFilter', {}))
        search_base = self.search_base
        if ICollection and ICollection.providedBy(search_base):
            # Whatever sorting is defined, we're overriding it.
            query = queryparser.parseFormquery(
                search_base, search_base.query,
                sort_on='start', sort_order=None
            )

            # restrict start/end with those from query, if given.
            if 'start' in query and query['start'] > start:
                start = query['start']
            if 'end' in query and query['end'] < end:
                end = query['end']

            start, end = _prepare_range(search_base, start, end)
            query.update(start_end_query(start, end))
            events = search_base.results(
                batch=False, brains=True, custom_query=query
            )
            events = expand_events(
                events, ret_mode=RET_MODE_OBJECTS,
                start=start, end=end,
                sort='start', sort_reverse=False
            )
        else:
            search_base_path = self.search_base_path
            if search_base_path:
                query['path'] = {'query': search_base_path}
            events = get_events(context, start=start, end=end,
                                ret_mode=RET_MODE_OBJECTS,
                                expand=True, **query)

        cal_dict = construct_calendar(events, start=start, end=end)

        # [[day1week1, day2week1, ... day7week1], [day1week2, ...]]
        caldata = [[]]
        for dat in monthdates:
            if len(caldata[-1]) == 7:
                caldata.append([])
            date_events = None
            isodat = dat.isoformat()
            if isodat in cal_dict:
                date_events = cal_dict[isodat]

            events_string = u""
            events_title = u""
            if date_events:
                for occ in date_events:
                    accessor = IEventAccessor(occ)
                    location = accessor.location
                    whole_day = accessor.whole_day
                    time = accessor.start.time().strftime('%H:%M')
                    # TODO: make 24/12 hr format configurable
                    base = u'<a href="%s"><span class="title">%s</span>'\
                           u'%s%s%s</a>'
                    events_title += accessor.title
                    events_string += base % (
                        accessor.url,
                        accessor.title,
                        u' %s' % time if not whole_day else u'',
                        u', ' if not whole_day and location else u'',
                        u' %s' % location if location else u'')

            caldata[-1].append(
                {'date': dat,
                 'day': dat.day,
                 'prev_month': dat.month < month,
                 'next_month': dat.month > month,
                 'today':
                    dat.year == today.year and
                    dat.month == today.month and
                    dat.day == today.day,
                 'date_string': u"%s-%s-%s" % (dat.year, dat.month, dat.day),
                 'events_string': events_string,
                 'events_title': events_title,
                 'events': date_events})
        return caldata
Пример #9
0
def get_filter_items(target_collection,
                     group_by,
                     filter_type=DEFAULT_FILTER_TYPE,
                     narrow_down=False,
                     show_count=False,
                     view_name='',
                     cache_enabled=True,
                     request_params=None):
    request_params = request_params or {}
    custom_query = {}  # Additional query to filter the collection

    collection = uuidToObject(target_collection)
    if not collection or not group_by:
        return None
    collection_url = collection.absolute_url()

    # Recursively transform all to unicode
    request_params = safe_decode(request_params)

    # Support for the Event Listing view from plone.app.event
    collection_layout = collection.getLayout()
    default_view = collection.restrictedTraverse(collection_layout)
    if isinstance(default_view, EventListing):
        mode = request_params.get('mode', 'future')
        date = request_params.get('date', None)
        date = guess_date_from(date) if date else None
        start, end = start_end_from_mode(mode, date, collection)
        start, end = _prepare_range(collection, start, end)
        custom_query.update(start_end_query(start, end))
        # TODO: expand events. better yet, let collection.results
        #       do that

    # Get index in question and the current filter value of this index, if set.
    groupby_criteria = getUtility(IGroupByCriteria).groupby
    idx = groupby_criteria[group_by]['index']
    current_idx_value = safe_iterable(request_params.get(idx))

    extra_ignores = []
    if not narrow_down:
        # Additive filtering is about adding other filter values of the same
        # index.
        extra_ignores = [idx, idx + '_op']
    urlquery = base_query(request_params, extra_ignores)

    # Get all collection results with additional filter defined by urlquery
    custom_query.update(urlquery)
    custom_query = make_query(custom_query)
    catalog_results = ICollection(collection).results(
        batch=False, brains=True, custom_query=custom_query)
    if narrow_down and show_count:
        # we need the extra_ignores to get a true count
        # even when narrow_down filters the display of indexed values
        # count_query allows us to do that true count
        count_query = {}
        count_urlquery = base_query(request_params, [idx, idx + '_op'])
        count_query.update(count_urlquery)
        catalog_results_fullcount = ICollection(collection).results(
            batch=False, brains=True, custom_query=count_query)
    if not catalog_results:
        return None

    # Attribute name for getting filter value from brain
    metadata_attr = groupby_criteria[group_by]['metadata']
    # Optional modifier to set title from filter value
    display_modifier = groupby_criteria[group_by].get('display_modifier', None)
    # CSS modifier to set class on filter item
    css_modifier = groupby_criteria[group_by].get('css_modifier', None)
    # Value blacklist
    value_blacklist = groupby_criteria[group_by].get('value_blacklist', None)
    # Allow value_blacklist to be callables for runtime-evaluation
    value_blacklist = value_blacklist() if callable(
        value_blacklist) else value_blacklist  # noqa
    # fallback to title sorted values
    sort_key_function = groupby_criteria[group_by].get(
        'sort_key_function', lambda it: it['title'].lower())

    grouped_results = {}
    for brain in catalog_results:

        # Get filter value
        val = getattr(brain, metadata_attr, None)
        if callable(val):
            val = val()
        # decode it to unicode
        val = safe_decode(val)
        # Make sure it's iterable, as it's the case for e.g. the subject index.
        val = safe_iterable(val)

        for filter_value in val:
            if filter_value is None or isinstance(filter_value, Missing):
                continue
            if value_blacklist and filter_value in value_blacklist:
                # Do not include blacklisted
                continue
            if filter_value in grouped_results:
                # Add counter, if filter value is already present
                grouped_results[filter_value]['count'] += 1
                continue

            # Set title from filter value with modifications,
            # e.g. uuid to title
            title = filter_value
            if filter_value is not EMPTY_MARKER and callable(display_modifier):
                title = safe_decode(display_modifier(filter_value))

            # Build filter url query
            _urlquery = urlquery.copy()
            # Allow deselection
            if filter_value in current_idx_value:
                _urlquery[idx] = [
                    it for it in current_idx_value if it != filter_value
                ]
            elif filter_type != 'single':
                # additive filter behavior
                _urlquery[idx] = current_idx_value + [filter_value]
                _urlquery[idx + '_op'] = filter_type  # additive operator
            else:
                _urlquery[idx] = filter_value

            query_param = urlencode(safe_encode(_urlquery), doseq=True)
            url = '/'.join([
                it for it in [
                    collection_url, view_name, '?' +
                    query_param if query_param else None
                ] if it
            ])

            # Set selected state
            selected = filter_value in current_idx_value
            css_class = 'filterItem {0}{1} {2}'.format(
                'filter-' + idnormalizer.normalize(filter_value),
                ' selected' if selected else '',
                css_modifier(filter_value) if css_modifier else '',
            )

            grouped_results[filter_value] = {
                'title': title,
                'url': url,
                'value': filter_value,
                'css_class': css_class,
                'count': 1,
                'selected': selected
            }

    # Entry to clear all filters
    urlquery_all = {
        k: v
        for k, v in list(urlquery.items()) if k not in (idx, idx + '_op')
    }
    if narrow_down and show_count:
        catalog_results = catalog_results_fullcount
    ret = [{
        'title':
        translate(_('subject_all', default=u'All'), context=getRequest()),
        'url':
        u'{0}/?{1}'.format(collection_url,
                           urlencode(safe_encode(urlquery_all), doseq=True)),
        'value':
        'all',
        'css_class':
        'filterItem filter-all',
        'count':
        len(catalog_results),
        'selected':
        idx not in request_params
    }]

    grouped_results = list(grouped_results.values())

    if callable(sort_key_function):
        grouped_results = sorted(grouped_results, key=sort_key_function)

    ret += grouped_results

    return ret
Пример #10
0
def get_events(context, start=None, end=None, limit=None,
               ret_mode=RET_MODE_BRAINS, expand=False,
               sort='start', sort_reverse=False, **kw):
    """Return all events as catalog brains, possibly within a given
    timeframe.

    :param context: [required] A context object.
    :type context: Content object

    :param start: Date, from which on events should be searched.
    :type start: Python datetime.

    :param end: Date, until which events should be searched.
    :type end: Python datetime

    :param limit: Number of items to be returned.
    :type limit: integer

    :param ret_mode: Return type of search results. These options are
                     available:

                         * 1 (brains): Return results as catalog brains.
                         * 2 (objects): Return results as IEvent and/or
                                        IOccurrence objects.
                         * 3 (accessors): Return results as IEventAccessor
                                          wrapper objects.
    :type ret_mode: integer [1|2|3]

    :param expand: Expand the results to all occurrences (within a timeframe,
                   if given). With this option set to True, the resultset also
                   includes the event's recurrence occurrences and is sorted by
                   the start date.
                   Only available in ret_mode 2 (objects) and 3 (accessors).
    :type expand: boolean

    :param sort: Catalog index id to sort on.
    :type sort: string

    :param sort_reverse: Change the order of the sorting.
    :type sort_reverse: boolean

    :returns: Portal events, matching the search criteria.
    :rtype: catalog brains, event objects or IEventAccessor object wrapper,
            depending on ret_mode.
    """
    start, end = _prepare_range(context, start, end)

    query = {}
    query['object_provides'] = IEvent.__identifier__
    query['object_provides'] = 'Products.ATContentTypes.interfaces.event.IATEvent'

    query.update(start_end_query(start, end))

    if 'path' not in kw:
        # limit to the current navigation root, usually (not always) site
        portal = getSite()
        navroot = getNavigationRootObject(context, portal)
        query['path'] = '/'.join(navroot.getPhysicalPath())
    else:
        query['path'] = kw['path']

    # Sorting
    # In expand mode we sort after calculation of recurrences again. But we
    # need to leave this sorting here in place, since no sort definition could
    # lead to arbitrary results when limiting with sort_limit.
    query['sort_on'] = sort
    if sort_reverse:
        query['sort_order'] = 'reverse'

    # cannot limit before resorting or expansion, see below

    query.update(kw)

    cat = getToolByName(context, 'portal_catalog')
    result = cat(**query)

    # unfiltered catalog results are already sorted correctly on brain.start
    # filtering on start/end requires a resort, see docstring below and
    # p.a.event.tests.test_base_module.TestGetEventsDX.test_get_event_sort
    if sort in ('start', 'end'):
        result = filter_and_resort(context, result,
                                   start, end,
                                   sort, sort_reverse)

        # Limiting a start/end-sorted result set is possible here
        # and provides an important optimization BEFORE costly expansion
        if limit:
            result = result[:limit]

    if ret_mode in (RET_MODE_OBJECTS, RET_MODE_ACCESSORS):
        if expand is False:
            result = [_obj_or_acc(it.getObject(), ret_mode) for it in result]
        else:
            result = expand_events(result, ret_mode, start, end, sort,
                                   sort_reverse)

    # Limiting a non-start-sorted result set can only happen here
    if limit:
        result = result[:limit]

    return result
    def _results(self, collection, request_params):
        ret = []
        if collection:
            collection_layout = collection.getLayout()
            default_view = collection.restrictedTraverse(collection_layout)
            results = []
            custom_query = {}
            if isinstance(default_view, EventListing):
                mode = request_params.get('mode', 'future')
                date = request_params.get('date', None)
                date = guess_date_from(date) if date else None

                start, end = start_end_from_mode(mode, date, collection)
                start, end = _prepare_range(collection, start, end)
                custom_query.update(start_end_query(start, end))
                # TODO: expand events. better yet, let collection.results
                #       do that

            idx = GROUPBY_CRITERIA[self.data.group_by]['index']
            urlquery = {}
            urlquery.update(request_params)
            for it in (idx, 'b_start', 'b_size', 'batch', 'sort_on', 'limit'):
                # Remove problematic url parameters
                # And make sure to not filter by previously selected terms from
                # this index. This narrows down too much (except for dedicated
                # facetted searches - TODO)
                if it in urlquery:
                    del urlquery[it]

            custom_query.update(urlquery)
            results = collection.results(
                batch=False, custom_query=custom_query
            )

            if results:

                ret.append(dict(
                    title=_('subject_all', default=u'All'),
                    url=u'{0}/?{1}'.format(
                        self.collection.absolute_url(),
                        urlencode(urlquery)
                    ),
                    count=len(results),
                    selected=idx not in request_params
                ))

                attr = GROUPBY_CRITERIA[self.data.group_by]['metadata']
                mod = GROUPBY_CRITERIA[self.data.group_by]['display_modifier']

                grouped_results = {}
                for item in results:
                    val = getattr(item, attr, None)
                    if callable(val):
                        val = val()
                    if not getattr(val, '__iter__', False):
                        val = [val]
                    for crit in val:
                        if crit not in grouped_results:
                            urlquery[idx] = crit
                            title = _(safe_decode(
                                mod(crit)
                                if mod and crit is not EMPTY_MARKER
                                else crit
                            ))  # mod modifies for displaying (e.g. uuid to title)  # noqa
                            url = u'{0}/?{1}'.format(
                                self.collection.absolute_url(),
                                urlencode(safe_encode(urlquery))  # need to be utf-8 encoded  # noqa
                            )
                            selected = safe_decode(request_params.get(idx)) == safe_decode(crit)  # noqa
                            sort_key = crit if crit else 'zzzzzz'
                            crit_dict = {
                                'sort_key': sort_key.lower(),
                                'count': 1,
                                'title': title,
                                'url': url,
                                'selected': selected
                            }
                            grouped_results[crit] = crit_dict

                        else:
                            grouped_results[crit]['count'] += 1

                ret += sorted(
                    grouped_results.values(),
                    key=lambda it: it['sort_key']
                )

        return ret
Пример #12
0
    def cal_data(self):
        """Calendar iterator over weeks and days of the month to display.
        """
        context = aq_inner(self.context)
        today = localized_today(context)
        year, month = self.year_month_display()
        monthdates = [dat for dat in self.cal.itermonthdates(year, month)]

        start = monthdates[0]
        end = monthdates[-1]

        data = self.data
        query = {}
        if data.state:
            query["review_state"] = data.state

        events = []
        query.update(self.request.get("contentFilter", {}))
        search_base = self.search_base
        if ICollection and ICollection.providedBy(search_base):
            # Whatever sorting is defined, we're overriding it.
            query = queryparser.parseFormquery(search_base, search_base.query, sort_on="start", sort_order=None)

            # restrict start/end with those from query, if given.
            if "start" in query and query["start"] > start:
                start = query["start"]
            if "end" in query and query["end"] < end:
                end = query["end"]

            start, end = _prepare_range(search_base, start, end)
            query.update(start_end_query(start, end))
            events = search_base.results(batch=False, brains=True, custom_query=query)
            events = expand_events(
                events, ret_mode=RET_MODE_OBJECTS, start=start, end=end, sort="start", sort_reverse=False
            )
        else:
            search_base_path = self.search_base_path
            if search_base_path:
                query["path"] = {"query": search_base_path}
            events = get_events(context, start=start, end=end, ret_mode=RET_MODE_OBJECTS, expand=True, **query)

        cal_dict = construct_calendar(events, start=start, end=end)

        # [[day1week1, day2week1, ... day7week1], [day1week2, ...]]
        caldata = [[]]
        for dat in monthdates:
            if len(caldata[-1]) == 7:
                caldata.append([])
            date_events = None
            isodat = dat.isoformat()
            if isodat in cal_dict:
                date_events = cal_dict[isodat]

            events_string_list = []
            if date_events:
                for occ in date_events:
                    accessor = IEventAccessor(occ)
                    location = accessor.location
                    whole_day = accessor.whole_day
                    time = accessor.start.time().strftime("%H:%M")
                    # TODO: make 24/12 hr format configurable
                    events_string_list.append(
                        u"{0}{1}{2}{3}".format(
                            accessor.title,
                            u" {0}".format(time) if not whole_day else u"",
                            u", " if not whole_day and location else u"",
                            u" {0}".format(location) if location else u"",
                        )
                    )

            caldata[-1].append(
                {
                    "date": dat,
                    "day": dat.day,
                    "prev_month": dat.month < month,
                    "next_month": dat.month > month,
                    "today": dat.year == today.year and dat.month == today.month and dat.day == today.day,
                    "date_string": u"%s-%s-%s" % (dat.year, dat.month, dat.day),
                    "events_string": u" | ".join(events_string_list),
                    "events": date_events,
                }
            )
        return caldata