コード例 #1
0
    def render(self):
        """Render a page supporting XRDS discovery."""
        # While Zope doesn't care about extra slashes, such
        # differences result in different identity URLs.  To avoid
        # confusion, we redirect to our canonical URL if we aren't
        # already there.
        current_url = self._getURL()
        expected_url = canonical_url(self.context)
        if current_url != expected_url:
            self.request.response.redirect(expected_url)
            return ''

        if self.enable_xrds_discovery:
            # Tell the user agent that we do different things depending on
            # the value of the "Accept" header.
            self.request.response.setHeader('Vary', 'Accept')

            accept_content = self.request.get('HTTP_ACCEPT', '')
            acceptable = getAcceptable(accept_content,
                                       ['text/html', YADIS_CONTENT_TYPE])
            # Return the XRDS document if it is preferred to text/html.
            for mtype in acceptable:
                if mtype == 'text/html':
                    break
                elif mtype == YADIS_CONTENT_TYPE:
                    return self.xrds()
                else:
                    raise AssertionError(
                        'Unexpected acceptable content type: %s' % mtype)

            # Add a header pointing to the location of the XRDS document
            # and chain to the default render() method.
            self.request.response.setHeader(
                YADIS_HEADER_NAME, '%s/+xrds' % canonical_url(self.context))
        return super(XRDSContentNegotiationMixin, self).render()
コード例 #2
0
 def _getTemplateParams(self, email, recipient):
     """See `BaseMailer`"""
     params = super(
         SourcePackageRecipeBuildMailer, self)._getTemplateParams(
             email, recipient)
     params.update({
         'status': self.build.status.title,
         'build_id': self.build.id,
         'distroseries': self.build.distroseries.name,
         'recipe': self.build.recipe.name,
         'recipe_owner': self.build.recipe.owner.name,
         'archive': self.build.archive.name,
         'archive_owner': self.build.archive.owner.name,
         'log_url': '',
         'component': self.build.current_component.name,
         'duration': '',
         'builder_url': '',
         'build_url': canonical_url(self.build),
         'upload_log_url': '',
     })
     if self.build.builder is not None:
         params['builder_url'] = canonical_url(self.build.builder)
     if self.build.duration is not None:
         duration_formatter = DurationFormatterAPI(self.build.duration)
         params['duration'] = duration_formatter.approximateduration()
     if self.build.log is not None:
         params['log_url'] = self.build.log.getURL()
     if self.build.upload_log is not None:
         params['upload_log_url'] = self.build.upload_log_url
     return params
コード例 #3
0
 def test_binary_query_counts(self):
     query_baseline = 40
     # Assess the baseline.
     collector = QueryCollector()
     collector.register()
     self.addCleanup(collector.unregister)
     ppa = self.factory.makeArchive()
     viewer = self.factory.makePerson()
     browser = self.getUserBrowser(user=viewer)
     with person_logged_in(viewer):
         # The baseline has one package, because otherwise the
         # short-circuit prevents the packages iteration happening at
         # all and we're not actually measuring scaling
         # appropriately.
         pkg = self.factory.makeBinaryPackagePublishingHistory(
             archive=ppa)
         url = canonical_url(ppa) + "/+packages"
     browser.open(url)
     self.assertThat(collector, HasQueryCount(LessThan(query_baseline)))
     expected_count = collector.count
     # Use all new objects - avoids caching issues invalidating the
     # gathered metrics.
     login(ADMIN_EMAIL)
     ppa = self.factory.makeArchive()
     viewer = self.factory.makePerson()
     browser = self.getUserBrowser(user=viewer)
     with person_logged_in(viewer):
         for i in range(3):
             pkg = self.factory.makeBinaryPackagePublishingHistory(
                 archive=ppa, distroarchseries=pkg.distroarchseries)
         url = canonical_url(ppa) + "/+packages"
     browser.open(url)
     self.assertThat(collector, HasQueryCount(Equals(expected_count)))
