#!/usr/bin/python # # pull-lp-source -- pull a source package from Launchpad # Basic usage: pull-lp-source [] # # Copyright (C) 2008, Iain Lane , # 2010-2011, Stefano Rivera # # ################################################################## # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # See file /usr/share/common-licenses/GPL for more details. # # ################################################################## import json import os import sys import urllib2 from optparse import OptionParser from distro_info import UbuntuDistroInfo, DistroDataOutdated from ubuntutools.archive import UbuntuSourcePackage, DownloadError from ubuntutools.config import UDTConfig from ubuntutools.lp.lpapicache import Distribution, Launchpad from ubuntutools.lp.udtexceptions import (SeriesNotFoundException, PackageNotFoundException, PocketDoesNotExistError) from ubuntutools.logger import Logger from ubuntutools.misc import split_release_pocket def source_package_for(binary, release): """Query DDE to find the source package for a particular binary Should really do this with LP, but it's not possible LP: #597041 """ url = ('http://dde.debian.net/dde/q/udd/dist/d:ubuntu/r:%s/p:%s/?t=json' % (release, binary)) data = None try: data = json.load(urllib2.urlopen(url))['r'] except urllib2.URLError, e: Logger.error('Unable to retrieve package information from DDE: ' '%s (%s)', url, str(e)) except ValueError, e: Logger.error('Unable to parse JSON response from DDE: ' '%s (%s)', url, str(e)) if not data: return None return data[0]['source'] def main(): usage = "Usage: %prog [release|version]" opt_parser = OptionParser(usage) opt_parser.add_option('-d', '--download-only', dest='download_only', default=False, action='store_true', help="Do not extract the source package") opt_parser.add_option('-m', '--mirror', metavar='UBUNTU_MIRROR', dest='ubuntu_mirror', help='Preferred Ubuntu mirror (default: Launchpad)') opt_parser.add_option('--no-conf', dest='no_conf', default=False, action='store_true', help="Don't read config files or environment " "variables") (options, args) = opt_parser.parse_args() if not args: opt_parser.error("Must specify package name") config = UDTConfig(options.no_conf) if options.ubuntu_mirror is None: options.ubuntu_mirror = config.get_value('UBUNTU_MIRROR') # Login anonymously to LP Launchpad.login_anonymously() package = str(args[0]).lower() ubuntu_info = UbuntuDistroInfo() if len(args) > 1: # Custom distribution specified. version = str(args[1]) else: try: version = os.getenv('DIST') or ubuntu_info.devel() except DistroDataOutdated, e: Logger.warn("%s\nOr specify a distribution.", e) sys.exit(1) component = None # Release, not package version number: release = None pocket = None try: (release, pocket) = split_release_pocket(version, default=None) except PocketDoesNotExistError, e: pass if release in ubuntu_info.all: archive = Distribution('ubuntu').getArchive() try: spph = archive.getSourcePackage(package, release, pocket) except SeriesNotFoundException, e: Logger.error(str(e)) sys.exit(1) except PackageNotFoundException, e: source_package = source_package_for(package, release) if source_package is not None and source_package != package: try: spph = archive.getSourcePackage(source_package, release, pocket) package = source_package except PackageNotFoundException: Logger.error(str(e)) sys.exit(1) else: Logger.error(str(e)) sys.exit(1) version = spph.getVersion() component = spph.getComponent() Logger.normal('Downloading %s version %s', package, version) srcpkg = UbuntuSourcePackage(package, version, component=component, mirrors=[options.ubuntu_mirror]) try: srcpkg.pull() except DownloadError, e: Logger.error('Failed to download: %s', str(e)) sys.exit(1) if not options.download_only: srcpkg.unpack() if __name__ == '__main__': try: main() except KeyboardInterrupt: Logger.normal('User abort.')