#!/usr/bin/python

import os, os.path, sys, urllib, subprocess, smtplib

changelog = 1

def cur_version_component(sourcepkg, release):
    madison = subprocess.Popen(['apt-cache', 'madison', sourcepkg], stdout=subprocess.PIPE)
    out = madison.communicate()[0]
    assert (madison.returncode == 0)

    for l in out.splitlines():
	(pkg, version, aptsrc) = l.split('|')
	if aptsrc.endswith('Sources') and aptsrc.find(release) > 0:
	    component = ''
	    for w in aptsrc.split():
		if w.startswith(release):
		    component = w.split('/')[1]
	    assert component != ''
	    return (version.strip(), component)

    raise Exception('apt-cache madison does not contain %s/%s' % (sourcepkg, release))

def debian_changelog(sourcepkg, version):
    '''Return the Debian changelog from the latest up to the given version
    (exclusive).'''

    ch = ''
    for l in urllib.urlopen('http://changelogs.debian.net/' + sourcepkg):
	if l.startswith(sourcepkg) and l.find(version + ')') > 0:
	    break
	ch += l

    return ch

#
# entry point
#

if len(sys.argv) < 3:
    print '''Usage: requestsync <source package> <target release> [basever]

In some cases, the base version (fork point from Debian) cannot be determined
automatically, and you'll get a complete Debian changelog. Specify the correct
base version in that case.'''
    sys.exit (1)

(srcpkg, release) = sys.argv[1:3]
force_base_ver = None
if len(sys.argv) >= 4:
    force_base_ver = sys.argv[3]
(cur_ver, component) = cur_version_component(srcpkg, release)

# TODO: figure this out from packages.qa.debian.org; changelogs.d.n only works
# for main ATM anyway, though
debiancomponent = 'main'

# generate bug report
report = ''

report += ''' affects ubuntu/%s
 status confirmed
 subscribe ubuntu-archive

''' % srcpkg

report += 'Please sync %s (%s) from Debian unstable (%s).\n' % (srcpkg, component, debiancomponent)

ubuntuchanges = False
base_ver = cur_ver
uidx = base_ver.find('ubuntu')
if uidx > 0:
    base_ver = base_ver[:uidx]
    ubuntuchanges = True

if changelog:
    uidx = base_ver.find('build')
    if uidx > 0:
	base_ver = base_ver[:uidx]

    if force_base_ver:
	base_ver = force_base_ver
    
    report += '\nChangelog since current %s version %s:\n\n' % (release, cur_ver)
    report += debian_changelog(srcpkg, base_ver) + '\n'

# sign it
sign_command = 'gpg'
if os.access('/usr/bin/gnome-gpg', os.X_OK):
    sign_command = 'gnome-gpg'

gpg = subprocess.Popen([sign_command, '--clearsign'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
signed_report = gpg.communicate(report)[0]
assert gpg.returncode == 0

# generate email
myemailaddr = os.getenv('DEBEMAIL')
assert myemailaddr
to = 'new@bugs.launchpad.net'

mail = '''From: %s
To: %s
Subject: Please sync %s (%s) from Debian unstable (%s)

%s''' % (myemailaddr, to, srcpkg, component, debiancomponent, signed_report)

print mail

print 'Press enter to file this bug, Control-C to abort'
sys.stdin.readline()

s = smtplib.SMTP('fiordland.ubuntu.com')
s.sendmail(myemailaddr, to, mail)
s.quit()

if ubuntuchanges:
    print 'You need to write a followup bug comment with some short explanation of the Ubuntu delta and why it can be dropped.'

