~launchpad-pqm/launchpad/devel

12293.1.11 by Curtis Hovey
Updated copyright.
1
# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
8687.15.17 by Karl Fogel
Add the copyright header block to the rest of the files under lib/lp/.
2
# GNU Affero General Public License version 3 (see the file LICENSE).
2457 by Canonical.com Patch Queue Manager
[r=lifeless] Launchpad Auto Build System User Interface Prototype (buildfarm UI) also minor fixes for buildd infrastructure, still needing mpt love.
3
4
"""Browser views for builders."""
5
6
__metaclass__ = type
7
6767.6.10 by Maris Fogels
Migrated the Builder breadcrumbs to the new system interface.
8
__all__ = [
9
    'BuilderFacets',
10
    'BuilderOverviewMenu',
11
    'BuilderNavigation',
12
    'BuilderSetAddView',
9209.4.5 by Guilherme Salgado
Update all existing breadcrumb adapters to use Breadcrumb rather than BreadcrumbBuilder. Also rename them all
13
    'BuilderSetBreadcrumb',
6767.6.10 by Maris Fogels
Migrated the Builder breadcrumbs to the new system interface.
14
    'BuilderSetFacets',
15
    'BuilderSetOverviewMenu',
16
    'BuilderSetNavigation',
17
    'BuilderSetView',
18
    'BuilderView',
19
    ]
2457 by Canonical.com Patch Queue Manager
[r=lifeless] Launchpad Auto Build System User Interface Prototype (buildfarm UI) also minor fixes for buildd infrastructure, still needing mpt love.
20
5852.3.5 by Celso Providelo
Grouping builders by category (ppa/others) and also by processor, so we can get rid of the buildqueue depth porlets and present this information in the page body.
21
import operator
2457 by Canonical.com Patch Queue Manager
[r=lifeless] Launchpad Auto Build System User Interface Prototype (buildfarm UI) also minor fixes for buildd infrastructure, still needing mpt love.
22
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
23
from zope.app.form.browser import (
24
    TextAreaWidget,
25
    TextWidget,
26
    )
2457 by Canonical.com Patch Queue Manager
[r=lifeless] Launchpad Auto Build System User Interface Prototype (buildfarm UI) also minor fixes for buildd infrastructure, still needing mpt love.
27
from zope.component import getUtility
28
from zope.event import notify
6061.13.2 by Curtis Hovey
Include zope.component in zopeapi.zcml.
29
from zope.lifecycleevent import ObjectCreatedEvent
2772.1.23 by Celso Providelo
applying review comments (except widget issue) and removing trailling whitspaces (emacs-fu) from some files, tests passing
30
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
31
from canonical.launchpad import _
32
from canonical.launchpad.webapp import (
33
    ApplicationMenu,
34
    canonical_url,
35
    enabled_with_permission,
36
    GetitemNavigation,
37
    LaunchpadView,
38
    Link,
39
    Navigation,
40
    StandardLaunchpadFacets,
41
    stepthrough,
42
    )
43
from canonical.launchpad.webapp.breadcrumb import Breadcrumb
9080.4.7 by Michael Nelson
Updated builder view with page_title and removed use of structured.
44
from canonical.lazr.utils import smartquote
11929.9.1 by Tim Penhey
Move launchpadform into lp.app.browser.
45
from lp.app.browser.launchpadform import (
46
    action,
47
    custom_widget,
48
    LaunchpadEditFormView,
49
    LaunchpadFormView,
50
    )
12293.1.10 by Curtis Hovey
Formatted imports.
51
from lp.app.widgets.owner import HiddenUserWidget
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
52
from lp.buildmaster.interfaces.builder import (
53
    IBuilder,
54
    IBuilderSet,
55
    )
11382.6.34 by Gavin Panella
Reformat imports in all files touched so far.
56
from lp.services.propertycache import cachedproperty
12119.1.23 by Tim Penhey
Refactor the build traversal code to use a mixin.
57
from lp.soyuz.browser.build import (
58
    BuildNavigationMixin,
59
    BuildRecordsView,
60
    )
