class ProductReleaseEditView(LaunchpadEditFormView):
    """Edit view for ProductRelease objects"""

    schema = IProductRelease
    field_names = [
        "datereleased",
        "release_notes",
        "changelog",
        ]

    custom_widget('datereleased', DateTimeWidget)
    custom_widget('release_notes', TextAreaWidget, height=7, width=62)
    custom_widget('changelog', TextAreaWidget, height=7, width=62)

    @property
    def label(self):
        """The form label."""
        return smartquote('Edit %s release details' % self.context.title)

    page_title = label

    @action('Change', name='change')
    def change_action(self, action, data):
        self.updateContextFromData(data)
        self.next_url = canonical_url(self.context)

    @property
    def cancel_url(self):
        return canonical_url(self.context)
Esempio n. 2
0
class BrandingChangeView(LaunchpadEditFormView):
    """This is a base class that MUST be subclassed for each object, because
    each object will have a different description for its branding that is
    part of its own interface.

    For each subclass, specify the schema ("IPerson") and the field_names
    (some subset of icon, logo, mugshot).
    """
    @property
    def label(self):
        return ('Change the images used to represent %s in Launchpad' %
                self.context.displayname)

    page_title = "Change branding"

    custom_widget('icon', ImageChangeWidget, ImageChangeWidget.EDIT_STYLE)
    custom_widget('logo', ImageChangeWidget, ImageChangeWidget.EDIT_STYLE)
    custom_widget('mugshot', ImageChangeWidget, ImageChangeWidget.EDIT_STYLE)

    @action("Change Branding", name='change')
    def change_action(self, action, data):
        self.updateContextFromData(data)

    @property
    def next_url(self):
        return canonical_url(self.context)

    cancel_url = next_url
Esempio n. 3
0
class ProductSeriesEditView(LaunchpadEditFormView):
    """A View to edit the attributes of a series."""
    schema = IProductSeries
    field_names = [
        'name', 'summary', 'status', 'branch', 'releasefileglob']
    custom_widget('summary', TextAreaWidget, height=7, width=62)
    custom_widget('releasefileglob', StrippedTextWidget, displayWidth=40)

    @property
    def label(self):
        """The form label."""
        return 'Edit %s %s series' % (
            self.context.product.displayname, self.context.name)

    page_title = label

    def validate(self, data):
        """See `LaunchpadFormView`."""
        branch = data.get('branch')
        if branch is not None:
            message = get_series_branch_error(self.context.product, branch)
            if message:
                self.setFieldError('branch', message)

    @action(_('Change'), name='change')
    def change_action(self, action, data):
        """Update the series."""
        self.updateContextFromData(data)

    @property
    def next_url(self):
        """See `LaunchpadFormView`."""
        return canonical_url(self.context)

    cancel_url = next_url
class DistroBugTrackerCreationStep(BugTrackerCreationStep):

    _next_step = DistroBugTaskCreationStep
    _field_names = ['distribution', 'sourcepackagename', 'bug_url']
    custom_widget('distribution', DropdownWidget, visible=False)
    custom_widget('sourcepackagename', DropdownWidget, visible=False)
    label = "Also affects distribution/package"
    template = ViewPageTemplateFile(
        '../templates/bugtask-confirm-bugtracker-creation.pt')
