def paged_search()

in ForgeTracker/forgetracker/model/ticket.py [0:0]


    def paged_search(cls, app_config, user, q, limit=None, page=0, sort=None, show_deleted=False,
                     filter=None, **kw):
        """Query tickets from Solr, filtering for 'read' permission, sorting and paginating the result.

        See also paged_query which does a mongo search.

        We do the sorting and skipping right in SOLR, before we ever ask
        Mongo for the actual tickets.  Other keywords for
        search_artifact (e.g., history) or for SOLR are accepted through
        kw.  The output is intended to be used directly in templates,
        e.g., exposed controller methods can just:

            return paged_query(q, ...)

        If you want all the results at once instead of paged you have
        these options:
          - don't call this routine, search directly in mongo
          - call this routine with a very high limit and TEST that
            count<=limit in the result
        limit=-1 is NOT recognized as 'all'.  500 is a reasonable limit.
        """

        limit, page, start = g.handle_paging(limit, page, default=25)
        count = 0
        tickets = []
        if filter is None:
            filter = {}
        refined_sort = sort if sort else 'ticket_num_i desc'
        if 'ticket_num_i' not in refined_sort:
            refined_sort += ',ticket_num_i asc'
        try:
            if q:
                # also query for choices for filter options right away
                params = kw.copy()
                params.update(tsearch.FACET_PARAMS)
                if not show_deleted:
                    params['fq'] = ['deleted_b:False']

                matches = search_artifact(
                    cls, q, short_timeout=True,
                    rows=limit, sort=refined_sort, start=start, fl='id',
                    filter=filter, **params)
            else:
                matches = None
            solr_error = None
        except SearchError as e:
            solr_error = e
            matches = None
        if matches:
            count = matches.hits
            # ticket_matches is in sorted order
            ticket_matches = [ObjectId(match['id'].split('#')[1]) for match in matches.docs]
            query = cls.query.find(
                dict(_id={'$in': ticket_matches}))
            # so stick all the results in a dictionary...
            ticket_by_id = {}
            for t in query:
                ticket_by_id[t._id] = t
            # and pull them out in the order given by ticket_numbers
            tickets = []
            for t_id in ticket_matches:
                if t_id in ticket_by_id:
                    show_deleted = show_deleted and security.has_access(
                        ticket_by_id[t_id], 'delete', user, app_config.project.root_project)
                    if (security.has_access(ticket_by_id[t_id], 'read', user,
                                            app_config.project.root_project if app_config else None) and
                            (show_deleted or ticket_by_id[t_id].deleted is False)):
                        tickets.append(ticket_by_id[t_id])
                    else:
                        count = count - 1
        return dict(tickets=tickets,
                    count=count, q=q, limit=limit, page=page, sort=sort,
                    filter=filter,
                    filter_choices=tsearch.get_facets(matches),
                    solr_error=solr_error, **kw)