コード例 #4
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))
コード例 #5
0
ファイル: bug.py プロジェクト: pombreda/UnnaturalCodeFork
    def duplicates(self):
        """Return a list of dicts of duplicates.

        Each dict contains the title that should be shown and the bug
        object itself. This allows us to protect private bugs using a
        title like 'Private Bug'.
        """
        duplicate_bugs = list(self.context.duplicates)
        current_task = self.current_bugtask
        dupes_in_current_context = dict(
            (bugtask.bug, bugtask)
            for bugtask in current_task.target.searchTasks(
                BugTaskSearchParams(self.user, bug=any(*duplicate_bugs))))
        dupes = []
        for bug in duplicate_bugs:
            dupe = {}
            try:
                dupe['title'] = bug.title
            except Unauthorized:
                dupe['title'] = 'Private Bug'
            dupe['id'] = bug.id
            # If the dupe has the same context as the one we're in, link
            # to that bug task directly.
            if bug in dupes_in_current_context:
                dupe['url'] = canonical_url(dupes_in_current_context[bug])
            else:
                dupe['url'] = canonical_url(bug)
            dupes.append(dupe)

        return dupes
コード例 #6
0
ファイル: project.py プロジェクト: pombreda/UnnaturalCodeFork
 def next_url(self):
     if self.context.active:
         return canonical_url(self.context)
     else:
         # If the project is inactive, we can't traverse to it
         # anymore.
         return canonical_url(getUtility(IProjectGroupSet))
コード例 #7
0
 def test_canonicalUrl(self):
     # The canonical_url of the merge diff is '+preview' after the
     # canonical_url of the merge proposal itself.
     mp = self._createProposalWithPreviewDiff()
     self.assertEqual(
         canonical_url(mp) + '/+preview-diff',
         canonical_url(mp.preview_diff))
コード例 #8
0
    def test_forCreation_with_review_request_and_private_bug(self):
        """Correctly format list of reviewers and bug info.

        Private bugs should not be listed in the email unless authorised.
        """
        reviewer = self.factory.makePerson(name='review-person')
        bmp, subscriber = self.makeProposalWithSubscriber(reviewer=reviewer)

        # Create and subscribe the owner of the private bug
        private_bug_owner = self.factory.makePerson(email="*****@*****.**")
        bmp.source_branch.subscribe(private_bug_owner,
            BranchSubscriptionNotificationLevel.NOEMAIL, None,
            CodeReviewNotificationLevel.FULL, private_bug_owner)

        # Create and link the bugs to the branch
        bug = self.factory.makeBug(title='I am a bug')
        bugtask = bug.default_bugtask
        bmp.source_branch.linkBug(bug, bmp.registrant)
        private_bug = self.factory.makeBug(
            title='I am a private bug', owner=private_bug_owner,
            information_type=InformationType.USERDATA)
        private_bugtask = private_bug.default_bugtask
        with person_logged_in(private_bug_owner):
            bmp.source_branch.linkBug(private_bug, bmp.registrant)

        # Set up the mailer
        bmp.nominateReviewer(reviewer, bmp.registrant, None)
        mailer = BMPMailer.forCreation(bmp, bmp.registrant)

        # A non authorised email recipient doesn't see the private bug.
        ctrl = mailer.generateEmail('*****@*****.**', subscriber)
        expected = (
            '\nRequested reviews:'
            '\n  Review-person (review-person)'
            '\nRelated bugs:'
            '\n  %s'
            '\n  %s\n'
            '\nFor more details, see:\n'
            '%s'
            '\n--' % (bugtask.title, canonical_url(bugtask),
                      canonical_url(bmp)))
        self.assertIn(expected, ctrl.body)

        # An authorised email recipient does see the private bug.
        ctrl = mailer.generateEmail('*****@*****.**', private_bug_owner)
        expected = (
            '\nRequested reviews:'
            '\n  Review-person (review-person)'
            '\nRelated bugs:'
            '\n  %s'
            '\n  %s'
            '\n  %s'
            '\n  %s\n'
            '\nFor more details, see:\n'
            '%s'
            '\n--' % (bugtask.title, canonical_url(bugtask),
                      private_bugtask.title, canonical_url(private_bugtask),
                      canonical_url(bmp)))
        self.assertIn(expected, ctrl.body)
