From 40f749c91b691028ae1a6535a1fd91a384ab5b06 Mon Sep 17 00:00:00 2001 From: Michael Bienia Date: Thu, 11 Jun 2009 20:23:30 +0200 Subject: [PATCH] * ubuntutools/lp/lpapiwrapper.py: Rewrite some functions from functions.py in a OO-way and add caching * ubuntutools/lp/functions.py: Use the lpapiwrapper.py where applicable and mark the rewritten functions as deprecated * ubuntutools/lp/udtexceptions.py: Add PocketDoesNotExistException * buildd: Make use of LpApiWrapper --- buildd | 11 ++-- ubuntutools/lp/functions.py | 61 ++++++++---------- ubuntutools/lp/lpapiwrapper.py | 109 +++++++++++++++++++++++++++++++- ubuntutools/lp/udtexceptions.py | 4 ++ 4 files changed, 144 insertions(+), 41 deletions(-) diff --git a/buildd b/buildd index 536eb78..6bd96ef 100755 --- a/buildd +++ b/buildd @@ -25,6 +25,8 @@ import sys from optparse import OptionGroup from optparse import OptionParser +import ubuntutools.lp.udtexceptions +from ubuntutools.lp.lpapiwrapper import LpApiWrapper # Usage. usage = "%prog \n\n" @@ -96,7 +98,6 @@ else: # ubuntu-dev-tools modules # Import here to improve speed perception parsing options for user. import ubuntutools.lp.functions as lp_functions -import ubuntutools.lp.udtexceptions # split release and pocket if '-' in release: @@ -109,16 +110,18 @@ if pocket not in ('Release', 'Security', 'Updates', 'Proposed', 'Backports'): sys.exit(1) # Initialize ubuntu distribution collection. -ubuntuDist = lp_functions.getUbuntuDistribution() +lpapiwrapper = LpApiWrapper() +ubuntuDist = lpapiwrapper.getUbuntuDistribution() # Get main Ubuntu archive. -archive = ubuntuDist.main_archive +archive = lpapiwrapper.getUbuntuArchive() # Check the release exists. try: - release_series = lp_functions.doesUbuntuReleaseExist(release) + release_series = lpapiwrapper.getUbuntuSeries(release) except ubuntutools.lp.udtexceptions.SeriesNotFoundException, e: print e sys.exit(1) # Get list of published sources for package in question. +#sources = lpapiwrapper.getUbuntuSourcePackage(package, release, pocket) sources = lp_functions._ubuntuSourcePackage(package, release, pocket) # Get list of builds for that package. builds = sources.getBuilds() diff --git a/ubuntutools/lp/functions.py b/ubuntutools/lp/functions.py index 1aa5aa6..60036c7 100644 --- a/ubuntutools/lp/functions.py +++ b/ubuntutools/lp/functions.py @@ -21,23 +21,36 @@ import urllib2 import sys from udtexceptions import PackageNotFoundException, SeriesNotFoundException -from lpapiwrapper import Launchpad +from lpapiwrapper import Launchpad, LpApiWrapper import launchpadlib from re import findall +import warnings + +# http://wiki.python.org/moin/PythonDecoratorLibrary#GeneratingDeprecationWarnings +def deprecated(func): + """This is a decorator which can be used to mark functions + as deprecated. It will result in a warning being emitted + when the function is used.""" + def new_func(*args, **kwargs): + warnings.warn("Call to deprecated function %s." % func.__name__, DeprecationWarning, 2) + return func(*args, **kwargs) + new_func.__name__ = func.__name__ + new_func.__doc__ = func.__doc__ + new_func.__dict__.update(func.__dict__) + return new_func + # Singleton to access LP API launchpad = Launchpad +@deprecated def getUbuntuDistribution(): - ubuntu = launchpad.distributions['ubuntu'] - - return ubuntu + return LpApiWrapper.getUbuntuDistribution() +@deprecated def ubuntuDevelopmentSeries(): """ Get the string repr of the current Ubuntu development series """ - - ubuntu = getUbuntuDistribution() - return ubuntu.current_series.name + return LpApiWrapper.getUbuntuDevelopmentSeries().name def doesUbuntuReleaseExist(name): """ Prettier name to use for _ubuntuSeries() """ @@ -49,15 +62,7 @@ def _ubuntuSeries(name): returns the LP API repr of a series passed by name (e.g. 'karmic') If the series is not found: raise SeriesNotFoundException """ - - ubuntu = getUbuntuDistribution() - try: - - return ubuntu.getSeries(name_or_version=name) - - except launchpadlib.errors.HTTPError: - - raise SeriesNotFoundException("Error: Unknown Ubuntu release: '%s'." % name) + return LpApiWrapper.getUbuntuSeries(name) def _ubuntuSourcePackage(package, series, pocket = 'Release'): """ Finds an Ubuntu source package on LP @@ -65,23 +70,8 @@ def _ubuntuSourcePackage(package, series, pocket = 'Release'): returns LP API repr of the source package If the package does not exist: raise PackageNotFoundException """ - - try: - - lpseries = _ubuntuSeries(series) - - ubuntu = launchpad.distributions['ubuntu'] - u_archive = ubuntu.main_archive - - component = u_archive.getPublishedSources(source_name=package, status="Published", - exact_match=True, distro_series=lpseries, pocket = pocket)[0] - - return component - - except IndexError: - - raise PackageNotFoundException("The package %s does not exist in the Ubuntu main archive" % - package) + lpapiwrapper = LpApiWrapper() + return lpapiwrapper.getUbuntuSourcePackage(package, series, pocket) def packageVersion(package, series=ubuntuDevelopmentSeries()): """ Retrieves the version of a given source package in the current @@ -112,8 +102,7 @@ def canUploadPackage(package, series=ubuntuDevelopmentSeries()): If the package does not exist: raise PackageNotFoundException """ - ubuntu = launchpad.distributions['ubuntu'] - u_archive = ubuntu.main_archive + u_archive = LpApiWrapper.getUbuntuArchive() uploaders = u_archive.getUploadersForComponent(component_name=packageComponent(package, series)) @@ -153,7 +142,7 @@ def isPerPackageUploader(package): # Checks if the user has upload privileges for a certain package. me = findall('~(\S+)', '%s' % launchpad.me)[0] - main_archive = launchpad.distributions["ubuntu"].main_archive + main_archive = LpApiWrapper.getUbuntuArchive() try: perms = main_archive.getUploadersForPackage(source_package_name=package) except launchpadlib.errors.HTTPError: diff --git a/ubuntutools/lp/lpapiwrapper.py b/ubuntutools/lp/lpapiwrapper.py index 47e228f..f5b761e 100644 --- a/ubuntutools/lp/lpapiwrapper.py +++ b/ubuntutools/lp/lpapiwrapper.py @@ -25,9 +25,12 @@ #httplib2.debuglevel = 1 import libsupport +from launchpadlib.errors import HTTPError +from launchpadlib.resource import Entry +from udtexceptions import PackageNotFoundException, SeriesNotFoundException, PocketDoesNotExist -# Singleton for Launchpad API access class Launchpad(object): + ''' Singleton for LP API access. ''' __lp = None def __getattr__(self, attr): @@ -38,3 +41,107 @@ class Launchpad(object): def __call__(self): return self Launchpad = Launchpad() + +class LpApiWrapper(object): + ''' + Wrapper around some common used LP API functions used in + ubuntu-dev-tools. + + It also caches LP API objects either as class variables or as + instance variables depending on the expected change of its value. + ''' + _ubuntu = None + _archive = None + _series = dict() + _devel_series = None + + def __init__(self): + self._src_pkg = dict() + + @classmethod + def getUbuntuDistribution(cls): + ''' + Returns the LP representation for Ubuntu. + ''' + if not cls._ubuntu: + cls._ubuntu = Launchpad.distributions['ubuntu'] + return cls._ubuntu + + @classmethod + def getUbuntuArchive(cls): + ''' + Returns the LP representation for the Ubuntu main archive. + ''' + if not cls._archive: + cls._archive = cls.getUbuntuDistribution().main_archive + return cls._archive + + @classmethod + def getUbuntuSeries(cls, name_or_version): + ''' + Returns the LP representation of a series passed by name (e.g. + 'karmic') or version (e.g. '9.10'). + If the series is not found: raise SeriesNotFoundException + ''' + name_or_version = str(name_or_version) + if name_or_version not in cls._series: + try: + series = cls.getUbuntuDistribution().getSeries(name_or_version = name_or_version) + # Cache with name and version + cls._series[series.name] = series + cls._series[series.version] = series + except HTTPError: + raise SeriesNotFoundException("Error: Unknown Ubuntu release: '%s'." % name) + + return cls._series[name_or_version] + + @classmethod + def getUbuntuDevelopmentSeries(cls): + ''' + Returns the LP representation of the current development series of + Ubuntu. + ''' + + if not cls._devel_series: + dev = cls.getUbuntuDistribution().current_series + cls._devel_series = dev + # Cache it in _series if not already done + if dev.name not in cls._series: + cls._series[dev.name] = dev + cls._series[dev.version] = dev + + return cls._devel_series + + def getUbuntuSourcePackage(self, name, series, pocket = 'Release'): + ''' + Finds an Ubuntu source package on LP. + + Returns LP representation of the source package. + If the package does not exist: raise PackageNotFoundException + ''' + + # Check if pocket has a valid value + if pocket not in ('Release', 'Security', 'Updates', 'Proposed', 'Backports'): + raise PocketDoesNotExist("Pocket '%s' does not exist." % pocket) + + # Check if we have already a LP representation of an Ubuntu series or not + if not isinstance(series, Entry): + series = self.getUbuntuSeries(str(series)) + + if (name, series, pocket) not in self._src_pkg: + try: + srcpkg = self.getUbuntuArchive().getPublishedSources( + source_name = name, distro_series = series, pocket = pocket, + status = 'Published', exact_match = True)[0] + self._src_pkg[(name, series, pocket)] = srcpkg + except IndexError: + if pocket == 'Release': + msg = "The package '%s' does not exist in the Ubuntu main archive in '%s'" % \ + (name, series.name) + else: + msg = "The package '%s' does not exist in the Ubuntu main archive in '%s-%s'" % \ + (name, series.name, pocket.lower()) + + raise PackageNotFoundException(msg) + + return self._src_pkg[(name, series, pocket)] diff --git a/ubuntutools/lp/udtexceptions.py b/ubuntutools/lp/udtexceptions.py index e834c4a..9f3bf05 100644 --- a/ubuntutools/lp/udtexceptions.py +++ b/ubuntutools/lp/udtexceptions.py @@ -5,3 +5,7 @@ class PackageNotFoundException(BaseException): class SeriesNotFoundException(BaseException): """ Thrown when a distroseries is not found """ pass + +class PocketDoesNotExist(BaseException): + """ Thrown when a invalid pocket is passed """ + pass