Esempio n. 5
0
class SprintAddView(LaunchpadFormView):
    """Form for creating sprints"""

    schema = ISprint
    label = "Register a meeting"
    field_names = ['name', 'title', 'summary', 'home_page', 'driver',
                   'time_zone', 'time_starts', 'time_ends', 'address',
                   ]
    custom_widget('summary', TextAreaWidget, height=5)
    custom_widget('time_starts', DateTimeWidget, display_zone=False)
    custom_widget('time_ends', DateTimeWidget, display_zone=False)
    custom_widget('address', TextAreaWidget, height=3)

    sprint = None

    def setUpWidgets(self):
        LaunchpadFormView.setUpWidgets(self)
        timeformat = '%Y-%m-%d %H:%M'
        self.widgets['time_starts'].timeformat = timeformat
        self.widgets['time_ends'].timeformat = timeformat
        time_zone_widget = self.widgets['time_zone']
        if time_zone_widget.hasValidInput():
            tz = pytz.timezone(time_zone_widget.getInputValue())
            self.widgets['time_starts'].required_time_zone = tz
            self.widgets['time_ends'].required_time_zone = tz

    def validate(self, data):
        time_starts = data.get('time_starts')
        time_ends = data.get('time_ends')
        if time_starts and time_ends and time_ends < time_starts:
            self.setFieldError(
                'time_ends', "This event can't start after it ends")

    @action(_('Add Sprint'), name='add')
    def add_action(self, action, data):
        self.sprint = getUtility(ISprintSet).new(
            owner=self.user,
            name=data['name'],
            title=data['title'],
            summary=data['summary'],
            home_page=data['home_page'],
            driver=data['driver'],
            time_zone=data['time_zone'],
            time_starts=data['time_starts'],
            time_ends=data['time_ends'],
            address=data['address'],
            )
        self.request.response.addInfoNotification('Sprint created.')

    @property
    def next_url(self):
        assert self.sprint is not None, 'No sprint has been created'
        return canonical_url(self.sprint)

    @property
    def cancel_url(self):
        return canonical_url(getUtility(ISprintSet))
Esempio n. 6
0
class CodeImportBaseView(LaunchpadFormView):
    """A base view for both new and edit code import views."""

    schema = ICodeImport

    custom_widget('cvs_root', StrippedTextWidget, displayWidth=50)
    custom_widget('cvs_module', StrippedTextWidget, displayWidth=20)
    custom_widget('url', URIWidget, displayWidth=50)

    @cachedproperty
    def _super_user(self):
        """Is the user an admin or member of vcs-imports?"""
        role = IPersonRoles(self.user)
        return role.in_admin or role.in_vcs_imports

    def showOptionalMarker(self, field_name):
        """Don't show the optional marker for rcs locations."""
        # No field in either the new or edit view needs an optional marker,
        # so we can be simple here.
        return False

    def setSecondaryFieldError(self, field, error):
        """Set the field error only if there isn't an error already."""
        if not self.getFieldError(field):
            self.setFieldError(field, error)

    def _validateCVS(self, cvs_root, cvs_module, existing_import=None):
        """If the user has specified cvs, then we need to make
        sure that there isn't already an import with those values."""
        if cvs_root is None:
            self.setSecondaryFieldError(
                'cvs_root', 'Enter a CVS root.')
        if cvs_module is None:
            self.setSecondaryFieldError(
                'cvs_module', 'Enter a CVS module.')

        if cvs_root and cvs_module:
            code_import = getUtility(ICodeImportSet).getByCVSDetails(
                cvs_root, cvs_module)
            if (code_import is not None and
                code_import != existing_import):
                self.addError(structured("""
                    Those CVS details are already specified for
                    the imported branch <a href="%s">%s</a>.""",
                    canonical_url(code_import.branch),
                    code_import.branch.unique_name))

    def _validateURL(self, url, existing_import=None, field_name='url'):
        """If the user has specified a url, we need to make sure that there
        isn't already an import with that url."""
        if url is None:
            self.setSecondaryFieldError(
                field_name, 'Enter the URL of a foreign VCS branch.')
        else:
            reason = validate_import_url(url, existing_import)
            if reason:
                self.setFieldError(field_name, reason)
class UpstreamBugTrackerCreationStep(BugTrackerCreationStep):

    schema = IAddBugTaskWithUpstreamLinkForm
    _next_step = ProductBugTaskCreationStep
    _field_names = ['product', 'bug_url', 'link_upstream_how']
    custom_widget('product', DropdownWidget, visible=False)
    custom_widget('link_upstream_how',
                  LaunchpadRadioWidget, visible=False)
    label = "Confirm project"
    template = ViewPageTemplateFile(
        '../templates/bugtask-confirm-bugtracker-creation.pt')
