Ejemplo n.º 1
0
    def test__start_end_from_mode(self):
        from plone.app.event.base import start_end_from_mode
        from plone.app.event.base import dt_end_of_day

        start, end = start_end_from_mode('all')
        self.assertTrue(start is None and end is None)

        start, end = start_end_from_mode('past')
        self.assertTrue(start is None and isinstance(end, datetime.datetime))

        start, end = start_end_from_mode('future')
        self.assertTrue(isinstance(start, datetime.datetime) and end is None)

        start, end = start_end_from_mode('now')
        self.assertTrue(isinstance(start, datetime.datetime) and
                        isinstance(end, datetime.datetime) and
                        end.hour==23 and end.minute==59 and end.second==59)

        start, end = start_end_from_mode('7days')
        self.assertTrue(isinstance(start, datetime.datetime) and
                        isinstance(end, datetime.datetime) and
                        end == dt_end_of_day(start+datetime.timedelta(days=7)))

        start, end = start_end_from_mode('today')
        self.assertTrue(isinstance(start, datetime.datetime) and
                        isinstance(end, datetime.datetime) and
                        start.hour==0 and start.minute==0 and start.second==0
                        and
                        end.hour==23 and end.minute==59 and end.second==59 and
                        (start, end) == start_end_from_mode('day'))

        day = datetime.datetime(2013,2,1,18,22)
        start, end = start_end_from_mode('day', day)
        self.assertTrue(start.date() == day.date() == end.date() and
                        start.hour==0 and start.minute==0 and start.second==0
                        and
                        end.hour==23 and end.minute==59 and end.second==59)

        # test with date-only
        day = datetime.datetime(2013,2,1)
        start, end = start_end_from_mode('day', day)
        self.assertTrue(start.date() == day.date() == end.date() and
                        start.hour==0 and start.minute==0 and start.second==0
                        and
                        end.hour==23 and end.minute==59 and end.second==59)
Ejemplo n.º 2
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
        )
Ejemplo n.º 3
0
    def get_events(self, start=None, end=None, batch=True, mode=None):
        context = self.context

        mode = mode or self.mode
        if not mode and not start and not end:
            mode = "future"
        if mode:
            dt = None
            if self.date:
                try:
                    dt = guess_date_from(self.date)
                except TypeError:
                    pass
            start, end = start_end_from_mode(mode, dt, context)

        b_start = b_size = None
        if batch:
            b_start = self.b_start
            b_size = self.b_size

        occs = get_occurrences_from_brains(
            context,
            get_portal_events(
                context,
                start,
                end,
                # b_start=b_start, b_size=b_size,
                path=context.getPhysicalPath(),
            ),
            start,
            end,
        )

        if batch:
            ret = Batch(occs, size=b_size, start=b_start, orphan=self.orphan)
        else:
            ret = occs

        return ret
    def _get_occs(self):
        date = guess_date_from(self.date)
        if date:
            start, end = start_end_from_mode('day', date, self.context)
            query = {}
            query['review_state'] = self.data.state
            
            search_base_path = self.search_base_path
            if search_base_path:
                query['path'] = {'query': search_base_path}

            list_events = []
            events = get_events(self.context, start=start, end=end, sort='start', sort_reverse=False, ret_mode=RET_MODE_OBJECTS, expand=True, **query)

            today = datetime.datetime.today().date()

            for occ in events:
                if IOccurrence.providedBy(occ):
                    occurrence_id = occ.id
                    event = aq_parent(occ)
                    occ_data = ITicketOccurrenceData(event)
                    occs = occ_data.ticket_occurrences(occurrence_id)
                    if occs:
                        occurrence_ticket = occs[0]
                        item_stock = get_item_stock(occurrence_ticket)
                        if item_stock:
                            stock = item_stock.available
                        else:
                            stock = 0

                        is_today = occ.start.date() == today

                        new_event = {
                            "start": occ.start,
                            "uid": occurrence_ticket.UID(),
                            "stock": stock,
                            "is_today": is_today
                        }
                        list_events.append(new_event)
                        
                elif IBuyableEvent.providedBy(occ):
                    occ_data = ITicketOccurrenceData(occ)
                    occs = occ_data.tickets
                    if occs:
                        occurrence_ticket = occs[0]
                        item_stock = get_item_stock(occurrence_ticket)
                        if item_stock:
                            stock = item_stock.available
                        else:
                            stock = 0
                        
                        is_today = occ.start.date() == today
  
                        new_event = {
                            "start": occ.start,
                            "uid": occurrence_ticket.UID(),
                            "stock": stock,
                            "is_today": is_today
                        }
                        list_events.append(new_event)
                else:
                    print 'NOT AVAILABLE'

            return list_events
        else:
            return []
