Beispiel #1
0
def parse_query(query):
    result = []
    for name, value in query.items():
        if name in ('Type', 'portal_type'):
            new_value = []
            if type(value) not in (list, tuple):
                value = [value]
            for v in value:
                if v in _type_name_mapping:
                    new_value.append(_type_name_mapping[v])
            value = new_value
            if IImage in value:
                result.append(Any('mimetype', _image_mimetypes))
            query = Any('interfaces', value)
        elif name == 'path':
            split = value.split('::')
            if len(split) == 2:
                path = split[0]
                depth = split[1]
            else:
                path = value
                depth = 1
            query = Eq(name, {
                'query': path,
                'depth': int(depth)
            })
        elif name in _index_mapping:
            name = _index_mapping[name]
            query = Eq(name, value)
        else:
            query = Eq(name, value)
        result.append(query)
    return result
Beispiel #2
0
    def query2(self, soup):

        # fetch user vendor uids
        vendor_uids = get_vendor_uids_for()
        # filter by given vendor uid or user vendor uids
        vendor_uid = self.request.form.get('vendor')

        if vendor_uid:
            vendor_uid = uuid.UUID(vendor_uid)
            # raise if given vendor uid not in user vendor uids
            if vendor_uid not in vendor_uids:
                raise Unauthorized
            query = Any('vendor_uids', [vendor_uid])
        else:
            query = Any('vendor_uids', vendor_uids)
        # filter by customer if given
        customer = self.request.form.get('customer')
        if customer:
            query = query & Eq('creator', customer)
        # filter by search term if given
        term = self.request.form['sSearch'].decode('utf-8')
        if term:
            query = query & Contains(self.search_text_index, term)
        # query orders and return result
        sort = self.sort()
        res = soup.lazy(query,
                        sort_index=sort['index'],
                        reverse=sort['reverse'],
                        with_size=True)
        length = res.next()

        return length, res
Beispiel #3
0
 def get_tag_count(self, tag):
     """ Returns total count for a tag withing the context this view was registered on. """
     try:
         return self.tag_count[tag]
     except KeyError:
         query = Eq('path', resource_path(self.context)) &\
                 Any('allowed_to_view', self.cached_effective_principals) &\
                 Any('tags', tag)
         self.tag_count[tag] = self.root.catalog.query(query)[0]
         return self.tag_count[tag]
Beispiel #4
0
    def query(self, soup):
        soup.reindex()

        # fetch user vendor uids
        vendor_uids = get_vendor_uids_for()
        # filter by given vendor uid or user vendor uids
        vendor_uid = self.request.form.get('vendor')

        if vendor_uid:
            vendor_uid = uuid.UUID(vendor_uid)
            # raise if given vendor uid not in user vendor uids
            if vendor_uid not in vendor_uids:
                raise Unauthorized
            query = Any('vendor_uid', [vendor_uid])
        else:
            query = Any('vendor_uid', vendor_uids)

        # filter by customer if given
        customer = self.request.form.get('customer')
        if customer:
            query = query & Eq('creator', customer)

        # filter by search term if given
        term = self.request.form['sSearch'].decode('utf-8')

        if term:
            query = query & Contains(self.search_text_index, term)

        # Show only tickets that are paid
        query = query & Eq('salaried', 'yes')

        if not IPloneSiteRoot.providedBy(self.context):
            buyable_uids = self._get_buyables_in_context()
            query = query & Any('buyable_uids', buyable_uids)

        # query orders and return result
        sort = self.sort()
        try:
            res = soup.lazy(query,
                            sort_index=sort['index'],
                            reverse=sort['reverse'],
                            with_size=True)

            length = res.next()
        except:
            length = 0
            pass

        return length, res
