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
Пример #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.reference,
         '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_url
     if self.build.upload_log is not None:
         params['upload_log_url'] = self.build.upload_log_url
     return params
Пример #3
0
 def _getTemplateParams(self, email, recipient):
     """See `BaseMailer`."""
     build = self.build
     params = super(LiveFSBuildMailer,
                    self)._getTemplateParams(email, recipient)
     params.update({
         "archive_tag": build.archive.reference,
         "build_id": build.id,
         "build_title": build.title,
         "livefs_name": build.livefs.name,
         "version": build.version,
         "distroseries": build.livefs.distro_series,
         "architecturetag": build.distro_arch_series.architecturetag,
         "pocket": build.pocket.name,
         "build_state": build.status.title,
         "build_duration": "",
         "log_url": "",
         "upload_log_url": "",
         "builder_url": "",
         "build_url": canonical_url(self.build),
     })
     if build.duration is not None:
         duration_formatter = DurationFormatterAPI(build.duration)
         params["build_duration"] = duration_formatter.approximateduration()
     if build.log is not None:
         params["log_url"] = build.log_url
     if build.upload_log is not None:
         params["upload_log_url"] = build.upload_log_url
     if build.builder is not None:
         params["builder_url"] = canonical_url(build.builder)
     return params
Пример #4
0
    def describeBacklog(self, estimated_backlog):
        """Return string describing the current export backlog."""
        threshold = timedelta(minutes=10)
        if estimated_backlog is None or estimated_backlog < threshold:
            return ""

        formatter = DurationFormatterAPI(estimated_backlog)
        time_string = formatter.approximateduration()
        return "The backlog is approximately %s." % time_string
Пример #5
0
    def describeBacklog(self, estimated_backlog):
        """Return string describing the current export backlog."""
        threshold = timedelta(minutes=10)
        if estimated_backlog is None or estimated_backlog < threshold:
            return ""

        formatter = DurationFormatterAPI(estimated_backlog)
        time_string = formatter.approximateduration()
        return "The backlog is approximately %s." % time_string
Пример #6
0
 def _getTemplateParams(self, email, recipient):
     """See `BaseMailer`."""
     build = self.build
     upload_job = build.last_store_upload_job
     if upload_job is None:
         error_message = ""
         store_url = ""
     else:
         error_message = upload_job.error_message or ""
         store_url = upload_job.store_url or ""
     params = super(SnapBuildMailer,
                    self)._getTemplateParams(email, recipient)
     params.update({
         "archive_tag":
         build.archive.reference,
         "build_id":
         build.id,
         "build_title":
         build.title,
         "snap_name":
         build.snap.name,
         "distroseries":
         build.snap.distro_series,
         "architecturetag":
         build.distro_arch_series.architecturetag,
         "pocket":
         build.pocket.name,
         "build_state":
         build.status.title,
         "build_duration":
         "",
         "log_url":
         "",
         "upload_log_url":
         "",
         "builder_url":
         "",
         "build_url":
         canonical_url(build),
         "snap_authorize_url":
         canonical_url(build.snap, view_name="+authorize"),
         "store_error_message":
         error_message,
         "store_url":
         store_url,
     })
     if build.duration is not None:
         duration_formatter = DurationFormatterAPI(build.duration)
         params["build_duration"] = duration_formatter.approximateduration()
     if build.log is not None:
         params["log_url"] = build.log_url
     if build.upload_log is not None:
         params["upload_log_url"] = build.upload_log_url
     if build.builder is not None:
         params["builder_url"] = canonical_url(build.builder)
     return params
Пример #7
0
 def __call__(self):
     if os.path.exists('+maintenancetime.txt'):
         message = file('+maintenancetime.txt').read()
         try:
             maintenancetime = parseDatetimetz(message)
         except DateTimeError:
             # XXX SteveAlexander 2005-09-22: log a warning here.
             return ''
         timeleft = maintenancetime - utc_now()
         if timeleft > self.toomuchtime:
             return ''
         elif timeleft < self.notmuchtime:
             self.timelefttext = 'very very soon'
         else:
             self.timelefttext = 'in %s' % (
                 DurationFormatterAPI(timeleft).approximateduration())
         return self.index()
     return ''