Ejemplo n.º 5
0
 def _start_end(self):
     start, end = start_end_from_mode(self.mode, self.date, self.context)
     return start, end
Ejemplo n.º 6
0
 def _start_end(self):
     start, end = start_end_from_mode(self.mode, self.date, self.context)
     return start, end
Ejemplo n.º 7
0
    def test__start_end_from_mode(self):
        from plone.app.event.base import start_end_from_mode
        from plone.app.event.base import dt_end_of_day

        # ALL
        #
        start, end = start_end_from_mode('all')
        self.assertTrue(start is None and end is None)

        # PAST
        #
        start, end = start_end_from_mode('past')
        self.assertTrue(start is None and isinstance(end, datetime))

        # FUTURE
        #
        start, end = start_end_from_mode('future')
        self.assertTrue(isinstance(start, datetime) and end is None)

        # NOW
        #
        start, end = start_end_from_mode('now')
        self.assertTrue(
            isinstance(start, datetime) and
            isinstance(end, datetime) and
            end.hour == 23 and end.minute == 59 and end.second == 59
        )

        # 7DAYS
        #
        start, end = start_end_from_mode('7days')
        self.assertTrue(
            isinstance(start, datetime) and
            isinstance(end, datetime) and
            end == dt_end_of_day(start + timedelta(days=6))
        )

        # TODAY
        #
        start, end = start_end_from_mode('today')
        self.assertTrue(
            isinstance(start, datetime) and
            isinstance(end, datetime) and
            start.hour == 0 and start.minute == 0 and start.second == 0 and
            end.hour == 23 and end.minute == 59 and end.second == 59 and
            (start, end) == start_end_from_mode('day')
        )

        # DAY
        #
        day = datetime(2013, 2, 1, 18, 22)
        start, end = start_end_from_mode('day', day)
        self.assertTrue(
            start.date() == day.date() == end.date() and
            start.hour == 0 and start.minute == 0 and start.second == 0 and
            end.hour == 23 and end.minute == 59 and end.second == 59
        )

        # test with date-only
        day = datetime(2013, 2, 1)
        start, end = start_end_from_mode('day', day)
        self.assertTrue(
            start.date() == day.date() == end.date() and
            start.hour == 0 and start.minute == 0 and start.second == 0 and
            end.hour == 23 and end.minute == 59 and end.second == 59
        )

        # WEEK
        #
        def ret_0():
            return 0  # Monday

        def ret_1():
            return 1  # Tuesday

        def ret_6():
            return 6  # Sunday

        # prepare patched first_weekday
        orig_first_weekday = base.first_weekday

        base.first_weekday = ret_0
        day = datetime(2013, 2, 2)
        start, end = start_end_from_mode('week', day)
        self.assertTrue(
            start.isoformat() == '2013-01-28T00:00:00' and
            end.isoformat() == '2013-02-03T23:59:59'
        )

        base.first_weekday = ret_1
        day = datetime(2013, 2, 2)
        start, end = start_end_from_mode('week', day)
        self.assertTrue(
            start.isoformat() == '2013-01-29T00:00:00' and
            end.isoformat() == '2013-02-04T23:59:59'
        )

        base.first_weekday = ret_6
        day = datetime(2013, 2, 1)
        start, end = start_end_from_mode('week', day)
        self.assertTrue(
            start.isoformat() == '2013-01-27T00:00:00' and
            end.isoformat() == '2013-02-02T23:59:59'
        )

        base.first_weekday = orig_first_weekday  # restore orig first_weekday

        # MONTH
        #
        start, end = start_end_from_mode('month')
        self.assertTrue(start < end and start.day == 1)

        day = datetime(2013, 2, 7)
        start, end = start_end_from_mode('month', day)
        self.assertTrue(
            start.year == 2013 and start.month == 2 and start.day == 1 and
            start.hour == 0 and start.minute == 0 and start.second == 0 and
            end.year == 2013 and end.month == 2 and end.day == 28 and
            end.hour == 23 and end.minute == 59 and end.second == 59
        )
Ejemplo n.º 8
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
    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