Beispiel #5
0
    def query(self, soup):
        # fetch user vendor uids
        vendor_uids = get_vendor_uids_for()
        # filter by given vendor uid or user vendor uids
        vendor_uid = self.request.form.get('vendor')
        if vendor_uid:
            vendor_uid = uuid.UUID(vendor_uid)
            # raise if given vendor uid not in user vendor uids
            if vendor_uid not in vendor_uids:
                raise Unauthorized
            query = Any('vendor_uids', [vendor_uid])
        else:
            query = Any('vendor_uids', vendor_uids)

        # filter by customer if given
        customer = self.request.form.get('customer')
        if customer:
            query = query & Eq('creator', customer)

        # Filter by state if given
        state = self.request.form.get('state')
        if state:
            query = query & Eq('state', state)

        # Filter by salaried if given
        salaried = self.request.form.get('salaried')
        if salaried:
            query = query & Eq('salaried', salaried)

        # filter by search term if given
        term = self.request.form['sSearch'].decode('utf-8')
        if term:
            # append * for proper fulltext search
            term += '*'
            query = query & Contains(self.search_text_index, term)
        # get buyable uids for given context, get all buyables on site root
        # use explicit IPloneSiteRoot to make it play nice with lineage
        if not IPloneSiteRoot.providedBy(self.context):
            buyable_uids = self._get_buyables_in_context()
            query = query & Any('buyable_uids', buyable_uids)
        # query orders and return result
        sort = self.sort()
        res = soup.lazy(query,
                        sort_index=sort['index'],
                        reverse=sort['reverse'],
                        with_size=True)
        length = res.next()
        return length, res
Beispiel #6
0
def evolve(root):
    from repoze.catalog.query import Any
    from repoze.catalog.query import Contains
    from repoze.catalog.query import Eq
    from pyramid.traversal import resource_path

    from voteit.core.models.catalog import reindex_object
    from voteit.core.models.catalog import resolve_catalog_docid
    print "Removing absolute urls in profile links"
    catalog = root.catalog

    host = None
    while not host:
        host = raw_input(
            "Enter a host to replace (ex http://127.0.0.1:6543): ")

    count, result = catalog.query(Eq('path', resource_path(root)) & \
                                  Contains('searchable_text', 'class="inlineinfo"') & \
                                  Any('content_type', ('DiscussionPost', 'Proposal', )))

    catalog = root.catalog
    print "Processing %s objects" % count
    for docid in result:
        # get object
        obj = resolve_catalog_docid(catalog, root, docid)
        obj.title = obj.title.replace(host, '')
        reindex_object(catalog, obj)
Beispiel #7
0
def agenda_data_json(context, request):
    if not request.is_participant:
        return {}
    query = Eq('path', resource_path(context)) & Eq('type_name', 'AgendaItem')
    # Sanitize to avoid exceptions?
    state = request.POST.get('state')
    if state not in _OPEN_STATES and not request.is_moderator:
        raise HTTPForbidden('State query not allowed')
    tag = request.session.get('voteit.ai_selected_tag', '')
    if tag and tag in request.meeting.tags:
        query &= Any('tags', [tag.lower()])
    results = []
    hide_type_count = request.session.get('voteit.agenda.hide_type_count',
                                          False)

    if state:
        query &= Eq('workflow_state', state)

    count, docids = request.root.catalog.query(query)
    for ai in request.resolve_docids(docids, perm=None):
        ai_res = {'title': ai.title, 'name': ai.__name__}
        if not hide_type_count:
            ai_res['contents'] = count_types(request, ai)
        if state is None:
            ai_res['state'] = ai.get_workflow_state()
        results.append(ai_res)

    return {'ais': results, 'hide_type_count': hide_type_count}
Beispiel #8
0
def day_entries(request, context, day=None, userid=_marker):
    """
    :param request:
    :param context: Fetch everything within this contexts path (may be root)
    :param group: Group entries together within tasks
    :param day: Limit within this day
    :type day: date
    :param userid: User to fetch for. None means all
    :return: OrderedDict with Task uid as key and time entry objects in a list as value.
    """
    if userid == _marker:
        userid = request.authenticated_userid
    #FIXME: Fetch exactly one day and all entries for that day. Sort according to Tasks
    #min_created = utcnow() - timedelta(days=days)
    query = Eq('path', resource_path(context)) &\
            Eq('type_name', 'TimeEntry')
    #       Gt('created', timegm(min_created.timetuple()))
    if userid:
        query &= Any('creator', [userid])
    docids = request.root.catalog.query(query,
                                        sort_index='created',
                                        reverse=True)[1]
    results = OrderedDict()
    for obj in request.resolve_docids(docids):
        items = results.setdefault(obj.__parent__.uid, [])
        items.append(obj)
    return results
