~launchpad-pqm/launchpad/devel

8687.15.17 by Karl Fogel
Add the copyright header block to the rest of the files under lib/lp/.
1
# Copyright 2009 Canonical Ltd.  This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
4983.1.1 by Curtis Hovey
Added lint exceptions to __init__.py and interface/*.py.
4
# pylint: disable-msg=E0211,E0213
2068 by Canonical.com Patch Queue Manager
[r=SteveA/trivial] import fascism, kill translationeffort, kill sshkey browser code, add __all__s to interfaces, other cleanings-up
5
6
"""Product release interfaces."""
7
8
__metaclass__ = type
9
10
__all__ = [
11
    'IProductRelease',
6935.4.6 by Edwin Grubbs
Moved IProductReleaseSet.new() to IProductSeries.addRelease()
12
    'IProductReleaseEditRestricted',
3691.105.2 by James Henstridge
some tests for the ProductReleaseFinder class
13
    'IProductReleaseFile',
4195.1.1 by Brad Crittenden
Implement upload and management of files associated with a product release.
14
    'IProductReleaseFileAddForm',
6935.4.7 by Edwin Grubbs
Protected ProductRelease.addReleaseFile() and ProductReleaseFile.destroySelf()
15
    'IProductReleaseFileEditRestricted',
16
    'IProductReleaseFilePublic',
6935.4.6 by Edwin Grubbs
Moved IProductReleaseSet.new() to IProductSeries.addRelease()
17
    'IProductReleasePublic',
18
    'IProductReleaseSet',
4919.1.3 by Francis J. Lacoste
Upgrade UpstreamFileType enum to use new DBEnumeratedType API.
19
    'UpstreamFileType',
2068 by Canonical.com Patch Queue Manager
[r=SteveA/trivial] import fascism, kill translationeffort, kill sshkey browser code, add __all__s to interfaces, other cleanings-up
20
    ]
21
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
22
from lazr.enum import (
23
    DBEnumeratedType,
24
    DBItem,
25
    )
26
from lazr.restful.declarations import (
27
    call_with,
28
    export_as_webservice_entry,
29
    export_factory_operation,
30
    export_operation_as,
31
    export_write_operation,
32
    exported,
33
    operation_parameters,
34
    REQUEST_USER,
35
    )
36
from lazr.restful.fields import (
37
    CollectionField,
38
    Reference,
39
    ReferenceChoice,
40
    )
41
from lazr.restful.interface import copy_field
42
from zope.component import getUtility
6973.1.2 by Leonard Richardson
Delinted.
43
from zope.interface import Interface
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
44
from zope.schema import (
45
    Bytes,
46
    Choice,
47
    Datetime,
48
    Int,
49
    Text,
50
    TextLine,
51
    )
1102 by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs
52
14600.1.12 by Curtis Hovey
Move i18n to lp.
53
from lp import _
12442.2.2 by j.c.sackett
Moved validators to app, which makes more sense.
54
from lp.app.validators import LaunchpadValidationError
55
from lp.app.validators.version import sane_version
14612.2.1 by William Grant
format-imports on lib/. So many imports.
56
from lp.services.config import config
11318.5.1 by j.c.sackett
Migrated canonical.launchpad.fields to lp.services.fields
57
from lp.services.fields import (
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
58
    ContentNameField,
59
    PersonChoice,
60
    )
4919.1.3 by Francis J. Lacoste
Upgrade UpstreamFileType enum to use new DBEnumeratedType API.
61
62
7675.110.1 by Curtis Hovey
semi-manual changes in preperation to the the migration script. The registry
63
def file_size_constraint(value, max_size):
64
    """Check constraints.
65
66
    The file cannot be empty and must be <= max_size.
67
    """
68
    size = len(value)
69
    if size == 0:
70
        raise LaunchpadValidationError(u'Cannot upload empty file.')
71
    elif max_size > 0 and size > max_size:
72
        raise LaunchpadValidationError(
73
            u'Cannot upload files larger than %i bytes' % max_size)
74
    else:
75
        return True
76
77
78
def productrelease_file_size_constraint(value):
79
    """Constraint for a product release file's size."""
80
    max_size = config.launchpad.max_productrelease_file_size
81
    return file_size_constraint(value, max_size)
82
83
84
def productrelease_signature_size_constraint(value):
85
    """Constraint for a product release signature's size."""
86
    max_size = config.launchpad.max_productrelease_signature_size
87
    return file_size_constraint(value, max_size)
88
89
4919.1.3 by Francis J. Lacoste
Upgrade UpstreamFileType enum to use new DBEnumeratedType API.
90
class UpstreamFileType(DBEnumeratedType):
91
    """Upstream File Type
92
93
    When upstream open source project release a product they will
94
    include several files in the release. All of these files are
95
    stored in Launchpad (we throw nothing away ;-). This schema
96
    gives the type of files that we know about.
97
    """
98
99
    CODETARBALL = DBItem(1, """
100
        Code Release Tarball
101
102
        This file contains code in a compressed package like
103
        a tar.gz or tar.bz or .zip file.
104
        """)
105
106
    README = DBItem(2, """
107
        README File
108
109
        This is a README associated with the upstream
110
        release. It might be in .txt or .html format, the
111
        filename would be an indicator.
112
        """)
113
114
    RELEASENOTES = DBItem(3, """
115
        Release Notes
116
117
        This file contains the release notes of the new
118
        upstream release. Again this could be in .txt or
119
        in .html format.
120
        """)
121
122
    CHANGELOG = DBItem(4, """
123
        ChangeLog File
124
125
        This file contains information about changes in this
126
        release from the previous release in the series. This
127
        is usually not a detailed changelog, but a high-level
128
        summary of major new features and fixes.
129
        """)
130
131
    INSTALLER = DBItem(5, """
132
        Installer file
133
134
        This file contains an installer for a product.  It may
135
        be a Debian package, an RPM file, an OS X disk image, a
136
        Windows installer, or some other type of installer.
137
        """)
138
2852.1.21 by gneuman at async
Fix https://launchpad.net/products/launchpad/+bug/3371, creates class ProductReleaseVersionField and method getBySeriesAndVersion, improve test milestone-add to test for dupe version, [trivial] change icon for addrelease from edit to add. r=kiko
139
140
class ProductReleaseVersionField(ContentNameField):
4195.1.1 by Brad Crittenden
Implement upload and management of files associated with a product release.
141
2852.1.21 by gneuman at async
Fix https://launchpad.net/products/launchpad/+bug/3371, creates class ProductReleaseVersionField and method getBySeriesAndVersion, improve test milestone-add to test for dupe version, [trivial] change icon for addrelease from edit to add. r=kiko
142
    errormessage = _(
4152.2.3 by Francis J. Lacoste
Rename "product" to "project" in browser code, and some "project" to "project group".
143
        "%s is already in use by another version in this release series.")
2852.1.21 by gneuman at async
Fix https://launchpad.net/products/launchpad/+bug/3371, creates class ProductReleaseVersionField and method getBySeriesAndVersion, improve test milestone-add to test for dupe version, [trivial] change icon for addrelease from edit to add. r=kiko
144
145
    @property
146
    def _content_iface(self):
147
        return IProductRelease
4195.1.1 by Brad Crittenden
Implement upload and management of files associated with a product release.
148
2852.1.21 by gneuman at async
Fix https://launchpad.net/products/launchpad/+bug/3371, creates class ProductReleaseVersionField and method getBySeriesAndVersion, improve test milestone-add to test for dupe version, [trivial] change icon for addrelease from edit to add. r=kiko
149
    def _getByName(self, version):
6901.1.3 by Brad Crittenden
Post-review changes.
150
        """Return the content object for the specified version.
151
152
        The version is specified either by the context directly or by the
153
        context's referenced productseries.  Overridden from
154
        `ContentFieldName`.
155
        """
6901.1.1 by Brad Crittenden
Add export of productseries to the API.
156
        # Import locally to avoid circular imports.
7675.110.3 by Curtis Hovey
Ran the migration script to move registry code to lp.registry.
157
        from lp.registry.interfaces.productseries import (
6901.1.1 by Brad Crittenden
Add export of productseries to the API.
158
            IProductSeries)
2852.1.21 by gneuman at async
Fix https://launchpad.net/products/launchpad/+bug/3371, creates class ProductReleaseVersionField and method getBySeriesAndVersion, improve test milestone-add to test for dupe version, [trivial] change icon for addrelease from edit to add. r=kiko
159
        if IProductSeries.providedBy(self.context):
160
            productseries = self.context
161
        else:
162
            productseries = self.context.productseries
163
        releaseset = getUtility(IProductReleaseSet)
7709.3.3 by Curtis Hovey
Fixed old tests and added new tests to verify that productreleases can manage their version field.
164
        release = releaseset.getBySeriesAndVersion(productseries, version)
165
        if release == self.context:
166
            # A ProductRelease may edit itself; do not report that another
167
            # ProductRelease exists with the same version.
168
            return None
169
        return release
1712 by Canonical.com Patch Queue Manager
Removing DB class import in browser/productrelease r=spiv.
170
171
6935.4.9 by Edwin Grubbs
Merged in RF
172
class IProductReleaseFileEditRestricted(Interface):
6935.4.10 by Edwin Grubbs
Fixed issues raised by reviewer.
173
    """`IProductReleaseFile` properties which require `launchpad.Edit`."""
6935.4.9 by Edwin Grubbs
Merged in RF
174
6935.7.7 by Brad Crittenden
Add IProductReleaseFile.delete
175
    @export_write_operation()
176
    @export_operation_as('delete')
6935.4.9 by Edwin Grubbs
Merged in RF
177
    def destroySelf():
178
        """Delete the product release file."""
179
180
181
class IProductReleaseFilePublic(Interface):
6935.4.10 by Edwin Grubbs
Fixed issues raised by reviewer.
182
    """Public properties for `IProductReleaseFile`."""
6916.3.1 by Brad Crittenden
Initial export of IProductReleaseFile.
183
184
    id = Int(title=_('ID'), required=True, readonly=True)
185
    productrelease = exported(
186
        ReferenceChoice(title=_('Project release'),
6916.3.2 by Brad Crittenden
Export ProductReleaseFile attributes.
187
                        description=_("The parent product release."),
188
                        schema=Interface, # Defined later.
189
                        required=True,
190
                        vocabulary='ProductRelease'),
6916.3.1 by Brad Crittenden
Initial export of IProductReleaseFile.
191
        exported_as='project_release')
6916.3.2 by Brad Crittenden
Export ProductReleaseFile attributes.
192
    libraryfile = exported(
193
        Bytes(title=_("File"),
194
              description=_("The file contents."),
6916.3.7 by Brad Crittenden
Updated test to show file and signature cannot be modified.
195
              readonly=True,
6916.3.2 by Brad Crittenden
Export ProductReleaseFile attributes.
196
              required=True),
197
        exported_as='file')
198
    signature = exported(
199
        Bytes(title=_("File signature"),
200
              description=_("The file signature."),
6916.3.7 by Brad Crittenden
Updated test to show file and signature cannot be modified.
201
              readonly=True,
6916.3.2 by Brad Crittenden
Export ProductReleaseFile attributes.
202
              required=False))
203
    filetype = exported(
204
        Choice(title=_("Upstream file type"), required=True,
205
               vocabulary=UpstreamFileType,
206
               default=UpstreamFileType.CODETARBALL),
207
        exported_as='file_type')
208
    description = exported(
209
        Text(title=_("Description"), required=False,
210
             description=_('A detailed description of the file contents')))
211
    date_uploaded = exported(
212
        Datetime(title=_('Upload date'),
213
                 description=_('The date this file was uploaded'),
214
                 required=True, readonly=True))
6916.3.1 by Brad Crittenden
Initial export of IProductReleaseFile.
215
216
6935.4.9 by Edwin Grubbs
Merged in RF
217
class IProductReleaseFile(IProductReleaseFileEditRestricted,
218
                          IProductReleaseFilePublic):
219
    """A file associated with a ProductRelease."""
12243.5.11 by Leonard Richardson
Cleared up some more test failures and things that shouldn't publish web_link.
220
    export_as_webservice_entry("project_release_file", publish_web_link=False)
6935.4.9 by Edwin Grubbs
Merged in RF
221
222
6935.4.6 by Edwin Grubbs
Moved IProductReleaseSet.new() to IProductSeries.addRelease()
223
class IProductReleaseEditRestricted(Interface):
6935.4.10 by Edwin Grubbs
Fixed issues raised by reviewer.
224
    """`IProductRelease` properties which require `launchpad.Edit`."""
6935.4.6 by Edwin Grubbs
Moved IProductReleaseSet.new() to IProductSeries.addRelease()
225
6935.7.3 by Brad Crittenden
Exporting add_files to IProductRelease. Interim checkin.
226
    @call_with(uploader=REQUEST_USER)
227
    @operation_parameters(
228
        filename=TextLine(),
229
        signature_filename=TextLine(),
230
        content_type=TextLine(),
231
        file_content=Bytes(constraint=productrelease_file_size_constraint),
6935.7.7 by Brad Crittenden
Add IProductReleaseFile.delete
232
        signature_content=Bytes(
233
            constraint=productrelease_signature_size_constraint),
234
        file_type=copy_field(IProductReleaseFile['filetype'], required=False)
6935.7.3 by Brad Crittenden
Exporting add_files to IProductRelease. Interim checkin.
235
        )
236
    @export_factory_operation(
6935.7.7 by Brad Crittenden
Add IProductReleaseFile.delete
237
        IProductReleaseFile, ['description'])
6935.7.3 by Brad Crittenden
Exporting add_files to IProductRelease. Interim checkin.
238
    @export_operation_as('add_file')
6935.7.7 by Brad Crittenden
Add IProductReleaseFile.delete
239
    def addReleaseFile(filename, file_content, content_type,
6935.4.13 by Edwin Grubbs
Fixed tests.
240
                       uploader, signature_filename=None,
6935.7.7 by Brad Crittenden
Add IProductReleaseFile.delete
241
                       signature_content=None,
242
                       file_type=UpstreamFileType.CODETARBALL,
6935.4.6 by Edwin Grubbs
Moved IProductReleaseSet.new() to IProductSeries.addRelease()
243
                       description=None):
6935.7.3 by Brad Crittenden
Exporting add_files to IProductRelease. Interim checkin.
244
        """Add file to the library and link to this `IProductRelease`.
6935.4.6 by Edwin Grubbs
Moved IProductReleaseSet.new() to IProductSeries.addRelease()
245
246
        The signature file will also be added if available.
6935.4.10 by Edwin Grubbs
Fixed issues raised by reviewer.
247
248
        :param filename: Name of the file being uploaded.
6935.4.13 by Edwin Grubbs
Fixed tests.
249
        :param file_content: StringIO or file object.
6935.4.10 by Edwin Grubbs
Fixed issues raised by reviewer.
250
        :param content_type: A MIME content type string.
6935.4.13 by Edwin Grubbs
Fixed tests.
251
        :param uploader: The person who uploaded the file.
6935.4.10 by Edwin Grubbs
Fixed issues raised by reviewer.
252
        :param signature_filename: Name of the uploaded gpg signature file.
6935.4.13 by Edwin Grubbs
Fixed tests.
253
        :param signature_content: StringIO or file object.
6935.7.7 by Brad Crittenden
Add IProductReleaseFile.delete
254
        :param file_type: An `UpstreamFileType` enum value.
6935.4.10 by Edwin Grubbs
Fixed issues raised by reviewer.
255
        :param description: Info about the file.
256
        :returns: `IProductReleaseFile` object.
6935.4.6 by Edwin Grubbs
Moved IProductReleaseSet.new() to IProductSeries.addRelease()
257
        """
258
7107.1.1 by Guilherme Salgado
Expose destroySelf() on IProductRelease
259
    @export_write_operation()
260
    @export_operation_as('delete')
261
    def destroySelf():
262
        """Delete this product release.
263
264
        This method must not be used if this product release has any
265
        release files associated with it.
266
        """
267
6935.4.6 by Edwin Grubbs
Moved IProductReleaseSet.new() to IProductSeries.addRelease()
268
269
class IProductReleasePublic(Interface):
6935.4.10 by Edwin Grubbs
Fixed issues raised by reviewer.
270
    """Public `IProductRelease` properties."""
6327.12.5 by Francis J. Lacoste
Made IProject, IProduct, IProductSeries, IProductRelease, IMilestone available on the web service.
271
1102 by Canonical.com Patch Queue Manager
Lucille had some XXXs which should have been NOTEs
272
    id = Int(title=_('ID'), required=True, readonly=True)
6973.1.1 by Leonard Richardson
Initial implementation.
273
274
    datereleased = exported(
275
        Datetime(
7675.85.2 by Jonathan Lange
Undo revision generated by step 2 of process.
276
            title=_('Date released'), required=True,
6973.1.1 by Leonard Richardson
Initial implementation.
277
            readonly=False,
278
            description=_('The date this release was published. Before '
279
                          'release, this should have an estimated '
280
                          'release date.')),
281
        exported_as="date_released"
282
        )
283
6327.12.5 by Francis J. Lacoste
Made IProject, IProduct, IProductSeries, IProductRelease, IMilestone available on the web service.
284
    version = exported(
285
        ProductReleaseVersionField(
286
            title=_('Version'),
6973.1.1 by Leonard Richardson
Initial implementation.
287
            description= u'The specific version number assigned to this '
288
            'release. Letters and numbers are acceptable, for releases like '
289
            '"1.2rc3".',
7709.3.2 by Curtis Hovey
Deleting a release now deletes the files attached to a release too. Updated the
290
            constraint=sane_version)
6973.1.1 by Leonard Richardson
Initial implementation.
291
        )
292
293
    owner = exported(
7675.759.1 by Brad Crittenden
Destroy PRIVATE_MEMBERSHIP teams and remove them from the face of the Earth.
294
        PersonChoice(
9606.1.5 by Brad Crittenden
Allow ProductRelease and TranslationImportQueueEntry to be owned/imported by a private team.
295
            title=u"The owner of this release.",
296
            required=True,
297
            vocabulary='ValidOwner',
298
            description=_("The person or team who owns  his product release.")
6973.1.1 by Leonard Richardson
Initial implementation.
299
            )
9606.1.5 by Brad Crittenden
Allow ProductRelease and TranslationImportQueueEntry to be owned/imported by a private team.
300
        )
6973.1.1 by Leonard Richardson
Initial implementation.
301
7675.85.2 by Jonathan Lange
Undo revision generated by step 2 of process.
302
    productseries = Choice(
303
        title=_('Release series'), readonly=True,
304
        vocabulary='FilteredProductSeries')
305
306
    codename = TextLine(
307
        title=u'Code name', required=False, readonly=True,
308
        description=_('The release code-name. This is deprecated, '
309
                      'since it was moved to the milestone.'))
310
311
    summary = Text(
312
        title=_("Summary"), required=False, readonly=True,
313
        description=_('A brief summary of the release highlights, to '
314
                      'be shown at the top of the release page, and in '
315
                      'listings.'))
316
317
    release_notes = exported(
318
        Text(
319
            title=_("Release notes"), required=False,
320
            description=_('A description of important new features '
6973.1.1 by Leonard Richardson
Initial implementation.
321
                          '(though the changelog below might repeat some of '
7675.85.2 by Jonathan Lange
Undo revision generated by step 2 of process.
322
                          'this information).'))
7276.2.25 by Edwin Grubbs
Add date_released and release_notes arguments to milestone.createProductRelease().
323
        )
6973.1.1 by Leonard Richardson
Initial implementation.
324
325
    changelog = exported(
326
        Text(
7675.85.2 by Jonathan Lange
Undo revision generated by step 2 of process.
327
            title=_('Changelog'), required=False,
328
            description=_('A description of every change in the release.'))
6973.1.1 by Leonard Richardson
Initial implementation.
329
        )
330
331
    datecreated = exported(
332
        Datetime(title=_('Date Created'),
333
                 description=_("The date this project release was created in "
334
                               "Launchpad."),
335
                 required=True, readonly=True),
336
        exported_as="date_created")
337
338
    displayname = exported(
339
        Text(title=u'Constructed display name for a project release.',
340
             readonly=True),
341
        exported_as="display_name")
342
343
    title = exported(
7675.85.2 by Jonathan Lange
Undo revision generated by step 2 of process.
344
        Text(title=u'Constructed title for a project release.', readonly=True)
6973.1.1 by Leonard Richardson
Initial implementation.
345
        )
346
347
    product = exported(
6973.1.4 by Leonard Richardson
Changed Objects to References.
348
        Reference(title=u'The upstream project of this release.',
349
                  schema=Interface, readonly=True),
6973.1.1 by Leonard Richardson
Initial implementation.
350
         exported_as="project")
351
6916.3.1 by Brad Crittenden
Initial export of IProductReleaseFile.
352
    files = exported(
353
        CollectionField(
354
            title=_('Project release files'),
6973.1.1 by Leonard Richardson
Initial implementation.
355
            description=_('A list of files for this release.'),
6916.3.1 by Brad Crittenden
Initial export of IProductReleaseFile.
356
            readonly=True,
357
            value_type=Reference(schema=IProductReleaseFile)))
1725 by Canonical.com Patch Queue Manager
merge fixes from carlos (r=sabdfl) and other small page changes (trivial)
358
7675.85.2 by Jonathan Lange
Undo revision generated by step 2 of process.
359
    milestone = exported(
7675.118.1 by Edwin Grubbs
Working form for creating a product release off of the series.
360
        ReferenceChoice(
7675.118.14 by Edwin Grubbs
Made fixes for review.
361
            title=u"Milestone for this release",
7675.119.3 by Edwin Grubbs
Handled review comments and fixed test.
362
            description=_("A release requires a corresponding milestone "
363
                          "that is not attached to another release."),
7675.85.2 by Jonathan Lange
Undo revision generated by step 2 of process.
364
            # Schema is set to IMilestone in interfaces/milestone.py.
365
            schema=Interface,
7675.118.1 by Edwin Grubbs
Working form for creating a product release off of the series.
366
            vocabulary='Milestone',
7675.85.2 by Jonathan Lange
Undo revision generated by step 2 of process.
367
            required=True))
368
4195.1.1 by Brad Crittenden
Implement upload and management of files associated with a product release.
369
    def getFileAliasByName(name):
6916.3.8 by Brad Crittenden
Post-review changes
370
        """Return the `LibraryFileAlias` by file name.
371
372
        Raises a NotFoundError if no matching ProductReleaseFile exists.
373
        """
6916.3.1 by Brad Crittenden
Initial export of IProductReleaseFile.
374
375
    def getProductReleaseFileByName(name):
6916.3.8 by Brad Crittenden
Post-review changes
376
        """Return the `ProductReleaseFile` by file name.
6916.3.1 by Brad Crittenden
Initial export of IProductReleaseFile.
377
6916.3.8 by Brad Crittenden
Post-review changes
378
        Raises a NotFoundError if no matching ProductReleaseFile exists.
6916.3.1 by Brad Crittenden
Initial export of IProductReleaseFile.
379
        """
4919.1.13 by Francis J. Lacoste
DBEnumeratedType can be used directly as vocabulary.
380
7675.759.10 by Brad Crittenden
Fixed lint issues
381
6935.4.6 by Edwin Grubbs
Moved IProductReleaseSet.new() to IProductSeries.addRelease()
382
class IProductRelease(IProductReleaseEditRestricted,
383
                      IProductReleasePublic):
6935.4.10 by Edwin Grubbs
Fixed issues raised by reviewer.
384
    """A specific release (i.e. version) of a product.
385
386
    For example: Mozilla 1.7.2 or Apache 2.0.48.
387
    """
6935.4.6 by Edwin Grubbs
Moved IProductReleaseSet.new() to IProductSeries.addRelease()
388
6935.4.9 by Edwin Grubbs
Merged in RF
389
    export_as_webservice_entry('project_release')
390
7675.759.10 by Brad Crittenden
Fixed lint issues
391
6916.3.2 by Brad Crittenden
Export ProductReleaseFile attributes.
392
# Set the schema for IProductReleaseFile now that IProductRelease is defined.
393
IProductReleaseFile['productrelease'].schema = IProductRelease
394
6935.4.7 by Edwin Grubbs
Protected ProductRelease.addReleaseFile() and ProductReleaseFile.destroySelf()
395
4195.1.1 by Brad Crittenden
Implement upload and management of files associated with a product release.
396
class IProductReleaseFileAddForm(Interface):
397
    """Schema for adding ProductReleaseFiles to a project."""
398
    description = Text(title=_("Description"), required=True,
399
        description=_('A short description of the file contents'))
400
401
    filecontent = Bytes(
402
        title=u"File", required=True,
403
        constraint=productrelease_file_size_constraint)
404
5258.3.6 by Brad Crittenden
changes from db review
405
    signature = Bytes(
406
        title=u"GPG signature (recommended)", required=False,
407
        constraint=productrelease_signature_size_constraint)
408
4195.1.1 by Brad Crittenden
Implement upload and management of files associated with a product release.
409
    contenttype = Choice(title=_("File content type"), required=True,
4919.1.13 by Francis J. Lacoste
DBEnumeratedType can be used directly as vocabulary.
410
                         vocabulary=UpstreamFileType,
4195.1.1 by Brad Crittenden
Implement upload and management of files associated with a product release.
411
                         default=UpstreamFileType.CODETARBALL)
3691.105.2 by James Henstridge
some tests for the ProductReleaseFinder class
412
6935.4.6 by Edwin Grubbs
Moved IProductReleaseSet.new() to IProductSeries.addRelease()
413
2162 by Canonical.com Patch Queue Manager
cleanup and portlet love [r=stevea]
414
class IProductReleaseSet(Interface):
415
    """Auxiliary class for ProductRelease handling."""
416
3504.1.48 by kiko
Remove self arguments from some interfaces
417
    def getBySeriesAndVersion(productseries, version, default=None):
2852.1.21 by gneuman at async
Fix https://launchpad.net/products/launchpad/+bug/3371, creates class ProductReleaseVersionField and method getBySeriesAndVersion, improve test milestone-add to test for dupe version, [trivial] change icon for addrelease from edit to add. r=kiko
418
        """Get a release by its version and productseries.
419
4195.1.1 by Brad Crittenden
Implement upload and management of files associated with a product release.
420
        If no release is found, default will be returned.
2852.1.21 by gneuman at async
Fix https://launchpad.net/products/launchpad/+bug/3371, creates class ProductReleaseVersionField and method getBySeriesAndVersion, improve test milestone-add to test for dupe version, [trivial] change icon for addrelease from edit to add. r=kiko
421
        """
6609.5.3 by Brad Crittenden
Add decorated classes for ProductSeries to view classes to reduce database accesses.
422
9760.8.1 by Brad Crittenden
Change the non-English 'serieses' to 'series' throughout our codebase.
423
    def getReleasesForSeries(series):
424
        """Get all releases for the series."""
6609.5.3 by Brad Crittenden
Add decorated classes for ProductSeries to view classes to reduce database accesses.
425
426
    def getFilesForReleases(releases):
427
        """Get all files for the releases."""