11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
1 |
# Copyright 2010 Canonical Ltd. This software is licensed under the
|
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
|
3 |
||
4 |
"""SourcePackageRecipeBuild views."""
|
|
5 |
||
6 |
__metaclass__ = type |
|
7 |
||
8 |
__all__ = [ |
|
11070.3.6
by Paul Hummer
Made the menu show up in the UI |
9 |
'SourcePackageRecipeBuildContextMenu', |
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
10 |
'SourcePackageRecipeBuildNavigation', |
11 |
'SourcePackageRecipeBuildView', |
|
11070.3.15
by Paul Hummer
Made changes per Aaron's review |
12 |
'SourcePackageRecipeBuildCancelView', |
11070.4.1
by Paul Hummer
Added rescore flow |
13 |
'SourcePackageRecipeBuildRescoreView', |
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
14 |
]
|
15 |
||
11070.3.8
by Paul Hummer
Tests, working, hooraybzr break-lock |
16 |
from zope.interface import Interface |
11227.1.2
by Paul Hummer
Fixed rescore to use a text field |
17 |
from zope.schema import Int |
11070.3.8
by Paul Hummer
Tests, working, hooraybzr break-lock |
18 |
|
11929.9.1
by Tim Penhey
Move launchpadform into lp.app.browser. |
19 |
from lp.app.browser.launchpadform import ( |
20 |
action, |
|
21 |
LaunchpadFormView, |
|
22 |
)
|
|
11458.1.1
by Jelmer Vernooij
Move enums of buildmaster. |
23 |
from lp.buildmaster.enums import BuildStatus |
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
24 |
from lp.code.interfaces.sourcepackagerecipebuild import ( |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
25 |
ISourcePackageRecipeBuild, |
26 |
)
|
|
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
27 |
from lp.services.job.interfaces.job import JobStatus |
14578.2.1
by William Grant
Move librarian stuff from canonical.launchpad to lp.services.librarian. canonical.librarian remains untouched. |
28 |
from lp.services.librarian.browser import FileNavigationMixin |
14513.4.3
by Raphael Badin
Cleanup cache when appropriate. |
29 |
from lp.services.propertycache import ( |
30 |
cachedproperty, |
|
31 |
)
|
|
14612.2.1
by William Grant
format-imports on lib/. So many imports. |
32 |
from lp.services.webapp import ( |
33 |
canonical_url, |
|
34 |
ContextMenu, |
|
35 |
enabled_with_permission, |
|
36 |
LaunchpadView, |
|
37 |
Link, |
|
38 |
Navigation, |
|
39 |
)
|
|
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
40 |
|
41 |
||
11213.1.1
by Paul Hummer
Cancel builds when in a non-final state. |
42 |
UNEDITABLE_BUILD_STATES = ( |
43 |
BuildStatus.FULLYBUILT, |
|
44 |
BuildStatus.FAILEDTOBUILD, |
|
45 |
BuildStatus.SUPERSEDED, |
|
46 |
BuildStatus.FAILEDTOUPLOAD,) |
|
47 |
||
12176.1.1
by Aaron Bentley
No oopses when rescoring non-queued recipe builds. |
48 |
|
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
49 |
class SourcePackageRecipeBuildNavigation(Navigation, FileNavigationMixin): |
50 |
||
51 |
usedfor = ISourcePackageRecipeBuild |
|
52 |
||
53 |
||
11070.3.6
by Paul Hummer
Made the menu show up in the UI |
54 |
class SourcePackageRecipeBuildContextMenu(ContextMenu): |
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
55 |
"""Navigation menu for sourcepackagerecipe build."""
|
56 |
||
57 |
usedfor = ISourcePackageRecipeBuild |
|
58 |
||
59 |
facet = 'branches' |
|
60 |
||
11070.4.1
by Paul Hummer
Added rescore flow |
61 |
links = ('cancel', 'rescore') |
11070.3.6
by Paul Hummer
Made the menu show up in the UI |
62 |
|
11316.3.6
by Paul Hummer
Swapped recipe build permissions launchpad.Edit to launchpad.Admin |
63 |
@enabled_with_permission('launchpad.Admin') |
11070.3.14
by Paul Hummer
Got cancel build working in the UI |
64 |
def cancel(self): |
11213.1.3
by Paul Hummer
Prevent breakage in db-devel |
65 |
if self.context.status in UNEDITABLE_BUILD_STATES: |
11070.4.4
by Paul Hummer
Made it so that the build can't be created in a wrong state |
66 |
enabled = False |
67 |
else: |
|
68 |
enabled = True |
|
69 |
return Link('+cancel', 'Cancel build', icon='remove', enabled=enabled) |
|
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
70 |
|
11316.3.6
by Paul Hummer
Swapped recipe build permissions launchpad.Edit to launchpad.Admin |
71 |
@enabled_with_permission('launchpad.Admin') |
11070.4.1
by Paul Hummer
Added rescore flow |
72 |
def rescore(self): |
11213.1.3
by Paul Hummer
Prevent breakage in db-devel |
73 |
if self.context.status in UNEDITABLE_BUILD_STATES: |
11070.4.3
by Paul Hummer
Enforced that the build actually has to be in progress to be able to rescore it |
74 |
enabled = False |
75 |
else: |
|
76 |
enabled = True |
|
77 |
return Link('+rescore', 'Rescore build', icon='edit', enabled=enabled) |
|
11070.4.1
by Paul Hummer
Added rescore flow |
78 |
|
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
79 |
|
80 |
class SourcePackageRecipeBuildView(LaunchpadView): |
|
81 |
"""Default view of a SourcePackageRecipeBuild."""
|
|
82 |
||
83 |
@property
|
|
84 |
def status(self): |
|
85 |
"""A human-friendly status string."""
|
|
11121.4.7
by Aaron Bentley
Merged db-devel into package-build-recipe. |
86 |
if (self.context.status == BuildStatus.NEEDSBUILD |
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
87 |
and self.eta is None): |
88 |
return 'No suitable builders' |
|
89 |
return { |
|
90 |
BuildStatus.NEEDSBUILD: 'Pending build', |
|
11039.2.31
by Jelmer Vernooij
Display uploading status properly. |
91 |
BuildStatus.UPLOADING: 'Build uploading', |
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
92 |
BuildStatus.FULLYBUILT: 'Successful build', |
93 |
BuildStatus.MANUALDEPWAIT: ( |
|
94 |
'Could not build because of missing dependencies'), |
|
95 |
BuildStatus.CHROOTWAIT: ( |
|
96 |
'Could not build because of chroot problem'), |
|
97 |
BuildStatus.SUPERSEDED: ( |
|
98 |
'Could not build because source package was superseded'), |
|
99 |
BuildStatus.FAILEDTOUPLOAD: 'Could not be uploaded correctly', |
|
11121.4.7
by Aaron Bentley
Merged db-devel into package-build-recipe. |
100 |
}.get(self.context.status, self.context.status.title) |
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
101 |
|
11889.4.4
by Tim Penhey
Cache some build properties in the view used on the recipe pages. |
102 |
@cachedproperty
|
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
103 |
def eta(self): |
104 |
"""The datetime when the build job is estimated to complete.
|
|
105 |
||
106 |
This is the BuildQueue.estimated_duration plus the
|
|
107 |
Job.date_started or BuildQueue.getEstimatedJobStartTime.
|
|
108 |
"""
|
|
109 |
if self.context.buildqueue_record is None: |
|
110 |
return None |
|
111 |
queue_record = self.context.buildqueue_record |
|
112 |
if queue_record.job.status == JobStatus.WAITING: |
|
113 |
start_time = queue_record.getEstimatedJobStartTime() |
|
114 |
if start_time is None: |
|
115 |
return None |
|
116 |
else: |
|
117 |
start_time = queue_record.job.date_started |
|
118 |
duration = queue_record.estimated_duration |
|
119 |
return start_time + duration |
|
120 |
||
11889.4.4
by Tim Penhey
Cache some build properties in the view used on the recipe pages. |
121 |
@cachedproperty
|
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
122 |
def date(self): |
123 |
"""The date when the build completed or is estimated to complete."""
|
|
124 |
if self.estimate: |
|
125 |
return self.eta |
|
11121.4.7
by Aaron Bentley
Merged db-devel into package-build-recipe. |
126 |
return self.context.date_finished |
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
127 |
|
11889.4.4
by Tim Penhey
Cache some build properties in the view used on the recipe pages. |
128 |
@cachedproperty
|
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
129 |
def estimate(self): |
130 |
"""If true, the date value is an estimate."""
|
|
11121.4.7
by Aaron Bentley
Merged db-devel into package-build-recipe. |
131 |
if self.context.date_finished is not None: |
11070.3.3
by Paul Hummer
Created lp.code.browser.sourcepackagerecipebuild |
132 |
return False |
133 |
return self.eta is not None |
|
134 |
||
135 |
def binary_builds(self): |
|
136 |
return list(self.context.binary_builds) |
|
137 |
||
138 |
||
11070.3.14
by Paul Hummer
Got cancel build working in the UI |
139 |
class SourcePackageRecipeBuildCancelView(LaunchpadFormView): |
11070.3.16
by Paul Hummer
More changes from review |
140 |
"""View for cancelling a build."""
|
11070.3.8
by Paul Hummer
Tests, working, hooraybzr break-lock |
141 |
|
142 |
class schema(Interface): |
|
11070.3.15
by Paul Hummer
Made changes per Aaron's review |
143 |
"""Schema for cancelling a build."""
|
11070.3.8
by Paul Hummer
Tests, working, hooraybzr break-lock |
144 |
|
11070.3.14
by Paul Hummer
Got cancel build working in the UI |
145 |
page_title = label = "Cancel build" |
11070.3.8
by Paul Hummer
Tests, working, hooraybzr break-lock |
146 |
|
147 |
@property
|
|
148 |
def cancel_url(self): |
|
149 |
return canonical_url(self.context) |
|
11070.3.14
by Paul Hummer
Got cancel build working in the UI |
150 |
next_url = cancel_url |
11070.3.8
by Paul Hummer
Tests, working, hooraybzr break-lock |
151 |
|
11070.3.14
by Paul Hummer
Got cancel build working in the UI |
152 |
@action('Cancel build', name='cancel') |
11070.3.8
by Paul Hummer
Tests, working, hooraybzr break-lock |
153 |
def request_action(self, action, data): |
11070.3.14
by Paul Hummer
Got cancel build working in the UI |
154 |
"""Cancel the build."""
|
155 |
self.context.cancelBuild() |
|
11070.4.1
by Paul Hummer
Added rescore flow |
156 |
|
157 |
||
158 |
class SourcePackageRecipeBuildRescoreView(LaunchpadFormView): |
|
159 |
"""View for rescoring a build."""
|
|
160 |
||
161 |
class schema(Interface): |
|
162 |
"""Schema for deleting a build."""
|
|
11227.1.2
by Paul Hummer
Fixed rescore to use a text field |
163 |
score = Int( |
11070.4.1
by Paul Hummer
Added rescore flow |
164 |
title=u'Score', required=True, |
165 |
description=u'The score of the recipe.') |
|
166 |
||
167 |
page_title = label = "Rescore build" |
|
168 |
||
12176.1.1
by Aaron Bentley
No oopses when rescoring non-queued recipe builds. |
169 |
def __call__(self): |
170 |
if self.context.buildqueue_record is not None: |
|
171 |
return super(SourcePackageRecipeBuildRescoreView, self).__call__() |
|
172 |
self.request.response.addWarningNotification( |
|
173 |
'Cannot rescore this build because it is not queued.') |
|
174 |
self.request.response.redirect(canonical_url(self.context)) |
|
175 |
||
11070.4.1
by Paul Hummer
Added rescore flow |
176 |
@property
|
177 |
def cancel_url(self): |
|
178 |
return canonical_url(self.context) |
|
179 |
next_url = cancel_url |
|
180 |
||
181 |
@action('Rescore build', name='rescore') |
|
182 |
def request_action(self, action, data): |
|
183 |
"""Rescore the build."""
|
|
184 |
self.context.buildqueue_record.lastscore = int(data['score']) |
|
185 |
||
186 |
@property
|
|
187 |
def initial_values(self): |
|
188 |
return {'score': str(self.context.buildqueue_record.lastscore)} |