Beispiel #9
0
 def get_proposal_objects(self):
     """ Return proposal objects relevant to this poll.
         Will sort them in specified order.
     """
     agenda_item = self.__parent__
     if agenda_item is None:
         raise ValueError("Can't find any agenda item in the polls lineage")
     query = Any('uid', tuple(self.proposal_uids)) & Eq(
         'type_name', 'Proposal')
     root = find_root(agenda_item)
     results = []
     for docid in root.catalog.query(query)[1]:
         path = root.document_map.address_for_docid(docid)
         obj = find_resource(root, path)
         # Permission check shouldn't be needed at this point
         if obj:
             results.append(obj)
     if self.proposal_order:
         proposal_order = self.proposal_order
     else:
         meeting = find_interface(self, IMeeting)
         # During tests, we might not have a real meeting here :)
         proposal_order = getattr(meeting, 'poll_proposals_default_order',
                                  '')
     key_method = PROPOSAL_ORDER_KEY_METHODS.get(
         proposal_order, PROPOSAL_ORDER_KEY_METHODS[PROPOSAL_ORDER_DEFAULT])
     return sorted(results, key=key_method)
Beispiel #10
0
 def count_tags(self, context, request, base_tag, num):
     results = {}
     query = Eq('path', resource_path(context)) & Eq('type_name', 'Proposal')
     query &= NotAny('workflow_state', ['retracted', 'unhandled'])
     cquery = request.root.catalog.query
     for i in range(1, num+1):
         tag = "%s-%s" % (base_tag, i)
         res = cquery(query & Any('tags', [tag]))[0]
         results[tag] = res.total
     return results
Beispiel #11
0
 def __call__(self):
     response = {}
     query = Eq('path', resource_path(self.context)) & \
             Eq('type_name', 'Proposal')
     tags = self.request.GET.getall('tag')
     if tags:
         tags = [x.lower() for x in tags]
         query &= Any('tags', tags)
     hide = self.request.params.getall('hide')
     load_hidden = self.request.params.get('load_hidden', False)
     if load_hidden:
         # Only load data previously hidden
         if hide:
             query &= Any('workflow_state', hide)
     else:
         invert_hidden = copy(query)
         # Normal operation, keep count of hidden
         if hide:
             invert_hidden &= Any('workflow_state', hide)
             query &= NotAny('workflow_state', hide)
     response['docids'] = tuple(
         self.catalog_query(query, sort_index='created'))
     read_names = self.request.get_read_names(self.context)
     unread_query = query & NotAny(
         '__name__',
         set(read_names.get(self.request.authenticated_userid, [])))
     response['unread_docids'] = tuple(
         self.catalog_query(unread_query, sort_index='created'))
     response['contents'] = self.resolve_docids(
         response['docids'])  # A generator
     if not load_hidden:
         response['hidden_count'] = self.request.root.catalog.query(
             invert_hidden)[0].total
         get_query = {'tag': tags, 'load_hidden': 1, 'hide': hide}
         response['load_hidden_url'] = self.request.resource_url(
             self.context, self.request.view_name, query=get_query)
     else:
         response['hidden_count'] = False
     # A more expensive but accurate permission check for a specific object.
     response['ck_mod'] = lambda obj: self.request.has_permission(
         security.MODERATE_MEETING, obj)
     return response
Beispiel #12
0
 def update_cached_len(self, userid):
     read_names = self.request.redis_conn.smembers(self.get_key(userid))
     base_query = self.path_query & Any('__name__', read_names)
     for type_name in self.track_types:
         res = self.request.root.catalog.query(
             base_query & Eq('type_name', type_name))[0]
         old_len = self.get_read_type(type_name, userid)
         self.request.redis_conn.set(self.get_len_key(type_name, userid),
                                     res.total)
         changed = res.total - old_len
         self.rnc.change(type_name, changed, userid)
Beispiel #13
0
 def booking(self):
     if self._booking:
         return self._booking
     soup = self.bookings_soup
     query = Eq('uid', self.uid)
     if self.vendor_uids:
         query = query & Any('vendor_uid', self.vendor_uids)
     result = soup.query(query, with_size=True)
     if result.next() != 1:  # first result is length
         return None
     self._booking = result.next()
     return self._booking
Beispiel #14
0
def tag_stats(context, request, *args, **kwargs):
    api = kwargs['api']
    if not api.meeting:
        return ""

    query = Eq('path', resource_path(context)) &\
            Any('allowed_to_view', effective_principals(request)) &\
            Any('content_type', ('Proposal', 'DiscussionPost',))

    num, docids = api.root.catalog.query(query)
    unique_tags = set()
    #FIXME: There must be a smarter way to load uniques!?
    for docid in docids:
        entry = api.root.catalog.document_map.get_metadata(docid)
        unique_tags.update(entry['tags'])

    results = []
    for tag in unique_tags:
        count = api.get_tag_count(tag)
        if count > 1:
            results.append((tag, count))

    if not results:
        return u""

    #Sort the tags based on occurence and show the top 5
    results = sorted(results, key=lambda x: x[1], reverse=True)[:5]

    def _make_url(tag):
        query = request.GET.copy()
        query['tag'] = tag
        return request.resource_url(context, query=query)

    response = dict(
        api=api,
        context=context,
        stats=results,
        make_url=_make_url,
    )
    return render('templates/tag_stats.pt', response, request=request)
