Example #1
0
 def getDistribution(self):
     """See `BugTaskSourcePackageNameWidget`"""
     distribution_name = self.request.form.get('field.distribution')
     if distribution_name is None:
         raise UnexpectedFormData(
             "field.distribution wasn't in the request")
     distribution = getUtility(IDistributionSet).getByName(
         distribution_name)
     if distribution is None:
         raise UnexpectedFormData("No such distribution: %s" %
                                  distribution_name)
     return distribution
Example #2
0
    def current_package(self):
        """Get the package whose bugs are currently being searched."""
        if not (self.widgets['distribution'].hasValidInput()
                and self.widgets['distribution'].getInputValue()):
            raise UnexpectedFormData("A distribution is required")
        if not (self.widgets['sourcepackagename'].hasValidInput()
                and self.widgets['sourcepackagename'].getInputValue()):
            raise UnexpectedFormData("A sourcepackagename is required")

        distribution = self.widgets['distribution'].getInputValue()
        return distribution.getSourcePackage(
            self.widgets['sourcepackagename'].getInputValue())
    def getEntriesFilteringOptions(self):
        """Return the selected filtering."""
        target = None
        file_extension = None
        status = None
        target_widget = self.widgets.get('filter_target')
        if target_widget is not None and target_widget.hasValidInput():
            target = target_widget.getInputValue()
            pillar_name_set = getUtility(IPillarNameSet)
            if target == 'all':
                target = None
            elif target.startswith('[') and target.endswith(']'):
                # This is a SpecialTranslationImportTargetFilter.
                target_code = target[1:-1]
                target = None
                for enum_item in SpecialTranslationImportTargetFilter.items:
                    if enum_item.name == target_code:
                        target = enum_item

                if target is None:
                    raise UnexpectedFormData(
                        "Got a bad special target option: %s" % target)

            elif '/' in target:
                # It's a distroseries, for them we have
                # 'distribution.name/distroseries.name' to identify it.
                distribution_name, distroseries_name = target.split('/', 1)
                pillar = pillar_name_set.getByName(distribution_name)
                if IDistribution.providedBy(pillar):
                    target = pillar.getSeries(distroseries_name)
                else:
                    raise UnexpectedFormData("Got a bad target option %s" %
                                             target)
            else:
                target = pillar_name_set.getByName(target)
        filter_extension_widget = self.widgets.get('filter_extension')
        if filter_extension_widget.hasValidInput():
            file_extension = filter_extension_widget.getInputValue()
            if file_extension == 'all':
                file_extension = None
        filter_status_widget = self.widgets.get('filter_status')
        if filter_status_widget.hasValidInput():
            status = filter_status_widget.getInputValue()
            if status == 'all':
                status = None
            else:
                status = RosettaImportStatus.items[status]
        return target, file_extension, status
Example #4
0
 def getInputValue(self):
     """See zope.formlib.interfaces.IInputWidget."""
     scope = self.request.form_ng.getOne(self.name)
     if scope == 'all':
         return None
     elif scope == 'project':
         if not self.request.form_ng.getOne(self.target_widget.name):
             self._error = WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError('Please enter a project name'))
             raise self._error
         try:
             return self.target_widget.getInputValue()
         except ConversionError:
             entered_name = self.request.form_ng.getOne("%s.target" %
                                                        self.name)
             self._error = WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError(
                     "There is no project named '%s' registered in"
                     " Launchpad" % entered_name))
             raise self._error
     elif self.required:
         raise UnexpectedFormData("No valid option was selected.")
     else:
         return None