Пример #8
0
    def sendExpirationWarningEmail(self):
        """See `ITeamMembership`."""
        if self.dateexpires is None:
            raise AssertionError(
                '%s in team %s has no membership expiration date.' %
                (self.person.name, self.team.name))
        if self.dateexpires < datetime.now(pytz.timezone('UTC')):
            # The membership has reached expiration. Silently return because
            # there is nothing to do. The member will have received emails
            # from previous calls by flag-expired-memberships.py
            return
        member = self.person
        team = self.team
        if member.is_team:
            recipient = member.teamowner
            templatename = 'membership-expiration-warning-bulk.txt'
            subject = '%s will expire soon from %s' % (member.name, team.name)
        else:
            recipient = member
            templatename = 'membership-expiration-warning-personal.txt'
            subject = 'Your membership in %s is about to expire' % team.name

        if team.renewal_policy == TeamMembershipRenewalPolicy.ONDEMAND:
            how_to_renew = (
                "If you want, you can renew this membership at\n"
                "<%s/+expiringmembership/%s>"
                % (canonical_url(member), team.name))
        elif not self.canChangeExpirationDate(recipient):
            admins_names = []
            admins = team.getDirectAdministrators()
            assert admins.count() >= 1
            if admins.count() == 1:
                admin = admins[0]
                how_to_renew = (
                    "To prevent this membership from expiring, you should "
                    "contact the\nteam's administrator, %s.\n<%s>"
                    % (admin.unique_displayname, canonical_url(admin)))
            else:
                for admin in admins:
                    admins_names.append(
                        "%s <%s>" % (admin.unique_displayname,
                                        canonical_url(admin)))

                how_to_renew = (
                    "To prevent this membership from expiring, you should "
                    "get in touch\nwith one of the team's administrators:\n")
                how_to_renew += "\n".join(admins_names)
        else:
            how_to_renew = (
                "To stay a member of this team you should extend your "
                "membership at\n<%s/+member/%s>"
                % (canonical_url(team), member.name))

        to_addrs = get_contact_email_addresses(recipient)
        if len(to_addrs) == 0:
            # The user does not have a preferred email address, he was
            # probably suspended.
            return
        formatter = DurationFormatterAPI(
            self.dateexpires - datetime.now(pytz.timezone('UTC')))
        replacements = {
            'recipient_name': recipient.displayname,
            'member_name': member.unique_displayname,
            'team_url': canonical_url(team),
            'how_to_renew': how_to_renew,
            'team_name': team.unique_displayname,
            'expiration_date': self.dateexpires.strftime('%Y-%m-%d'),
            'approximate_duration': formatter.approximateduration()}

        msg = get_email_template(templatename, app='registry') % replacements
        from_addr = format_address(
            team.displayname, config.canonical.noreply_from_address)
        simple_sendmail(from_addr, to_addrs, subject, msg)
Пример #9
0
    def forExpiringMembership(cls, member, team, dateexpires):
        """Create a mailer for warning about expiring membership."""
        membership = getUtility(ITeamMembershipSet).getByPersonAndTeam(
            member, team)
        assert membership is not None
        if member.is_team:
            target = member.teamowner
            template_name = "membership-expiration-warning-bulk.txt"
            subject = "%s will expire soon from %s" % (member.name, team.name)
        else:
            target = member
            template_name = "membership-expiration-warning-personal.txt"
            subject = "Your membership in %s is about to expire" % team.name

        if team.renewal_policy == TeamMembershipRenewalPolicy.ONDEMAND:
            how_to_renew = ("If you want, you can renew this membership at\n"
                            "<%s/+expiringmembership/%s>" %
                            (canonical_url(member), team.name))
        elif not membership.canChangeExpirationDate(target):
            admins_names = []
            admins = team.getDirectAdministrators()
            assert admins.count() >= 1
            if admins.count() == 1:
                admin = admins[0]
                how_to_renew = (
                    "To prevent this membership from expiring, you should "
                    "contact the\nteam's administrator, %s.\n<%s>" %
                    (admin.unique_displayname, canonical_url(admin)))
            else:
                for admin in admins:
                    admins_names.append(
                        "%s <%s>" %
                        (admin.unique_displayname, canonical_url(admin)))

                how_to_renew = (
                    "To prevent this membership from expiring, you should "
                    "get in touch\nwith one of the team's administrators:\n")
                how_to_renew += "\n".join(admins_names)
        else:
            how_to_renew = (
                "To stay a member of this team you should extend your "
                "membership at\n<%s/+member/%s>" %
                (canonical_url(team), member.name))

        recipients = OrderedDict()
        for recipient in get_recipients(target):
            recipients[recipient] = TeamMembershipRecipientReason.forMember(
                member, team, recipient)

        formatter = DurationFormatterAPI(dateexpires - datetime.now(pytz.UTC))
        extra_params = {
            "how_to_renew": how_to_renew,
            "expiration_date": dateexpires.strftime("%Y-%m-%d"),
            "approximate_duration": formatter.approximateduration(),
        }

        from_addr = format_address(team.displayname,
                                   config.canonical.noreply_from_address)
        return cls(subject,
                   template_name,
                   recipients,
                   from_addr,
                   "team-membership-expiration-warning",
                   member,
                   team,
                   membership.proposed_by,
                   membership=membership,
                   extra_params=extra_params,
                   wrap=False,
                   force_wrap=False)
