~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/soyuz/model/distroarchseriesbinarypackage.py

[r=sinzui][bug=855670] Add additional checks to the private team
        launchpad.LimitedView security adaptor so more users in defined
        roles can see the team.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2009 Canonical Ltd.  This software is licensed under the
 
2
# GNU Affero General Public License version 3 (see the file LICENSE).
 
3
 
 
4
# pylint: disable-msg=E0611,W0212
 
5
 
 
6
"""Classes to represent a binary package in a distroarchseries."""
 
7
 
 
8
__metaclass__ = type
 
9
 
 
10
__all__ = [
 
11
    'DistroArchSeriesBinaryPackage',
 
12
    ]
 
13
 
 
14
from storm.locals import Desc
 
15
from zope.interface import implements
 
16
 
 
17
from canonical.database.sqlbase import sqlvalues
 
18
from lp.services.database.lpstorm import IStore
 
19
from lp.app.errors import NotFoundError
 
20
from lp.services.propertycache import cachedproperty
 
21
from lp.soyuz.enums import PackagePublishingStatus
 
22
from lp.soyuz.interfaces.distroarchseriesbinarypackage import (
 
23
    IDistroArchSeriesBinaryPackage,
 
24
    )
 
25
from lp.soyuz.model.binarypackagerelease import BinaryPackageRelease
 
26
from lp.soyuz.model.distroarchseriesbinarypackagerelease import (
 
27
    DistroArchSeriesBinaryPackageRelease,
 
28
    )
 
29
from lp.soyuz.model.publishing import BinaryPackagePublishingHistory
 
30
 
 
31
 
 
32
class DistroArchSeriesBinaryPackage:
 
33
    """A Binary Package in the context of a Distro Arch Series.
 
34
 
 
35
    Binary Packages are "magic": they don't really exist in the
 
36
    database. Instead, they are synthesized based on information from
 
37
    the publishing and binarypackagerelease tables.
 
38
    """
 
39
 
 
40
    implements(IDistroArchSeriesBinaryPackage)
 
41
 
 
42
    def __init__(self, distroarchseries, binarypackagename):
 
43
        self.distroarchseries = distroarchseries
 
44
        self.binarypackagename = binarypackagename
 
45
 
 
46
    @property
 
47
    def name(self):
 
48
        """See IDistroArchSeriesBinaryPackage."""
 
49
        return self.binarypackagename.name
 
50
 
 
51
    @property
 
52
    def distroseries(self):
 
53
        """See IDistroArchSeries."""
 
54
        return self.distroarchseries.distroseries
 
55
 
 
56
    @property
 
57
    def distribution(self):
 
58
        """See IDistroArchSeries."""
 
59
        return self.distroseries.distribution
 
60
 
 
61
    @property
 
62
    def displayname(self):
 
63
        """See IDistroArchSeriesBinaryPackage."""
 
64
        return '%s in %s %s' % (
 
65
            self.binarypackagename.name,
 
66
            self.distroarchseries.distroseries.name,
 
67
            self.distroarchseries.architecturetag)
 
68
 
 
69
    @property
 
70
    def title(self):
 
71
        """See IDistroArchSeriesBinaryPackage."""
 
72
        return '"%s" binary package in %s' % (
 
73
            self.binarypackagename.name, self.distroarchseries.displayname)
 
74
 
 
75
    @cachedproperty
 
76
    def cache(self):
 
77
        """See IDistroArchSeriesBinaryPackage."""
 
78
        from lp.soyuz.model.distroseriespackagecache import (
 
79
            DistroSeriesPackageCache)
 
80
        query = """
 
81
            distroseries = %s AND
 
82
            archive IN %s AND
 
83
            binarypackagename = %s
 
84
        """ % sqlvalues(self.distroseries,
 
85
                        self.distribution.all_distro_archive_ids,
 
86
                        self.binarypackagename)
 
87
 
 
88
        return DistroSeriesPackageCache.selectOne(query)
 
89
 
 
90
    @property
 
91
    def summary(self):
 
92
        """See IDistroArchSeriesBinaryPackage."""
 
93
        curr = self.currentrelease
 
94
        if curr is not None:
 
95
            return curr.summary
 
96
        if self.cache is not None:
 
97
            return self.cache.summary
 
98
        return None
 
99
 
 
100
    @property
 
101
    def description(self):
 
102
        """See IDistroArchSeriesBinaryPackage."""
 
103
        curr = self.currentrelease
 
104
        if curr is not None:
 
105
            return curr.description
 
106
        if self.cache is not None:
 
107
            return self.cache.description
 
108
        return None
 
109
 
 
110
    def __getitem__(self, version):
 
111
        """See IDistroArchSeriesBinaryPackage."""
 
112
        query = """
 
113
        BinaryPackagePublishingHistory.distroarchseries = %s AND
 
114
        BinaryPackagePublishingHistory.archive IN %s AND
 
115
        BinaryPackagePublishingHistory.binarypackagerelease =
 
116
            BinaryPackageRelease.id AND
 
117
        BinaryPackageRelease.version = %s AND
 
118
        BinaryPackageRelease.binarypackagename = %s
 
119
        """ % sqlvalues(
 
120
                self.distroarchseries,
 
121
                self.distribution.all_distro_archive_ids,
 
122
                version,
 
123
                self.binarypackagename)
 
124
 
 
125
        bpph = BinaryPackagePublishingHistory.selectFirst(
 
126
            query, clauseTables=['binarypackagerelease'],
 
127
            orderBy=["-datecreated"])
 
128
 
 
129
        if bpph is None:
 
