diff options
Diffstat (limited to 'layman/dbbase.py')
-rw-r--r-- | layman/dbbase.py | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/layman/dbbase.py b/layman/dbbase.py new file mode 100644 index 0000000..c5cd8a5 --- /dev/null +++ b/layman/dbbase.py @@ -0,0 +1,233 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +################################################################################# +# LAYMAN OVERLAY HANDLER +################################################################################# +# File: overlay.py +# +# Access to an xml list of overlays +# +# Copyright: +# (c) 2005 - 2009 Gunnar Wrobel +# (c) 2009 Sebastian Pipping +# (c) 2009 Christian Groschupp +# Distributed under the terms of the GNU General Public License v2 +# +# Author(s): +# Gunnar Wrobel <wrobel@gentoo.org> +# Sebastian Pipping <sebastian@pipping.org> +# Christian Groschupp <christian@groschupp.org> +# +'''Main handler for overlays.''' + +__version__ = "$Id: overlay.py 273 2006-12-30 15:54:50Z wrobel $" + +#=============================================================================== +# +# Dependencies +# +#------------------------------------------------------------------------------- + +import sys, codecs, os, os.path +import xml.etree.ElementTree as ET # Python 2.5 + +from layman.debug import OUT +from layman.utils import indent +from layman.overlays.overlay import Overlay + +#=============================================================================== +# +# Class UnknownOverlayException +# +#------------------------------------------------------------------------------- + +class UnknownOverlayException(Exception): + def __init__(self, repo_name): + message = 'Overlay "%s" does not exist.' % repo_name + super(UnknownOverlayException, self).__init__(message) + + +#=============================================================================== +# +# Class DbBase +# +#------------------------------------------------------------------------------- + +class DbBase: + ''' Handle a list of overlays.''' + + def __init__(self, paths, config, ignore = 0, quiet = False): + + self.config = config + self.quiet = quiet + self.paths = paths + self.ignore = ignore + + self.overlays = {} + + OUT.debug('Initializing overlay list handler', 8) + + for path in self.paths: + if os.path.exists(path): + self.read_file(path) + + def __eq__(self, other): + for key in set(self.overlays.keys() + other.overlays.keys()): + if self.overlays[key] != other.overlays[key]: + return False + return True + + def __ne__(self, other): + return not self.__eq__(other) + + def read_file(self, path): + '''Read the overlay definition file.''' + + try: + document = open(path, 'r').read() + + except Exception, error: + raise IOError('Failed to read the overlay list at ("' + + path + '")!\nError was:\n' + str(error)) + + self.read(document) + + def read(self, text): + ''' + Read an xml list of overlays. + + >>> here = os.path.dirname(os.path.realpath(__file__)) + >>> config = {'svn_command': '/usr/bin/svn', 'rsync_command':'/usr/bin/rsync'} + >>> a = DbBase([here + '/tests/testfiles/global-overlays.xml', ], config) + >>> a.overlays.keys() + [u'wrobel', u'wrobel-stable'] + + >>> list(a.overlays['wrobel-stable'].source_uris()) + [u'rsync://gunnarwrobel.de/wrobel-stable'] + ''' + document = ET.fromstring(text) + overlays = document.findall('overlay') + \ + document.findall('repo') + + for overlay in overlays: + OUT.debug('Parsing overlay entry', 8) + try: + ovl = Overlay(overlay, self.config, self.ignore, self.quiet) + self.overlays[ovl.name] = ovl + except Exception, error: + OUT.warn(str(error), 3) + + + def write(self, path): + ''' + Write the list of overlays to a file. + + >>> write = os.tmpnam() + >>> here = os.path.dirname(os.path.realpath(__file__)) + >>> config = {'svn_command': '/usr/bin/svn', 'rsync_command':'/usr/bin/rsync'} + >>> a = DbBase([here + '/tests/testfiles/global-overlays.xml', ], config) + >>> b = DbBase([write,], dict()) + >>> b.overlays['wrobel-stable'] = a.overlays['wrobel-stable'] + >>> b.write(write) + >>> c = DbBase([write,], dict()) + >>> c.overlays.keys() + [u'wrobel-stable'] + + >>> os.unlink(write) + ''' + + xml = ET.Element('repositories', version="1.0") + xml[:] = [e.to_xml() for e in self.overlays.values()] + indent(xml) + tree = ET.ElementTree(xml) + try: + f = open(path, 'w') + f.write("""\ +<?xml version="1.0" encoding="UTF-8"?> +""") + tree.write(f, encoding='utf-8') + f.close() + except Exception, error: + raise Exception('Failed to write to local overlays file: ' + + path + '\nError was:\n' + str(error)) + + def select(self, overlay): + ''' + Select an overlay from the list. + + >>> here = os.path.dirname(os.path.realpath(__file__)) + >>> config = {'svn_command': '/usr/bin/svn', 'rsync_command':'/usr/bin/rsync'} + >>> a = DbBase([here + '/tests/testfiles/global-overlays.xml', ], config) + >>> list(a.select('wrobel-stable').source_uris()) + [u'rsync://gunnarwrobel.de/wrobel-stable'] + ''' + if not overlay in self.overlays.keys(): + raise UnknownOverlayException(overlay) + return self.overlays[overlay] + + def list(self, verbose = False, width = 0): + ''' + List all overlays. + + >>> here = os.path.dirname(os.path.realpath(__file__)) + >>> config = {'svn_command': '/usr/bin/svn', 'rsync_command':'/usr/bin/rsync'} + >>> a = DbBase([here + '/tests/testfiles/global-overlays.xml', ], config) + >>> for i in a.list(True): + ... print i[0] + wrobel + ~~~~~~ + Source : https://overlays.gentoo.org/svn/dev/wrobel + Contact : nobody@gentoo.org + Type : Subversion; Priority: 10 + Quality : experimental + <BLANKLINE> + Description: + Test + <BLANKLINE> + wrobel-stable + ~~~~~~~~~~~~~ + Source : rsync://gunnarwrobel.de/wrobel-stable + Contact : nobody@gentoo.org + Type : Rsync; Priority: 50 + Quality : experimental + <BLANKLINE> + Description: + A collection of ebuilds from Gunnar Wrobel [wrobel@gentoo.org]. + <BLANKLINE> + + >>> for i in a.list(False, 80): + ... print i[0] + wrobel [Subversion] (https://o.g.o/svn/dev/wrobel ) + wrobel-stable [Rsync ] (rsync://gunnarwrobel.de/wrobel-stable) + ''' + result = [] + + for name, overlay in self.overlays.items(): + + if verbose: + result.append((str(overlay), overlay.is_supported(), + overlay.is_official())) + else: + result.append((overlay.short_list(width), overlay.is_supported(), + overlay.is_official())) + + result = sorted(result) + + return result + +#=============================================================================== +# +# Testing +# +#------------------------------------------------------------------------------- + +if __name__ == '__main__': + import doctest, sys + + # Ignore warnings here. We are just testing + from warnings import filterwarnings, resetwarnings + filterwarnings('ignore') + + doctest.testmod(sys.modules[__name__]) + + resetwarnings() |