Example #5
0
    def processActiveMember(self):
        # This method checks the current status to ensure that we don't
        # crash because of users reposting a form.
        form = self.request.form
        context = self.context
        if form.get('deactivate'):
            if self.context.status == TeamMembershipStatus.DEACTIVATED:
                # This branch and redirect is necessary because
                # TeamMembership.setStatus() does not allow us to set an
                # already-deactivated account to deactivated, causing
                # double form posts to crash there. We instead manually
                # ensure that the double-post is harmless.
                self.request.response.redirect('%s/+members' %
                                               canonical_url(context.team))
                return
            new_status = TeamMembershipStatus.DEACTIVATED
        elif form.get('change'):
            if (form.get('admin') == "no"
                    and context.status == TeamMembershipStatus.ADMIN):
                new_status = TeamMembershipStatus.APPROVED
            elif (form.get('admin') == "yes"
                  and context.status == TeamMembershipStatus.APPROVED):
                new_status = TeamMembershipStatus.ADMIN
            else:
                # No status change will happen
                new_status = self.context.status
        else:
            raise UnexpectedFormData(
                "None of the expected actions were found.")

        if self._setMembershipData(new_status):
            self.request.response.redirect('%s/+members' %
                                           canonical_url(context.team))
Example #6
0
    def initialize(self):
        self.storeTokenContext()
        try:
            form = get_oauth_authorization(self.request)
        except UnicodeDecodeError:
            raise UnexpectedFormData("Invalid UTF-8.")
        key = form.get('oauth_token')
        if key:
            self.token = getUtility(IOAuthRequestTokenSet).getByKey(key)

        callback = self.request.form.get('oauth_callback')
        if (self.token is not None
            and self.token.consumer.is_integrated_desktop):
            # Nip problems in the bud by appling special rules about
            # what desktop integrations are allowed to do.
            if callback is not None:
                # A desktop integration is not allowed to specify a callback.
                raise Unauthorized(
                    "A desktop integration may not specify an "
                    "OAuth callback URL.")
            # A desktop integration token can only have one of two
            # permission levels: "Desktop Integration" and
            # "Unauthorized". It shouldn't even be able to ask for any
            # other level.
            for action in self.visible_actions:
                if action.permission not in (
                    OAuthPermission.DESKTOP_INTEGRATION,
                    OAuthPermission.UNAUTHORIZED):
                    raise Unauthorized(
                        ("Desktop integration token requested a permission "
                         '("%s") not supported for desktop-wide use.')
                         % action.label)

        super(OAuthAuthorizeTokenView, self).initialize()
 def getInputValue(self):
     """See zope.formlib.interfaces.IInputWidget."""
     self.setUpSubWidgets()
     form_value = self.request.form_ng.getOne(self.name)
     if form_value == 'product':
         try:
             return self.product_widget.getInputValue()
         except MissingInputError:
             self._error = WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError('Please enter a project name'))
             raise self._error
         except ConversionError:
             entered_name = self.request.form_ng.getOne("%s.product" %
                                                        self.name)
             self._error = WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError(
                     "There is no project named '%s' registered in"
                     " Launchpad" % entered_name))
             raise self._error
     elif form_value == 'package':
         try:
             distribution = self.distribution_widget.getInputValue()
         except ConversionError:
             entered_name = self.request.form_ng.getOne("%s.distribution" %
                                                        self.name)
             self._error = WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError(
                     "There is no distribution named '%s' registered in"
                     " Launchpad" % entered_name))
             raise self._error
         if self.package_widget.hasInput():
             try:
                 package_name = self.package_widget.getInputValue()
                 if package_name is None:
                     return distribution
                 if IDistributionSourcePackage.providedBy(package_name):
                     dsp = package_name
                 else:
                     source_name = (
                         distribution.guessPublishedSourcePackageName(
                             package_name.name))
                     dsp = distribution.getSourcePackage(source_name)
             except (ConversionError, NotFoundError):
                 entered_name = self.request.form_ng.getOne('%s.package' %
                                                            self.name)
                 self._error = WidgetInputError(
                     self.name, self.label,
                     LaunchpadValidationError(
                         "There is no package named '%s' published in %s." %
                         (entered_name, distribution.displayname)))
                 raise self._error
             return dsp
         else:
             return distribution
     else:
         raise UnexpectedFormData("No valid option was selected.")