Esempio n. 8
0
class ProductSeriesTranslationsSettingsView(ReturnToReferrerMixin,
                                            LaunchpadEditFormView,
                                            ProductSeriesTranslationsMixin,
                                            ):
    """Edit settings for translations import and export."""

    schema = IProductSeries

    label = "Translations synchronization settings"
    page_title = "Settings"

    field_names = ['translations_autoimport_mode']
    settings_widget = custom_widget('translations_autoimport_mode',
                  SettingsRadioWidget)

    @action(u"Save settings", name="save_settings")
    def change_settings_action(self, action, data):
        """Change the translation settings."""
        if (self.context.translations_autoimport_mode !=
            data['translations_autoimport_mode']):
            self.updateContextFromData(data)
            # Request an initial upload of translation files.
            getUtility(IRosettaUploadJobSource).create(
                self.context.branch, NULL_REVISION)
        else:
            self.updateContextFromData(data)
        self.request.response.addInfoNotification(
            _("The settings have been updated."))
Esempio n. 9
0
class AnnouncementAddView(LaunchpadFormView):
    """A view for creating a new Announcement."""

    schema = AddAnnouncementForm
    label = "Make an announcement"
    page_title = label

    custom_widget('publication_date', AnnouncementDateWidget)

    @action(_('Make announcement'), name='announce')
    def announce_action(self, action, data):
        """Registers a new announcement."""
        self.context.announce(user=self.user,
                              title=data.get('title'),
                              summary=data.get('summary'),
                              url=data.get('url'),
                              publication_date=data.get('publication_date'))
        self.next_url = canonical_url(self.context)

    @property
    def action_url(self):
        return "%s/+announce" % canonical_url(self.context)

    @property
    def cancel_url(self):
        """The project's URL."""
        return canonical_url(self.context)
Esempio n. 10
0
class NameBlacklistAddView(NameBlacklistValidationMixin, LaunchpadFormView):
    """View for adding a blacklist expression."""

    schema = INameBlacklist
    field_names = ['regexp', 'admin', 'comment']
    label = "Add a new blacklist expression"
    page_title = label

    custom_widget('regexp', TextWidget, displayWidth=60)

    @property
    def cancel_url(self):
        """See `LaunchpadFormView`."""
        return canonical_url(self.context)

    next_url = cancel_url

    @action("Add to blacklist", name='add')
    def add_action(self, action, data):
        name_blacklist_set = getUtility(INameBlacklistSet)
        name_blacklist_set.create(
            regexp=data['regexp'],
            comment=data['comment'],
            admin=data['admin'],
        )
        self.request.response.addInfoNotification(
            'Regular expression "%s" has been added to the name blacklist.' %
            data['regexp'])
class FeaturedProjectsView(LaunchpadFormView):
    """A view for adding and removing featured projects."""

    label = 'Manage featured projects in Launchpad'
    page_title = label

    schema = FeaturedProjectForm
    custom_widget('remove', LabeledMultiCheckBoxWidget)

    @action(_('Update featured project list'), name='update')
    def update_action(self, action, data):
        """Add and remove featured projects."""

        add = data.get('add')
        if add is not None:
            getUtility(IPillarNameSet).add_featured_project(add)

        remove = data.get('remove')
        if remove is not None:
            for project in remove:
                getUtility(IPillarNameSet).remove_featured_project(project)

        self.next_url = canonical_url(self.context)

    @action(_("Cancel"), name="cancel", validator='validate_cancel')
    def action_cancel(self, action, data):
        self.next_url = canonical_url(self.context)

    @property
    def action_url(self):
        return "/+featuredprojects"
