Convert last Python code from mixed tabs and spaces to spaces

This commit is contained in:
Stefano Rivera 2010-12-22 23:04:29 +02:00
parent 63f418c534
commit f01beda01c
6 changed files with 625 additions and 625 deletions

View File

@ -42,234 +42,234 @@ from ubuntutools.requestsync.common import (edit_report, getDebianChangelog,
# #
if __name__ == '__main__': if __name__ == '__main__':
# Our usage options. # Our usage options.
usage = 'Usage: %prog [options] ' \ usage = 'Usage: %prog [options] ' \
'<source package> [<target release> [base version]]' '<source package> [<target release> [base version]]'
optParser = OptionParser(usage) optParser = OptionParser(usage)
optParser.add_option('-d', type='string', optParser.add_option('-d', type='string',
dest='dist', default='unstable', dest='dist', default='unstable',
help='Debian distribution to sync from.') help='Debian distribution to sync from.')
optParser.add_option('-k', type='string', optParser.add_option('-k', type='string',
dest='keyid', default=None, dest='keyid', default=None,
help='GnuPG key ID to use for signing report (only used when emailing the sync request).') help='GnuPG key ID to use for signing report (only used when emailing the sync request).')
optParser.add_option('-n', action='store_true', optParser.add_option('-n', action='store_true',
dest='newpkg', default=False, dest='newpkg', default=False,
help='Whether package to sync is a new package in Ubuntu.') help='Whether package to sync is a new package in Ubuntu.')
optParser.add_option('--lp', action='store_true', optParser.add_option('--lp', action='store_true',
dest='lpapi', default=False, dest='lpapi', default=False,
help='Specify whether to use the LP API for filing the sync request (recommended).') help='Specify whether to use the LP API for filing the sync request (recommended).')
optParser.add_option('-l', '--lpinstance', type='string', metavar='INSTANCE', optParser.add_option('-l', '--lpinstance', type='string', metavar='INSTANCE',
dest='lpinstance', default=None, dest='lpinstance', default=None,
help='Launchpad instance to connect to (default: production).') help='Launchpad instance to connect to (default: production).')
optParser.add_option('-s', action='store_true', optParser.add_option('-s', action='store_true',
dest='sponsorship', default=False, dest='sponsorship', default=False,
help='Force sponsorship') help='Force sponsorship')
optParser.add_option('-C', action='store_true', optParser.add_option('-C', action='store_true',
dest='missing_changelog_ok', default=False, dest='missing_changelog_ok', default=False,
help='Allow changelog to be manually filled in when missing') help='Allow changelog to be manually filled in when missing')
optParser.add_option('-e', action='store_true', optParser.add_option('-e', action='store_true',
dest='ffe', default=False, dest='ffe', default=False,
help='Use this after FeatureFreeze for non-bug fix syncs, changes ' \ help='Use this after FeatureFreeze for non-bug fix syncs, changes ' \
'default subscription to the appropriate release team.') 'default subscription to the appropriate release team.')
optParser.add_option('--no-conf', action='store_true', optParser.add_option('--no-conf', action='store_true',
dest='no_conf', default=False, dest='no_conf', default=False,
help="Don't read config files or environment variables") help="Don't read config files or environment variables")
(options, args) = optParser.parse_args() (options, args) = optParser.parse_args()
if not len(args): if not len(args):
optParser.print_help() optParser.print_help()
sys.exit(1) sys.exit(1)
config = UDTConfig(options.no_conf) config = UDTConfig(options.no_conf)
if not options.lpapi: if not options.lpapi:
options.lpapi = config.get_value('USE_LPAPI', default=False, options.lpapi = config.get_value('USE_LPAPI', default=False,
boolean=True) boolean=True)
if options.lpinstance is None: if options.lpinstance is None:
options.lpinstance = config.get_value('LPINSTANCE') options.lpinstance = config.get_value('LPINSTANCE')
mailserver_host = config.get_value('SMTP_SERVER', mailserver_host = config.get_value('SMTP_SERVER',
default='fiordland.ubuntu.com', default='fiordland.ubuntu.com',
compat_keys=['UBUSMTP', 'DEBSMTP']) compat_keys=['UBUSMTP', 'DEBSMTP'])
mailserver_port = config.get_value('SMTP_PORT', default=25, mailserver_port = config.get_value('SMTP_PORT', default=25,
compat_keys=['UBUSMTP_PORT', 'DEBSMTP_PORT']) compat_keys=['UBUSMTP_PORT', 'DEBSMTP_PORT'])
mailserver_user = config.get_value('SMTP_USER', mailserver_user = config.get_value('SMTP_USER',
compat_keys=['UBUSMTP_USER', 'DEBSMTP_USER']) compat_keys=['UBUSMTP_USER', 'DEBSMTP_USER'])
mailserver_pass = config.get_value('SMTP_PASS', mailserver_pass = config.get_value('SMTP_PASS',
compat_keys=['UBUSMTP_PASS', 'DEBSMTP_PASS']) compat_keys=['UBUSMTP_PASS', 'DEBSMTP_PASS'])
# import the needed requestsync module # import the needed requestsync module
if options.lpapi: if options.lpapi:
from ubuntutools.requestsync.lp import (checkExistingReports, from ubuntutools.requestsync.lp import (checkExistingReports,
getDebianSrcPkg, getDebianSrcPkg,
getUbuntuSrcPkg, getUbuntuSrcPkg,
needSponsorship, postBug) needSponsorship, postBug)
from ubuntutools.lp.lpapicache import Distribution, Launchpad from ubuntutools.lp.lpapicache import Distribution, Launchpad
# See if we have LP credentials and exit if we don't - cannot continue in this case # See if we have LP credentials and exit if we don't - cannot continue in this case
try: try:
Launchpad.login(service=options.lpinstance) Launchpad.login(service=options.lpinstance)
except IOError: except IOError:
sys.exit(1) sys.exit(1)
else: else:
from ubuntutools.requestsync.mail import (checkExistingReports, from ubuntutools.requestsync.mail import (checkExistingReports,
getDebianSrcPkg, getDebianSrcPkg,
getUbuntuSrcPkg, getUbuntuSrcPkg,
mailBug, needSponsorship) mailBug, needSponsorship)
if not any(x in os.environ for x in ('UBUMAIL', 'DEBEMAIL', 'EMAIL')): if not any(x in os.environ for x in ('UBUMAIL', 'DEBEMAIL', 'EMAIL')):
print >> sys.stderr, ( print >> sys.stderr, (
'E: The environment variable UBUMAIL, DEBEMAIL or EMAIL needs ' 'E: The environment variable UBUMAIL, DEBEMAIL or EMAIL needs '
'to be set to let this script mail the sync request.') 'to be set to let this script mail the sync request.')
sys.exit(1) sys.exit(1)
newsource = options.newpkg newsource = options.newpkg
sponsorship = options.sponsorship sponsorship = options.sponsorship
distro = options.dist distro = options.dist
ffe = options.ffe ffe = options.ffe
lpapi = options.lpapi lpapi = options.lpapi
need_interaction = False need_interaction = False
force_base_version = None force_base_version = None
srcpkg = args[0] srcpkg = args[0]
if len(args) == 1: if len(args) == 1:
if lpapi: if lpapi:
release = Distribution('ubuntu').getDevelopmentSeries().name release = Distribution('ubuntu').getDevelopmentSeries().name
else: else:
release = 'natty' release = 'natty'
print >> sys.stderr, 'W: Target release missing - assuming %s' % release print >> sys.stderr, 'W: Target release missing - assuming %s' % release
elif len(args) == 2: elif len(args) == 2:
release = args[1] release = args[1]
elif len(args) == 3: elif len(args) == 3:
release = args[1] release = args[1]
force_base_version = Version(args[2]) force_base_version = Version(args[2])
else: else:
print >> sys.stderr, 'E: Too many arguments.' print >> sys.stderr, 'E: Too many arguments.'
optParser.print_help() optParser.print_help()
sys.exit(1) sys.exit(1)
# Get the current Ubuntu source package # Get the current Ubuntu source package
try: try:
ubuntu_srcpkg = getUbuntuSrcPkg(srcpkg, release) ubuntu_srcpkg = getUbuntuSrcPkg(srcpkg, release)
ubuntu_version = Version(ubuntu_srcpkg.getVersion()) ubuntu_version = Version(ubuntu_srcpkg.getVersion())
ubuntu_component = ubuntu_srcpkg.getComponent() ubuntu_component = ubuntu_srcpkg.getComponent()
newsource = False # override the -n flag newsource = False # override the -n flag
except udtexceptions.PackageNotFoundException: except udtexceptions.PackageNotFoundException:
ubuntu_srcpkg = None ubuntu_srcpkg = None
ubuntu_version = Version('~') ubuntu_version = Version('~')
ubuntu_component = 'universe' # let's assume universe ubuntu_component = 'universe' # let's assume universe
if not newsource: if not newsource:
print "'%s' doesn't exist in 'Ubuntu %s'.\nDo you want to sync a new package?" % \ print "'%s' doesn't exist in 'Ubuntu %s'.\nDo you want to sync a new package?" % \
(srcpkg, release) (srcpkg, release)
raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ') raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ')
newsource = True newsource = True
# Get the requested Debian source package # Get the requested Debian source package
try: try:
debian_srcpkg = getDebianSrcPkg(srcpkg, distro) debian_srcpkg = getDebianSrcPkg(srcpkg, distro)
debian_version = Version(debian_srcpkg.getVersion()) debian_version = Version(debian_srcpkg.getVersion())
debian_component = debian_srcpkg.getComponent() debian_component = debian_srcpkg.getComponent()
except udtexceptions.PackageNotFoundException, e: except udtexceptions.PackageNotFoundException, e:
print >> sys.stderr, "E: %s" % e print >> sys.stderr, "E: %s" % e
sys.exit(1) sys.exit(1)
# Stop if Ubuntu has already the version from Debian or a newer version # Stop if Ubuntu has already the version from Debian or a newer version
if (ubuntu_version >= debian_version) and options.lpapi: if (ubuntu_version >= debian_version) and options.lpapi:
# try rmadison # try rmadison
import ubuntutools.requestsync.mail import ubuntutools.requestsync.mail
try: try:
debian_srcpkg = ubuntutools.requestsync.mail.getDebianSrcPkg(srcpkg, distro) debian_srcpkg = ubuntutools.requestsync.mail.getDebianSrcPkg(srcpkg, distro)
debian_version = Version(debian_srcpkg.getVersion()) debian_version = Version(debian_srcpkg.getVersion())
debian_component = debian_srcpkg.getComponent() debian_component = debian_srcpkg.getComponent()
except udtexceptions.PackageNotFoundException, e: except udtexceptions.PackageNotFoundException, e:
print >> sys.stderr, "E: %s" % e print >> sys.stderr, "E: %s" % e
sys.exit(1) sys.exit(1)
if ubuntu_version == debian_version: if ubuntu_version == debian_version:
print >> sys.stderr, \ print >> sys.stderr, \
'E: The versions in Debian and Ubuntu are the same already (%s). Aborting.' % ubuntu_version 'E: The versions in Debian and Ubuntu are the same already (%s). Aborting.' % ubuntu_version
sys.exit(1) sys.exit(1)
if ubuntu_version > debian_version: if ubuntu_version > debian_version:
print >> sys.stderr, \ print >> sys.stderr, \
'E: The version in Ubuntu (%s) is newer than the version in Debian (%s). Aborting.' % (ubuntu_version, debian_version) 'E: The version in Ubuntu (%s) is newer than the version in Debian (%s). Aborting.' % (ubuntu_version, debian_version)
sys.exit(1) sys.exit(1)
# -s flag not specified - check if we do need sponsorship # -s flag not specified - check if we do need sponsorship
if not sponsorship: if not sponsorship:
sponsorship = needSponsorship(srcpkg, ubuntu_component, release) sponsorship = needSponsorship(srcpkg, ubuntu_component, release)
# Check for existing package reports # Check for existing package reports
if not newsource: if not newsource:
checkExistingReports(srcpkg) checkExistingReports(srcpkg)
# Generate bug report # Generate bug report
pkg_to_sync = '%s %s (%s) from Debian %s (%s)' % \ pkg_to_sync = '%s %s (%s) from Debian %s (%s)' % \
(srcpkg, debian_version, ubuntu_component, distro, debian_component) (srcpkg, debian_version, ubuntu_component, distro, debian_component)
title = "Sync %s" % pkg_to_sync title = "Sync %s" % pkg_to_sync
if ffe: if ffe:
title = "FFe: " + title title = "FFe: " + title
report = "Please sync %s\n\n" % pkg_to_sync report = "Please sync %s\n\n" % pkg_to_sync
if 'ubuntu' in str(ubuntu_version): if 'ubuntu' in str(ubuntu_version):
need_interaction = True need_interaction = True
print 'Changes have been made to the package in Ubuntu.\n' \ print 'Changes have been made to the package in Ubuntu.\n' \
'Please edit the report and give an explanation.\n' \ 'Please edit the report and give an explanation.\n' \
'Not saving the report file will abort the request.' 'Not saving the report file will abort the request.'
report += 'Explanation of the Ubuntu delta and why it can be dropped:\n' \ report += 'Explanation of the Ubuntu delta and why it can be dropped:\n' \
'>>> ENTER_EXPLANATION_HERE <<<\n\n' '>>> ENTER_EXPLANATION_HERE <<<\n\n'
if ffe: if ffe:
need_interaction = True need_interaction = True
print 'To approve FeatureFreeze exception, you need to state\n' \ print 'To approve FeatureFreeze exception, you need to state\n' \
'the reason why you feel it is necessary.\n' \ 'the reason why you feel it is necessary.\n' \
'Not saving the report file will abort the request.' 'Not saving the report file will abort the request.'
report += 'Explanation of FeatureFreeze exception:\n' \ report += 'Explanation of FeatureFreeze exception:\n' \
'>>> ENTER_EXPLANATION_HERE <<<\n\n' '>>> ENTER_EXPLANATION_HERE <<<\n\n'
if need_interaction: if need_interaction:
raw_input_exit_on_ctrlc('Press [Enter] to continue. Press [Ctrl-C] to abort now. ') raw_input_exit_on_ctrlc('Press [Enter] to continue. Press [Ctrl-C] to abort now. ')
base_version = force_base_version or ubuntu_version base_version = force_base_version or ubuntu_version
if newsource: if newsource:
report += 'All changelog entries:\n\n' report += 'All changelog entries:\n\n'
else: else:
report += 'Changelog entries since current %s version %s:\n\n' % (release, ubuntu_version) report += 'Changelog entries since current %s version %s:\n\n' % (release, ubuntu_version)
changelog = getDebianChangelog(debian_srcpkg, base_version) changelog = getDebianChangelog(debian_srcpkg, base_version)
if not changelog: if not changelog:
if not options.missing_changelog_ok: if not options.missing_changelog_ok:
print >> sys.stderr, "E: Did not retrieve any changelog entries. Do you need to specify '-C'? Was the package recently uploaded? (check http://packages.debian.org/changelogs/)" print >> sys.stderr, "E: Did not retrieve any changelog entries. Do you need to specify '-C'? Was the package recently uploaded? (check http://packages.debian.org/changelogs/)"
sys.exit(1) sys.exit(1)
else: else:
need_interaction = True need_interaction = True
changelog = "XXX FIXME: add changelog here XXX" changelog = "XXX FIXME: add changelog here XXX"
report += changelog report += changelog
(title, report) = edit_report(title, report, changes_required = need_interaction) (title, report) = edit_report(title, report, changes_required = need_interaction)
if 'XXX FIXME' in report: if 'XXX FIXME' in report:
print >> sys.stderr, "E: changelog boilerplate found in report, please manually add changelog when using '-C'" print >> sys.stderr, "E: changelog boilerplate found in report, please manually add changelog when using '-C'"
sys.exit(1) sys.exit(1)
# bug status and bug subscriber # bug status and bug subscriber
status = 'confirmed' status = 'confirmed'
subscribe = 'ubuntu-archive' subscribe = 'ubuntu-archive'
if sponsorship: if sponsorship:
status = 'new' status = 'new'
subscribe = 'ubuntu-sponsors' subscribe = 'ubuntu-sponsors'
if ffe: if ffe:
status = 'new' status = 'new'
subscribe = 'ubuntu-release' subscribe = 'ubuntu-release'
srcpkg = not newsource and srcpkg or None srcpkg = not newsource and srcpkg or None
if lpapi: if lpapi:
# Map status to the values expected by LP API # Map status to the values expected by LP API
mapping = {'new': 'New', 'confirmed': 'Confirmed'} mapping = {'new': 'New', 'confirmed': 'Confirmed'}
# Post sync request using LP API # Post sync request using LP API
postBug(srcpkg, subscribe, mapping[status], title, report) postBug(srcpkg, subscribe, mapping[status], title, report)
else: else:
email_from = ubu_email(export=False)[1] email_from = ubu_email(export=False)[1]
# Mail sync request # Mail sync request
mailBug(srcpkg, subscribe, status, title, report, options.lpinstance, mailBug(srcpkg, subscribe, status, title, report, options.lpinstance,
options.keyid, email_from, mailserver_host, mailserver_port, options.keyid, email_from, mailserver_host, mailserver_port,
mailserver_user, mailserver_pass) mailserver_user, mailserver_pass)