Example #8
0
    def _setupMappedStates(self, tag):
        """Build self.state and self.availableStates structures.

        self.state is the corresponding dbschema for requested state_tag

        self.available_states is a dictionary containing the options with
        suitables attributes (name, value, selected) to easily fill an HTML
        <select> section.

        Raise UnexpectedFormData if no corresponding state for passed 'tag'
        was found.
        """
        # Default states map.
        state_map = {
            'built': BuildStatus.FULLYBUILT,
            'failed': BuildStatus.FAILEDTOBUILD,
            'depwait': BuildStatus.MANUALDEPWAIT,
            'chrootwait': BuildStatus.CHROOTWAIT,
            'superseded': BuildStatus.SUPERSEDED,
            'uploadfail': BuildStatus.FAILEDTOUPLOAD,
            'all': None,
            }
        # Include pristine (not yet assigned to a builder) builds,
        # if requested.
        if self.show_builder_info:
            extra_state_map = {
                'building': BuildStatus.BUILDING,
                'pending': BuildStatus.NEEDSBUILD,
                }
            state_map.update(**extra_state_map)

        # Lookup for the correspondent state or fallback to the default
        # one if tag is empty string.
        if tag:
            try:
                self.state = state_map[tag]
            except (KeyError, TypeError):
                raise UnexpectedFormData(
                    'No suitable state found for value "%s"' % tag)
        else:
            self.state = self.default_build_state

        # Build a dictionary with organized information for rendering
        # the HTML <select> section.
        self.available_states = []
        for tag, state in state_map.items():
            if state:
                name = state.title.strip()
            else:
                name = 'All states'

            if state == self.state:
                selected = 'selected'
            else:
                selected = None

            self.available_states.append(
                dict(name=name, value=tag, selected=selected))
Example #9
0
 def getDistribution(self):
     """See `SourcePackageNameWidgetBase`."""
     distribution_name = self.request.form.get('field.distribution')
     if distribution_name is None:
         return None
     distribution = getUtility(IDistributionSet).getByName(
         distribution_name)
     if distribution is None:
         raise UnexpectedFormData("No such distribution: %s" %
                                  distribution_name)
     return distribution
Example #10
0
 def storeTokenContext(self):
     """Store the context given by the consumer in this view."""
     self.token_context = None
     # We have no guarantees that lp.context will be together with the
     # OAuth parameters, so we need to check in the Authorization header
     # and on the request's form if it's not in the former.
     try:
         oauth_data = get_oauth_authorization(self.request)
     except UnicodeDecodeError:
         raise UnexpectedFormData("Invalid UTF-8.")
     context = oauth_data.get('lp.context')
     if not context:
         context = self.request.form.get('lp.context')
         if not context:
             return
     try:
         context = lookup_oauth_context(context)
     except ValueError:
         raise UnexpectedFormData("Unknown context.")
     self.token_context = context
Example #11
0
 def getDistribution(self):
     """See `SourcePackageNameWidgetBase`."""
     distroseries_token = self.request.form.get('field.distroseries')
     if distroseries_token is None:
         # Fall back to the POTemplate's current distribution.
         return self.context.context.distribution
     distroseries_vocab = DistroSeriesVocabulary()
     try:
         term = distroseries_vocab.getTermByToken(distroseries_token)
     except LookupError:
         raise UnexpectedFormData("No such distribution series: %s" %
                                  distroseries_token)
     return term.value.distribution
