~launchpad-pqm/launchpad/devel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# Copyright 2009 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

# pylint: disable-msg=E0211,E0213

"""Interfaces for a Question."""

__metaclass__ = type

__all__ = [
    'IQuestionCollection',
    'IQuestionSet',
    'ISearchableByQuestionOwner',
    'QUESTION_STATUS_DEFAULT_SEARCH',
    ]

from zope.interface import (
    Attribute,
    Interface,
    )
from zope.schema import Int

from lazr.restful.declarations import (
    collection_default_content,
    export_as_webservice_collection,
    export_operation_as,
    export_read_operation,
    operation_for_version,
    operation_parameters,
    )

from canonical.launchpad import _
from lp.answers.interfaces.questionenums import QuestionStatus


QUESTION_STATUS_DEFAULT_SEARCH = (
    QuestionStatus.OPEN, QuestionStatus.NEEDSINFO, QuestionStatus.ANSWERED,
    QuestionStatus.SOLVED)


class IQuestionCollection(Interface):
    """An object that can be used to search through a collection of questions.
    """

    def searchQuestions(search_text=None,
                        status=QUESTION_STATUS_DEFAULT_SEARCH,
                        language=None, sort=None):
        """Return the questions from the collection matching search criteria.

        :search_text: A string that is matched against the question
        title and description. If None, the search_text is not included as
        a filter criteria.

        :status: A sequence of QuestionStatus Items. If None or an empty
        sequence, the status is not included as a filter criteria.

        :language: An ILanguage or a sequence of ILanguage objects to match
        against the question's language. If None or an empty sequence,
        the language is not included as a filter criteria.

        :sort: An attribute of QuestionSort. If None, a default value is used.
        When there is a search_text value, the default is to sort by
        RELEVANCY, otherwise results are sorted NEWEST_FIRST.
        """

    def getQuestionLanguages():
        """Return the set of ILanguage used by all the questions in the
        collection."""


class ISearchableByQuestionOwner(IQuestionCollection):
    """Collection that support searching by question owner."""

    def searchQuestions(search_text=None,
                        status=QUESTION_STATUS_DEFAULT_SEARCH,
                        language=None, sort=None, owner=None,
                        needs_attention_from=None):
        """Return the questions from the collection matching search criteria.

        See `IQuestionCollection` for the description of the standard search
        parameters.

        :owner: The IPerson that created the question.

        :needs_attention_from: Selects questions that nee attention from an
        IPerson. These are the questions in the NEEDSINFO or ANSWERED state
        owned by the person. The questions not owned by the person but on
        which the person requested for more information or gave an answer
        and that are back in the OPEN state are also included.
        """


class IQuestionSet(IQuestionCollection):
    """A utility that contain all the questions published in Launchpad."""

    export_as_webservice_collection(Interface)

    title = Attribute('Title')

    @operation_parameters(
        question_id=Int(
            title=_('The id of the question to get'),
            required=True))
    @export_read_operation()
    @export_operation_as("getByID")
    @operation_for_version('devel')
    def get(question_id, default=None):
        """Return the question with the given id.

        Return :default: if no such question exists.
        """

    def findExpiredQuestions(days_before_expiration):
        """Return the questions that are expired.

        Return all the questions in the Open or Needs information state,
        without an assignee or bug links, that did not receive any new
        comments in the last <days_before_expiration> days.
        """

    @collection_default_content(limit=5)
    def getMostActiveProjects(limit=5):
        """Return the list of projects that asked the most questions in
        the last 60 days.

        It should only return projects that officially uses the Answer
        Tracker.

        :param limit: The number of projects to return.
        """

    def getOpenQuestionCountByPackages(packages):
        """Return number of open questions for the list of packages.

        :param packages: A list of `IDistributionSourcePackage`
            instances.

        :return: a dictionary, where the package is the key, and the
            number of open questions the value.
        """