Beispiel #15
0
def change_mentions(root, userid, userid_lower):
    catalog = root.catalog
    result = catalog.query(Eq('path', resource_path(root)) & \
                           Contains('searchable_text', userid) & \
                           Any('content_type', ('DiscussionPost', 'Proposal', )))[1]
    for docid in result:
        # get object
        obj = resolve_catalog_docid(catalog, root, docid)
        title = obj.title
        for match in re.finditer('<a class="inlineinfo" href="http:\/\/[\da-z.-:]*/[\w-]*/_userinfo\?userid=('+userid+')" title="[\w\s-]*">@('+userid+')</a>', title, re.UNICODE):
            title = title[0:match.start(1)] + userid_lower + title[match.end(1):len(title)] # replace in url
            title = title[0:match.start(2)] + userid_lower + title[match.end(2):len(title)] # replace in text
        obj.title = title
Beispiel #16
0
def get_vendor_order_uids_for(context, user=None):
    """Get order uids all orders a given or current user has vendor
    permissions for.

    :param user: Optional user object to check permissions on vendor areas. If
                 no user object is give, the current user is used.
    :type user: MemberData object
    :returns: List of order UUID objects.
    :rtype: List of uuid.UUID
    """
    vendors = get_vendor_uids_for(user=user)
    soup = get_bookings_soup(context)
    res = soup.query(Any('vendor_uid', vendors))
    order_uids = set(booking.attrs['order_uid'] for booking in res)
    return order_uids
Beispiel #17
0
def sum_time(request, context, userid=_marker):
    """ Build a dict with time summary
    """
    query = Eq('path', resource_path(context)) & Eq('type_name', 'TimeEntry')
    if userid == _marker:
        userid = request.authenticated_userid
    if userid:
        query &= Any('creator', [userid])
    docids = request.root.catalog.query(query)[1]
    results = {}
    for obj in request.resolve_docids(docids, perm=None):
        if obj.stop_time:
            creator = obj.creator[0]
            if creator not in results:
                results[creator] = timedelta()
            results[creator] += obj.timedelta
    return results
Beispiel #18
0
 def _mk_query(self):
     self.docids = ()
     query = self.request.GET.get('query', None)
     if not query:
         return
     if self.request.GET.get('glob', False):
         if '*' not in query:
             query = "%s*" % query
     query_obj = Contains('searchable_text', query) & Eq(
         'search_visible', True)
     type_name = self.request.GET.getall('type_name')
     if type_name:
         query_obj &= Any('type_name', type_name)
     try:
         self.docids = self.root.catalog.query(query_obj)[1]
     except ParseError:
         if not self.request.is_xhr:
             msg = _(u"Invalid search query - try something else!")
             self.flash_messages.add(msg, type="danger")
Beispiel #19
0
 def parse_query_params(self, query):
     if not query:
         return []
     queries = []
     for index, value in query.items():
         if not value or value in ["*", "**"]:
             continue
         if index not in self.indexes:
             continue
         if six.PY2:
             value = value.decode("utf-8")
         if index == self.text_index:
             queries.append(Contains("text", value))
         elif index in self.keyword_indexes:
             queries.append(Any(index, value))
         else:
             queries.append(Eq(index, value))
     if not queries:
         return None
     return And(*queries)
Beispiel #20
0
 def __call__(self):
     path = resource_path(self.context)
     query = Eq('path', path) & Eq('type_name', 'Poll') & Any(
         'workflow_state', ('private', 'upcoming'))
     docids = self.request.root.catalog.query(query)[1]
     polls = tuple(self.request.resolve_docids(
         docids, perm=security.EDIT))  #Must be able to modify poll
     query = Eq('path', path) & Eq('type_name', 'Proposal')
     only_uid = self.request.GET.get('uid', None)
     if only_uid:
         query &= Eq('uid', only_uid)
     docids = self.request.root.catalog.query(query)[1]
     proposals = tuple(self.request.resolve_docids(docids))
     response = {}
     for proposal in proposals:
         values = {'context': proposal, 'polls': polls}
         response[proposal.uid] = render(
             'voteit.core:templates/snippets/pick_polls.pt',
             values,
             request=self.request)
     return response