Example #12
0
    def update_action(self, action, data):
        branch_type = data.get('branch_type')
        if branch_type == LINK_LP_BZR:
            branch_location = data.get('branch_location')
            if branch_location != self.context.branch:
                self.context.branch = branch_location
                # Request an initial upload of translation files.
                getUtility(IRosettaUploadJobSource).create(
                    self.context.branch, NULL_REVISION)
            else:
                self.context.branch = branch_location
            self.request.response.addInfoNotification(
                'Series code location updated.')
        else:
            branch_name = data.get('branch_name')
            branch_owner = data.get('branch_owner')

            if branch_type == IMPORT_EXTERNAL:
                rcs_type = data.get('rcs_type')
                if rcs_type == RevisionControlSystems.CVS:
                    cvs_root = data.get('repo_url')
                    cvs_module = data.get('cvs_module')
                    url = None
                else:
                    cvs_root = None
                    cvs_module = None
                    url = data.get('repo_url')
                rcs_item = RevisionControlSystems.items[rcs_type.name]
                try:
                    code_import = getUtility(ICodeImportSet).new(
                        owner=branch_owner,
                        registrant=self.user,
                        target=IBranchTarget(self.context.product),
                        branch_name=branch_name,
                        rcs_type=rcs_item,
                        url=url,
                        cvs_root=cvs_root,
                        cvs_module=cvs_module)
                except BranchExists as e:
                    self._setBranchExists(e.existing_branch, 'branch_name')
                    self.errors_in_action = True
                    # Abort transaction. This is normally handled
                    # by LaunchpadFormView, but we are already in
                    # the success handler.
                    self._abort()
                    return
                self.context.branch = code_import.branch
                self.request.response.addInfoNotification(
                    'Code import created and branch linked to the series.')
            else:
                raise UnexpectedFormData(branch_type)
Example #13
0
    def _submitTranslations(self):
        """See BaseTranslationView._submitTranslations."""
        for key in self.request.form:
            match = re.match('msgset_(\d+)$', key)
            if not match:
                continue

            id = int(match.group(1))
            potmsgset = self.context.potemplate.getPOTMsgSetByID(id)
            if potmsgset is None:
                # This should only happen if someone tries to POST his own
                # form instead of ours, and he uses a POTMsgSet id that
                # does not exist for this POTemplate.
                raise UnexpectedFormData(
                    "Got translation for POTMsgID %d which is not in the "
                    "template." % id)

            error = self._receiveTranslations(potmsgset)
            if error and potmsgset.getSequence(self.context.potemplate) != 0:
                # There is an error, we should store it to be rendered
                # together with its respective view.
                #
                # The check for potmsgset.getSequence() != 0 is meant to catch
                # messages which are not current anymore. This only
                # happens as part of a race condition, when someone gets
                # a translation form, we get a new template for
                # that context that disables some entries in that
                # translation form, and after that, the user submits the
                # form. We accept the translation, but if it has an
                # error, we cannot render that error so we discard it,
                # that translation is not being used anyway, so it's not
                # a big loss.
                self.errors[potmsgset] = error

        if self.errors:
            if len(self.errors) == 1:
                message = ("There is an error in a translation you provided. "
                           "Please correct it before continuing.")
            else:
                message = ("There are %d errors in the translations you "
                           "provided. Please correct them before "
                           "continuing." % len(self.errors))
            self.request.response.addErrorNotification(message)
            return False

        if self.batchnav.batch.nextBatch() is not None:
            # Update the start of the next batch by the number of messages
            # that were removed from the batch.
            self.batchnav.batch.start -= self.start_offset
        self._redirectToNextPage()
        return True
    def __call__(self, context):
        import_queue = getUtility(ITranslationImportQueue)
        if hasattr(self, 'view'):
            user = self.view.user
        else:
            user = None
        targets = import_queue.getRequestTargets(user)
        filtered_targets = set()

        # Read filter_status, in order to mark targets that have requests with
        # that status pending.  This works because we set up the filter_status
        # widget before the filter_target one, which uses this vocabulary
        # factory.
        status_widget = self.view.widgets['filter_status']
        if status_widget.hasInput():
            try:
                status_filter = status_widget.getInputValue()
            except ConversionError:
                raise UnexpectedFormData("Invalid status parameter.")
            if status_filter != 'all':
                try:
                    status = RosettaImportStatus.items[status_filter]
                    filtered_targets = set(
                        import_queue.getRequestTargets(user=None,
                                                       status=status))
                except LookupError:
                    # Unknown status.  Ignore.
                    pass

        terms = [SimpleTerm('all', 'all', 'All targets')]

        for item in SpecialTranslationImportTargetFilter.items:
            term_name = '[%s]' % item.name
            terms.append(SimpleTerm(term_name, term_name, item.title))

        for target in targets:
            if IDistroSeries.providedBy(target):
                # Distroseries are not pillar names, we need to note
                # distribution.name/distroseries.name
                term_name = '%s/%s' % (target.distribution.name, target.name)
            else:
                term_name = target.name

            displayname = target.displayname
            if target in filtered_targets:
                displayname += '*'

            terms.append(SimpleTerm(term_name, term_name, displayname))
        return SimpleVocabulary(terms)
