Merge lp:~michael.nelson/launchpad/418024-ppa-packages-traversal into lp:launchpad

Proposed by Michael Nelson
Status: Merged
Merged at revision: not available
Proposed branch: lp:~michael.nelson/launchpad/418024-ppa-packages-traversal
Merge into: lp:launchpad
Diff against target: None lines
To merge this branch: bzr merge lp:~michael.nelson/launchpad/418024-ppa-packages-traversal
Reviewer Review Type Date Requested Status
Gavin Panella (community) code Approve
Review via email: mp+11048@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Michael Nelson (michael.nelson) wrote :

= Summary =

This is the first branch of a pipeline of changes for the new PPA-index
page described at:

https://dev.launchpad.net/VersionThreeDotO/Soyuz/PPAUI

This branch specifically creates a new traversal from a PPA, /+packages
and replicates all the detailed package info/interactions from the
current ppa/index to /+packages.

A subsequent branch in the pipeline then updates the PPA index page.

== Proposed fix ==

== Pre-implementation notes ==

== Implementation details ==

There are two XXX's in this branch.

bug 420376 is related to the copy/delete packages links displayed on the
/+packages traversal. I've not used a main_side layout as (1) there is
no other information for the side-bar, and (2) these links will
disappear when the copy/delete functionality is presented on this page.

bug 419921 - in the build status summary, we want to link to a filtered
view of each summary (Pending, Successful, Failed), but currently cannot
as the filtering options do not yet match.

== Tests ==
bin/test -vv -t archive-views.txt -t xx-ppa-packages.txt

== Demo and Q/A ==

Visit:

https://launchpad.dev/~cprov/+archive/ppa/+packages

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/canonical/launchpad/icing/style.css
  lib/lp/soyuz/browser/tests/archive-views.txt
  lib/lp/soyuz/interfaces/archive.py
  lib/lp/soyuz/templates/archive-macros.pt
  lib/lp/soyuz/templates/archive-packages.pt
  lib/lp/soyuz/browser/configure.zcml
  lib/lp/soyuz/stories/ppa/xx-ppa-packages.txt
  lib/lp/soyuz/model/archive.py
  lib/lp/soyuz/browser/archive.py

== Pylint notices ==

lib/lp/soyuz/interfaces/archive.py
    41: [F0401] Unable to import 'lazr.enum' (No module named enum)
    54: [F0401] Unable to import 'lazr.restful.declarations' (No module
named restful)
    60: [F0401] Unable to import 'lazr.restful.fields' (No module named
restful)

lib/lp/soyuz/model/archive.py
    14: [F0401] Unable to import 'lazr.lifecycle.event' (No module named
lifecycle)

--
Michael

Revision history for this message
Gavin Panella (allenap) wrote :
Download full text (24.8 KiB)

Hi Michael,

Hardly anything to say, it's all good. I have a few comments, but
they're all trivial. I mentioned on IRC that the package counters
javascript appeared to be broken, but I haven't commented seeing as
there is more work in another branch; this is more of a checkpoint
review.

Gavin.

> === modified file 'lib/canonical/launchpad/icing/style.css'
> --- lib/canonical/launchpad/icing/style.css 2009-08-31 00:06:29 +0000
> +++ lib/canonical/launchpad/icing/style.css 2009-09-02 11:25:06 +0000
> @@ -1690,14 +1690,6 @@
> float: left; /* So the border doesn't use 100% of the page */
> }
>
> -div#build-status-summary {
> - clear:right;
> - float:right;
> -}
> -
> -div#build-status-summary h2 {
> - margin-top:0;
> -}
>
> div#build-status-summary th {
> text-align:left;
> @@ -1844,6 +1836,18 @@
> padding: 1em 1em 2em 0em;
> }
>
> +/* XXX Michael Nelson 20090828 bug=420376
> + * Temporary style for actions on the ppa/+packages page until we move
> + * the copy/delete packages functionality into the page itself. */
> +div.ppa-packaging-tmp-actions {
> + float:right;
> +}
> +
> +div.ppa-packaging-tmp-actions .portlet {
> + border-top: 0 none;
> +}
> +
> +
> /* --- Code --- */
>
> body.tab-branches #applications {background: url(app-code-wm.gif) no-repeat;}
>
> === modified file 'lib/lp/soyuz/browser/archive.py'
> --- lib/lp/soyuz/browser/archive.py 2009-09-01 18:26:21 +0000
> +++ lib/lp/soyuz/browser/archive.py 2009-09-02 11:25:06 +0000
> @@ -18,6 +18,8 @@
> 'ArchiveNavigationMenu',
> 'ArchivePackageCopyingView',
> 'ArchivePackageDeletionView',
> + 'ArchivePackagesView',
> + 'ArchivePackagesActionMenu',