130
            return None
 
131
 
 
132
        return DistroArchSeriesBinaryPackageRelease(
 
133
            distroarchseries=self.distroarchseries,
 
134
            binarypackagerelease=bpph.binarypackagerelease)
 
135
 
 
136
    @property
 
137
    def releases(self):
 
138
        """See IDistroArchSeriesBinaryPackage."""
 
139
        ret = BinaryPackageRelease.select("""
 
140
            BinaryPackagePublishingHistory.distroarchseries = %s AND
 
141
            BinaryPackagePublishingHistory.archive IN %s AND
 
142
            BinaryPackagePublishingHistory.binarypackagerelease =
 
143
                BinaryPackageRelease.id AND
 
144
            BinaryPackageRelease.binarypackagename = %s
 
145
            """ % sqlvalues(
 
146
                    self.distroarchseries,
 
147
                    self.distribution.all_distro_archive_ids,
 
148
                    self.binarypackagename),
 
149
            orderBy='-datecreated',
 
150
            distinct=True,
 
151
            clauseTables=['BinaryPackagePublishingHistory'])
 
152
        result = []
 
153
        versions = set()
 
154
        for bpr in ret:
 
155
            if bpr.version not in versions:
 
156
                versions.add(bpr.version)
 
157
                darbpr = DistroArchSeriesBinaryPackageRelease(
 
158
                    distroarchseries=self.distroarchseries,
 
159
                    binarypackagerelease=bpr)
 
160
                result.append(darbpr)
 
161
        return result
 
162
 
 
163
    @property
 
164
    def currentrelease(self):
 
165
        """See IDistroArchSeriesBinaryPackage."""
 
166
        releases = BinaryPackageRelease.select("""
 
167
            BinaryPackageRelease.binarypackagename = %s AND
 
168
            BinaryPackageRelease.id =
 
169
                BinaryPackagePublishingHistory.binarypackagerelease AND
 
170
            BinaryPackagePublishingHistory.distroarchseries = %s AND
 
171
            BinaryPackagePublishingHistory.archive IN %s AND
 
172
            BinaryPackagePublishingHistory.status = %s
 
173
            """ % sqlvalues(
 
174
                    self.binarypackagename,
 
175
                    self.distroarchseries,
 
176
                    self.distribution.all_distro_archive_ids,
 
177
                    PackagePublishingStatus.PUBLISHED),
 
178
            orderBy='-datecreated',
 
179
            limit=1,
 
180
            distinct=True,
 
181
            clauseTables=['BinaryPackagePublishingHistory'])
 
182
 
 
183
        # Listify to limit the SQL queries to one only.
 
184
        results = list(releases)
 
185
        if len(results) == 0:
 
186
            return None
 
187
        return DistroArchSeriesBinaryPackageRelease(
 
188
            distroarchseries=self.distroarchseries,
 
189
            binarypackagerelease=results[0])
 
190
 
 
191
    @property
 
192
    def publishing_history(self):
 
193
        """See IDistroArchSeriesBinaryPackage."""
 
194
        return IStore(BinaryPackagePublishingHistory).find(
 
195
            BinaryPackagePublishingHistory,
 
196
            BinaryPackageRelease.binarypackagename == self.binarypackagename,
 
197
            BinaryPackagePublishingHistory.distroarchseries ==
 
198
                self.distroarchseries,
 
199
            BinaryPackagePublishingHistory.archiveID.is_in(
 
200
                self.distribution.all_distro_archive_ids),
 
201
            BinaryPackagePublishingHistory.binarypackagereleaseID ==
 
202
                BinaryPackageRelease.id).config(distinct=True).order_by(
 
203
                Desc(BinaryPackagePublishingHistory.datecreated))
 
204
 
 
205
    @property
 
206
    def current_published(self):
 
207
        """See IDistroArchSeriesBinaryPackage."""
 
208
        current = BinaryPackagePublishingHistory.selectFirst("""
 
209
            BinaryPackagePublishingHistory.distroarchseries = %s AND
 
210
            BinaryPackagePublishingHistory.archive IN %s AND
 
211
            BinaryPackagePublishingHistory.binarypackagerelease =
 
212
                BinaryPackageRelease.id AND
 
213
            BinaryPackageRelease.binarypackagename = %s AND
 
214
            BinaryPackagePublishingHistory.status = %s
 
215
            """ % sqlvalues(
 
216
                    self.distroarchseries,
 
217
                    self.distribution.all_distro_archive_ids,
 
218
                    self.binarypackagename,
 
219
                    PackagePublishingStatus.PUBLISHED),
 
220
            clauseTables=['BinaryPackageRelease'],
 
221
            orderBy='-datecreated')
 
222
 
 
223
        if current is None:
 
224
            raise NotFoundError("Binary package %s not published in %s/%s"
 
225
                                % (self.binarypackagename.name,
 
226
                                   self.distroarchseries.distroseries.name,
 
227
                                   self.distroarchseries.architecturetag))
 
228
 
 
229
        return current
 
230
 
 
231
    @property
 
232
    def distro_source_package(self):
 
233
        """See `IDistroArchSeriesBinaryPackage`."""
 
234
        # We provide a source package iff we have a current release
 
235
        # with a source package release.
 
236
        current_release = self.currentrelease
 
237
        if current_release is None:
 
238
            return None
 
239
 
 
240
        src_pkg_release = current_release.distributionsourcepackagerelease
 
241
        if src_pkg_release is None:
 
242
            return None
 
243
        else:
 
244
            return src_pkg_release.sourcepackage