~launchpad-pqm/launchpad/devel

14022.1.2 by Curtis Hovey
Add UsesAnswersDistributionVocabulary.
1
# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
8687.15.11 by Karl Fogel
Add the copyright header block to files under lib/lp/answers/.
2
# GNU Affero General Public License version 3 (see the file LICENSE).
7944.3.24 by Francis J. Lacoste
Extracted out FAQVocabulary.
3
4
"""Named vocabularies defined by the Answers application."""
5
6
__metaclass__ = type
7
__all__ = [
8
    'FAQVocabulary',
14022.1.2 by Curtis Hovey
Add UsesAnswersDistributionVocabulary.
9
    'UsesAnswersDistributionVocabulary',
7944.3.24 by Francis J. Lacoste
Extracted out FAQVocabulary.
10
    ]
11
14022.1.2 by Curtis Hovey
Add UsesAnswersDistributionVocabulary.
12
from sqlobject import OR
7944.3.24 by Francis J. Lacoste
Extracted out FAQVocabulary.
13
from zope.interface import implements
14
from zope.schema.vocabulary import SimpleTerm
15
16
from canonical.launchpad.webapp.vocabulary import (
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
17
    CountableIterator,
13635.3.16 by Ian Booth
Fix some tests
18
    FilteredVocabularyBase,
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
19
    IHugeVocabulary,
20
    )
7944.3.24 by Francis J. Lacoste
Extracted out FAQVocabulary.
21
from lp.answers.interfaces.faq import IFAQ
22
from lp.answers.interfaces.faqtarget import IFAQTarget
14022.1.2 by Curtis Hovey
Add UsesAnswersDistributionVocabulary.
23
from lp.registry.interfaces.distribution import IDistribution
24
from lp.registry.vocabularies import DistributionVocabulary
7944.3.24 by Francis J. Lacoste
Extracted out FAQVocabulary.
25
26
13635.3.16 by Ian Booth
Fix some tests
27
class FAQVocabulary(FilteredVocabularyBase):
7944.3.24 by Francis J. Lacoste
Extracted out FAQVocabulary.
28
    """Vocabulary containing all the FAQs in an `IFAQTarget`."""
29
    implements(IHugeVocabulary)
30
31
    displayname = 'Select a FAQ'
11954.6.15 by Curtis Hovey
Added step_title to IHugeVocabulary.
32
    step_title = 'Search'
7944.3.24 by Francis J. Lacoste
Extracted out FAQVocabulary.
33
34
    def __init__(self, context):
35
        """Create a new vocabulary for the context.
36
37
        :param context: It should adaptable to `IFAQTarget`.
38
        """
39
        self.context = IFAQTarget(context)
40
41
    def __len__(self):
42
        """See `IIterableVocabulary`."""
43
        return self.context.searchFAQs().count()
44
45
    def __iter__(self):
46
        """See `IIterableVocabulary`."""
47
        for faq in self.context.searchFAQs():
48
            yield self.toTerm(faq)
49
50
    def __contains__(self, value):
51
        """See `IVocabulary`."""
52
        if not IFAQ.providedBy(value):
53
            return False
54
        return self.context.getFAQ(value.id) is not None
55
56
    def getTerm(self, value):
57
        """See `IVocabulary`."""
58
        if value not in self:
59
            raise LookupError(value)
60
        return self.toTerm(value)
61
62
    def getTermByToken(self, token):
63
        """See `IVocabularyTokenized`."""
64
        try:
14022.1.5 by Curtis Hovey
hush lint.
65
            int(token)
7944.3.24 by Francis J. Lacoste
Extracted out FAQVocabulary.
66
        except ValueError:
67
            raise LookupError(token)
68
        faq = self.context.getFAQ(token)
69
        if faq is None:
70
            raise LookupError(token)
71
        return self.toTerm(faq)
72
73
    def toTerm(self, faq):
74
        """Return the term for a FAQ."""
75
        return SimpleTerm(faq, faq.id, faq.title)
76
13635.3.1 by Ian Booth
Add basic vocab filtering infrastructure
77
    def searchForTerms(self, query=None, vocab_filter=None):
7944.3.24 by Francis J. Lacoste
Extracted out FAQVocabulary.
78
        """See `IHugeVocabulary`."""
79
        results = self.context.findSimilarFAQs(query)
80
        return CountableIterator(results.count(), results, self.toTerm)
14022.1.2 by Curtis Hovey
Add UsesAnswersDistributionVocabulary.
81
82
83
class UsesAnswersDistributionVocabulary(DistributionVocabulary):
84
    """Distributions that use Launchpad to track questions.
85
86
    If the context is a distribution, it is always included in the
87
    vocabulary. Historic data is not invalidated if a distro stops
88
    using Launchpad to track questions. This vocabulary offers the correct
89
    choices of distributions at this moment.
90
    """
91
92
    def __init__(self, context=None):
93
        super(UsesAnswersDistributionVocabulary, self).__init__(
94
            context=context)
95
        self.distribution = IDistribution(self.context, None)
96
97
    @property
98
    def _filter(self):
99
        if self.distribution is None:
100
            distro_id = 0
101
        else:
102
            distro_id = self.distribution.id
103
        return OR(
104
            self._table.q.official_answers == True,
105
            self._table.id == distro_id)