Example #15
0
    def restoreRequestFromSession(self):
        """Get the OpenIDRequest from our session."""
        session = self.getSession()
        cache = get_property_cache(self)
        try:
            cache.openid_parameters = session[OPENID_REQUEST_SESSION_KEY]
        except KeyError:
            raise UnexpectedFormData("No OpenID request in session")

        # Decode the request parameters and create the request object.
        self.openid_request = self.openid_server.decodeRequest(
            self.openid_parameters)
        assert zisinstance(
            self.openid_request,
            CheckIDRequest), ('Invalid OpenIDRequest in session')
Example #16
0
    def setupQueueList(self):
        """Setup a batched queue list.

        Returns None, so use tal:condition="not: view/setupQueueList" to
        invoke it in template.
        """

        # recover selected queue state and name filter
        self.name_filter = self.request.get('queue_text', '')

        try:
            state_value = int(self.request.get('queue_state', ''))
        except ValueError:
            state_value = PackageUploadStatus.NEW.value

        try:
            self.state = PackageUploadStatus.items[state_value]
        except KeyError:
            raise UnexpectedFormData(
                'No suitable status found for value "%s"' % state_value)

        self.queue = self.context.getPackageUploadQueue(self.state)

        valid_states = [
            PackageUploadStatus.NEW,
            PackageUploadStatus.ACCEPTED,
            PackageUploadStatus.REJECTED,
            PackageUploadStatus.DONE,
            PackageUploadStatus.UNAPPROVED,
        ]

        self.filtered_options = []

        for state in valid_states:
            selected = (state == self.state)
            self.filtered_options.append(
                dict(name=state.title, value=state.value, selected=selected))

        queue_items = self.context.getPackageUploads(status=self.state,
                                                     name=self.name_filter)
        self.batchnav = BatchNavigator(queue_items,
                                       self.request,
                                       size=QUEUE_SIZE)
Example #17
0
    def processProposedMember(self):
        if self.context.status != TeamMembershipStatus.PROPOSED:
            # Catch a double-form-post.
            self.errormessage = _(
                'The membership request for %s has already been processed.' %
                self.context.person.displayname)
            return

        assert self.context.status == TeamMembershipStatus.PROPOSED

        if self.request.form.get('decline'):
            status = TeamMembershipStatus.DECLINED
        elif self.request.form.get('approve'):
            status = TeamMembershipStatus.APPROVED
        else:
            raise UnexpectedFormData(
                "None of the expected actions were found.")
        if self._setMembershipData(status):
            self.request.response.redirect('%s/+members' %
                                           canonical_url(self.context.team))
Example #18
0
    def render(self):
        """Handle all OpenID requests and form submissions."""
        # NB: Will be None if there are no parameters in the request.
        self.openid_request = self.openid_server.decodeRequest(
            self.openid_parameters)

        if self.openid_request.mode == 'checkid_setup':
            referer = self.request.get("HTTP_REFERER")
            if referer:
                self.request.response.setCookie("openid_referer", referer)

            # Log the user out and present the login page so that they can
            # authenticate as somebody else if they want.
            logoutPerson(self.request)
            return self.showLoginPage()
        elif self.openid_request.mode == 'checkid_immediate':
            raise UnexpectedFormData(
                'We do not handle checkid_immediate requests.')
        else:
            return self.renderOpenIDResponse(
                self.openid_server.handleRequest(self.openid_request))