Beispiel #21
0
def agenda_states(context, request, va, **kw):
    states = ['ongoing', 'upcoming', 'closed']
    if request.is_moderator:
        states.append('private')
    tag = request.session.get('voteit.ai_selected_tag', '')
    if tag in context.tags:
        tag = tag.lower()
    else:
        tag = None
    results = {}
    query = Eq('path', kw['meeting_path']) & Eq('type_name', 'AgendaItem')
    for state in states:
        squery = query & Eq('workflow_state', state)
        res, docids = request.root.catalog.query(squery)
        results[state] = {
            'hash': hash(tuple(docids)),
            'count': res.total and str(res.total) or '',
        }
        if tag and res.total:
            tagres = request.root.catalog.query(squery & Any('tags', [tag]))[0]
            results[state]['count'] = "%s / %s" % (tagres.total, res.total)
    return results
Beispiel #22
0
def poll_listing(context, request, va, **kw):
    """ This is a view of a poll when it's displayed within an agenda item.
        It's not the listing for when a user votes.
    """
    api = kw['api']
    #The poll query doesn't have to care about path and such since we already have the uids
    query = Any('uid', context.proposal_uids)
    get_metadata = api.root.catalog.document_map.get_metadata
    count, docids = api.root.catalog.query(query, sort_index='created')
    results = []
    for docid in docids:
        results.append(get_metadata(docid))
    response = {}
    response['proposals'] = tuple(results)
    response['api'] = api
    response['poll_plugin'] = context.get_poll_plugin()
    response['can_vote'] = api.context_has_permission(security.ADD_VOTE,
                                                      context)
    response['has_voted'] = api.userid in context
    response['wf_state'] = wf_state = context.get_workflow_state()
    response[
        'context'] = context  #make sure context within the template is this context and nothing else
    if wf_state in ('ongoing', 'closed'):
        response['voted_count'] = len(context.get_voted_userids())
        if wf_state == 'ongoing':
            response['voters_count'] = len(
                security.find_authorized_userids(context, [security.ADD_VOTE]))
        else:
            response['voters_count'] = len(context.voters_mark_closed)
        try:
            response['voted_percentage'] = round(
                100 * float(response['voted_count']) /
                float(response['voters_count']), 1)
        except ZeroDivisionError:
            response['voted_percentage'] = 0
    return render('templates/polls/poll.pt', response, request=request)
Beispiel #23
0
def proposal_response(context, request, va, **kw):
    """ Prepair a response dict for the proposal view.
    """
    api = kw['api']
    #Start with checking which polls that exist in this context and store shown uids
    shown_uids = set()
    polls = []
    for poll in api.get_restricted_content(context,
                                           iface=IPoll,
                                           sort_on='created'):
        try:
            plugin = poll.get_poll_plugin()
        except ComponentLookupError:
            err_msg = _(
                u"plugin_missing_error",
                default=
                u"Can't find any poll plugin with name '${name}'. Perhaps that package has been uninstalled?",
                mapping={'name': poll.get_field_value('poll_plugin')})
            api.flash_messages.add(err_msg, type="error")
            continue
        shown_uids.update(poll.proposal_uids)
        polls.append(poll)

    #The agenda item query must be based on the context and to exclude all already shown
    #This view also cares about retracted proposals where as poll version doesn't
    query = Eq('path', resource_path(context)) &\
            Eq('content_type', 'Proposal') &\
            NotAny('uid', shown_uids)

    hide_retracted = api.meeting.get_field_value('hide_retracted', False)
    hide_unhandled = api.meeting.get_field_value('hide_unhandled_proposals',
                                                 False)
    hidden_states = []
    if hide_retracted:
        hidden_states.append('retracted')
    if hide_unhandled:
        hidden_states.append('unhandled')
    if hidden_states:
        query &= NotAny('workflow_state', hidden_states)

    tag = request.GET.get('tag', None)
    if tag:
        #Only apply tag limit for things that aren't polls.
        #This is a safegard against user errors
        query &= Any('tags', (tag, ))

    # build query string and remove tag
    clear_tag_query = request.GET.copy()
    if 'tag' in clear_tag_query:
        del clear_tag_query['tag']

    count, docids = api.root.catalog.query(query, sort_index='created')
    get_metadata = api.root.catalog.document_map.get_metadata
    results = [get_metadata(x) for x in docids]
    hidden_proposals = []
    if hidden_states:
        query = Eq('path', resource_path(context)) &\
                Eq('content_type', 'Proposal') &\
                NotAny('uid', shown_uids) &\
                Any('workflow_state', hidden_states)
        if tag:
            query &= Any('tags', (tag, ))
        count, docids = api.root.catalog.query(query, sort_index='created')
        hidden_proposals = [get_metadata(x) for x in docids]

    response = {}
    response['clear_tag_url'] = request.resource_url(context,
                                                     query=clear_tag_query)
    response['proposals'] = tuple(results)
    response['hidden_proposals'] = tuple(hidden_proposals)
    response['tag'] = tag
    response['api'] = api
    response['polls'] = polls
    return response