Esempio n. 12
0
class BugMarkAsAffectingUserView(LaunchpadFormView):
    """Page for marking a bug as affecting the user."""

    schema = BugMarkAsAffectingUserForm

    field_names = ['affects']
    label = "Does this bug affect you?"
    page_title = label

    custom_widget('affects', LaunchpadRadioWidgetWithDescription)

    @property
    def initial_values(self):
        """See `LaunchpadFormView.`"""
        affected = self.context.bug.isUserAffected(self.user)
        if affected or affected is None:
            affects = BugAffectingUserChoice.YES
        else:
            affects = BugAffectingUserChoice.NO

        return {'affects': affects}

    @action('Change', name='change')
    def change_action(self, action, data):
        """Mark the bug according to the selection."""
        self.context.bug.markUserAffected(
            self.user, data['affects'] == BugAffectingUserChoice.YES)
        self.request.response.redirect(canonical_url(self.context.bug))
Esempio n. 13
0
class ProductSeriesReviewView(LaunchpadEditFormView):
    """A view to review and change the series `IProduct` and name."""
    schema = IProductSeries
    field_names = ['product', 'name']
    custom_widget('name', TextWidget, displayWidth=20)

    @property
    def label(self):
        """The form label."""
        return 'Administer %s %s series' % (
            self.context.product.displayname, self.context.name)

    page_title = label

    @property
    def cancel_url(self):
        """See `LaunchpadFormView`."""
        return canonical_url(self.context)

    @action(_('Change'), name='change')
    def change_action(self, action, data):
        """Update the series."""
        self.updateContextFromData(data)
        self.request.response.addInfoNotification(
            _('This Series has been changed'))
        self.next_url = canonical_url(self.context)
Esempio n. 14
0
class MilestoneAddView(MilestoneTagBase, LaunchpadFormView):
    """A view for creating a new Milestone."""

    schema = IMilestone
    field_names = ['name', 'code_name', 'dateexpected', 'summary']
    label = "Register a new milestone"

    custom_widget('dateexpected', DateWidget)

    @action(_('Register Milestone'), name='register')
    def register_action(self, action, data):
        """Use the newMilestone method on the context to make a milestone."""
        milestone = self.context.newMilestone(
            name=data.get('name'),
            code_name=data.get('code_name'),
            dateexpected=data.get('dateexpected'),
            summary=data.get('summary'))
        tags = data.get('tags')
        if tags:
            milestone.setTags(tags.lower().split(), self.user)
        self.next_url = canonical_url(self.context)

    @property
    def action_url(self):
        """See `LaunchpadFormView`."""
        return "%s/+addmilestone" % canonical_url(self.context)

    @property
    def cancel_url(self):
        """See `LaunchpadFormView`."""
        return canonical_url(self.context)
Esempio n. 15
0
class ProjectAddView(LaunchpadFormView):

    schema = IProjectGroup
    field_names = [
        'name',
        'displayname',
        'title',
        'summary',
        'description',
        'owner',
        'homepageurl',
    ]
    custom_widget('homepageurl', TextWidget, displayWidth=30)
    label = _('Register a project group with Launchpad')
    page_title = label
    project = None

    @action(_('Add'), name='add')
    def add_action(self, action, data):
        """Create the new Project from the form details."""
        self.project = getUtility(IProjectGroupSet).new(
            name=data['name'].lower().strip(),
            displayname=data['displayname'],
            title=data['title'],
            homepageurl=data['homepageurl'],
            summary=data['summary'],
            description=data['description'],
            owner=data['owner'],
        )
        notify(ObjectCreatedEvent(self.project))

    @property
    def next_url(self):
        assert self.project is not None, 'No project has been created'
        return canonical_url(self.project)