61
62
63
class BuilderSetNavigation(GetitemNavigation, BuildNavigationMixin):
2772.1.14 by Celso Providelo
Fixing navigation for builder and builderset, fixing permissions for menus, renaming classes properly and improving tests
64
    """Navigation methods for IBuilderSet."""
2628 by Canonical.com Patch Queue Manager
[trivial] converted a bunch of browser:traverse into navigation
65
    usedfor = IBuilderSet
66
12957.1.2 by William Grant
Shift BPB URLs back to +build, and recipes to a new +recipebuild.
67
    @stepthrough('+build')
68
    def traverse_build(self, name):
69
        build = super(BuilderSetNavigation, self).traverse_build(name)
12119.1.23 by Tim Penhey
Refactor the build traversal code to use a mixin.
70
        if build is None:
12119.1.18 by Tim Penhey
Add buildjob redirect from builders, needs a test.
71
            return None
72
        else:
73
            return self.redirectSubTree(canonical_url(build))
74
2457 by Canonical.com Patch Queue Manager
[r=lifeless] Launchpad Auto Build System User Interface Prototype (buildfarm UI) also minor fixes for buildd infrastructure, still needing mpt love.
75
9209.4.5 by Guilherme Salgado
Update all existing breadcrumb adapters to use Breadcrumb rather than BreadcrumbBuilder. Also rename them all
76
class BuilderSetBreadcrumb(Breadcrumb):
6767.6.26 by Maris Fogels
Rework based on reviewer feedback.
77
    """Builds a breadcrumb for an `IBuilderSet`."""
6767.6.10 by Maris Fogels
Migrated the Builder breadcrumbs to the new system interface.
78
    text = 'Build Farm'
79
80
3564.2.36 by Diogo Matsubara
Fix OOPS-208C344 (Broken traversal in builder page)
81
class BuilderNavigation(Navigation):
2772.1.14 by Celso Providelo
Fixing navigation for builder and builderset, fixing permissions for menus, renaming classes properly and improving tests
82
    """Navigation methods for IBuilder."""
83
    usedfor = IBuilder
84
6767.6.10 by Maris Fogels
Migrated the Builder breadcrumbs to the new system interface.
85
2772.1.14 by Celso Providelo
Fixing navigation for builder and builderset, fixing permissions for menus, renaming classes properly and improving tests
86
class BuilderSetFacets(StandardLaunchpadFacets):
2457 by Canonical.com Patch Queue Manager
[r=lifeless] Launchpad Auto Build System User Interface Prototype (buildfarm UI) also minor fixes for buildd infrastructure, still needing mpt love.
87
    """The links that will appear in the facet menu for an IBuilderSet."""
88
    enable_only = ['overview']
89
90
    usedfor = IBuilderSet
91
92
93
class BuilderFacets(StandardLaunchpadFacets):
94
    """The links that will appear in the facet menu for an IBuilder."""
95
    enable_only = ['overview']
96
97
    usedfor = IBuilder
98
99
2772.1.14 by Celso Providelo
Fixing navigation for builder and builderset, fixing permissions for menus, renaming classes properly and improving tests
100
class BuilderSetOverviewMenu(ApplicationMenu):
101
    """Overview Menu for IBuilderSet."""
102
    usedfor = IBuilderSet
103
    facet = 'overview'
104
    links = ['add']
105
106
    @enabled_with_permission('launchpad.Admin')
107
    def add(self):
6301.2.5 by Celso Providelo
Session with mpt and mark.
108
        text = 'Register a new build machine'
2772.1.14 by Celso Providelo
Fixing navigation for builder and builderset, fixing permissions for menus, renaming classes properly and improving tests
109
        return Link('+new', text, icon='add')