These should be in alphabetical order :)

> 'ArchiveView',
> 'ArchiveViewBase',
> 'traverse_distro_archive',
> @@ -30,7 +32,7 @@
> from zope.app.form.utility import setUpWidget
> from zope.component import getUtility
> from zope.formlib import form
> -from zope.interface import implements
> +from zope.interface import implements, Interface
> from zope.schema import Choice, List
> from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
>
> @@ -38,6 +40,8 @@
>
> from canonical.cachedproperty import cachedproperty
> from canonical.launchpad import _
> +from canonical.launchpad.helpers import english_list
> +from canonical.lazr.utils import smartquote
> from lp.soyuz.browser.build import BuildRecordsView
> from lp.soyuz.browser.sourceslist import (
> SourcesListEntries, SourcesListEntriesView)
> @@ -308,13 +312,8 @@
>
> return self.context.getArchiveDependency(archive)
>
> -class ArchiveContextMenu(ContextMenu):
> - """Overview Menu for IArchive."""
> -
> - usedfor = IArchive
> - links = ['ppa', 'admin', 'edit', 'builds', 'delete', 'copy',
> - 'edit_dependencies', 'manage_subscribers']
> -
> +
> +class ArchiveMenuMixin:
> def ppa(self):
> text = 'View PPA'
> return Link(canonical_url(self.context), text, icon='info')
> @@ -341,9 +340,13 @@
> return Link('+edit', text, icon='edit')
>
> def builds(self):
> - text = 'View build records'
> + text = 'View all builds'
> return ...