Esempio n. 16
0
class LanguageAdminView(LaunchpadEditFormView):
    """Handle an admin form submission."""

    rootsite = 'translations'

    schema = ILanguage

    custom_widget('countries',
                  LabeledMultiCheckBoxWidget,
                  orientation='vertical')

    field_names = [
        'code', 'englishname', 'nativename', 'pluralforms', 'pluralexpression',
        'visible', 'direction', 'countries'
    ]

    page_title = "Change details"

    @property
    def label(self):
        """The form label"""
        return "Edit %s in Launchpad" % describe_language(self.context)

    @property
    def cancel_url(self):
        """See LaunchpadFormView."""
        return canonical_url(self.context, rootsite=self.rootsite)

    @property
    def next_url(self):
        return canonical_url(self.context, rootsite=self.rootsite)

    @action("Admin Language", name="admin")
    def admin_action(self, action, data):
        self.updateContextFromData(data)

    def _validateCode(self, new_code):
        """Validate a change in language code."""
        language_set = getUtility(ILanguageSet)
        if language_set.getLanguageByCode(new_code) is not None:
            self.setFieldError('code',
                               'There is already a language with that code.')

    def _validatePluralData(self, pluralforms, pluralexpression):
        """Validate plural expression and number of plural forms."""
        try:
            make_friendly_plural_forms(pluralexpression, pluralforms)
        except BadPluralExpression as e:
            self.setFieldError('pluralexpression', str(e))

    def validate(self, data):
        new_code = data.get('code')
        if new_code != self.context.code:
            self._validateCode(new_code)

        pluralexpression = data.get('pluralexpression')
        pluralforms = data.get('pluralforms')
        if pluralexpression is not None:
            self._validatePluralData(pluralforms, pluralexpression)
Esempio n. 17
0
class ProductReleaseAddViewBase(LaunchpadFormView):
    """Base class for creating a release from an existing or new milestone.

    Subclasses need to define the field_names a form action.
    """
    schema = IProductRelease

    custom_widget('datereleased', DateTimeWidget)
    custom_widget('release_notes', TextAreaWidget, height=7, width=62)
    custom_widget('changelog', TextAreaWidget, height=7, width=62)

    def _prependKeepMilestoneActiveField(self):
        keep_milestone_active_checkbox = FormFields(
            Bool(
                __name__='keep_milestone_active',
                title=_("Keep the %s milestone active." % self.context.name),
                description=_(
                    "Only select this if bugs or blueprints still need "
                    "to be targeted to this project release's milestone.")),
            render_context=self.render_context)
        self.form_fields = keep_milestone_active_checkbox + self.form_fields

    def _createRelease(self, milestone, data):
        """Create product release for this milestone."""
        newrelease = milestone.createProductRelease(
            self.user, changelog=data['changelog'],
            release_notes=data['release_notes'],
            datereleased=data['datereleased'])
        # Set Milestone.active to false, since bugs & blueprints
        # should not be targeted to a milestone in the past.
        if data.get('keep_milestone_active') is False:
            milestone.active = False
        self.next_url = canonical_url(newrelease.milestone)
        notify(ObjectCreatedEvent(newrelease))

    @property
    def label(self):
        """The form label."""
        return smartquote('Create a new release for %s' %
                          self.context.product.displayname)

    page_title = label

    @property
    def cancel_url(self):
        return canonical_url(self.context)
Esempio n. 18
0
class SprintEditView(LaunchpadEditFormView):
    """Form for editing sprints"""

    schema = ISprint
    label = "Edit sprint details"

    field_names = ['name', 'title', 'summary', 'home_page', 'driver',
                   'time_zone', 'time_starts', 'time_ends', 'address',
                   ]
    custom_widget('summary', TextAreaWidget, height=5)
    custom_widget('time_starts', DateTimeWidget, display_zone=False)
    custom_widget('time_ends', DateTimeWidget, display_zone=False)
    custom_widget('address', TextAreaWidget, height=3)

    def setUpWidgets(self):
        LaunchpadEditFormView.setUpWidgets(self)
        timeformat = '%Y-%m-%d %H:%M'
        self.widgets['time_starts'].timeformat = timeformat
        self.widgets['time_ends'].timeformat = timeformat
        time_zone_widget = self.widgets['time_zone']
        # What time zone are the start and end values relative to?
        if time_zone_widget.hasValidInput():
            tz = pytz.timezone(time_zone_widget.getInputValue())
        else:
            tz = pytz.timezone(self.context.time_zone)
        self.widgets['time_starts'].required_time_zone = tz
        self.widgets['time_ends'].required_time_zone = tz

    def validate(self, data):
        time_starts = data.get('time_starts')
        time_ends = data.get('time_ends')
        if time_starts and time_ends and time_ends < time_starts:
            self.setFieldError(
                'time_ends', "This event can't start after it ends")

    @action(_('Change'), name='change')
    def change_action(self, action, data):
        self.updateContextFromData(data)

    @property
    def next_url(self):
        return canonical_url(self.context)

    @property
    def cancel_url(self):
        return canonical_url(self.context)