Example #19
0
    def _getSelectedPOTMsgSets(self):
        """Return a list of the POTMsgSets that will be rendered."""
        # The set of message sets we get is based on the selection of kind
        # of strings we have in our form.
        get_functions = {
            'all': self._handleShowAll,
            'translated': self.context.getPOTMsgSetTranslated,
            'untranslated': self.context.getPOTMsgSetUntranslated,
            'new_suggestions': self.context.getPOTMsgSetWithNewSuggestions,
            'changed_in_ubuntu':
                self.context.getPOTMsgSetDifferentTranslations,
            }

        if self.show not in get_functions:
            raise UnexpectedFormData('show = "%s"' % self.show)

        # We cannot listify the results to avoid additional count queries,
        # because we could end up with a list of more than 32000 items with
        # an average list of 5000 items.
        # The batch system will slice the list of items so we will fetch only
        # the exact number of entries we need to render the page.
        return get_functions[self.show]()
 def getInputValue(self):
     """See zope.formlib.interfaces.IInputWidget."""
     self.setUpSubWidgets()
     form_value = self.request.form_ng.getOne(self.name)
     if form_value == 'product':
         try:
             return self.product_widget.getInputValue()
         except MissingInputError:
             raise WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError('Please enter a project name'))
         except ConversionError:
             entered_name = self.request.form_ng.getOne("%s.product" %
                                                        self.name)
             raise WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError(
                     "There is no project named '%s' registered in"
                     " Launchpad" % entered_name))
     elif form_value == 'personal':
         return '+junk'
     else:
         raise UnexpectedFormData("No valid option was selected.")
Example #21
0
    def __call__(self):
        """Create a request token and include its key/secret in the response.

        If the consumer key is empty or the signature doesn't match, respond
        with a 401 status.  If the key is not empty but there's no consumer
        with it, we register a new consumer.
        """
        try:
            form = get_oauth_authorization(self.request)
        except UnicodeDecodeError:
            raise UnexpectedFormData("Invalid UTF-8.")
        consumer_key = form.get('oauth_consumer_key')
        if not consumer_key:
            self.request.unauthorized(OAUTH_CHALLENGE)
            return u''

        consumer_set = getUtility(IOAuthConsumerSet)
        consumer = consumer_set.getByKey(consumer_key)
        if consumer is None:
            consumer = consumer_set.new(key=consumer_key)

        if not check_oauth_signature(self.request, consumer, None):
            return u''

        token, secret = consumer.newRequestToken()
        if self.request.headers.get('Accept') == HTTPResource.JSON_TYPE:
            # Don't show the client the DESKTOP_INTEGRATION access
            # level. If they have a legitimate need to use it, they'll
            # already know about it.
            permissions = [
                permission for permission in OAuthPermission.items
                if (permission != OAuthPermission.DESKTOP_INTEGRATION)
                ]
            return self.getJSONRepresentation(
                permissions, token, secret=secret)
        return u'oauth_token=%s&oauth_token_secret=%s' % (token.key, secret)
Example #22
0
 def getInputValue(self):
     """See `zope.formlib.interfaces.IInputWidget`."""
     self.setUpSubWidgets()
     form_value = self.request.form_ng.getOne(self.name)
     if form_value == "repository_owner":
         return GitGranteeType.REPOSITORY_OWNER
     elif form_value == "person":
         try:
             return self.person_widget.getInputValue()
         except MissingInputError:
             raise WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError(
                     "Please enter a person or team name"))
         except ConversionError:
             entered_name = self.request.form_ng.getOne("%s.person" %
                                                        self.name)
             raise WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError(
                     "There is no person or team named '%s' registered in "
                     "Launchpad" % entered_name))
     else:
         raise UnexpectedFormData("No valid option was selected.")
 def initialize(self):
     """Useful initialization for this view class."""
     super(TranslationImportQueueView, self).initialize()
     target_filter = self.widgets['filter_target']
     if target_filter.hasInput() and not target_filter.hasValidInput():
         raise UnexpectedFormData("Unknown target.")