コード例 #9
0
 def test_canonical_url(self):
     # The canonical URL of a GPG key is ???
     person = self.factory.makePerson()
     gpgkey = self.factory.makeGPGKey(person)
     self.assertEqual(
         '%s/+gpg-keys/%s' % (
             canonical_url(person, rootsite='api'), gpgkey.keyid),
         canonical_url(gpgkey))
コード例 #10
0
 def test_token_for_different_target_dep_is_url(self):
     # The 'token' part of the term for a dependency candidate that has a
     # different target is the canonical url of the candidate.
     spec = self.factory.makeSpecification()
     candidate = self.factory.makeSpecification()
     vocab = self.getVocabularyForSpec(spec)
     term = vocab.getTermByToken(canonical_url(candidate))
     self.assertEqual(term.token, canonical_url(candidate))
コード例 #11
0
 def test_more_private_bugs_query_count_is_constant(self):
     # This test tests that as we add more private bugs to a milestone
     # index page, the number of queries issued by the page does not
     # change. It also sets a cap on the queries for this page: if the
     # baseline were to increase, the test would fail. As the baseline
     # is very large already, if the test fails due to such a change,
     # please cut some more of the existing fat out of it rather than
     # increasing the cap.
     page_query_limit = 37
     product = self.factory.makeProduct()
     product_owner = product.owner
     login_person(product.owner)
     milestone = self.factory.makeMilestone(productseries=product.development_focus)
     bug1 = self.factory.makeBug(target=product, information_type=InformationType.USERDATA, owner=product.owner)
     bug1.bugtasks[0].transitionToMilestone(milestone, product.owner)
     # We look at the page as someone who is a member of a team and the
     # team is subscribed to the bugs, so that we don't get trivial
     # shortcuts avoiding queries : test the worst case.
     subscribed_team = self.factory.makeTeam(membership_policy=TeamMembershipPolicy.MODERATED)
     viewer = self.factory.makePerson()
     with person_logged_in(subscribed_team.teamowner):
         subscribed_team.addMember(viewer, subscribed_team.teamowner)
     bug1.subscribe(subscribed_team, product.owner)
     bug1_url = canonical_url(bug1)
     milestone_url = canonical_url(milestone)
     browser = self.getUserBrowser(user=viewer)
     # Seed the cookie cache and any other cross-request state we may gain
     # in future.  See lp.services.webapp.serssion: _get_secret.
     browser.open(milestone_url)
     collector = QueryCollector()
     collector.register()
     self.addCleanup(collector.unregister)
     browser.open(milestone_url)
     # Check that the test found the bug
     self.assertTrue(bug1_url in browser.contents)
     self.assertThat(collector, HasQueryCount(LessThan(page_query_limit)))
     with_1_private_bug = collector.count
     with_1_queries = ["%s: %s" % (pos, stmt[3]) for (pos, stmt) in enumerate(collector.queries)]
     login_person(product_owner)
     bug2 = self.factory.makeBug(target=product, information_type=InformationType.USERDATA, owner=product.owner)
     bug2.bugtasks[0].transitionToMilestone(milestone, product.owner)
     bug2.subscribe(subscribed_team, product.owner)
     bug2_url = canonical_url(bug2)
     bug3 = self.factory.makeBug(target=product, information_type=InformationType.USERDATA, owner=product.owner)
     bug3.bugtasks[0].transitionToMilestone(milestone, product.owner)
     bug3.subscribe(subscribed_team, product.owner)
     logout()
     browser.open(milestone_url)
     self.assertTrue(bug2_url in browser.contents)
     self.assertThat(collector, HasQueryCount(LessThan(page_query_limit)))
     with_3_private_bugs = collector.count
     with_3_queries = ["%s: %s" % (pos, stmt[3]) for (pos, stmt) in enumerate(collector.queries)]
     self.assertEqual(
         with_1_private_bug,
         with_3_private_bugs,
         "different query count: \n%s\n******************\n%s\n"
         % ("\n".join(with_1_queries), "\n".join(with_3_queries)),
     )
