~gary/launchpad/prodprepbuildout

« back to all changes in this revision

Viewing changes to lib/lp/registry/browser/product.py

  • Committer: Launchpad Patch Queue Manager
  • Date: 2010-03-09 16:31:11 UTC
  • mfrom: (9072.1.6 max-heat-from-context)
  • Revision ID: launchpad@pqm.canonical.com-20100309163111-2n17zsb7myoz34kf
[release-critical=flacoste][r=abel][ui=none][bug=531443] In bug
        listings, use the current context, rather than the bugtask target,
        to determine the maximum bug heat to use.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
    'ProductNavigationMenu',
22
22
    'ProductOverviewMenu',
23
23
    'ProductPackagesView',
 
24
    'ProductPackagesPortletView',
24
25
    'ProductRdfView',
25
26
    'ProductReviewLicenseView',
26
27
    'ProductSeriesView',
37
38
    ]
38
39
 
39
40
 
 
41
from cgi import escape
40
42
from operator import attrgetter
41
43
 
42
44
from zope.component import getUtility
45
47
from zope.lifecycleevent import ObjectCreatedEvent
46
48
from zope.interface import implements, Interface
47
49
from zope.formlib import form
 
50
from zope.schema import Choice
 
51
from zope.schema.vocabulary import (
 
52
    SimpleVocabulary, SimpleTerm)
48
53
 
49
54
from z3c.ptcompat import ViewPageTemplateFile
50
55
 
81
86
from lp.registry.browser.distribution import UsesLaunchpadMixin
82
87
from lp.registry.browser.menu import (
83
88
    IRegistryCollectionNavigationMenu, RegistryCollectionActionMenuBase)
84
 
from lp.registry.browser.packaging import PackagingDeleteView
85
89
from lp.answers.browser.faqtarget import FAQTargetNavigationMixin
86
90
from canonical.launchpad.browser.feeds import FeedsMixin
87
91
from lp.registry.browser.productseries import get_series_branch_error
95
99
    StructuralSubscriptionTargetTraversalMixin)
96
100
from canonical.launchpad.mail import format_address, simple_sendmail
97
101
from canonical.launchpad.webapp import (
98
 
    ApplicationMenu, LaunchpadEditFormView, LaunchpadFormView, LaunchpadView,
99
 
    Link, Navigation, StandardLaunchpadFacets, action, canonical_url,
100
 
    custom_widget, enabled_with_permission, sorted_version_numbers,
 
102
    ApplicationMenu, canonical_url, enabled_with_permission, LaunchpadView,
 
103
    Link, Navigation, sorted_version_numbers, StandardLaunchpadFacets,
101
104
    stepthrough, stepto, structured)
102
105
from canonical.launchpad.webapp.authorization import check_permission
103
106
from canonical.launchpad.webapp.batching import BatchNavigator
104
107
from canonical.launchpad.webapp.breadcrumb import Breadcrumb
 
108
from canonical.launchpad.webapp.launchpadform import (
 
109
    action, custom_widget, LaunchpadEditFormView, LaunchpadFormView,
 
110
    ReturnToReferrerMixin)
105
111
from canonical.launchpad.webapp.menu import NavigationMenu
106
112
from canonical.widgets.popup import PersonPickerWidget
107
113
from canonical.widgets.date import DateWidget
897
903
                check_permission('launchpad.Commercial', self.context))
898
904
 
899
905
 
900
 
class ProductPackagesView(PackagingDeleteView):
 
906
class ProductPackagesView(LaunchpadView):
901
907
    """View for displaying product packaging"""
902
908
 
903
909
    label = 'Linked packages'
904
 
 
905
 
    @property
906
 
    def all_packaging(self):
907
 
        """See `PackagingDeleteView`."""
908
 
        for series in self.context.series:
909
 
            for packaging in series.packagings:
910
 
                yield packaging
 
910
    page_title = label
911
911
 
912
912
    @cachedproperty
913
913
    def series_packages(self):
921
921
                field: '<input type=''hidden' ...>},
922
922
                }]