110
111
2772.1.13 by Celso Providelo
Fixing builder-index layout, navigation menu, portlet-details and batched list of builds.
112
class BuilderOverviewMenu(ApplicationMenu):
2772.1.14 by Celso Providelo
Fixing navigation for builder and builderset, fixing permissions for menus, renaming classes properly and improving tests
113
    """Overview Menu for IBuilder."""
2772.1.13 by Celso Providelo
Fixing builder-index layout, navigation menu, portlet-details and batched list of builds.
114
    usedfor = IBuilder
115
    facet = 'overview'
9080.4.1 by Michael Nelson
Removed admin/cancel forms, updated edit form merging the admin functionality.
116
    links = ['history', 'edit', 'mode']
3147.5.24 by Celso Providelo
Move build history browser widget from builder index to +history page (cleaner and faster page), fix options generator to avoid python call inside template, fix tests.
117
118
    def history(self):
9080.6.1 by Michael Nelson
Style updates to index page for screenshot.
119
        text = 'View full history'
3147.5.24 by Celso Providelo
Move build history browser widget from builder index to +history page (cleaner and faster page), fix options generator to avoid python call inside template, fix tests.
120
        return Link('+history', text, icon='info')
2772.1.13 by Celso Providelo
Fixing builder-index layout, navigation menu, portlet-details and batched list of builds.
121
2772.1.14 by Celso Providelo
Fixing navigation for builder and builderset, fixing permissions for menus, renaming classes properly and improving tests
122
    @enabled_with_permission('launchpad.Edit')
2772.1.13 by Celso Providelo
Fixing builder-index layout, navigation menu, portlet-details and batched list of builds.
123
    def edit(self):
3847.2.15 by Mark Shuttleworth
Consistency in menu text and capitalisation
124
        text = 'Change details'
2772.1.13 by Celso Providelo
Fixing builder-index layout, navigation menu, portlet-details and batched list of builds.
125
        return Link('+edit', text, icon='edit')
126
2772.1.14 by Celso Providelo
Fixing navigation for builder and builderset, fixing permissions for menus, renaming classes properly and improving tests
127
    @enabled_with_permission('launchpad.Edit')
2772.1.13 by Celso Providelo
Fixing builder-index layout, navigation menu, portlet-details and batched list of builds.
128
    def mode(self):
3847.2.15 by Mark Shuttleworth
Consistency in menu text and capitalisation
129
        text = 'Change mode'
2772.1.13 by Celso Providelo
Fixing builder-index layout, navigation menu, portlet-details and batched list of builds.
130
        return Link('+mode', text, icon='edit')
131
132
9461.7.2 by Celso Providelo
getting rid of HiddenBuilder design.
133
class BuilderSetView(LaunchpadView):
134
    """Default BuilderSet view class."""
2772.1.14 by Celso Providelo
Fixing navigation for builder and builderset, fixing permissions for menus, renaming classes properly and improving tests
135
9461.7.5 by Celso Providelo
adjusting heading of BuilderSet:+index.
136
    @property
137
    def label(self):
138
        return self.context.title
139
9461.7.6 by Celso Providelo
adding missing page_title for BuilderSet:+index.
140
    @property
141
    def page_title(self):
142
        return self.label
143
5278.1.1 by Mark Shuttleworth
Show build queue depth by architecture on builders listing page
144
    @cachedproperty
5855.1.3 by Julian Edwards
Convert view/getBuilders to a view/builders property as per the
145
    def builders(self):
9461.7.2 by Celso Providelo
getting rid of HiddenBuilder design.
146
        """All active builders"""
147
        return list(self.context.getBuilders())
5855.1.1 by Julian Edwards
Fix the /+builds page so that it does not display private build details.
148
5852.3.5 by Celso Providelo
Grouping builders by category (ppa/others) and also by processor, so we can get rid of the buildqueue depth porlets and present this information in the page body.
149
    @property
9209.7.2 by Celso Providelo
3.0 Layout for /builders page.
150
    def number_of_registered_builders(self):
151
        return len(self.builders)
152
153
    @property
154
    def number_of_available_builders(self):