コード例 #12
0
def assemble_body(blamer, spr, bprs, archive, distroseries, summary, changes,
                  action, previous_version=None):
    """Assemble the e-mail notification body."""
    if changes is None:
        changes = {}
    info = fetch_information(
        spr, bprs, changes, previous_version=previous_version)
    information = {
        'STATUS': ACTION_DESCRIPTIONS[action],
        'SUMMARY': summary,
        'DATE': 'Date: %s' % info['date'],
        'CHANGESFILE': info['changelog'],
        'DISTRO': distroseries.distribution.title,
        'ANNOUNCE': 'No announcement sent',
        'CHANGEDBY': '',
        'MAINTAINER': '',
        'ORIGIN': '',
        'SIGNER': '',
        'SPR_URL': '',
        'ARCHIVE_URL': '\n%s' % canonical_url(archive),
        'USERS_ADDRESS': config.launchpad.users_address,
        }
    if spr:
        # Yay, circular imports.
        from lp.soyuz.model.distroseriessourcepackagerelease import (
            DistroSeriesSourcePackageRelease,
            )
        dsspr = DistroSeriesSourcePackageRelease(distroseries, spr)
        information['SPR_URL'] = canonical_url(dsspr)
    changedby_displayname = info['changedby_displayname']
    if changedby_displayname:
        information['CHANGEDBY'] = '\nChanged-By: %s' % changedby_displayname
    origin = changes.get('Origin')
    if origin:
        information['ORIGIN'] = '\nOrigin: %s' % origin
    if action == 'unapproved':
        information['SUMMARY'] += (
            "\nThis upload awaits approval by a distro manager\n")
    if distroseries.changeslist:
        information['ANNOUNCE'] = "Announcing to %s" % (
            distroseries.changeslist)

    # Some syncs (e.g. from Debian) will involve packages whose
    # changed-by person was auto-created in LP and hence does not have a
    # preferred email address set.  We'll get a None here.
    changedby_person = email_to_person(info['changedby'])

    if blamer is not None and blamer != changedby_person:
        signer_signature = person_to_email(blamer)
        if signer_signature != info['changedby']:
            information['SIGNER'] = '\nSigned-By: %s' % signer_signature
    # Add maintainer if present and different from changed-by.
    maintainer = info['maintainer']
    changedby = info['changedby']
    if maintainer and maintainer != changedby:
        information['MAINTAINER'] = '\nMaintainer: %s' % maintainer
    return get_template(archive, action) % information
コード例 #13
0
 def test_canonical_url(self):
     # The canonical URL of a GPG key is ssh-keys
     person = self.factory.makePerson()
     with person_logged_in(person):
         sshkey = self.factory.makeSSHKey(person)
         self.assertEqual(
             '%s/+ssh-keys/%s' % (
                 canonical_url(person, rootsite='api'), sshkey.id),
             canonical_url(sshkey))
コード例 #14
0
 def next_url(self):
     url = canonical_url(self.branch)
     # If the subscriber can no longer see the branch, redirect them away.
     service = getUtility(IService, 'sharing')
     ignored, branches, ignored = service.getVisibleArtifacts(
         self.person, branches=[self.branch], ignore_permissions=True)
     if not branches:
         url = canonical_url(self.branch.target)
     return url
コード例 #15
0
 def test_excessive_comments_redirect_to_download(self):
     """View for excessive comments redirects to download page."""
     comment = self.factory.makeCodeReviewComment(body='x ' * 5001)
     view_url = canonical_url(comment)
     download_url = canonical_url(comment, view_name='+download')
     browser = self.getUserBrowser(view_url)
     self.assertNotEqual(view_url, browser.url)
     self.assertEqual(download_url, browser.url)
     self.assertEqual('x ' * 5001, browser.contents)