View File

@ -38,7 +38,7 @@ usage += "Only Launchpad Buildd Admins may rescore package builds."
# Valid architectures. # Valid architectures.
valid_archs = set(["armel", "amd64", "hppa", "i386", valid_archs = set(["armel", "amd64", "hppa", "i386",
"ia64", "lpia", "powerpc", "sparc"]) "ia64", "lpia", "powerpc", "sparc"])
# Prepare our option parser. # Prepare our option parser.
optParser = OptionParser(usage) optParser = OptionParser(usage)
@ -49,30 +49,30 @@ retryRescoreOptions = OptionGroup(optParser, "Retry and rescore options",
retryRescoreOptions.add_option("-a", "--arch", type = "string", retryRescoreOptions.add_option("-a", "--arch", type = "string",
action = "append", dest = "architecture", action = "append", dest = "architecture",
help = "Rebuild or rescore a specific architecture. " \ help = "Rebuild or rescore a specific architecture. " \
"Valid architectures include: " \ "Valid architectures include: " \
"%s." % ", ".join(valid_archs)) "%s." % ", ".join(valid_archs))
# Batch processing options # Batch processing options
batch_options = OptionGroup( batch_options = OptionGroup(
optParser, "Batch processing", optParser, "Batch processing",
"These options and parameter ordering is only available in --batch mode.\n" "These options and parameter ordering is only available in --batch mode.\n"
"Usage: ubuntu-build --batch [options] <package>...") "Usage: ubuntu-build --batch [options] <package>...")
batch_options.add_option( batch_options.add_option(
'--batch', action = 'store_true', dest = 'batch', default = False, '--batch', action = 'store_true', dest = 'batch', default = False,
help = 'Enable batch mode') help = 'Enable batch mode')
batch_options.add_option( batch_options.add_option(
'--series', action = 'store', dest = 'series', type = 'string', '--series', action = 'store', dest = 'series', type = 'string',
help = 'Selects the Ubuntu series to operate on (default: current development series)') help = 'Selects the Ubuntu series to operate on (default: current development series)')
batch_options.add_option( batch_options.add_option(
'--retry', action = 'store_true', dest = 'retry', default = False, '--retry', action = 'store_true', dest = 'retry', default = False,
help = 'Retry builds (give-back).') help = 'Retry builds (give-back).')
batch_options.add_option( batch_options.add_option(
'--rescore', action = 'store', dest = 'priority', type = 'int', '--rescore', action = 'store', dest = 'priority', type = 'int',
help = 'Rescore builds to <priority>.') help = 'Rescore builds to <priority>.')
batch_options.add_option( batch_options.add_option(
'--arch2', action = 'append', dest = 'architecture', type = 'string', '--arch2', action = 'append', dest = 'architecture', type = 'string',
help = "Affect only 'architecture' (can be used several times). " help = "Affect only 'architecture' (can be used several times). "
"Valid architectures are: %s." % ', '.join(valid_archs)) "Valid architectures are: %s." % ', '.join(valid_archs))
# Add the retry options to the main group. # Add the retry options to the main group.
optParser.add_option_group(retryRescoreOptions) optParser.add_option_group(retryRescoreOptions)
@ -83,122 +83,122 @@ optParser.add_option_group(batch_options)
(options, args) = optParser.parse_args() (options, args) = optParser.parse_args()
if not len(args): if not len(args):
optParser.print_help() optParser.print_help()
sys.exit(1) sys.exit(1)
if not options.batch: if not options.batch:
# Check we have the correct number of arguments. # Check we have the correct number of arguments.
if len(args) < 3: if len(args) < 3:
optParser.error("Incorrect number of arguments.") optParser.error("Incorrect number of arguments.")
try: try:
package = str(args[0]).lower() package = str(args[0]).lower()
release = str(args[1]).lower() release = str(args[1]).lower()
op = str(args[2]).lower() op = str(args[2]).lower()
except IndexError: except IndexError:
optParser.print_help() optParser.print_help()
sys.exit(1) sys.exit(1)
# Check our operation. # Check our operation.
if op not in ("rescore", "retry", "status"): if op not in ("rescore", "retry", "status"):
print >> sys.stderr, "Invalid operation: %s." % op print >> sys.stderr, "Invalid operation: %s." % op
sys.exit(1) sys.exit(1)
# If the user has specified an architecture to build, we only wish to rebuild it # If the user has specified an architecture to build, we only wish to rebuild it
# and nothing else. # and nothing else.
if options.architecture: if options.architecture:
if options.architecture[0] not in valid_archs: if options.architecture[0] not in valid_archs:
print >> sys.stderr, "Invalid architecture specified: %s." % options.architecture[0] print >> sys.stderr, "Invalid architecture specified: %s." % options.architecture[0]
sys.exit(1) sys.exit(1)
else: else:
oneArch = True oneArch = True
else: else:
oneArch = False oneArch = False
# split release and pocket # split release and pocket
try: try:
(release, pocket) = splitReleasePocket(release) (release, pocket) = splitReleasePocket(release)
except PocketDoesNotExistError, e: except PocketDoesNotExistError, e:
print 'E: %s' % e print 'E: %s' % e
sys.exit(1) sys.exit(1)
# Get the ubuntu archive # Get the ubuntu archive
try: try:
ubuntu_archive = Distribution('ubuntu').getArchive() ubuntu_archive = Distribution('ubuntu').getArchive()
# Will fail here if we have no credentials, bail out # Will fail here if we have no credentials, bail out
except IOError: except IOError:
sys.exit(1) sys.exit(1)
# Get list of published sources for package in question. # Get list of published sources for package in question.
try: try:
sources = ubuntu_archive.getSourcePackage(package, release, pocket) sources = ubuntu_archive.getSourcePackage(package, release, pocket)
distroseries = Distribution('ubuntu').getSeries(release) distroseries = Distribution('ubuntu').getSeries(release)
except (SeriesNotFoundException, PackageNotFoundException), e: except (SeriesNotFoundException, PackageNotFoundException), e:
print e print e
sys.exit(1) sys.exit(1)
# Get list of builds for that package. # Get list of builds for that package.
builds = sources.getBuilds() builds = sources.getBuilds()
# Find out the version and component in given release. # Find out the version and component in given release.
version = sources.getVersion() version = sources.getVersion()
component = sources.getComponent() component = sources.getComponent()
# Operations that are remaining may only be done by Ubuntu developers (retry) # Operations that are remaining may only be done by Ubuntu developers (retry)
# or buildd admins (rescore). Check if the proper permissions are in place. # or buildd admins (rescore). Check if the proper permissions are in place.
me = PersonTeam.me me = PersonTeam.me
if op == "rescore": necessaryPrivs = me.isLpTeamMember('launchpad-buildd-admins') if op == "rescore": necessaryPrivs = me.isLpTeamMember('launchpad-buildd-admins')
if op == "retry": necessaryPrivs = me.canUploadPackage( if op == "retry": necessaryPrivs = me.canUploadPackage(
ubuntu_archive, distroseries, sources.getPackageName(), sources.getComponent()) ubuntu_archive, distroseries, sources.getPackageName(), sources.getComponent())
if op in ('rescore', 'retry') and not necessaryPrivs: if op in ('rescore', 'retry') and not necessaryPrivs:
print >> sys.stderr, "You cannot perform the %s operation on a %s package " \ print >> sys.stderr, "You cannot perform the %s operation on a %s package " \
"as you do not have the permissions to do this action." % (op, component) "as you do not have the permissions to do this action." % (op, component)
sys.exit(1) sys.exit(1)
# Output details. # Output details.
print "The source version for '%s' in %s (%s) is at %s." % (package, print "The source version for '%s' in %s (%s) is at %s." % (package,
release.capitalize(), component, version) release.capitalize(), component, version)
print "Current build status for this package:" print "Current build status for this package:"
# Output list of arches for package and their status. # Output list of arches for package and their status.
done = False done = False
for build in builds: for build in builds:
if oneArch and build.arch_tag != options.architecture[0]: if oneArch and build.arch_tag != options.architecture[0]:
# Skip this architecture. # Skip this architecture.
continue continue
done = True done = True
print "%s: %s." % (build.arch_tag, build.buildstate) print "%s: %s." % (build.arch_tag, build.buildstate)
if op == 'rescore': if op == 'rescore':
if build.can_be_rescored: if build.can_be_rescored:
# FIXME: make priority an option # FIXME: make priority an option
priority = 5000 priority = 5000
print 'Rescoring build %s to %d...' % (build.arch_tag, priority) print 'Rescoring build %s to %d...' % (build.arch_tag, priority)
build.rescore(score = priority) build.rescore(score = priority)
else: else:
print 'Cannot rescore build on %s.' % build.arch_tag print 'Cannot rescore build on %s.' % build.arch_tag
if op == 'retry': if op == 'retry':
if build.can_be_retried: if build.can_be_retried:
print 'Retrying build on %s...' % build.arch_tag print 'Retrying build on %s...' % build.arch_tag
build.retry() build.retry()
else: else:
print 'Cannot retry build on %s.' % build.arch_tag print 'Cannot retry build on %s.' % build.arch_tag
# We are done # We are done
if done: sys.exit(0) if done: sys.exit(0)
print "No builds for '%s' found in the %s release - it may have been " \ print "No builds for '%s' found in the %s release - it may have been " \
"built in a former release." % (package, release.capitalize()) "built in a former release." % (package, release.capitalize())
sys.exit(0) sys.exit(0)
# Batch mode # Batch mode
if not options.architecture: if not options.architecture:
# no specific architectures specified, assume all valid ones # no specific architectures specified, assume all valid ones
archs = valid_archs archs = valid_archs
else: else:
archs = set(options.architecture) archs = set(options.architecture)
# filter out duplicate and invalid architectures # filter out duplicate and invalid architectures
archs.intersection_update(valid_archs) archs.intersection_update(valid_archs)
@ -212,36 +212,36 @@ except PocketDoesNotExistError, e:
ubuntu_archive = Distribution('ubuntu').getArchive() ubuntu_archive = Distribution('ubuntu').getArchive()
try: try:
distroseries = Distribution('ubuntu').getSeries(release) distroseries = Distribution('ubuntu').getSeries(release)
except SeriesNotFoundException, e: except SeriesNotFoundException, e:
print e print e
sys.exit(1) sys.exit(1)
me = PersonTeam.me me = PersonTeam.me
# Check permisions (part 1): Rescoring can only be done by buildd admins # Check permisions (part 1): Rescoring can only be done by buildd admins
can_rescore = options.priority and me.isLpTeamMember('launchpad-buildd-admins') or False can_rescore = options.priority and me.isLpTeamMember('launchpad-buildd-admins') or False
if options.priority and not can_rescore: if options.priority and not can_rescore:
print >> sys.stderr, "You don't have the permissions to rescore builds. Ignoring your rescore request." print >> sys.stderr, "You don't have the permissions to rescore builds. Ignoring your rescore request."
for pkg in args: for pkg in args:
try: try:
pkg = ubuntu_archive.getSourcePackage(pkg, release, pocket) pkg = ubuntu_archive.getSourcePackage(pkg, release, pocket)
except PackageNotFoundException, e: except PackageNotFoundException, e:
print e print e
continue continue
# Check permissions (part 2): check upload permissions for the source package # Check permissions (part 2): check upload permissions for the source package
can_retry = options.retry and me.canUploadPackage(ubuntu_archive, distroseries, pkg.getPackageName(), pkg.getComponent()) can_retry = options.retry and me.canUploadPackage(ubuntu_archive, distroseries, pkg.getPackageName(), pkg.getComponent())
if options.retry and not can_retry: if options.retry and not can_retry:
print >> sys.stderr, "You don't have the permissions to retry the build of '%s'. Ignoring your request." % pkg.getPackageName() print >> sys.stderr, "You don't have the permissions to retry the build of '%s'. Ignoring your request." % pkg.getPackageName()
print "The source version for '%s' in '%s' (%s) is: %s" % ( print "The source version for '%s' in '%s' (%s) is: %s" % (
pkg.getPackageName(), release, pocket, pkg.getVersion()) pkg.getPackageName(), release, pocket, pkg.getVersion())
print pkg.getBuildStates(archs) print pkg.getBuildStates(archs)
if can_retry: if can_retry:
print pkg.retryBuilds(archs) print pkg.retryBuilds(archs)
if options.priority and can_rescore: if options.priority and can_rescore:
print pkg.rescoreBuilds(archs, options.priority) print pkg.rescoreBuilds(archs, options.priority)
print '' print ''

View File

@ -1,18 +1,18 @@
class PackageNotFoundException(BaseException): class PackageNotFoundException(BaseException):
""" Thrown when a package is not found """ """ Thrown when a package is not found """
pass pass
class SeriesNotFoundException(BaseException): class SeriesNotFoundException(BaseException):
""" Thrown when a distroseries is not found """ """ Thrown when a distroseries is not found """
pass pass
class PocketDoesNotExistError(Exception): class PocketDoesNotExistError(Exception):
'''Raised when a invalid pocket is used.''' '''Raised when a invalid pocket is used.'''
pass pass
class ArchiveNotFoundException(BaseException): class ArchiveNotFoundException(BaseException):
""" Thrown when an archive for a distibution is not found """ """ Thrown when an archive for a distibution is not found """
pass pass
class AlreadyLoggedInError(Exception): class AlreadyLoggedInError(Exception):
'''Raised when a second login is attempted.''' '''Raised when a second login is attempted.'''

View File

@ -28,105 +28,105 @@ import subprocess
from debian.changelog import Changelog from debian.changelog import Changelog
def raw_input_exit_on_ctrlc(*args, **kwargs): def raw_input_exit_on_ctrlc(*args, **kwargs):
''' '''
A wrapper around raw_input() to exit with a normalized message on Control-C A wrapper around raw_input() to exit with a normalized message on Control-C
''' '''
try: try:
return raw_input(*args, **kwargs) return raw_input(*args, **kwargs)
except KeyboardInterrupt: except KeyboardInterrupt:
print '\nAbort requested. No sync request filed.' print '\nAbort requested. No sync request filed.'
sys.exit(1) sys.exit(1)
def getDebianChangelog(srcpkg, version): def getDebianChangelog(srcpkg, version):
''' '''
Return the new changelog entries upto 'version'. Return the new changelog entries upto 'version'.
''' '''
pkgname = srcpkg.getPackageName() pkgname = srcpkg.getPackageName()
pkgversion = srcpkg.getVersion() pkgversion = srcpkg.getVersion()
component = srcpkg.getComponent() component = srcpkg.getComponent()
if pkgname.startswith('lib'): if pkgname.startswith('lib'):
subdir = 'lib%s' % pkgname[3] subdir = 'lib%s' % pkgname[3]
else: else:
subdir = pkgname[0] subdir = pkgname[0]
# Strip epoch from version # Strip epoch from version
if ':' in pkgversion: if ':' in pkgversion:
pkgversion = pkgversion[pkgversion.find(':')+1:] pkgversion = pkgversion[pkgversion.find(':')+1:]
# Get the debian changelog file from packages.debian.org # Get the debian changelog file from packages.debian.org
try: try:
changelog = urllib2.urlopen( changelog = urllib2.urlopen(
'http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog.txt' % \ 'http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog.txt' % \
(component, subdir, pkgname, pkgname, pkgversion)) (component, subdir, pkgname, pkgname, pkgversion))
except urllib2.HTTPError, error: except urllib2.HTTPError, error:
print >> sys.stderr, 'Unable to connect to packages.debian.org: %s' % error print >> sys.stderr, 'Unable to connect to packages.debian.org: %s' % error
return None return None
new_entries = '' new_entries = ''
changelog = Changelog(changelog.read()) changelog = Changelog(changelog.read())
for block in changelog: for block in changelog:
if block.version > version: if block.version > version:
# see also Debian #561805 # see also Debian #561805
new_entries += unicode(str(block).decode('utf-8')) new_entries += unicode(str(block).decode('utf-8'))
return new_entries return new_entries
def edit_report(subject, body, changes_required = False): def edit_report(subject, body, changes_required = False):
''' '''
Ask if the user wants to edit a report (consisting of subject and body) Ask if the user wants to edit a report (consisting of subject and body)
in sensible-editor. in sensible-editor.
If changes_required is True then the file has to be edited before we If changes_required is True then the file has to be edited before we
can proceed. can proceed.
Returns (new_subject, new_body). Returns (new_subject, new_body).
''' '''
editing_finished = False editing_finished = False
while not editing_finished: while not editing_finished:
report = 'Summary (one line):\n%s\n\nDescription:\n%s' % (subject, body) report = 'Summary (one line):\n%s\n\nDescription:\n%s' % (subject, body)
if not changes_required: if not changes_required:
print 'Currently the report looks as follows:\n%s' % report print 'Currently the report looks as follows:\n%s' % report
while True: while True:
val = raw_input_exit_on_ctrlc('Do you want to edit the report [y/N]? ') val = raw_input_exit_on_ctrlc('Do you want to edit the report [y/N]? ')
if val.lower() in ('y', 'yes'): if val.lower() in ('y', 'yes'):
break break
elif val.lower() in ('n', 'no', ''): elif val.lower() in ('n', 'no', ''):
editing_finished = True editing_finished = True
break break
else: else:
print 'Invalid answer.' print 'Invalid answer.'
if not editing_finished: if not editing_finished:
# Create tempfile and remember mtime # Create tempfile and remember mtime
report_file = tempfile.NamedTemporaryFile(prefix='requestsync_') report_file = tempfile.NamedTemporaryFile(prefix='requestsync_')
report_file.write(report.encode('utf-8')) report_file.write(report.encode('utf-8'))
report_file.flush() report_file.flush()
mtime_before = os.stat(report_file.name).st_mtime mtime_before = os.stat(report_file.name).st_mtime
# Launch editor # Launch editor
try: try:
subprocess.check_call(['sensible-editor', report_file.name]) subprocess.check_call(['sensible-editor', report_file.name])
except subprocess.CalledProcessError, e: except subprocess.CalledProcessError, e:
print >> sys.stderr, 'Error calling sensible-editor: %s\nAborting.' % e print >> sys.stderr, 'Error calling sensible-editor: %s\nAborting.' % e
sys.exit(1) sys.exit(1)
# Check if the tempfile has been changed # Check if the tempfile has been changed
if changes_required: if changes_required:
if mtime_before == os.stat(report_file.name).st_mtime: if mtime_before == os.stat(report_file.name).st_mtime:
print 'The report has not been changed, but you have to explain why ' \ print 'The report has not been changed, but you have to explain why ' \
'the Ubuntu changes can be dropped.' 'the Ubuntu changes can be dropped.'
raw_input_exit_on_ctrlc('Press [Enter] to retry or [Control-C] to abort. ') raw_input_exit_on_ctrlc('Press [Enter] to retry or [Control-C] to abort. ')
else: else:
changes_required = False changes_required = False
report_file.seek(0) report_file.seek(0)
report = report_file.read().decode('utf-8') report = report_file.read().decode('utf-8')
report_file.close() report_file.close()
# Undecorate report again # Undecorate report again
(subject, body) = report.split("\nDescription:\n", 1) (subject, body) = report.split("\nDescription:\n", 1)
# Remove prefix and whitespace from subject # Remove prefix and whitespace from subject
subject = re.sub('^Summary \(one line\):\s*', '', subject, 1).strip() subject = re.sub('^Summary \(one line\):\s*', '', subject, 1).strip()
return (subject, body) return (subject, body)

View File

@ -25,91 +25,91 @@ from ubuntutools.lp.lpapicache import Launchpad, Distribution, PersonTeam, Distr
from ubuntutools.lp.libsupport import translate_api_web from ubuntutools.lp.libsupport import translate_api_web
def getDebianSrcPkg(name, release): def getDebianSrcPkg(name, release):
debian = Distribution('debian') debian = Distribution('debian')
debian_archive = debian.getArchive() debian_archive = debian.getArchive()
# Map 'unstable' and 'testing' to their codenames as LP knows only them # Map 'unstable' and 'testing' to their codenames as LP knows only them
codenames = { codenames = {
'unstable': 'sid', 'unstable': 'sid',
'testing': 'squeeze', # Needs updating after each Debian release 'testing': 'squeeze', # Needs updating after each Debian release
} }
release = codenames.get(release, release) release = codenames.get(release, release)
return debian_archive.getSourcePackage(name, release) return debian_archive.getSourcePackage(name, release)
def getUbuntuSrcPkg(name, release): def getUbuntuSrcPkg(name, release):
ubuntu = Distribution('ubuntu') ubuntu = Distribution('ubuntu')
ubuntu_archive = ubuntu.getArchive() ubuntu_archive = ubuntu.getArchive()
return ubuntu_archive.getSourcePackage(name, release) return ubuntu_archive.getSourcePackage(name, release)
def needSponsorship(name, component, release): def needSponsorship(name, component, release):
''' '''
Check if the user has upload permissions for either the package Check if the user has upload permissions for either the package
itself or the component itself or the component
''' '''
archive = Distribution('ubuntu').getArchive() archive = Distribution('ubuntu').getArchive()
distroseries = Distribution('ubuntu').getSeries(release) distroseries = Distribution('ubuntu').getSeries(release)
need_sponsor = not PersonTeam.me.canUploadPackage(archive, distroseries, name, component) need_sponsor = not PersonTeam.me.canUploadPackage(archive, distroseries, name, component)
if need_sponsor: if need_sponsor:
print '''You are not able to upload this package directly to Ubuntu. print '''You are not able to upload this package directly to Ubuntu.
Your sync request shall require an approval by a member of the appropriate Your sync request shall require an approval by a member of the appropriate
sponsorship team, who shall be subscribed to this bug report. sponsorship team, who shall be subscribed to this bug report.
This must be done before it can be processed by a member of the Ubuntu Archive This must be done before it can be processed by a member of the Ubuntu Archive
team.''' team.'''
raw_input_exit_on_ctrlc('If the above is correct please press [Enter] ') raw_input_exit_on_ctrlc('If the above is correct please press [Enter] ')
return need_sponsor return need_sponsor
def checkExistingReports(srcpkg): def checkExistingReports(srcpkg):
''' '''
Check existing bug reports on Launchpad for a possible sync request. Check existing bug reports on Launchpad for a possible sync request.
If found ask for confirmation on filing a request. If found ask for confirmation on filing a request.
''' '''
# Fetch the package's bug list from Launchpad # Fetch the package's bug list from Launchpad
pkg = Distribution('ubuntu').getSourcePackage(name = srcpkg) pkg = Distribution('ubuntu').getSourcePackage(name = srcpkg)
pkgBugList = pkg.getBugTasks() pkgBugList = pkg.getBugTasks()
# Search bug list for other sync requests. # Search bug list for other sync requests.
for bug in pkgBugList: for bug in pkgBugList:
# check for Sync or sync and the package name # check for Sync or sync and the package name
if not bug.is_complete and 'ync %s' % srcpkg in bug.title: if not bug.is_complete and 'ync %s' % srcpkg in bug.title:
print 'The following bug could be a possible duplicate sync bug on Launchpad:' print 'The following bug could be a possible duplicate sync bug on Launchpad:'
print ' * %s (%s)' % \ print ' * %s (%s)' % \
(bug.title, translate_api_web(bug.self_link)) (bug.title, translate_api_web(bug.self_link))
print 'Please check the above URL to verify this before continuing.' print 'Please check the above URL to verify this before continuing.'
raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ') raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ')
def postBug(srcpkg, subscribe, status, bugtitle, bugtext): def postBug(srcpkg, subscribe, status, bugtitle, bugtext):
''' '''
Use the LP API to file the sync request. Use the LP API to file the sync request.
''' '''
print 'The final report is:\nSummary: %s\nDescription:\n%s\n' % (bugtitle, bugtext) print 'The final report is:\nSummary: %s\nDescription:\n%s\n' % (bugtitle, bugtext)
raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ') raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ')
if srcpkg: if srcpkg:
bug_target = DistributionSourcePackage( bug_target = DistributionSourcePackage(
'%subuntu/+source/%s' % (Launchpad._root_uri, srcpkg)) '%subuntu/+source/%s' % (Launchpad._root_uri, srcpkg))
else: else:
# new source package # new source package
bug_target = Distribution('ubuntu') bug_target = Distribution('ubuntu')
# create bug # create bug
bug = Launchpad.bugs.createBug(title = bugtitle, description = bugtext, target = bug_target()) bug = Launchpad.bugs.createBug(title = bugtitle, description = bugtext, target = bug_target())
# newly created bugreports have only one task # newly created bugreports have only one task
task = bug.bug_tasks[0] task = bug.bug_tasks[0]
# only members of ubuntu-bugcontrol can set importance # only members of ubuntu-bugcontrol can set importance
if PersonTeam.me.isLpTeamMember('ubuntu-bugcontrol'): if PersonTeam.me.isLpTeamMember('ubuntu-bugcontrol'):
task.importance = 'Wishlist' task.importance = 'Wishlist'
task.status = status task.status = status
task.lp_save() task.lp_save()
bug.subscribe(person = PersonTeam(subscribe)()) bug.subscribe(person = PersonTeam(subscribe)())
print 'Sync request filed as bug #%i: %s' % (bug.id, print 'Sync request filed as bug #%i: %s' % (bug.id,
translate_api_web(bug.self_link)) translate_api_web(bug.self_link))