class BugSubscriptionFilterEditViewBase(LaunchpadEditFormView,
                                        AdvancedSubscriptionMixin):
    """Base class for edit or create views of `IBugSubscriptionFilter`."""

    schema = IBugSubscriptionFilter
    field_names = (
        "description",
        "statuses",
        "importances",
        "information_types",
        "tags",
        "find_all_tags",
    )

    custom_widget("description", TextWidget, displayWidth=50)
    custom_widget("statuses", LabeledMultiCheckBoxWidget)
    custom_widget("importances", LabeledMultiCheckBoxWidget)
    custom_widget("information_types", LabeledMultiCheckBoxWidget)
    custom_widget("tags", BugTagsFrozenSetWidget, displayWidth=35)

    # Define in concrete subclass to be the target of the
    # structural subscription that we are modifying.
    target = None

    # This is used by the AdvancedSubscriptionMixin.
    current_user_subscription = None

    @cachedproperty
    def _bug_notification_level_descriptions(self):
        return bug_notification_level_description_mapping(
            'a bug in %s' % self.target.displayname)

    def setUpFields(self):
        """Set up fields for form.

        Overrides the usual implementation to also set up bug notification."""
        super(BugSubscriptionFilterEditViewBase, self).setUpFields()
        self._setUpBugNotificationLevelField()

    @property
    def next_url(self):
        """Return to the user's structural subscriptions page."""
        return canonical_url(self.user, view_name="+structural-subscriptions")

    cancel_url = next_url
Esempio n. 20
0
class BugEditView(BugEditViewBase):
    """The view for the edit bug page."""

    field_names = ['title', 'description', 'tags']
    custom_widget('title', TextWidget, displayWidth=30)
    custom_widget('tags', BugTagsWidget)

    @property
    def label(self):
        """The form label."""
        return 'Edit details for bug #%d' % self.context.bug.id

    page_title = label

    @action('Change', name='change')
    def change_action(self, action, data):
        """Update the bug with submitted changes."""
        self.updateBugFromData(data)
Esempio n. 21
0
class BuilderSetAddView(LaunchpadFormView):
    """View class for adding new Builders."""

    schema = IBuilder

    label = "Register a new build machine"

    field_names = [
        'name', 'title', 'processor', 'url', 'active', 'virtualized',
        'vm_host', 'owner'
    ]

    custom_widget('owner', HiddenUserWidget)
    custom_widget('url', TextWidget, displayWidth=30)
    custom_widget('vm_host', TextWidget, displayWidth=30)

    @action(_('Register builder'), name='register')
    def register_action(self, action, data):
        """Register a new builder."""
        builder = getUtility(IBuilderSet).new(
            processor=data.get('processor'),
            url=data.get('url'),
            name=data.get('name'),
            title=data.get('title'),
            owner=data.get('owner'),
            active=data.get('active'),
            virtualized=data.get('virtualized'),
            vm_host=data.get('vm_host'),
        )
        notify(ObjectCreatedEvent(builder))
        self.next_url = canonical_url(builder)

    @property
    def page_title(self):
        """Return a relevant page title for this view."""
        return self.label

    @property
    def cancel_url(self):
        """Canceling the add action should go back to the build farm."""
        return canonical_url(self.context)
Esempio n. 22
0
class AnnouncementPublishView(AnnouncementFormMixin, LaunchpadFormView):
    """A view to publish an annoucement."""

    schema = AddAnnouncementForm
    field_names = ['publication_date']
    page_title = 'Publish announcement'

    custom_widget('publication_date', AnnouncementDateWidget)

    @action(_('Publish'), name='publish')
    def publish_action(self, action, data):
        publication_date = data['publication_date']
        self.context.setPublicationDate(publication_date)
        self.next_url = canonical_url(self.context.target) + '/+announcements'