コード例 #16
0
def get_series_branch_error(product, branch):
    """Check if the given branch is suitable for the given product.

    Returns an HTML error message on error, and None otherwise.
    """
    if branch.product != product:
        return structured(
            '<a href="%s">%s</a> is not a branch of <a href="%s">%s</a>.',
            canonical_url(branch), branch.unique_name, canonical_url(product),
            product.displayname)
コード例 #17
0
 def _setBranchExists(self, existing_branch):
     """Set a field error indicating that the branch already exists."""
     self.setFieldError(
        'branch_name',
         structured("""
         There is already an existing import for
         <a href="%(product_url)s">%(product_name)s</a>
         with the name of
         <a href="%(branch_url)s">%(branch_name)s</a>.""",
                    product_url=canonical_url(existing_branch.target),
                    product_name=existing_branch.target.name,
                    branch_url=canonical_url(existing_branch),
                    branch_name=existing_branch.name))
コード例 #18
0
    def sendProfileCreatedEmail(self, profile, comment):
        """See ILoginToken."""
        template = get_email_template('profile-created.txt', app=MAIL_APP)
        replacements = {'token_url': canonical_url(self),
                        'requester': self.requester.displayname,
                        'comment': comment,
                        'profile_url': canonical_url(profile)}
        message = template % replacements

        headers = {'Reply-To': self.requester.preferredemail.email}
        from_name = "Launchpad"
        subject = "Launchpad profile"
        self._send_email(from_name, subject, message, headers=headers)
コード例 #19
0
ファイル: sprint.py プロジェクト: pombreda/UnnaturalCodeFork
    def process_form(self):
        """Largely copied from webapp/generalform.py, without the
        schema processing bits because we are not rendering the form in the
        usual way. Instead, we are creating our own form in the page
        template and interpreting it here.
        """
        form = self.request.form

        if 'SUBMIT_CANCEL' in form:
            self.status_message = 'Cancelled'
            self.request.response.redirect(
                canonical_url(self.context) + '/+specs')
            return

        if 'SUBMIT_ACCEPT' not in form and 'SUBMIT_DECLINE' not in form:
            self.status_message = ''
            return

        if self.request.method == 'POST':
            if 'speclink' not in form:
                self.status_message = (
                    'Please select specifications to accept or decline.')
                return
            # determine if we are accepting or declining
            if 'SUBMIT_ACCEPT' in form:
                assert 'SUBMIT_DECLINE' not in form
                action = 'Accepted'
            else:
                assert 'SUBMIT_DECLINE' in form
                action = 'Declined'

        selected_specs = form['speclink']
        if isinstance(selected_specs, unicode):
            # only a single item was selected, but we want to deal with a
            # list for the general case, so convert it to a list
            selected_specs = [selected_specs]

        if action == 'Accepted':
            action_fn = self.context.acceptSpecificationLinks
        else:
            action_fn = self.context.declineSpecificationLinks
        leftover = action_fn(selected_specs, self.user)

        # Status message like: "Accepted 27 specification(s)."
        self.status_message = '%s %d specification(s).' % (
            action, len(selected_specs))

        if leftover == 0:
            # they are all done, so redirect back to the spec listing page
            self.request.response.redirect(
                canonical_url(self.context) + '/+specs')
コード例 #20
0
    def delete_action(self, action, data):
        # Although users will never be able to see/submit this form for a
        # mirror which has been probed already, they may have a stale page
        # and so we do this check here.
        if self.context.last_probe_record is not None:
            self.request.response.addInfoNotification(
                "This mirror has been probed and thus can't be deleted.")
            self.next_url = canonical_url(self.context)
            return

        self.next_url = canonical_url(self.context.distribution,
            view_name='+pendingreviewmirrors')
        self.request.response.addInfoNotification(
            "Mirror %s has been deleted." % self.context.title)
        self.context.destroySelf()