155
        return len([b for b in self.builders if b.builderok])
156
157
    @property
158
    def number_of_disabled_builders(self):
159
        return len([b for b in self.builders if not b.builderok])
160
161
    @property
162
    def number_of_building_builders(self):
163
        return len([b for b in self.builders if b.currentjob is not None])
164
10940.2.3 by Michael Nelson
Updated builderset view to use the new single query.
165
    @cachedproperty
166
    def build_queue_sizes(self):
167
        """Return the build queue sizes for all processors."""
168
        builderset = getUtility(IBuilderSet)
169
        return builderset.getBuildQueueSizes()
170
9209.7.2 by Celso Providelo
3.0 Layout for /builders page.
171
    @property
5852.3.5 by Celso Providelo
Grouping builders by category (ppa/others) and also by processor, so we can get rid of the buildqueue depth porlets and present this information in the page body.
172
    def ppa_builders(self):
173
        """Return a BuilderCategory object for PPA builders."""
174
        builder_category = BuilderCategory(
9209.7.2 by Celso Providelo
3.0 Layout for /builders page.
175
            'PPA build status', virtualized=True)
10940.2.3 by Michael Nelson
Updated builderset view to use the new single query.
176
        builder_category.groupBuilders(self.builders, self.build_queue_sizes)
5852.3.5 by Celso Providelo
Grouping builders by category (ppa/others) and also by processor, so we can get rid of the buildqueue depth porlets and present this information in the page body.
177
        return builder_category
178
179
    @property
180
    def other_builders(self):
181
        """Return a BuilderCategory object for PPA builders."""
182
        builder_category = BuilderCategory(
9209.7.2 by Celso Providelo
3.0 Layout for /builders page.
183
            'Official distributions build status', virtualized=False)
10940.2.3 by Michael Nelson
Updated builderset view to use the new single query.
184
        builder_category.groupBuilders(self.builders, self.build_queue_sizes)
5852.3.5 by Celso Providelo
Grouping builders by category (ppa/others) and also by processor, so we can get rid of the buildqueue depth porlets and present this information in the page body.
185
        return builder_category
186
187
188
class BuilderGroup:
189
    """A group of builders for the processor.
190
191
    Also stores the corresponding 'queue_size', the number of pending jobs
192
    in this context.
193
    """
9209.7.2 by Celso Providelo
3.0 Layout for /builders page.
194
    def __init__(self, processor_name, queue_size, duration, builders):
5852.3.5 by Celso Providelo
Grouping builders by category (ppa/others) and also by processor, so we can get rid of the buildqueue depth porlets and present this information in the page body.
195
        self.processor_name = processor_name
196
        self.queue_size = queue_size
9209.7.2 by Celso Providelo
3.0 Layout for /builders page.
197
        self.number_of_available_builders = len(
198
            [b for b in builders if b.builderok])
199
        if duration and self.number_of_available_builders:
200
            self.duration = duration / self.number_of_available_builders
201
        else:
202
            self.duration = duration
5852.3.5 by Celso Providelo
Grouping builders by category (ppa/others) and also by processor, so we can get rid of the buildqueue depth porlets and present this information in the page body.
203
9461.7.2 by Celso Providelo
getting rid of HiddenBuilder design.
204
5852.3.5 by Celso Providelo
Grouping builders by category (ppa/others) and also by processor, so we can get rid of the buildqueue depth porlets and present this information in the page body.
205
class BuilderCategory:
5852.3.11 by Celso Providelo
applying review comments, r=intellectronica.
206
    """A category of builders.
5852.3.5 by Celso Providelo
Grouping builders by category (ppa/others) and also by processor, so we can get rid of the buildqueue depth porlets and present this information in the page body.
207
208
    A collection of BuilderGroups as 'PPA builders' and 'Other builders'.
209
    """
210
    def __init__(self, title, virtualized):
211
        self.title = title
212
        self.virtualized = virtualized
213
        self._builder_groups = []
214
215
    @property
216
    def groups(self):
