#!/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 # Sebastian Pipping # Christian Groschupp # '''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 Overlays # #------------------------------------------------------------------------------- class Overlays: ''' 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 = Overlays([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 = Overlays([here + '/tests/testfiles/global-overlays.xml', ], config) >>> b = Overlays([write,], dict()) >>> b.overlays['wrobel-stable'] = a.overlays['wrobel-stable'] >>> b.write(write) >>> c = Overlays([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("""\ """) 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 = Overlays([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 Exception('No overlay "%s" in database' % 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 = Overlays([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 Description: Test wrobel-stable ~~~~~~~~~~~~~ Source : rsync://gunnarwrobel.de/wrobel-stable Contact : nobody@gentoo.org Type : Rsync; Priority: 50 Quality : experimental Description: A collection of ebuilds from Gunnar Wrobel [wrobel@gentoo.org]. >>> 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()