Beispiel #24
0
 def test_negate(self):
     from repoze.catalog.query import Any
     inst = self._makeOne('index', 'val')
     self.assertEqual(inst.negate(), Any('index', 'val'))
Beispiel #25
0
from repoze.catalog.query import Contains
from repoze.catalog.query import Name
from betahaus.pyracont.factories import createSchema
from zope.index.text.parsetree import ParseError

from voteit.core.views.base_view import BaseView
from voteit.core.models.interfaces import IMeeting
from voteit.core.models.schemas import button_search
from voteit.core.security import VIEW
from voteit.core.helpers import strip_and_truncate
from voteit.core import VoteITMF as _


SEARCH_VIEW_QUERY = Eq('path', Name('path')) \
    & Contains('searchable_text', Name('searchable_text')) \
    & Any('content_type', ('DiscussionPost', 'Proposal', 'AgendaItem' )) \
    & Any('allowed_to_view', Name('allowed_to_view'))


class SearchView(BaseView):
    """ Handle incoming search query and display result. """

    @view_config(context=IMeeting, name="search", renderer="templates/search.pt", permission = VIEW)
    def search(self):
        schema = createSchema('SearchSchema').bind(context = self.context, request = self.request)
        form = Form(schema, buttons=(button_search,))
        self.api.register_form_resources(form)
        appstruct = {}
        self.response['results'] = []

        def _results_ts(count):
Beispiel #26
0
def vocabulary_view(context, request):
    try:
        attributes = json.loads(request.params.get('attributes', '["title", "id"]'))
    except:
        attributes = ['title', 'id']
    if 'UID' in attributes:
        # always put in anyways
        attributes.remove('UID')

    try:
        batch = json.loads(request.params.get('batch'))
    except:
        batch = DEFAULT_BATCH

    query = normalize_query(json.loads(request.params['query']))
    criteria = parse_query(query)

    resolver = ResovlerFactory(context)
    if 'UID' in query:
        docids = query['UID']
        if type(docids) not in (list, tuple):
            docids = [docids]
        # convert to ints
        new_docids = []
        for docid in docids:
            try:
                new_docids.append(int(docid))
            except:
                pass
        docids = new_docids
        numdocs = len(docids)
    else:
        criteria.append(Any('allowed', effective_principals(request)))
        if 'title' not in query:
            # we default to requiring a title in these results or
            # else we get a bunch of junky results
            criteria.append(NotEq('title', ''))
        catalog = find_catalog(context)
        numdocs, docids = catalog.query(And(*criteria))

    if batch and ('size' not in batch or 'page' not in batch):
        batch = DEFAULT_BATCH
    if batch:
        # must be slicable for batching support
        page = int(batch['page'])
        # page is being passed in is 1-based
        start = (max(page - 1, 0)) * int(batch['size'])
        end = start + int(batch['size'])
        # Try __getitem__-based slice, then iterator slice.
        # The iterator slice has to consume the iterator through
        # to the desired slice, but that shouldn't be the end
        # of the world because at some point the user will hopefully
        # give up scrolling and search instead.
        try:
            docids = docids[start:end]
        except TypeError:
            docids = itertools.islice(docids, start, end)

    # build result items
    items = []
    for docid in docids:
        result = resolver(docid)
        if result is None:
            continue
        data = {
            'UID': docid
        }
        for attribute in attributes:
            attr = attribute
            if attribute in _attribute_mapping:
                attr = _attribute_mapping[attribute]
            if attr in ('Type', 'portal_type'):
                value = 'Page'
                if IImage.providedBy(result):
                    value = 'Image'
                elif ICommunityFile.providedBy(result):
                    value = 'File'
                elif IFolder.providedBy(result):
                    value = 'Folder'
            elif attr == 'getURL':
                value = resource_url(result, request)
            elif attr == 'path':
                # a bit weird here...
                value = resource_path(result, request).split('/GET')[0]
            else:
                value = getattr(result, attr, None)
            data[attribute] = value
        items.append(data)
    return {
        'results': items,
        'total': numdocs
    }