217
        """Return a list of BuilderGroups ordered by 'processor_name'."""
218
        return sorted(self._builder_groups,
219
                      key=operator.attrgetter('processor_name'))
220
10940.2.3 by Michael Nelson
Updated builderset view to use the new single query.
221
    def groupBuilders(self, all_builders, build_queue_sizes):
5852.3.5 by Celso Providelo
Grouping builders by category (ppa/others) and also by processor, so we can get rid of the buildqueue depth porlets and present this information in the page body.
222
        """Group the given builders as a collection of Buildergroups.
223
224
        A BuilderGroup will be initialized for each processor.
225
        """
5852.3.7 by Celso Providelo
Adding tests for BuilderSetView, covering BuilderCategory and BuilderGroup.
226
        builders = [builder for builder in all_builders
227
                    if builder.virtualized is self.virtualized]
228
5852.3.5 by Celso Providelo
Grouping builders by category (ppa/others) and also by processor, so we can get rid of the buildqueue depth porlets and present this information in the page body.
229
        grouped_builders = {}
230
        for builder in builders:
5852.3.11 by Celso Providelo
applying review comments, r=intellectronica.
231
            if builder.processor in grouped_builders:
232
                grouped_builders[builder.processor].append(builder)
233
            else:
234
                grouped_builders[builder.processor] = [builder]
5852.3.5 by Celso Providelo
Grouping builders by category (ppa/others) and also by processor, so we can get rid of the buildqueue depth porlets and present this information in the page body.
235
236
        for processor, builders in grouped_builders.iteritems():
10940.2.3 by Michael Nelson
Updated builderset view to use the new single query.
237
            virt_str = 'virt' if self.virtualized else 'nonvirt'
238
            queue_size, duration = build_queue_sizes[virt_str].get(
239
                processor.name, (0, None))
5852.3.5 by Celso Providelo
Grouping builders by category (ppa/others) and also by processor, so we can get rid of the buildqueue depth porlets and present this information in the page body.
240
            builder_group = BuilderGroup(
9209.7.2 by Celso Providelo
3.0 Layout for /builders page.
241
                processor.name, queue_size, duration,
5852.3.5 by Celso Providelo
Grouping builders by category (ppa/others) and also by processor, so we can get rid of the buildqueue depth porlets and present this information in the page body.
242
                sorted(builders, key=operator.attrgetter('title')))
243
            self._builder_groups.append(builder_group)
244
2772.1.14 by Celso Providelo
Fixing navigation for builder and builderset, fixing permissions for menus, renaming classes properly and improving tests
245
9461.7.2 by Celso Providelo
getting rid of HiddenBuilder design.
246
class BuilderView(LaunchpadView):
2772.1.14 by Celso Providelo
Fixing navigation for builder and builderset, fixing permissions for menus, renaming classes properly and improving tests
247
    """Default Builder view class
248
5565.5.11 by Julian Edwards
Hide private builds data (in private PPAs) from the UI.
249
    Implements useful actions for the page template.
2772.1.14 by Celso Providelo
Fixing navigation for builder and builderset, fixing permissions for menus, renaming classes properly and improving tests
250
    """
251
8550.2.2 by Michael Nelson
Added current_job_duration property to BuilderView.
252
    @property
253
    def current_build_duration(self):
10466.9.5 by Jeroen Vermeulen
Prototype with weird timezone-related test failure in test_min_time_to_next_builder.
254
        if self.context.currentjob is None:
8550.2.2 by Michael Nelson
Added current_job_duration property to BuilderView.
255
            return None
256
        else:
10466.9.5 by Jeroen Vermeulen
Prototype with weird timezone-related test failure in test_min_time_to_next_builder.
257
            return self.context.currentjob.current_build_duration
8550.2.2 by Michael Nelson
Added current_job_duration property to BuilderView.
258
9080.6.7 by Michael Nelson
Removed old page titles and replaced with view.page_title.
259
    @property
260
    def page_title(self):