コード例 #21
0
 def test_build_rescoring_view(self):
     # `BuildRescoringView` is used for setting new values to the
     # corresponding `BuildQueue.lastscore` record for a `Build`.
     # It redirects users to the `Build` page when the build cannot be
     # rescored.
     build = self.factory.makeBinaryPackageBuild(
         status=BuildStatus.FAILEDTOBUILD)
     self.assertFalse(build.can_be_rescored)
     view = create_initialized_view(build, name='+rescore')
     self.assertEquals(view.request.response.getStatus(), 302)
     self.assertEquals(view.request.response.getHeader('Location'),
         canonical_url(build))
     pending_build = self.factory.makeBinaryPackageBuild()
     view = create_initialized_view(pending_build, name='+rescore')
     self.assertEquals(view.cancel_url, canonical_url(pending_build))
コード例 #22
0
 def branches(self):
     """Return a link to view the branches related to this series."""
     # Override to go to the branches for the product.
     text = 'Code'
     summary = 'View related branches of code'
     link = canonical_url(self.context.product, rootsite='code')
     return Link(link, text, summary=summary)
コード例 #23
0
ファイル: bug.py プロジェクト: pombreda/UnnaturalCodeFork
 def __init__(self, context, request):
     redirected_context = context.default_bugtask
     viewname = getDefaultViewName(redirected_context, request)
     cache_view = getMultiAdapter(
         (redirected_context, request), name=viewname)
     super(BugWithoutContextView, self).__init__(
         canonical_url(redirected_context), request, cache_view=cache_view)
コード例 #24
0
 def test_configure_codehosting_shown(self):
     # If the user has driver permissions, they are shown the configure
     # codehosting link.
     product = self.factory.makeProduct()
     browser = self.getUserBrowser(
         canonical_url(product, rootsite='code'), user=product.owner)
     self.assertTrue('Configure code hosting' in browser.contents)
コード例 #25
0
 def rescheduleAction(self, action, data):
     """Reschedule all the watches for the bugtracker."""
     self.context.resetWatches()
     self.request.response.addInfoNotification(
         "All bug watches on %s have been rescheduled." %
         self.context.title)
     self.next_url = canonical_url(self.context)
コード例 #26
0
 def test_configure_codehosting_hidden(self):
     # If the user does not have driver permissions, they are not shown
     # the configure codehosting link.
     product = self.factory.makeProduct()
     browser = self.getUserBrowser(
         canonical_url(product, rootsite='code'))
     self.assertFalse('Configure code hosting' in browser.contents)
コード例 #27
0
ファイル: login.py プロジェクト: pombreda/UnnaturalCodeFork
def require_fresh_login(request, context, view_name):
    """Redirect request to login if the request is not recently logged in."""
    if not isFreshLogin(request):
        reauth_query = '+login?reauth=1'
        base_url = canonical_url(context, view_name=view_name)
        login_url = '%s/%s' % (base_url, reauth_query)
        request.response.redirect(login_url)
コード例 #28
0
 def test_getTermByToken_by_url_disallows_context(self):
     # getTermByToken with the URL of the vocab's context raises
     # LookupError.
     spec = self.factory.makeSpecification()
     vocab = self.getVocabularyForSpec(spec)
     self.assertRaises(
         LookupError, vocab.getTermByToken, canonical_url(spec))
コード例 #29
0
 def configure_bugtracker(self):
     text = 'Configure bug tracker'
     summary = 'Specify where bugs are tracked for this project'
     return Link(
         canonical_url(
             self.context.product, view_name='+configure-bugtracker'),
         text, summary, icon='edit')
コード例 #30
0
    def direct_subscriber_data(self, question):
        """Get the direct subscriber data.

        This method is isolated from the subscriber_data_js so that query
        count testing can be done accurately and robustly.
        """
        data = []
        details = list(question.getDirectSubscribersWithDetails())
        for person, subscription in details:
            can_edit = subscription.canBeUnsubscribedByUser(self.user)
            if person.private and not can_edit:
                # Skip private teams user is not a member of.
                continue

            subscriber = {
                'name': person.name,
                'display_name': person.displayname,
                'web_link': canonical_url(person, rootsite='mainsite'),
                'self_link': absoluteURL(person, self.api_request),
                'is_team': person.is_team,
                'can_edit': can_edit
                }
            record = {
                'subscriber': subscriber,
                'subscription_level': 'Direct',
                }
            data.append(record)
        return data