Esempio n. 23
0
class DistroSeriesEditView(LaunchpadEditFormView, SeriesStatusMixin):
    """View class that lets you edit a DistroSeries object.

    It redirects to the main distroseries page after a successful edit.
    """
    schema = IDistroSeries
    field_names = ['displayname', 'title', 'summary', 'description']
    custom_widget('status', LaunchpadDropdownWidget)

    @property
    def label(self):
        """See `LaunchpadFormView`."""
        return 'Edit %s details' % self.context.title

    @property
    def page_title(self):
        """The page title."""
        return self.label

    @property
    def cancel_url(self):
        """See `LaunchpadFormView`."""
        return canonical_url(self.context)

    def setUpFields(self):
        """See `LaunchpadFormView`.

        In addition to setting schema fields, also initialize the
        'status' field. See `createStatusField` method.
        """
        LaunchpadEditFormView.setUpFields(self)
        self.is_derivative = (
            not self.context.distribution.full_functionality)
        self.has_admin = check_permission('launchpad.Admin', self.context)
        if self.has_admin or self.is_derivative:
            # The user is an admin or this is an IDerivativeDistribution.
            self.form_fields = (
                self.form_fields + self.createStatusField())

    @action("Change")
    def change_action(self, action, data):
        """Update the context and redirects to its overviw page."""
        if self.has_admin or self.is_derivative:
            self.updateDateReleased(data.get('status'))
        self.updateContextFromData(data)
        self.request.response.addInfoNotification(
            'Your changes have been applied.')
        self.next_url = canonical_url(self.context)
Esempio n. 24
0
class DistroSeriesAdminView(LaunchpadEditFormView, SeriesStatusMixin):
    """View class for administering a DistroSeries object.

    It redirects to the main distroseries page after a successful edit.
    """
    schema = IDistroSeries
    field_names = ['name', 'version', 'changeslist']
    custom_widget('status', LaunchpadDropdownWidget)

    @property
    def label(self):
        """See `LaunchpadFormView`."""
        return 'Administer %s' % self.context.title

    @property
    def page_title(self):
        """The page title."""
        return self.label

    @property
    def cancel_url(self):
        """See `LaunchpadFormView`."""
        return canonical_url(self.context)

    def setUpFields(self):
        """Override `LaunchpadFormView`.

        In addition to setting schema fields, also initialize the
        'status' field. See `createStatusField` method.
        """
        LaunchpadEditFormView.setUpFields(self)
        self.form_fields = (
            self.form_fields + self.createStatusField())

    @action("Change")
    def change_action(self, action, data):
        """Update the context and redirects to its overviw page.

        Also, set 'datereleased' when a unstable distroseries is made
        CURRENT.
        """
        self.updateDateReleased(data.get('status'))
        self.updateContextFromData(data)

        self.request.response.addInfoNotification(
            'Your changes have been applied.')
        self.next_url = canonical_url(self.context)
Esempio n. 25
0
class AppFrontPageSearchView(LaunchpadFormView):

    schema = IAppFrontPageSearchForm
    custom_widget('scope', ProjectScopeWidget)

    @property
    def scope_css_class(self):
        """The CSS class for used in the scope widget."""
        if self.scope_error:
            return 'error'
        else:
            return None

    @property
    def scope_error(self):
        """The error message for the scope widget."""
        return self.getFieldError('scope')
Esempio n. 26
0
class PollOptionEditView(LaunchpadEditFormView):
    """Edit one of a poll's options."""

    schema = IPollOption
    label = "Edit option details"
    page_title = 'Edit option'
    field_names = ["name", "title"]
    custom_widget("title", TextWidget, displayWidth=30)

    @property
    def cancel_url(self):
        """See `LaunchpadFormView`."""
        return canonical_url(self.context.poll)

    @action("Save", name="save")
    def save_action(self, action, data):
        self.updateContextFromData(data)
        self.next_url = canonical_url(self.context.poll)