261
        """Return a relevant page title for this view."""
262
        return smartquote(
263
            'Builder "%s"' % self.context.title)
264
9080.6.11 by Michael Nelson
Update the text for the toggle button depending on context (suggestion by intellectronica).
265
    @property
266
    def toggle_mode_text(self):
267
        """Return the text to use on the toggle mode button."""
268
        if self.context.manual:
269
            return "Switch to auto-mode"
270
        else:
271
            return "Switch to manual-mode"
5565.5.10 by Julian Edwards
Move IBuilder.status to BuilderView, it does not belong on the content
272
9080.7.4 by Michael Nelson
Finished update of builder-history (updating tests etc.).
273
9461.7.2 by Celso Providelo
getting rid of HiddenBuilder design.
274
class BuilderHistoryView(BuildRecordsView):
9080.7.4 by Michael Nelson
Finished update of builder-history (updating tests etc.).
275
    """This class exists only to override the page_title."""
276
9855.3.8 by William Grant
Make BuilderHistoryView use the normal BuildRecordsView template, and make the label/title a bit more sane than the default.
277
    page_title = 'Build history'
11005.3.21 by Michael Nelson
Switch the builder history view to show general builds, not just binary ones.
278
    binary_only = False
9855.3.8 by William Grant
Make BuilderHistoryView use the normal BuildRecordsView template, and make the label/title a bit more sane than the default.
279
9080.7.4 by Michael Nelson
Finished update of builder-history (updating tests etc.).
280
    @property
9855.3.8 by William Grant
Make BuilderHistoryView use the normal BuildRecordsView template, and make the label/title a bit more sane than the default.
281
    def label(self):
9080.7.4 by Michael Nelson
Finished update of builder-history (updating tests etc.).
282
        return smartquote(
283
            'Build history for "%s"' % self.context.title)
284
9461.7.2 by Celso Providelo
getting rid of HiddenBuilder design.
285
    @property
286
    def default_build_state(self):
287
        """Present all jobs by default."""
288
        return None
289
290
    @property
291
    def show_builder_info(self):
292
        """Hide Builder info, see BuildRecordsView for further details"""
293
        return False
294
9080.7.4 by Michael Nelson
Finished update of builder-history (updating tests etc.).
295
6912.1.1 by Celso Providelo
Fixing bug #262024 (Form to register new builds was using the wrong master template). Additionally Builder and IBuilder fields where adjusted to represent exactly what we have in out database, IBuilderSet.new() was modified to cope with the new required fields in that form (virtualization and visibility options), the view class used in the form was ported to use LaunchpadFormView and finally the pagetests were updated.
296
class BuilderSetAddView(LaunchpadFormView):
297
    """View class for adding new Builders."""
298
299
    schema = IBuilder
300
301
    label = "Register a new build machine"
302
6912.1.3 by Celso Providelo
fixing lint issue.
303
    field_names = [
6912.1.1 by Celso Providelo
Fixing bug #262024 (Form to register new builds was using the wrong master template). Additionally Builder and IBuilder fields where adjusted to represent exactly what we have in out database, IBuilderSet.new() was modified to cope with the new required fields in that form (virtualization and visibility options), the view class used in the form was ported to use LaunchpadFormView and finally the pagetests were updated.
304
        'name', 'title', 'description', 'processor', 'url',
305
        'active', 'virtualized', 'vm_host', 'owner'
306
        ]
307
308
    custom_widget('owner', HiddenUserWidget)
309
    custom_widget('description', TextAreaWidget, height=3)
310
    custom_widget('url', TextWidget, displayWidth=30)
311
    custom_widget('vm_host', TextWidget, displayWidth=30)
312
313
    @action(_('Register builder'), name='register')
314
    def register_action(self, action, data):
315
        """Register a new builder."""
