~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/registry/vocabularies.py

  • Committer: Launchpad Patch Queue Manager
  • Date: 2011-07-28 17:34:34 UTC
  • mfrom: (13506.9.10 dsp-vocab-contracts)
  • Revision ID: launchpad@pqm.canonical.com-20110728173434-xm8jb9xmnhjuzb0i
[r=jcsackett][bug=817066] Fix DSP vocabs contract with
 IHugeVocabulary and its widgets. Added IDistribution adapters.

Show diffs side-by-side

added added

removed removed

Lines of Context:
80
80
    With,
81
81
    )
82
82
from storm.info import ClassAlias
 
83
from storm.store import EmptyResultSet
83
84
from zope.component import getUtility
84
85
from zope.interface import implements
85
86
from zope.schema.interfaces import IVocabularyTokenized
129
130
from lp.app.interfaces.launchpad import ILaunchpadCelebrities
130
131
from lp.blueprints.interfaces.specification import ISpecification
131
132
from lp.bugs.interfaces.bugtask import IBugTask
132
 
from lp.registry.interfaces.distribution import IDistribution
 
133
from lp.registry.interfaces.distribution import (
 
134
    IDistribution,
 
135
    IDistributionSet,
 
136
    )
133
137
from lp.registry.interfaces.distributionsourcepackage import (
134
138
    IDistributionSourcePackage,
135
139
    )
634
638
                    Person.id.is_in(public_inner_textual_select),
635
639
                    Person.visibility == PersonVisibility.PUBLIC,
636
640
                    Person.merged == None,
637
 
                    Or(# A valid person-or-team is either a team...
 
641
                    Or(  # A valid person-or-team is either a team...
638
642
                       # Note: 'Not' due to Bug 244768.
639
643
                       Not(Person.teamowner == None),
640
644
                       # Or a person who has a preferred email address.
830
834
                And(
831
835
                    SQL("Person.id = MatchingPerson.id"),
832
836
                    Or(
833
 
                        And(# A public person or team
 
837
                        And(  # A public person or team
834
838
                            Person.visibility == PersonVisibility.PUBLIC,
835
839
                            Person.merged == None,
836
 
                            Or(# A valid person-or-team is either a team...
 
840
                            Or(  # A valid person-or-team is either a team...
837
841
                                # Note: 'Not' due to Bug 244768.
838
842
                                Not(Person.teamowner == None),
839
843
                                # Or a person who has preferred email address.
1979
1983
 
1980
1984
    implements(IHugeVocabulary)
1981
1985
    displayname = 'Select a package'
1982
 
    step_title = 'Search'
 
1986
    step_title = 'Search by name or distro/name'
1983
1987
 
1984
1988
    def __init__(self, context):
1985
1989
        self.context = context
 
1990
        # Avoid circular import issues.
 
1991
        from lp.answers.interfaces.question import IQuestion
 
1992
        if IBugTask.providedBy(context) or IQuestion.providedBy(context):
 
1993
            target = context.target
 
1994
        else:
 
1995
            target = context
 
1996
        try:
 
1997
            self.distribution = IDistribution(target)
 
1998
        except TypeError:
 
1999
            self.distribution = None
1986
2000
 
1987
 
    def __contains__(self, obj):
1988
 
        pass
 
2001
    def __contains__(self, spn_or_dsp):
 
2002
        try:
 
2003
            self.toTerm(spn_or_dsp)
 
2004
            return True
 
2005
        except LookupError:
 
2006
            return False
1989
2007
 
1990
2008
    def __iter__(self):
1991
2009
        pass
1993
2011
    def __len__(self):
1994
2012
        pass
1995
2013
 
1996
 
    def toTerm(self, spn):
 
2014
    def getDistributionAndPackageName(self, text):
 
2015
        "Return the distribution and package name from the parsed text."
 
2016
        # Match the toTerm() format, but also use it to select a distribution.
 
2017
        distribution = None
 
2018
        if '/' in text:
 
2019
            distro_name, text = text.split('/', 1)
 
2020
            distribution = getUtility(IDistributionSet).getByName(distro_name)
 
2021
        if distribution is None:
 
2022
            distribution = self.distribution
 
2023
        return distribution, text
 
2024
 
 
2025
    def toTerm(self, spn_or_dsp, distribution=None):
1997
2026
        """See `IVocabulary`."""
1998
 
        dsp = self.context.getSourcePackage(spn)
1999
 
        if dsp.publishing_history:
 
2027
        dsp = None
 
2028
        if IDistributionSourcePackage.providedBy(spn_or_dsp):
 
2029
            dsp = spn_or_dsp
 
2030
            distribution = spn_or_dsp.distribution
 
2031
        else:
 
2032
            distribution = distribution or self.distribution
 
2033
            if distribution is not None and spn_or_dsp is not None:
 
2034
                dsp = distribution.getSourcePackage(spn_or_dsp)
 
2035
        try:
2000
2036
            binaries = dsp.publishing_history[0].getBuiltBinaries()
2001
 
            summary = ', '.join(
2002
 
                [binary.binary_package_name for binary in binaries])
2003
 
        else:
2004
 
            summary = "Not yet built."
2005
 
        token = '%s/%s' % (dsp.distribution.name, dsp.name)
2006
 
        return SimpleTerm(summary, token, dsp.name)
 
2037
            binary_names = [binary.binary_package_name for binary in binaries]
 
2038
            if binary_names != []:
 
2039
                summary = ', '.join(binary_names)
 
2040
            else:
 
2041
                summary = 'Not yet built.'
 
2042
            token = '%s/%s' % (dsp.distribution.name, dsp.name)
 
2043
            return SimpleTerm(dsp.sourcepackagename, token, summary)
 
2044
        except (IndexError, AttributeError):
 
2045
            # Either the DSP was None or there is no publishing history.
 
2046
            raise LookupError(distribution, spn_or_dsp)
2007
2047
 
2008
 
    def getTerm(self, spn):
 
2048
    def getTerm(self, spn_or_dsp):
2009
2049
        """See `IBaseVocabulary`."""
2010
 
        return self.toTerm(spn)
 
2050
        return self.toTerm(spn_or_dsp)
2011
2051
 
2012
2052
    def getTermByToken(self, token):
2013
2053
        """See `IVocabularyTokenized`."""
2014
 
        pass
 
2054
        distribution, package_name = self.getDistributionAndPackageName(token)
 
2055
        return self.toTerm(package_name, distribution)
2015
2056
 
2016
2057
    def searchForTerms(self, query=None):
2017
2058
        """See `IHugeVocabulary`."""
2018
 
        distribution = self.context
2019
 
        if query is None:
2020
 
            return
 
2059
        if not query:
 
2060
            return EmptyResultSet()
 
2061
        distribution, query = self.getDistributionAndPackageName(query)
 
2062
        if distribution is None:
 
2063
            # This could failover to ubuntu, but that is non-obvious. The
 
2064
            # Python widget must set the default distribution and the JS
 
2065
            # widget must encourage the <distro>/<package> search format.
 
2066
            return EmptyResultSet()
2021
2067
        search_term = unicode(query)
2022
2068
        store = IStore(SourcePackagePublishingHistory)
2023
2069
        spns = store.using(
2057
2103
                    SourcePackageName.name.contains_string(search_term),
2058
2104
                    BinaryPackageName.name.contains_string(
2059
2105
                        search_term))).config(distinct=True)
 
2106
        # XXX sinzui 2011-07-26: This query ignored SPN branches.
2060
2107
        return CountableIterator(spns.count(), spns, self.toTerm)