Пример #10
0
    def _assert_mail_is_correct(self,
                                build,
                                notification,
                                recipient,
                                reason,
                                ppa=False):
        # Assert that the mail sent (which is in notification), matches
        # the data from the build
        self.assertEqual(format_address_for_person(recipient),
                         notification['To'])
        if reason == "buildd-admin":
            rationale = "Buildd-Admin @launchpad-buildd-admins"
            expected_for = "launchpad-buildd-admins"
        else:
            rationale = reason.title()
            expected_for = recipient.name
        self.assertEqual(rationale,
                         notification['X-Launchpad-Message-Rationale'])
        self.assertEqual(expected_for, notification['X-Launchpad-Message-For'])
        self.assertEqual('package-build-status',
                         notification['X-Launchpad-Notification-Type'])
        self.assertEqual('*****@*****.**',
                         notification['X-Creator-Recipient'])
        self.assertEqual(self.das.architecturetag,
                         notification['X-Launchpad-Build-Arch'])
        self.assertEqual('main', notification['X-Launchpad-Build-Component'])
        self.assertEqual(build.status.name,
                         notification['X-Launchpad-Build-State'])
        self.assertEqual(build.archive.reference,
                         notification['X-Launchpad-Archive'])
        if ppa and build.archive.distribution.name == 'ubuntu':
            self.assertEqual(get_ppa_reference(self.ppa),
                             notification['X-Launchpad-PPA'])
        body = notification.get_payload(decode=True)
        build_log = 'None'
        if ppa:
            source = 'not available'
        else:
            source = canonical_url(build.distributionsourcepackagerelease)
        if build.status == BuildStatus.BUILDING:
            duration = 'not finished'
            build_log = 'see builder page'
            builder = canonical_url(build.builder)
        elif (build.status == BuildStatus.SUPERSEDED
              or build.status == BuildStatus.NEEDSBUILD):
            duration = 'not available'
            build_log = 'not available'
            builder = 'not available'
        elif build.status == BuildStatus.UPLOADING:
            duration = 'uploading'
            build_log = 'see builder page'
            builder = 'not available'
        else:
            duration = DurationFormatterAPI(
                build.duration).approximateduration()
            builder = canonical_url(build.builder)
        expected_body = dedent(
            """
         * Source Package: %s
         * Version: %s
         * Architecture: %s
         * Archive: %s
         * Component: main
         * State: %s
         * Duration: %s
         * Build Log: %s
         * Builder: %s
         * Source: %s



        If you want further information about this situation, feel free to
        contact us by asking a question on Launchpad
        (https://answers.launchpad.net/launchpad/+addquestion).

        %s
        %s
        %s
        """ %
            (build.source_package_release.sourcepackagename.name,
             build.source_package_release.version, self.das.architecturetag,
             build.archive.reference, build.status.title, duration, build_log,
             builder, source, "-- ", build.title, canonical_url(build)))
        expected_body += "\n" + REASONS[reason] + "\n"
        self.assertEqual(expected_body, body)
Пример #11
0
    def _assert_mail_is_correct(self, build, notification, ppa=False):
        # Assert that the mail sent (which is in notification), matches
        # the data from the build
        self.assertEquals('*****@*****.**',
                          notification['X-Creator-Recipient'])
        self.assertEquals(self.das.architecturetag,
                          notification['X-Launchpad-Build-Arch'])
        self.assertEquals('main', notification['X-Launchpad-Build-Component'])
        self.assertEquals(build.status.name,
                          notification['X-Launchpad-Build-State'])
        if ppa is True:
            self.assertEquals(get_ppa_reference(self.ppa),
                              notification['X-Launchpad-PPA'])
        body = notification.get_payload(decode=True)
        build_log = 'None'
        if ppa is True:
            archive = '%s PPA' % get_ppa_reference(build.archive)
            source = 'not available'
        else:
            archive = '%s primary archive' % (
                self.distroseries.distribution.name)
            source = canonical_url(build.distributionsourcepackagerelease)
        builder = canonical_url(build.builder)
        if build.status == BuildStatus.BUILDING:
            duration = 'not finished'
            build_log = 'see builder page'
        elif (build.status == BuildStatus.SUPERSEDED
              or build.status == BuildStatus.NEEDSBUILD):
            duration = 'not available'
            build_log = 'not available'
            builder = 'not available'
        elif build.status == BuildStatus.UPLOADING:
            duration = 'uploading'
            build_log = 'see builder page'
            builder = 'not available'
        else:
            duration = DurationFormatterAPI(
                build.duration).approximateduration()
        expected_body = dedent("""
         * Source Package: %s
         * Version: %s
         * Architecture: %s
         * Archive: %s
         * Component: main
         * State: %s
         * Duration: %s
         * Build Log: %s
         * Builder: %s
         * Source: %s



        If you want further information about this situation, feel free to
        contact a member of the Launchpad Buildd Administrators team.

        --
        %s
        %s
        """ % (build.source_package_release.sourcepackagename.name,
               build.source_package_release.version, self.das.architecturetag,
               archive, build.status.title, duration, build_log, builder,
               source, build.title, canonical_url(build)))
        self.assertEquals(expected_body, body)