316
        builder = getUtility(IBuilderSet).new(
317
            processor=data.get('processor'),
318
            url=data.get('url'),
319
            name=data.get('name'),
320
            title=data.get('title'),
321
            description=data.get('description'),
322
            owner=data.get('owner'),
323
            active=data.get('active'),
324
            virtualized=data.get('virtualized'),
325
            vm_host=data.get('vm_host'),
326
            )
2457 by Canonical.com Patch Queue Manager
[r=lifeless] Launchpad Auto Build System User Interface Prototype (buildfarm UI) also minor fixes for buildd infrastructure, still needing mpt love.
327
        notify(ObjectCreatedEvent(builder))
6912.1.1 by Celso Providelo
Fixing bug #262024 (Form to register new builds was using the wrong master template). Additionally Builder and IBuilder fields where adjusted to represent exactly what we have in out database, IBuilderSet.new() was modified to cope with the new required fields in that form (virtualization and visibility options), the view class used in the form was ported to use LaunchpadFormView and finally the pagetests were updated.
328
        self.next_url = canonical_url(builder)
9080.4.3 by Michael Nelson
Initial replacement of zcml builder-edit form.
329
9080.7.5 by Michael Nelson
Removed old page_titles and added for builder-add.pt.
330
    @property
331
    def page_title(self):
332
        """Return a relevant page title for this view."""
333
        return self.label
334
335
    @property
336
    def cancel_url(self):
337
        """Canceling the add action should go back to the build farm."""
338
        return canonical_url(self.context)
339
9080.4.3 by Michael Nelson
Initial replacement of zcml builder-edit form.
340
341
class BuilderEditView(LaunchpadEditFormView):
342
    """View class for changing builder details."""
343
344
    schema = IBuilder
345
346
    field_names = [
347
        'name', 'title', 'description', 'processor', 'url', 'manual',
348
        'owner', 'virtualized', 'builderok', 'failnotes', 'vm_host',
349
        'active',
350
        ]
351
352
    @action(_('Change'), name='update')
9080.4.5 by Michael Nelson
Added notification after updating builder details.
353
    def change_details(self, action, data):
9080.4.3 by Michael Nelson
Initial replacement of zcml builder-edit form.
354
        """Update the builder with the data from the form."""
10914.1.2 by Julian Edwards
Add code fix for the bug
355
        # notify_modified is set False here because it uses
356
        # lazr.lifecycle.snapshot to store the state of the object
357
        # before and after modification.  This is dangerous for the
358
        # builder model class because it causes some properties to be
359
        # queried that try and communicate with the slave, which cannot
360
        # be done from the webapp (it's generally firewalled).  We could
361
        # prevent snapshots for individual properties by defining the
362
        # interface properties with doNotSnapshot() but this doesn't
363
        # guard against future properties being created.
364
        builder_was_modified = self.updateContextFromData(
365
            data, notify_modified=False)
9080.4.5 by Michael Nelson
Added notification after updating builder details.
366
367
        if builder_was_modified:
368
            notification = 'The builder "%s" was updated successfully.' % (
369
                self.context.title)
9080.4.7 by Michael Nelson
Updated builder view with page_title and removed use of structured.
370
            self.request.response.addNotification(notification)
9080.4.5 by Michael Nelson
Added notification after updating builder details.
371
372
        return builder_was_modified
373
374
    @property
375
    def next_url(self):
376
        """Redirect back to the builder-index page."""
377
        return canonical_url(self.context)
9080.4.3 by Michael Nelson
Initial replacement of zcml builder-edit form.
378
9080.4.7 by Michael Nelson
Updated builder view with page_title and removed use of structured.
379
    @property
380
    def cancel_url(self):
381
        """Return the url to which we want to go to if user cancels."""
382
        return self.next_url
383
384
    @property
385
    def page_title(self):
386
        """Return a relevant page title for this view."""
387
        return smartquote(
388
            'Change details for builder "%s"' % self.context.title)
389
9080.6.16 by Michael Nelson
Updated the builder change details form to use correct heading slots.
390
    @property
391
    def label(self):
392
        """The form label should be the same as the pagetitle."""
393
        return self.page_title