View File

@ -29,128 +29,128 @@ from ubuntutools.requestsync.common import raw_input_exit_on_ctrlc
from ubuntutools.lp.udtexceptions import PackageNotFoundException from ubuntutools.lp.udtexceptions import PackageNotFoundException
__all__ = [ __all__ = [
'getDebianSrcPkg', 'getDebianSrcPkg',
'getUbuntuSrcPkg', 'getUbuntuSrcPkg',
'needSponsorship', 'needSponsorship',
'checkExistingReports', 'checkExistingReports',
'mailBug', 'mailBug',
] ]
class SourcePackagePublishingHistory(object): class SourcePackagePublishingHistory(object):
''' '''
Simulate a SourcePackagePublishingHistory class from the LP API caching Simulate a SourcePackagePublishingHistory class from the LP API caching
module. module.
''' '''
def __init__(self, name, version, component): def __init__(self, name, version, component):
self.name = name self.name = name
self.version = version self.version = version
self.component = component self.component = component
def getPackageName(self): def getPackageName(self):
return self.name return self.name
def getVersion(self): def getVersion(self):
return self.version return self.version
def getComponent(self): def getComponent(self):
return self.component return self.component
def rmadison(distro, package, release): def rmadison(distro, package, release):
# Map 'sid' and 'squeeze' to their releasenames else rmadison gets a python # Map 'sid' and 'squeeze' to their releasenames else rmadison gets a python
# traceback back from the remote script # traceback back from the remote script
releasenames = { releasenames = {
'sid': 'unstable', 'sid': 'unstable',
'squeeze': 'testing', # Needs updating after each Debian release 'squeeze': 'testing', # Needs updating after each Debian release
} }
release = releasenames.get(release, release) release = releasenames.get(release, release)
rmadison_cmd = subprocess.Popen( rmadison_cmd = subprocess.Popen(
['rmadison', '-u', distro, '-a', 'source', '-s', release, package], ['rmadison', '-u', distro, '-a', 'source', '-s', release, package],
stdout = subprocess.PIPE) stdout = subprocess.PIPE)
rmadison_out = rmadison_cmd.communicate()[0] rmadison_out = rmadison_cmd.communicate()[0]
assert (rmadison_cmd.returncode == 0) assert (rmadison_cmd.returncode == 0)
# Return the most recent source line # Return the most recent source line
lines = rmadison_out.splitlines() lines = rmadison_out.splitlines()
if not lines: if not lines:
# no output # no output
return None return None
lines = [map(lambda x: x.strip(), line.split('|')) for line in lines] lines = [map(lambda x: x.strip(), line.split('|')) for line in lines]
lines = [line for line in lines if line[3].find('source') != -1] lines = [line for line in lines if line[3].find('source') != -1]
if lines: if lines:
return max(lines, key = lambda x: Version(x[1])) return max(lines, key = lambda x: Version(x[1]))
else: else:
# no source line # no source line
return None return None
def getSrcPkg(distro, name, release): def getSrcPkg(distro, name, release):
out = rmadison(distro, name, release) out = rmadison(distro, name, release)
if not out: if not out:
raise PackageNotFoundException( raise PackageNotFoundException(
"'%s' doesn't appear to exist in %s '%s'" % \ "'%s' doesn't appear to exist in %s '%s'" % \
(name, distro.capitalize(), release)) (name, distro.capitalize(), release))
version = out[1] version = out[1]
component = 'main' component = 'main'
raw_comp = out[2].split('/') raw_comp = out[2].split('/')
if len(raw_comp) == 2: if len(raw_comp) == 2:
component = raw_comp[1] component = raw_comp[1]
return SourcePackagePublishingHistory(name, version, component) return SourcePackagePublishingHistory(name, version, component)
def getDebianSrcPkg(name, release): def getDebianSrcPkg(name, release):
return getSrcPkg('debian', name, release) return getSrcPkg('debian', name, release)
def getUbuntuSrcPkg(name, release): def getUbuntuSrcPkg(name, release):
return getSrcPkg('ubuntu', name, release) return getSrcPkg('ubuntu', name, release)
def needSponsorship(name, component, release): def needSponsorship(name, component, release):
''' '''
Ask the user if he has upload permissions for the package or the Ask the user if he has upload permissions for the package or the
component. component.
''' '''
while True: while True:
print "Do you have upload permissions for the '%s' component " \ print "Do you have upload permissions for the '%s' component " \
"or the package '%s' in Ubuntu %s?" % (component, name, release) "or the package '%s' in Ubuntu %s?" % (component, name, release)
val = raw_input_exit_on_ctrlc("If in doubt answer 'n'. [y/N]? ") val = raw_input_exit_on_ctrlc("If in doubt answer 'n'. [y/N]? ")
if val.lower() in ('y', 'yes'): if val.lower() in ('y', 'yes'):
return False return False
elif val.lower() in ('n', 'no', ''): elif val.lower() in ('n', 'no', ''):
return True return True
else: else:
print 'Invalid answer' print 'Invalid answer'
def checkExistingReports(srcpkg): def checkExistingReports(srcpkg):
''' '''
Point the user to the URL to manually check for duplicate bug reports. Point the user to the URL to manually check for duplicate bug reports.
''' '''
print 'Please check on https://bugs.launchpad.net/ubuntu/+source/%s/+bugs\n' \ print 'Please check on https://bugs.launchpad.net/ubuntu/+source/%s/+bugs\n' \
'for duplicate sync requests before continuing.' % srcpkg 'for duplicate sync requests before continuing.' % srcpkg
raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ') raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ')
def mailBug(srcpkg, subscribe, status, bugtitle, bugtext, lpinstance, keyid, def mailBug(srcpkg, subscribe, status, bugtitle, bugtext, lpinstance, keyid,
myemailaddr, mailserver_host, mailserver_port, mailserver_user, myemailaddr, mailserver_host, mailserver_port, mailserver_user,
mailserver_pass): mailserver_pass):
''' '''
Submit the sync request per email. Submit the sync request per email.
''' '''
if lpinstance == 'production': if lpinstance == 'production':
to = 'new@bugs.launchpad.net' to = 'new@bugs.launchpad.net'
elif lpinstance == 'staging': elif lpinstance == 'staging':
to = 'new@bugs.staging.launchpad.net' to = 'new@bugs.staging.launchpad.net'
else: else:
print >> sys.stderr, 'Error: Unknown launchpad instance:', lpinstance print >> sys.stderr, 'Error: Unknown launchpad instance:', lpinstance
sys.exit(1) sys.exit(1)
# generate mailbody # generate mailbody
if srcpkg: if srcpkg:
mailbody = ' affects ubuntu/%s\n' % srcpkg mailbody = ' affects ubuntu/%s\n' % srcpkg
else: else:
mailbody = ' affects ubuntu\n' mailbody = ' affects ubuntu\n'
mailbody += '''\ mailbody += '''\
status %s status %s
importance wishlist importance wishlist
subscribe %s subscribe %s
@ -158,24 +158,24 @@ def mailBug(srcpkg, subscribe, status, bugtitle, bugtext, lpinstance, keyid,
%s''' % (status, subscribe, bugtext) %s''' % (status, subscribe, bugtext)
# prepare sign command # prepare sign command
gpg_command = None gpg_command = None
for cmd in ('gpg', 'gpg2', 'gnome-gpg'): for cmd in ('gpg', 'gpg2', 'gnome-gpg'):
if os.access('/usr/bin/%s' % cmd, os.X_OK): if os.access('/usr/bin/%s' % cmd, os.X_OK):
gpg_command = [cmd] gpg_command = [cmd]
assert gpg_command # TODO: catch exception and produce error message assert gpg_command # TODO: catch exception and produce error message
gpg_command.append('--clearsign') gpg_command.append('--clearsign')
if keyid: if keyid:
gpg_command.extend(('-u', keyid)) gpg_command.extend(('-u', keyid))
# sign the mail body # sign the mail body
gpg = subprocess.Popen(gpg_command, stdin = subprocess.PIPE, stdout = subprocess.PIPE) gpg = subprocess.Popen(gpg_command, stdin = subprocess.PIPE, stdout = subprocess.PIPE)
signed_report = gpg.communicate(mailbody.encode('utf-8'))[0].decode('utf-8') signed_report = gpg.communicate(mailbody.encode('utf-8'))[0].decode('utf-8')
assert gpg.returncode == 0 assert gpg.returncode == 0
# generate email # generate email
mail = u'''\ mail = u'''\
From: %s From: %s
To: %s To: %s
Subject: %s Subject: %s
@ -183,30 +183,30 @@ Content-Type: text/plain; charset=UTF-8
%s''' % (myemailaddr, to, bugtitle, signed_report) %s''' % (myemailaddr, to, bugtitle, signed_report)
print 'The final report is:\n%s' % mail print 'The final report is:\n%s' % mail
raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ') raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ')
# connect to the server # connect to the server
try: try:
print 'Connecting to %s:%s ...' % (mailserver_host, mailserver_port) print 'Connecting to %s:%s ...' % (mailserver_host, mailserver_port)
s = smtplib.SMTP(mailserver_host, mailserver_port) s = smtplib.SMTP(mailserver_host, mailserver_port)
except socket.error, s: except socket.error, s:
print >> sys.stderr, 'E: Could not connect to %s:%s: %s (%i)' % \ print >> sys.stderr, 'E: Could not connect to %s:%s: %s (%i)' % \
(mailserver_host, mailserver_port, s[1], s[0]) (mailserver_host, mailserver_port, s[1], s[0])
return return
if mailserver_user and mailserver_pass: if mailserver_user and mailserver_pass:
try: try:
s.login(mailserver_user, mailserver_pass) s.login(mailserver_user, mailserver_pass)
except smtplib.SMTPAuthenticationError: except smtplib.SMTPAuthenticationError:
print >> sys.stderr, 'E: Error authenticating to the server: invalid username and password.' print >> sys.stderr, 'E: Error authenticating to the server: invalid username and password.'
s.quit() s.quit()
return return
except: except:
print >> sys.stderr, 'E: Unknown SMTP error.' print >> sys.stderr, 'E: Unknown SMTP error.'
s.quit() s.quit()
return return
s.sendmail(myemailaddr, to, mail.encode('utf-8')) s.sendmail(myemailaddr, to, mail.encode('utf-8'))
s.quit() s.quit()
print 'Sync request mailed.' print 'Sync request mailed.'