コード例 #31
0
 def traverse(self, name):
     # Raise a 404 on an invalid distribution name
     distribution = self.context.getByName(name)
     if distribution is None:
         raise NotFoundError(name)
     return self.redirectSubTree(canonical_url(distribution))
コード例 #32
0
 def __init__(self, context, request):
     LaunchpadFormView.__init__(self, context, request)
     self.next_url = self.cancel_url = (
         canonical_url(ICanonicalUrlData(context).inside))
コード例 #33
0
 def nextUrlForInconsistentPatchFlags(self, attachment):
     """The next_url value used for an inconistent patch flag."""
     return canonical_url(attachment) + '/+confirm-is-patch'
コード例 #34
0
ファイル: browser.py プロジェクト: pombredanne/launchpad-3
    def traverse(self, name):
        """Traverse the paths of a feed.

        If a query string is provided it is normalized.  'bugs' paths and
        persons ('~') are special cased.
        """
        # Normalize the query string so caching is more effective.  This is
        # done by simply sorting the entries.

        # XXX bac 20071019, we would like to normalize with respect to case
        # too but cannot due to a problem with the bug search requiring status
        # values to be of a particular case.  See bug 154562.
        query_string = self.request.get('QUERY_STRING', '')
        fields = sorted(query_string.split('&'))
        normalized_query_string = '&'.join(fields)
        if query_string != normalized_query_string:
            # We must empty the traversal stack to prevent an error
            # when calling RedirectionView.publishTraverse().
            self.request.setTraversalStack([])
            target = "%s%s?%s" % (self.request.getApplicationURL(),
                                  self.request['PATH_INFO'],
                                  normalized_query_string)
            redirect = RedirectionView(target, self.request, 301)
            return redirect

        # Handle the three formats of urls:
        # http://feeds.launchpad.net/bugs/latest-bugs.atom
        # http://feeds.launchpad.net/bugs/+bugs.atom?...
        # http://feeds.launchpad.net/bugs/1/bug.atom
        if name == 'bugs':
            stack = self.request.getTraversalStack()
            if len(stack) == 0:
                raise NotFound(self, '', self.request)
            bug_id = stack.pop()
            if bug_id.startswith('+'):
                if config.launchpad.is_bug_search_feed_active:
                    return getUtility(IBugTaskSet)
                else:
                    raise Unauthorized("Bug search feed deactivated")
            elif bug_id.startswith('latest-bugs.'):
                return getUtility(IMaloneApplication)
            else:
                self.request.stepstogo.consume()
                return getUtility(IBugSet).getByNameOrID(bug_id)

        # Redirect to the canonical name before doing the lookup.
        if canonical_name(name) != name:
            return self.redirectSubTree(canonical_url(self.context) +
                                        canonical_name(name),
                                        status=301)

        try:
            if name.startswith('~'):
                # Handle persons and teams.
                # http://feeds.launchpad.net/~salgado/latest-bugs.html
                person = getUtility(IPersonSet).getByName(name[1:])
                return person
            else:
                # Otherwise, handle products, projects, and distros
                return getUtility(IPillarNameSet)[name]
        except NotFoundError:
            raise NotFound(self, name, self.request)
コード例 #35
0
 def redirect_imports(self):
     """Redirect /translations/imports to Translations root site."""
     target_url = canonical_url(
         getUtility(ILaunchpadRoot), rootsite='translations')
     return self.redirectSubTree(
         target_url + '+imports', status=301)
コード例 #36
0
 def answers_url(self):
     return canonical_url(
         getUtility(ILaunchpadCelebrities).launchpad,
         rootsite='answers')
コード例 #37
0
 def next_url(self):
     return canonical_url(self.current_bugtask)
コード例 #38
0
ファイル: browser.py プロジェクト: pombredanne/launchpad-3
 def href(self):
     return urlappend(canonical_url(self.context, rootsite="feeds"),
                      'revisions.atom')