923
923
        """
924
 
        # This method is a superset of all_packaging. While all_packaging will
925
 
        # be called several times as data is mutated, series_packages should
926
 
        # only be called during render().
927
924
        packaged_series = []
928
925
        for series in self.context.series:
929
926
            packagings = []
930
927
            for packaging in series.packagings:
931
 
                form_id = 'delete-%s-%s-%s' % (
932
 
                    packaging.distroseries.name,
933
 
                    packaging.sourcepackagename.name,
934
 
                    packaging.productseries.name,
935
 
                    )
936
 
                packaging_field = dict(
937
 
                    packaging=packaging,
938
 
                    form_id=form_id,
939
 
                    field=self._renderHiddenPackagingField(packaging))
940
 
                packagings.append(packaging_field)
 
928
                packagings.append(packaging)
941
929
            packaged_series.append(dict(
942
930
                series=series, packagings=packagings))
943
931
        return packaged_series
981
969
        return results
982
970
 
983
971
 
 
972
class ProductPackagesPortletView(LaunchpadFormView):
 
973
    """View class for product packaging portlet."""
 
974
 
 
975
    schema = Interface
 
976
    custom_widget(
 
977
        'distributionsourcepackage', LaunchpadRadioWidget,
 
978
        orientation='vertical')
 
979
    suggestions = None
 
980
 
 
981
    def setUpFields(self):
 
982
        """See `LaunchpadFormView`."""
 
983
        super(ProductPackagesPortletView, self).setUpFields()
 
984
        ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
 
985
        source_packages = ubuntu.searchSourcePackages(self.context.name)
 
986
        # Based upon the matches, create a new vocabulary with
 
987
        # term descriptions that include a link to the source package.
 
988
        self.suggestions = []
 
989
        vocab_terms = []
 
990
        for package in source_packages:
 
991
            if package.upstream_product is not None:
 
992
                continue
 
993
            self.suggestions.append(package)
 
994
            item_url = canonical_url(package)
 
995
            description = """<a href="%s">%s</a>""" % (
 
996
                item_url, escape(package.name))
 
997
            vocab_terms.append(SimpleTerm(package, package.name, description))
 
998
        vocabulary = SimpleVocabulary(vocab_terms)
 
999
        self.form_fields = form.Fields(
 
1000
            Choice(__name__='distributionsourcepackage',
 
1001
                   title=_('Ubuntu packages'),
 
1002
                   default=None,
 
1003
                   vocabulary=vocabulary,
 
1004
                   required=True))
 
1005
 
 
1006
    @action(_('Link to this Ubuntu Package'), name='link')
 
1007
    def link(self, action, data):
 
1008
        product = self.context
 
1009
        dsp = data.get('distributionsourcepackage')
 
1010
        assert dsp is not None, "distributionsourcepackage was not specified"
 
1011
        product_series = product.development_focus
 
1012
        ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
 
1013
        product_series.setPackaging(ubuntu.currentseries,
 
1014
                                    dsp.sourcepackagename,
 
1015
                                    self.user)
 
1016
        self.request.response.addInfoNotification(
 
1017
            'This project was linked to the source package "%s"' %
 
1018
            dsp.displayname)
 
1019
        self.next_url = self.request.getURL()
 
1020
 
 
1021
 
984
1022
class SeriesReleasePair:
985
1023
    """Class for holding a series and release.
986
1024
 
1262
1300
        return canonical_url(self.context)
1263
1301
 
1264
1302
 
1265
 
class ProductReviewLicenseView(ProductEditView, EditPrivateBugsMixin):
 
1303
class ProductReviewLicenseView(ReturnToReferrerMixin,
 
1304
                               ProductEditView, EditPrivateBugsMixin):
1266
1305
    """A view to review a project and change project privileges."""
1267
1306
    label = "Review project"
1268
1307
    field_names = [
1302
1341
        # supervisor.
1303
1342
        self.validate_private_bugs(data)
1304
1343
 
1305
 
    @property
1306
 
    def next_url(self):
1307
 
        """See `LaunchpadFormView`."""
1308
 
        # The referer header we want is only available before the view's
1309
 
        # form submits to itself. This field is a hidden input in the form.
1310
 
        referrer = self.request.form.get('next_url')
1311
 
        if referrer is None:
1312
 
            referrer = self.request.getHeader('referer')
1313
 
 
1314
 
        if (referrer is not None
1315
 
            and referrer.startswith(self.request.getApplicationURL())):
1316
 
            return referrer
1317
 
        else:
1318
 
            return canonical_url(self.context)
1319
 
 
1320
 
    @property
1321
 
    def cancel_url(self):
1322
 
        """See `LaunchpadFormView`."""
1323
 
        return self.next_url
1324
 
 
1325
 
 
1326
1344
class ProductAddSeriesView(LaunchpadFormView):
1327
1345
    """A form to add new product series"""
1328
1346
 
1613
1631
        self.request.form['summary'] = data['summary']
1614
1632
 
1615
1633
 
1616
 
class ProjectAddStepTwo(StepView, ProductLicenseMixin):
 
1634
class ProjectAddStepTwo(StepView, ProductLicenseMixin, ReturnToReferrerMixin):
1617
1635
    """Step 2 (of 2) in the +new project add wizard."""
1618
1636
 
1619
1637
    _field_names = ['displayname', 'name', 'title', 'summary',