Example #24
0
 def _toFieldValue(self, input):
     if isinstance(input, list):
         raise UnexpectedFormData('Only a single value is expected')
     return super(URIWidget, self)._toFieldValue(input)
    def change_status_action(self, action, data):
        """Handle a queue submission changing the status of its entries."""
        # The user must be logged in.
        if self.user is None:
            raise UnexpectedFormData(
                'Users not logged cannot submit this form.')

        number_of_changes = 0
        for form_item in data:
            if not form_item.startswith('status_'):
                # We are not interested on this form_item.
                continue

            # It's an form_item to handle.
            try:
                # 'ignored' is 'status' due to the previous check, so we could
                # ignore that part.
                ignored, id_string = form_item.split('_')
                # The id is an integer
                id = int(id_string)
            except ValueError:
                # We got an form_item with more than one '_' char or with an
                # id that is not a number, that means that someone is playing
                # badly with our system so it's safe to just ignore the
                # request.
                raise UnexpectedFormData(
                    'Ignored your request because it is broken.')
            # Get the entry we are working on.
            import_queue_set = getUtility(ITranslationImportQueue)
            entry = import_queue_set.get(id)
            new_status_name = data.get(form_item)
            if new_status_name == entry.status.name:
                # The entry's status didn't change we can jump to the next
                # entry.
                continue

            # The status changed.
            number_of_changes += 1

            # Determine status enum from from value.
            new_status = None
            for status in RosettaImportStatus.items:
                if new_status_name == status.name:
                    new_status = status
                    break
            if new_status is None:
                # We are trying to set a bogus status.
                # That means that it's a broken request.
                raise UnexpectedFormData(
                    'Ignored the request to change the status from %s to %s.' %
                    (entry.status.name, new_status_name))
            else:
                # This will raise an exception if the user is not authorized.
                entry.setStatus(new_status, self.user)

            # Update the date_status_change field.
            UTC = pytz.timezone('UTC')
            entry.date_status_changed = datetime.datetime.now(UTC)

        if number_of_changes == 0:
            self.request.response.addWarningNotification(
                "Ignored your status change request as you didn't select any"
                " change.")
        else:
            self.request.response.addInfoNotification(
                "Changed the status of %d queue entries." % number_of_changes)
 def getInputValue(self):
     """See `zope.formlib.interfaces.IInputWidget`."""
     self.setUpSubWidgets()
     form_value = self.request.form_ng.getOne(self.name)
     if form_value == "project":
         try:
             return self.project_widget.getInputValue()
         except MissingInputError:
             raise WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError("Please enter a project name"))
         except ConversionError:
             entered_name = self.request.form_ng.getOne("%s.project" %
                                                        self.name)
             raise WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError(
                     "There is no project named '%s' registered in "
                     "Launchpad" % entered_name))
     elif form_value == "package":
         try:
             distribution = self.distribution_widget.getInputValue()
         except ConversionError:
             entered_name = self.request.form_ng.getOne("%s.distribution" %
                                                        self.name)
             raise WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError(
                     "There is no distribution named '%s' registered in "
                     "Launchpad" % entered_name))
         try:
             if self.package_widget.hasInput():
                 if bool(getFeatureFlag('disclosure.dsp_picker.enabled')):
                     self.package_widget.vocabulary.setDistribution(
                         distribution)
                 package_name = self.package_widget.getInputValue()
             else:
                 package_name = None
             if package_name is None:
                 raise WidgetInputError(
                     self.name, self.label,
                     LaunchpadValidationError(
                         "Please enter a package name"))
             if IDistributionSourcePackage.providedBy(package_name):
                 dsp = package_name
             else:
                 source_name = distribution.guessPublishedSourcePackageName(
                     package_name.name)
                 dsp = distribution.getSourcePackage(source_name)
         except (ConversionError, NotFoundError):
             entered_name = self.request.form_ng.getOne("%s.package" %
                                                        self.name)
             raise WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError(
                     "There is no package named '%s' published in %s." %
                     (entered_name, distribution.displayname)))
         return dsp
     elif form_value == "personal":
         return None
     else:
         raise UnexpectedFormData("No valid option was selected.")