コード例 #39
0
 def traverse(self, name):
     try:
         return super(DistributionNavigation, self).traverse(name)
     except NotFoundError:
         resolved = self.context.resolveSeriesAlias(name)
         return self.redirectSubTree(canonical_url(resolved), status=303)
コード例 #40
0
 def initialize(self):
     """See `LaunchpadFormView`."""
     filebug_url = "%s/+filebug" % canonical_url(self.context.product)
     self.request.response.redirect(filebug_url)
コード例 #41
0
 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)
コード例 #42
0
ファイル: browser.py プロジェクト: pombredanne/launchpad-3
 def href(self):
     return urlappend(canonical_url(self.context, rootsite="feeds"),
                      'branch.atom')
コード例 #43
0
 def linked_packages_message(self):
     url = canonical_url(self.context.product, view_name="+packages")
     return ("You cannot delete a series that is linked to packages in "
             "distributions. You can remove the links from the "
             '<a href="%s">project packaging</a> page.' % url)
コード例 #44
0
 def request_import_link(self):
     """A link to the page for requesting a new code import."""
     return canonical_url(self.context.product,
                          view_name='+new-import',
                          rootsite='code')
コード例 #45
0
 def getNominationEditLink(self):
     """Return a link to the nomination edit form."""
     return (
         "%s/nominations/%d/+editstatus" %
         (canonical_url(getUtility(ILaunchBag).bugtask), self.context.id))
コード例 #46
0
 def launchpad_users_team(self):
     """The url of the launchpad-users team."""
     team = getUtility(IPersonSet).getByName('launchpad-users')
     return canonical_url(team)
コード例 #47
0
 def redirect_source(self):
     return canonical_url(self.context)
コード例 #48
0
 def referrer_url(self):
     referrer = self.request.getHeader('referer')
     if referrer != canonical_url(self.context):
         return referrer
     else:
         return None
コード例 #49
0
 def change_action(self, action, data):
     self.updateContextFromData(data)
     self.next_url = canonical_url(self.context)
コード例 #50
0
 def action_url(self):
     return "%s/nominations/%d/+editstatus" % (canonical_url(
         self.current_bugtask), self.context.id)
コード例 #51
0
 def _composeProductSeriesLink(self, productseries):
     """Produce HTML to link to `productseries`."""
     return '<a href="%s">%s</a>' % (canonical_url(
         productseries, rootsite='translations'), productseries.name)
コード例 #52
0
 def __init__(self, context, request):
     target = canonical_url(
         context, rootsite='translations', view_name='+translations')
     super(TranslationsRedirectView, self).__init__(
         target, request, status=301)
コード例 #53
0
 def cancel_url(self):
     return canonical_url(self.context)
コード例 #54
0
ファイル: browser.py プロジェクト: pombredanne/launchpad-3
 def href(self):
     return urlappend(canonical_url(self.context, rootsite='feeds'),
                      'latest-bugs.atom')
コード例 #55
0
 def cancel_url(self):
     return canonical_url(self.context.specification)
コード例 #56
0
ファイル: karma.py プロジェクト: pombreda/UnnaturalCodeFork
 def cancel_url(self):
     """See `LaunchpadFormView`."""
     return canonical_url(getUtility(IKarmaActionSet))
コード例 #57
0
ファイル: browser.py プロジェクト: pombredanne/launchpad-3
 def href(self):
     if IAnnouncementSet.providedBy(self.context):
         return urlappend(self.rooturl, 'announcements.atom')
     else:
         return urlappend(canonical_url(self.context, rootsite='feeds'),
                          'announcements.atom')
コード例 #58
0
 def cancel_url(self):
     """Return the URL for the current context."""
     return canonical_url(self.context)
コード例 #59
0
 def cancel_url(self):
     """See `LaunchpadFormView`."""
     return canonical_url(self.context)
コード例 #60
0
 def next_url(self):
     return canonical_url(getUtility(ILaunchBag).bugtask)