Esempio n. 27
0
class BugAttachmentPatchConfirmationView(LaunchpadFormView):
    """Confirmation of the "patch" flag setting.

    If the user sets the "patch" flag to a value that is inconsistent
    with the result of a call of guess_content_type() for this
    attachment, we show this view to ask the user if he is sure
    about his selection.
    """

    schema = IBugAttachmentIsPatchConfirmationForm

    custom_widget('patch', LaunchpadBooleanRadioWidget)

    def __init__(self, context, request):
        LaunchpadFormView.__init__(self, context, request)
        self.next_url = self.cancel_url = (canonical_url(
            ICanonicalUrlData(context).inside))

    def initialize(self):
        super(BugAttachmentPatchConfirmationView, self).initialize()
        self.widgets['patch'].setRenderedValue(self.is_patch)

    @property
    def label(self):
        return smartquote('Confirm attachment type of "%s"') % (
            self.context.title)

    page_title = 'Confirm attachment type'

    @action('Change', name='change')
    def change_action(self, action, data):
        current_patch_setting = self.context.type == BugAttachmentType.PATCH
        if data['patch'] != current_patch_setting:
            if data['patch']:
                self.context.type = BugAttachmentType.PATCH
                #xxxxxxxxxx adjust content type!
                # xxx use mixin, together with BugAttachmnetEditView
            else:
                self.context.type = BugAttachmentType.UNSPECIFIED

    @property
    def is_patch(self):
        """True if this attachment contains a patch, else False."""
        return self.context.type == BugAttachmentType.PATCH
Esempio n. 28
0
class PollOptionAddView(LaunchpadFormView):
    """Create a new option in a given poll."""

    schema = IPollOption
    label = "Create new poll option"
    page_title = "New option"
    field_names = ["name", "title"]
    custom_widget("title", TextWidget, displayWidth=30)

    @property
    def cancel_url(self):
        """See `LaunchpadFormView`."""
        return canonical_url(self.context)

    @action("Create", name="create")
    def create_action(self, action, data):
        polloption = self.context.newOption(data['name'], data['title'])
        self.next_url = canonical_url(self.context)
        notify(ObjectCreatedEvent(polloption))
Esempio n. 29
0
class FAQCreateView(LaunchpadFormView):
    """A view to create a new FAQ."""

    schema = IFAQ
    label = _('Create a new FAQ')
    field_names = ['title', 'keywords', 'content']

    custom_widget('keywords', TokensTextWidget)

    @property
    def page_title(self):
        return 'Create a FAQ for %s' % self.context.displayname

    @action(_('Create'), name='create')
    def create__action(self, action, data):
        """Creates the FAQ."""
        faq = self.context.newFAQ(self.user,
                                  data['title'],
                                  data['content'],
                                  keywords=data['keywords'])
        self.next_url = canonical_url(faq)
Esempio n. 30
0
class LanguageSetView(LaunchpadFormView):
    """View class to render main ILanguageSet page."""
    label = "Languages in Launchpad"
    page_title = "Languages"

    schema = ILanguageSetSearch

    custom_widget('search_lang', TextWidget, displayWidth=30)

    def initialize(self):
        """See `LaunchpadFormView`."""
        LaunchpadFormView.initialize(self)

        self.language_search = None

        search_lang_widget = self.widgets.get('search_lang')
        if (search_lang_widget is not None
                and search_lang_widget.hasValidInput()):
            self.language_search = search_lang_widget.getInputValue()
        self.search_requested = self.language_search is not None

    @cachedproperty
    def search_results(self):
        return self.context.search(text=self.language_search)

    @cachedproperty
    def search_matches(self):
        if self.search_results is not None:
            return self.search_results.count()
        else:
            return 0

    @cachedproperty
    def user_languages(self):
        """The user's preferred languages, or English if none are set."""
        languages = list(self.user.languages)
        if len(languages) == 0:
            languages = [getUtility(ILaunchpadCelebrities).english]
        return ", ".join(map(_format_language, languages))