Beispiel #27
0
def _get_motions(request, context, states):
    query = (Eq("type_name", "Motion")
             & Any("wf_state", states)
             & Eq("path", resource_path(context)))
    docids = request.root.catalog.query(query, sort_index="created")[1]
    return request.resolve_docids(docids, perm=None)
Beispiel #28
0
def get_docids_to_show(request,
                       context,
                       type_name,
                       tags=(),
                       limit=5,
                       start_after=None,
                       end_before=None):
    """ Helper method to fetch docids that would be a resonable batch to show.
        This is mostly to allow agenda views to load fast.

        - Fetch batch from the first unread docid so there will be no items
            skipped in case they were read from a tag view.
        - If batch contains less items than limit, insert items from previous.
        - start_after - remove everything before this docid and the value specified.
        - end_before - remove this value and everything after it.
        
        Result example:
        {'batch': [4, 5, 6], 'previous': [1, 2, 3], 'over_limit': [7, 8, 9], 'unread': [4, 5, 6, 7, 8, 9]}
    """
    assert IAgendaItem.providedBy(context)
    query = Eq('path', resource_path(context))
    query &= Eq('type_name', type_name)
    if tags:
        query &= Any('tags', list(tags))
    read_names = request.get_read_names(context)
    unread_query = query & NotAny(
        '__name__', set(read_names.get(request.authenticated_userid, [])))
    unread_docids = list(
        request.root.catalog.query(unread_query, sort_index='created')[1])
    docids_pool = list(
        request.root.catalog.query(query, sort_index='created')[1])

    if start_after and start_after in docids_pool:
        i = docids_pool.index(start_after)
        for docid in docids_pool[:i + 1]:
            if docid in unread_docids:
                unread_docids.remove(docid)
        docids_pool[0:i + 1] = []
    if end_before and end_before in docids_pool:
        i = docids_pool.index(end_before)
        for docid in docids_pool[i:]:
            if docid in unread_docids:
                unread_docids.remove(docid)
        docids_pool[i:] = []
    if limit:
        if unread_docids:
            first_pos = docids_pool.index(unread_docids[0])
            batch = docids_pool[first_pos:first_pos + limit]
            over_limit = docids_pool[first_pos + limit:]
            previous = docids_pool[:first_pos]
            # Fill batch from last item of previous if batch is too small
            while previous and len(batch) < limit:
                batch.insert(0, previous.pop(-1))
        else:
            batch = docids_pool[-limit:]
            previous = docids_pool[:-limit]
            over_limit = []
        return {
            'batch': batch,
            'previous': previous,
            'over_limit': over_limit,
            'unread': unread_docids
        }
    # no limit
    return {
        'batch': docids_pool,
        'previous': [],
        'over_limit': [],
        'unread': unread_docids
    }
Beispiel #29
0
    def get_csv(self):
        context = self.context

        # prepare csv writer
        sio = StringIO()
        ex = csv.writer(sio, dialect='excel-colon', quoting=csv.QUOTE_MINIMAL)
        # exported column keys as first line
        ex.writerow(ORDER_EXPORT_ATTRS + COMPUTED_ORDER_EXPORT_ATTRS.keys() +
                    BOOKING_EXPORT_ATTRS +
                    COMPUTED_BOOKING_EXPORT_ATTRS.keys())

        bookings_soup = get_bookings_soup(context)

        # First, filter by allowed vendor areas
        vendor_uids = get_vendor_uids_for()
        query_b = Any('vendor_uid', vendor_uids)

        # Second, query for the buyable
        query_cat = {}
        query_cat['object_provides'] = IBuyable.__identifier__
        query_cat['path'] = '/'.join(context.getPhysicalPath())
        cat = getToolByName(context, 'portal_catalog')
        res = cat(**query_cat)
        buyable_uids = [IUUID(it.getObject()) for it in res]

        query_b = query_b & Any('buyable_uid', buyable_uids)

        all_orders = {}
        for booking in bookings_soup.query(query_b):
            booking_attrs = []
            # booking export attrs
            for attr_name in BOOKING_EXPORT_ATTRS:
                val = self.export_val(booking, attr_name)
                booking_attrs.append(val)
            # computed booking export attrs
            for attr_name in COMPUTED_BOOKING_EXPORT_ATTRS:
                cb = COMPUTED_BOOKING_EXPORT_ATTRS[attr_name]
                val = cb(context, booking)
                val = cleanup_for_csv(val)
                booking_attrs.append(val)

            # create order_attrs, if it doesn't exist
            order_uid = booking.attrs.get('order_uid')
            if order_uid not in all_orders:
                order = get_order(context, order_uid)
                order_data = OrderData(context,
                                       order=order,
                                       vendor_uids=vendor_uids)
                order_attrs = []
                # order export attrs
                for attr_name in ORDER_EXPORT_ATTRS:
                    val = self.export_val(order, attr_name)
                    order_attrs.append(val)
                # computed order export attrs
                for attr_name in COMPUTED_ORDER_EXPORT_ATTRS:
                    cb = COMPUTED_ORDER_EXPORT_ATTRS[attr_name]
                    val = cb(self.context, order_data)
                    val = cleanup_for_csv(val)
                    order_attrs.append(val)
                all_orders[order_uid] = order_attrs

            ex.writerow(all_orders[order_uid] + booking_attrs)

            # TODO: also set for contextual exports? i'd say no.
            # booking.attrs['exported'] = True
            # bookings_soup.reindex(booking)

        ret = sio.getvalue()
        sio.close()
        return ret