Revision history for this message
Gavin Panella (allenap) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/icing/style.css'
2--- lib/canonical/launchpad/icing/style.css 2009-08-31 00:06:29 +0000
3+++ lib/canonical/launchpad/icing/style.css 2009-09-02 09:20:43 +0000
4@@ -1690,14 +1690,6 @@
5 float: left; /* So the border doesn't use 100% of the page */
6 }
7
8-div#build-status-summary {
9- clear:right;
10- float:right;
11-}
12-
13-div#build-status-summary h2 {
14- margin-top:0;
15-}
16
17 div#build-status-summary th {
18 text-align:left;
19@@ -1844,6 +1836,18 @@
20 padding: 1em 1em 2em 0em;
21 }
22
23+/* XXX Michael Nelson 20090828 bug=420376
24+ * Temporary style for actions on the ppa/+packages page until we move
25+ * the copy/delete packages functionality into the page itself. */
26+div.ppa-packaging-tmp-actions {
27+ float:right;
28+}
29+
30+div.ppa-packaging-tmp-actions .portlet {
31+ border-top: 0 none;
32+}
33+
34+
35 /* --- Code --- */
36
37 body.tab-branches #applications {background: url(app-code-wm.gif) no-repeat;}
38
39=== modified file 'lib/lp/soyuz/browser/archive.py'
40--- lib/lp/soyuz/browser/archive.py 2009-09-01 18:26:21 +0000
41+++ lib/lp/soyuz/browser/archive.py 2009-09-02 09:20:43 +0000
42@@ -18,6 +18,8 @@
43 'ArchiveNavigationMenu',
44 'ArchivePackageCopyingView',
45 'ArchivePackageDeletionView',
46+ 'ArchivePackagesView',
47+ 'ArchivePackagesActionMenu',
48 'ArchiveView',
49 'ArchiveViewBase',
50 'traverse_distro_archive',
51@@ -30,7 +32,7 @@
52 from zope.app.form.utility import setUpWidget
53 from zope.component import getUtility
54 from zope.formlib import form
55-from zope.interface import implements
56+from zope.interface import implements, Interface
57 from zope.schema import Choice, List
58 from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
59
60@@ -38,6 +40,8 @@
61
62 from canonical.cachedproperty import cachedproperty
63 from canonical.launchpad import _
64+from canonical.launchpad.helpers import english_list
65+from canonical.lazr.utils import smartquote
66 from lp.soyuz.browser.build import BuildRecordsView
67 from lp.soyuz.browser.sourceslist import (
68 SourcesListEntries, SourcesListEntriesView)
69@@ -308,13 +312,8 @@
70
71 return self.context.getArchiveDependency(archive)
72
73-class ArchiveContextMenu(ContextMenu):
74- """Overview Menu for IArchive."""
75-
76- usedfor = IArchive
77- links = ['ppa', 'admin', 'edit', 'builds', 'delete', 'copy',
78- 'edit_dependencies', 'manage_subscribers']
79-
80+
81+class ArchiveMenuMixin:
82 def ppa(self):
83 text = 'View PPA'
84 return Link(canonical_url(self.context), text, icon='info')
85@@ -341,9 +340,13 @@
86 return Link('+edit', text, icon='edit')
87
88 def builds(self):
89- text = 'View build records'
90+ text = 'View all builds'
91 return Link('+builds', text, icon='info')
92
93+ def builds_successful(self):
94+ text = 'View successful builds'
95+ return Link('+builds?build_state=built', text, icon='info')
96+
97 @enabled_with_permission('launchpad.Edit')
98 def delete(self):
99 """Display a delete menu option for non-copy archives."""
100@@ -372,6 +375,14 @@
101 return Link('+edit-dependencies', text, icon='edit')
102
103
104+class ArchiveContextMenu(ContextMenu, ArchiveMenuMixin):
105+ """Overview Menu for IArchive."""
106+
107+ usedfor = IArchive
108+ links = ['ppa', 'admin', 'edit', 'builds', 'builds_successful', 'delete',
109+ 'copy', 'edit_dependencies', 'manage_subscribers']
110+
111+
112 class ArchiveNavigationMenu(NavigationMenu):
113 """IArchive navigation menu.
114
115@@ -382,6 +393,17 @@
116 links = []
117
118
119+class IArchivePackagesActionMenu(Interface):
120+ """A marker interface for the packages action menu."""
121+
122+
123+class ArchivePackagesActionMenu(NavigationMenu, ArchiveMenuMixin):
124+ """An action menu for archive package-related actions."""
125+ usedfor = IArchivePackagesActionMenu
126+ facet = 'overview'
127+ links = ['copy', 'delete']
128+
129+
130 class ArchiveBreadcrumb(Breadcrumb):
131 """Builds a breadcrumb for an `IArchive`."""
132
133@@ -555,6 +577,11 @@
134 return SimpleVocabulary(status_terms)
135
136 @cachedproperty
137+ def series_with_sources(self):
138+ """Cache the context's series with sources."""
139+ return self.context.series_with_sources
140+
141+ @property
142 def series_vocabulary(self):
143 """Return a vocabulary for selecting a distribution series.
144
145@@ -562,7 +589,7 @@
146 selection of a series
147 """
148 series_terms = [SimpleTerm(None, token='any', title='Any Series')]
149- for distroseries in self.context.series_with_sources:
150+ for distroseries in self.series_with_sources:
151 series_terms.append(
152 SimpleTerm(distroseries, token=distroseries.name,
153 title=distroseries.displayname))
154@@ -692,15 +719,13 @@
155 canonical_url(self.context, view_name='+edit'),
156 id="displayname", title="Edit this displayname")
157
158- self.setupSourcesListEntries()
159-
160- def setupSourcesListEntries(self):
161- """Setup of the sources list entries widget."""
162+ @property
163+ def sources_list_entries(self):
164+ """Setup and return the source list entries widget."""
165 entries = SourcesListEntries(
166 self.context.distribution, self.archive_url,
167 self.context.series_with_sources)
168- self.sources_list_entries = SourcesListEntriesView(
169- entries, self.request)
170+ return SourcesListEntriesView(entries, self.request)
171
172 @property
173 def package_copy_requests(self):
174@@ -709,6 +734,28 @@
175 IPackageCopyRequestSet).getByTargetArchive(self.context))
176
177
178+class ArchivePackagesView(ArchiveSourcePackageListViewBase):
179+ """Detailed packages view for an archive."""
180+ implements(IArchivePackagesActionMenu)
181+
182+ @property
183+ def page_title(self):
184+ return smartquote('Packages in "%s"' % self.context.displayname)
185+
186+ @property
187+ def series_list_string(self):
188+ """Return an English string of the distroseries."""
189+ return english_list(
190+ [series.displayname for series in self.series_with_sources])
191+
192+ @property
193+ def is_copy(self):
194+ """Return whether the context of this view is a copy archive."""
195+ # This property enables menu items to be shared between
196+ # context and view menues.
197+ return self.context.is_copy
198+
199+
200 class ArchiveSourceSelectionFormView(ArchiveSourcePackageListViewBase,
201 LaunchpadFormView):
202 """Base class to implement a source selection widget for PPAs."""
203
204=== modified file 'lib/lp/soyuz/browser/configure.zcml'
205--- lib/lp/soyuz/browser/configure.zcml 2009-08-21 18:05:01 +0000
206+++ lib/lp/soyuz/browser/configure.zcml 2009-08-25 08:21:09 +0000
207@@ -234,15 +234,20 @@
208 name="+macros"
209 permission="zope.Public"
210 template="../templates/archive-macros.pt"/>
211- <browser:pages
212- for="lp.soyuz.interfaces.archive.IArchive"
213- permission="launchpad.View"
214- class="lp.soyuz.browser.archive.ArchiveView">
215- <browser:page
216- template="../templates/archive-index.pt"
217- facet="overview"
218- name="+index"/>
219- </browser:pages>
220+ <browser:page
221+ for="lp.soyuz.interfaces.archive.IArchive"
222+ permission="launchpad.View"
223+ name="+index"
224+ template="../templates/archive-index.pt"
225+ facet="overview"
226+ class="lp.soyuz.browser.archive.ArchiveView"/>
227+ <browser:page
228+ for="lp.soyuz.interfaces.archive.IArchive"
229+ permission="launchpad.View"
230+ name="+packages"
231+ template="../templates/archive-packages.pt"
232+ facet="overview"
233+ class="lp.soyuz.browser.archive.ArchivePackagesView"/>
234 <browser:pages
235 for="lp.soyuz.interfaces.archive.IArchive"
236 permission="launchpad.View">
237@@ -322,7 +327,8 @@
238 <browser:menus
239 classes="
240 ArchiveContextMenu
241- ArchiveNavigationMenu"
242+ ArchiveNavigationMenu
243+ ArchivePackagesActionMenu"
244 module="lp.soyuz.browser.archive"/>
245 <browser:url
246 for="lp.soyuz.interfaces.archivepermission.IArchiveUploader"
247
248=== modified file 'lib/lp/soyuz/browser/tests/archive-views.txt'
249--- lib/lp/soyuz/browser/tests/archive-views.txt 2009-09-01 18:26:21 +0000
250+++ lib/lp/soyuz/browser/tests/archive-views.txt 2009-09-02 09:20:43 +0000
251@@ -285,6 +285,40 @@
252 >>> login(ANONYMOUS)
253
254
255+== ArchivePackageView ==
256+
257+This view displays detailed information about the archive packages that
258+is not so relevant for the PPA index page, such as a summary of build
259+statuses, repository usage, full publishing details and access to
260+copy/delete packages where appropriate.
261+
262+And let's create two views to compare:
263+
264+ >>> ppa_archive_view = create_initialized_view(
265+ ... cprov.archive, name="+packages")
266+ >>> copy_archive_view = create_initialized_view(
267+ ... copy_archive, name="+packages")
268+
269+ >>> print ppa_archive_view.page_title
270+ Packages in ...PPA for Celso Providelo...
271+
272+ >>> print copy_archive_view.page_title
273+ Packages in ...Copy archive intrepid-security-rebuild...
274+
275+This view inherits from ArchiveViewBase and has all the
276+corresponding properties such as archive_url, build_counters etc.
277+(see ArchiveView above).
278+
279+Additionally, ArchivePackageView can display a string representation
280+of the series supported by this archive.
281+
282+ >>> print ppa_archive_view.series_list_string
283+ Breezy Badger Autotest and Warty
284+
285+ >>> copy_archive_view.series_list_string
286+ ''
287+
288+
289 == ArchivePackageDeletionView ==
290
291 We use ArchivePackageDeletionView to provide the mechnisms used to
292
293=== modified file 'lib/lp/soyuz/interfaces/archive.py'
294--- lib/lp/soyuz/interfaces/archive.py 2009-08-07 12:44:22 +0000
295+++ lib/lp/soyuz/interfaces/archive.py 2009-08-27 13:19:19 +0000
296@@ -134,6 +134,8 @@
297 title=_("Displayname"), required=True,
298 description=_("Displayname for this archive.")))
299
300+ title = TextLine(title=_("Name"), required=False, readonly=True)
301+
302 enabled = Bool(
303 title=_("Enabled"), required=False,
304 description=_("Whether the archive is enabled or not."))
305
306=== modified file 'lib/lp/soyuz/model/archive.py'
307--- lib/lp/soyuz/model/archive.py 2009-07-31 19:45:21 +0000
308+++ lib/lp/soyuz/model/archive.py 2009-08-27 13:19:19 +0000
309@@ -187,6 +187,11 @@
310 alsoProvides(self, IDistributionArchive)
311
312 @property
313+ def title(self):
314+ """See `IArchive`."""
315+ return self.displayname
316+
317+ @property
318 def is_ppa(self):
319 """See `IArchive`."""
320 return self.purpose == ArchivePurpose.PPA
321
322=== added file 'lib/lp/soyuz/stories/ppa/xx-ppa-packages.txt'
323--- lib/lp/soyuz/stories/ppa/xx-ppa-packages.txt 1970-01-01 00:00:00 +0000
324+++ lib/lp/soyuz/stories/ppa/xx-ppa-packages.txt 2009-08-28 15:19:43 +0000
325@@ -0,0 +1,76 @@
326+The PPA packages page
327+=====================
328+
329+The PPA packages page is accessible from the PPA page.
330+NOTE: The PPA page will be updated in a following branch.
331+
332+ >> anon_browser.open('http://launchpad.dev/~cprov/+archive/ppa')
333+ >> anon_browser.getLink('View package details').click()
334+ >> anon_browser.url
335+ 'http://launchpad.dev/~cprov/+archive/ppa/+packages'
336+
337+ >>> anon_browser.open('http://launchpad.dev/~cprov/+archive/ppa/+packages')
338+
339+ >>> print anon_browser.title
340+ Packages in ...PPA for Celso Providelo...
341+
342+While navigating around the PPA the "structural location" includes a PPA:
343+
344+ >>> print_location(anon_browser.contents)
345+ Hierarchy: Celso Providelo > PPA for Celso Providelo
346+ Tabs:
347+ * Overview (selected) - http://launchpad.dev/~cprov
348+ * Code - http://code.launchpad.dev/~cprov
349+ * Bugs - http://bugs.launchpad.dev/~cprov
350+ * Blueprints - http://blueprints.launchpad.dev/~cprov
351+ * Translations - http://translations.launchpad.dev/~cprov
352+ * Answers - http://answers.launchpad.dev/~cprov
353+ Main heading: Packages in ...PPA for Celso Providelo...
354+
355+You can see the build details of the packages in the archive by using
356+the 'View all builds' link.
357+
358+ >>> anon_browser.getLink('View all builds').click()
359+ >>> print anon_browser.title
360+ Builds for PPA for Celso Providelo
361+
362+ >>> print anon_browser.url
363+ http://launchpad.dev/~cprov/+archive/ppa/+builds
364+
365+
366+The rest of the builds page functionality is tested generically at
367+in xx-builds-pages.txt.
368+
369+
370+Package totals
371+--------------
372+
373+A summary of the package totals is presented in a portlet (although the
374+actual values are loaded in asynchronously.
375+
376+ >>> anon_browser.open('http://launchpad.dev/~cprov/+archive/ppa/+packages')
377+ >>> package_totals = find_portlet(
378+ ... anon_browser.contents, "Package totals")
379+ >>> print extract_text(package_totals)
380+ Package totals
381+ ...
382+ Package counters and estimated archive size temporarily
383+ unavailable.
384+
385+A summary of the builds for the PPA is also presented.
386+
387+ >>> build_summary = find_portlet(
388+ ... anon_browser.contents, "View all builds Package build summary")
389+ >>> print extract_text(build_summary)
390+ View...
391+ A total of 4 builds have been dispatched for this PPA.
392+ Completed builds
393+ 3 successful
394+ 1 failed
395+
396+Successful builds link directly to the builds filter.
397+
398+ >>> successful_builds_link = anon_browser.getLink('3 successful')
399+ >>> print successful_builds_link.url
400+ http://launchpad.dev/~cprov/+archive/ppa/+builds?build_state=built
401+
402
403=== modified file 'lib/lp/soyuz/templates/archive-macros.pt'
404--- lib/lp/soyuz/templates/archive-macros.pt 2009-09-01 10:21:45 +0000
405+++ lib/lp/soyuz/templates/archive-macros.pt 2009-09-02 09:20:43 +0000
406@@ -261,61 +261,63 @@
407 :archive: targeted IArchive.
408 </tal:comment>
409
410- <ul tal:define="usage_summary archive/@@+index/repository_usage">
411- <li id="source_counter">
412- <tal:source_label replace="usage_summary/source_label" />
413+ <dl tal:define="usage_summary archive/@@+index/repository_usage">
414+ <dt>Number of packages:</dt>
415+ <dd><tal:source_label replace="usage_summary/source_label" />
416 (<tal:sources_size
417- replace="usage_summary/sources_size/fmt:bytes" />)</li>
418- <li id="binary_counter">
419+ replace="usage_summary/sources_size/fmt:bytes" />)</dd>
420+ <dd>
421 <tal:binary_label replace="usage_summary/binary_label" />
422 (<tal:binaries_size
423- replace="usage_summary/binaries_size/fmt:bytes" />)</li>
424- <li id="total_size">
425- Estimated repository size:
426- <tal:used replace="usage_summary/used/fmt:bytes" />
427+ replace="usage_summary/binaries_size/fmt:bytes" />)</dd>
428+ <dt>Repository size:</dt>
429+ <dd><tal:used replace="usage_summary/used/fmt:bytes" />
430 (<span tal:attributes="class usage_summary/used_css_class"
431 tal:content="string:${usage_summary/used_percentage}%"/>)
432- of <tal:quota replace="usage_summary/quota/fmt:bytes" /></li>
433- </ul>
434-
435+ of <tal:quota replace="usage_summary/quota/fmt:bytes" /></dd>
436+ </dl>
437
438 </metal:package_counters>
439
440 <metal:build_status_summary define-macro="build-status-summary">
441
442 <tal:comment replace="nothing">
443- Present the build pie chart for the context IArchiveRebuild.
444+ Present a summary of the packages with build statuses for the archive.
445 :archive: targetted IArchive.
446+
447+ XXX noodles 20090827 bug=419921
448+ Currently we can only provide a direct link to successful builds
449+ as there is no single filtering option for failed and pending
450+ builds.
451 </tal:comment>
452
453- <table id="build-count-table"
454- summary="An overview of the build status for this archive."
455- tal:define="build_counters view/build_counters">
456- <thead>
457- <tr>
458- <th>Total builds:</th>
459- <td class="total" tal:content="view/build_counters/total">100</td>
460- </tr>
461- </thead>
462- <tbody>
463- <tr>
464- <th>Failed</th>
465- <td class="failed" tal:content="build_counters/failed">100</td>
466- </tr>
467- <tr>
468- <th>Pending</th>
469- <td class="pending" tal:content="build_counters/pending">100</td>
470- </tr>
471- <tr>
472- <th>Superseded</th>
473- <td class="superseded" tal:content="build_counters/superseded">100</td>
474- </tr>
475- <tr>
476- <th>Succeeded</th>
477- <td class="succeeded" tal:content="build_counters/succeeded">100</td>
478- </tr>
479- </tbody>
480- </table>
481+ <div id="build-count-summary">
482+
483+ <p>A total of
484+ <span class="build-count total"
485+ tal:content="view/build_counters/total">100</span> builds have
486+ been dispatched for this PPA.</p>
487+
488+ <dl>
489+ <dt>Completed builds</dt>
490+ <dd>
491+ <a tal:attributes="href context/menu:context/builds_successful/fmt:url">
492+ <span class="build-count succeeded"
493+ tal:content="view/build_counters/succeeded">100</span>
494+ successful</a></dd>
495+ <dd>
496+ <span class="build-count failed"
497+ tal:content="view/build_counters/failed">100</span>
498+ failed</dd>
499+ </dl>
500+
501+ <p tal:condition="view/build_counters/pending">
502+ A recent upload has resulted in
503+ <span class="build-count pending"
504+ tal:content="view/build_counters/pending">100</span>
505+ pending builds.
506+ </p>
507+ </div>
508 </metal:build_status_summary>
509
510 <metal:package_filter_form define-macro="package-filter-form">
511
512=== added file 'lib/lp/soyuz/templates/archive-packages.pt'
513--- lib/lp/soyuz/templates/archive-packages.pt 1970-01-01 00:00:00 +0000
514+++ lib/lp/soyuz/templates/archive-packages.pt 2009-08-25 09:56:04 +0000
515@@ -0,0 +1,183 @@
516+<html
517+ xmlns="http://www.w3.org/1999/xhtml"
518+ xmlns:tal="http://xml.zope.org/namespaces/tal"
519+ xmlns:metal="http://xml.zope.org/namespaces/metal"
520+ xmlns:i18n="http://xml.zope.org/namespaces/i18n"
521+ metal:use-macro="view/macro:page/main_only"
522+ i18n:domain="launchpad"
523+ >
524+<body>
525+ <metal:block fill-slot="head_epilogue">
526+ <tal:devmode condition="devmode">
527+ <tal:archive_js define="lp_js string:${icingroot}/build">
528+ <script type="text/javascript"
529+ tal:attributes="src string:${lp_js}/soyuz/base.js">
530+ </script>
531+ <script type="text/javascript"
532+ tal:attributes="src string:${lp_js}/soyuz/lp_dynamic_dom_updater.js">
533+ </script>
534+ <script type="text/javascript"
535+ tal:attributes="src string:${lp_js}/soyuz/update_archive_build_statuses.js">
536+ </script>
537+ </tal:archive_js>
538+ </tal:devmode>
539+ <script type="text/javascript" id="repository-size-update"
540+ tal:condition="view/archive_url">
541+YUI().use('io-base', 'lazr.anim', 'node', 'soyuz-base',
542+ 'soyuz.update_archive_build_statuses', function(Y) {
543+
544+
545+/*
546+ * Update the page based on the XHR response.
547+ */
548+function doUpdate(transaction_id, response, args) {
549+ args.container.set('innerHTML', response.responseText);
550+}
551+
552+
553+/*
554+ * Communicate the update has failed and allow the user to retry
555+ * the operation.
556+ */
557+function informFailure(transaction_id, response, args) {
558+ function retry_handler (e) {
559+ e.preventDefault();
560+ dispatchUpdate();
561+ };
562+
563+ var failure_message = Y.soyuz.makeFailureNode(
564+ 'Failed to fetch repository size ...', retry_handler);
565+
566+ args.container.set('innerHTML', '');
567+ args.container.appendChild(failure_message);
568+
569+ var anim = Y.lazr.anim.red_flash({
570+ node: failure_message
571+ });
572+ anim.run();
573+}
574+
575+
576+/*
577+ * Communicate an update is in progress and fire the XHR.
578+ */
579+function dispatchUpdate () {
580+ in_progress_message = Y.soyuz.makeInProgressNode(
581+ 'Fetching repository size ...')
582+
583+ var container = Y.get('#package-counters');
584+ container.set('innerHTML', '');
585+ container.appendChild(in_progress_message);
586+
587+ var uri = '+repository-size';
588+ var xhr_config = {
589+ on: {
590+ success: doUpdate,
591+ failure: informFailure
592+ },
593+ arguments: {
594+ 'container': container
595+ }
596+ };
597+
598+ Y.io(uri, xhr_config);
599+}
600+
601+Y.on("domready", dispatchUpdate);
602+});
603+ </script>
604+ <style type="text/css" media="screen, print">
605+tr#package-counters p{
606+ margin-bottom: 3.4em;
607+}
608+ </style>
609+ </metal:block>
610+
611+ <div metal:fill-slot="main"
612+ tal:define="archive_active view/has_sources;
613+ archive_label view/archive_label;"
614+ tal:attributes="class string:archive">
615+
616+ <div class="top-portlet">
617+
618+ <div class="ppa-packaging-tmp-actions"
619+ tal:content="structure view/@@+global-actions" />
620+ <h1 tal:content="view/page_title">
621+ PPA for user
622+ </h1>
623+
624+ <p tal:condition="not: context/enabled"
625+ style="clear: right;" class="warning message">
626+ This archive has been disabled.
627+ </p>
628+
629+ <p>This
630+ <tal:archive_label replace="archive_label">PPA</tal:archive_label>
631+ currently publishes packages for
632+ <tal:series_list replace="view/series_list_string">
633+ Gutsy, Hardy and Karmic
634+ </tal:series_list>.
635+ </p>
636+ </div>
637+
638+ <div class="yui-g">
639+ <div class="first yui-u"><div class="portlet">
640+ <h2>Package totals</h2>
641+ <p>The following information is related to the total published
642+ packages in the repository (not on your system).</p>
643+ <div id="package-counters">
644+ <p class="discreet">
645+ Package counters and estimated archive size temporarily
646+ unavailable.
647+ </p>
648+ </div>
649+ </div></div> <!-- portlet, yui-u -->
650+
651+ <div class="yui-u">
652+ <div tal:define="archive context"
653+ tal:condition="archive_active"
654+ id="build-status-summary"
655+ class="portlet">
656+ <h2>
657+ <span class="see-all"><a
658+ tal:replace="structure context/menu:context/builds/fmt:link" />
659+ </span>
660+ Package build summary
661+ </h2>
662+
663+ <metal:build-status-summary
664+ use-macro="archive/@@+macros/build-status-summary" />
665+ </div>
666+ </div>
667+
668+ </div> <!-- yui-g -->
669+
670+ <div class="portlet">
671+ <h2>Packages</h2>
672+ <tal:package-copy-request-list tal:condition="context/is_copy">
673+ <metal:package-copy-request-list
674+ use-macro="context/@@+macros/package-copy-request-list" />
675+ </tal:package-copy-request-list>
676+
677+ <p tal:condition="not: archive_active">
678+ This <tal:archive_label replace="archive_label" /> does not contain
679+ any packages yet. Find more information about how to upload
680+ packages in the <a href="https://help.launchpad.net/Packaging/PPA"
681+ >PPA help page</a>
682+ </p>
683+
684+ <tal:active_archive condition="archive_active">
685+
686+ <metal:package_filter_form
687+ use-macro="context/@@+macros/package-filter-form" />
688+
689+ <metal:package-list
690+ use-macro="context/@@+macros/source-package-list" />
691+
692+ </tal:active_archive>
693+ </div> <!-- portlet -->
694+ </div> <!--main -->
695+
696+ </body>
697+
698+</html>