Example #27
0
    def __call__(self):
        name = self.request.form.get('name')
        if name is None:
            raise MissingInputError('name', '')

        search_text = self.request.form.get('search_text')
        if search_text is None:
            raise MissingInputError('search_text', '')
        search_filter = self.request.form.get('search_filter')

        try:
            factory = getUtility(IVocabularyFactory, name)
        except ComponentLookupError:
            raise UnexpectedFormData(
                'Unknown vocabulary %r' % name)

        vocabulary = factory(self.context)

        if IHugeVocabulary.providedBy(vocabulary):
            matches = vocabulary.searchForTerms(search_text, search_filter)
            total_size = matches.count()
        else:
            matches = list(vocabulary)
            total_size = len(matches)

        batch_navigator = BatchNavigator(matches, self.request)

        # We need to collate what IPickerEntrySource adapters are required for
        # the items in the current batch. We expect that the batch will be
        # homogenous and so only one adapter instance is required, but we
        # allow for the case where the batch may contain disparate entries
        # requiring different adapter implementations.

        # A mapping from adapter class name -> adapter instance
        adapter_cache = {}
        # A mapping from adapter class name -> list of vocab terms
        picker_entry_terms = {}
        for term in batch_navigator.currentBatch():
            picker_entry_source = IPickerEntrySource(term.value)
            adapter_class = picker_entry_source.__class__.__name__
            picker_terms = picker_entry_terms.get(adapter_class)
            if picker_terms is None:
                picker_terms = []
                picker_entry_terms[adapter_class] = picker_terms
                adapter_cache[adapter_class] = picker_entry_source
            picker_terms.append(term.value)

        # A mapping from vocab terms -> picker entries
        picker_term_entries = {}

        # For the list of terms associated with a picker adapter, we get the
        # corresponding picker entries by calling the adapter.
        for adapter_class, term_values in picker_entry_terms.items():
            picker_entries = adapter_cache[adapter_class].getPickerEntries(
                term_values,
                self.context)
            for term_value, picker_entry in izip(term_values, picker_entries):
                picker_term_entries[term_value] = picker_entry

        result = []
        for term in batch_navigator.currentBatch():
            entry = dict(value=term.token, title=term.title)
            # The canonical_url without just the path (no hostname) can
            # be passed directly into the REST PATCH call.
            api_request = IWebServiceClientRequest(self.request)
            try:
                entry['api_uri'] = canonical_url(
                    term.value, request=api_request,
                    path_only_if_possible=True)
            except NoCanonicalUrl:
                # The exception is caught, because the api_url is only
                # needed for inplace editing via a REST call. The
                # form picker doesn't need the api_url.
                entry['api_uri'] = 'Could not find canonical url.'
            picker_entry = picker_term_entries[term.value]
            if picker_entry.description is not None:
                if len(picker_entry.description) > MAX_DESCRIPTION_LENGTH:
                    entry['description'] = (
                        picker_entry.description[:MAX_DESCRIPTION_LENGTH - 3]
                        + '...')
                else:
                    entry['description'] = picker_entry.description
            if picker_entry.image is not None:
                entry['image'] = picker_entry.image
            if picker_entry.css is not None:
                entry['css'] = picker_entry.css
            if picker_entry.alt_title is not None:
                entry['alt_title'] = picker_entry.alt_title
            if picker_entry.title_link is not None:
                entry['title_link'] = picker_entry.title_link
            if picker_entry.details is not None:
                entry['details'] = picker_entry.details
            if picker_entry.alt_title_link is not None:
                entry['alt_title_link'] = picker_entry.alt_title_link
            if picker_entry.link_css is not None:
                entry['link_css'] = picker_entry.link_css
            if picker_entry.badges:
                entry['badges'] = picker_entry.badges
            if picker_entry.metadata is not None:
                entry['metadata'] = picker_entry.metadata
            if picker_entry.target_type is not None:
                entry['target_type'] = picker_entry.target_type
            result.append(entry)

        self.request.response.setHeader('Content-type', 'application/json')
        return simplejson.dumps(dict(total_size=total_size, entries=result))