Beispiel #30
0
 def csv(self, request):
     # get orders soup
     orders_soup = get_orders_soup(self.context)
     # get bookings soup
     bookings_soup = get_bookings_soup(self.context)
     # fetch user vendor uids
     vendor_uids = get_vendor_uids_for()
     # base query for time range
     query = Ge('created', self.from_date) & Le('created', self.to_date)
     # filter by given vendor uid or user vendor uids
     vendor_uid = self.vendor
     if vendor_uid:
         vendor_uid = uuid.UUID(vendor_uid)
         # raise if given vendor uid not in user vendor uids
         if vendor_uid not in vendor_uids:
             raise Unauthorized
         query = query & Any('vendor_uids', [vendor_uid])
     else:
         query = query & Any('vendor_uids', vendor_uids)
     # filter by customer if given
     customer = self.customer
     if customer:
         query = query & Eq('creator', customer)
     # prepare csv writer
     sio = StringIO()
     ex = csv.writer(sio, dialect='excel-colon', quoting=csv.QUOTE_MINIMAL)
     # exported column keys as first line
     ex.writerow(ORDER_EXPORT_ATTRS + COMPUTED_ORDER_EXPORT_ATTRS.keys() +
                 BOOKING_EXPORT_ATTRS +
                 COMPUTED_BOOKING_EXPORT_ATTRS.keys())
     # query orders
     for order in orders_soup.query(query):
         # restrict order bookings for current vendor_uids
         order_data = OrderData(self.context,
                                order=order,
                                vendor_uids=vendor_uids)
         order_attrs = list()
         # order export attrs
         for attr_name in ORDER_EXPORT_ATTRS:
             val = self.export_val(order, attr_name)
             order_attrs.append(val)
         # computed order export attrs
         for attr_name in COMPUTED_ORDER_EXPORT_ATTRS:
             cb = COMPUTED_ORDER_EXPORT_ATTRS[attr_name]
             val = cb(self.context, order_data)
             val = cleanup_for_csv(val)
             order_attrs.append(val)
         for booking in order_data.bookings:
             booking_attrs = list()
             # booking export attrs
             for attr_name in BOOKING_EXPORT_ATTRS:
                 val = self.export_val(booking, attr_name)
                 booking_attrs.append(val)
             # computed booking export attrs
             for attr_name in COMPUTED_BOOKING_EXPORT_ATTRS:
                 cb = COMPUTED_BOOKING_EXPORT_ATTRS[attr_name]
                 val = cb(self.context, booking)
                 val = cleanup_for_csv(val)
                 booking_attrs.append(val)
             ex.writerow(order_attrs + booking_attrs)
             booking.attrs['exported'] = True
             bookings_soup.reindex(booking)
     # create and return response
     s_start = self.from_date.strftime('%G-%m-%d_%H-%M-%S')
     s_end = self.to_date.strftime('%G-%m-%d_%H-%M-%S')
     filename = 'orders-export-%s-%s.csv' % (s_start, s_end)
     self.request.response.setHeader('Content-Type', 'text/csv')
     self.request.response.setHeader('Content-Disposition',
                                     'attachment; filename=%s' % filename)
     ret = sio.getvalue()
     sio.close()
     return ret