diff options
Diffstat (limited to 'layman/db.py')
-rw-r--r-- | layman/db.py | 215 |
1 files changed, 1 insertions, 214 deletions
diff --git a/layman/db.py b/layman/db.py index e2d740c..8dc968e 100644 --- a/layman/db.py +++ b/layman/db.py @@ -27,17 +27,11 @@ __version__ = "$Id: db.py 309 2007-04-09 16:23:38Z wrobel $" #------------------------------------------------------------------------------- import os, os.path -import sys -import urllib2 -import hashlib -from layman.utils import path, delete_empty_directory, encoder +from layman.utils import path, delete_empty_directory from layman.dbbase import DbBase from layman.makeconf import MakeConf -from layman.version import VERSION -from layman.compatibility import fileopen -#from layman.debug import OUT #=============================================================================== # @@ -238,213 +232,6 @@ class DB(DbBase): '" returned status ' + str(result) + '!' + '\ndb.sync()') -#=============================================================================== -# -# Class RemoteDB -# -#------------------------------------------------------------------------------- - -class RemoteDB(DbBase): - '''Handles fetching the remote overlay list.''' - - def __init__(self, config, ignore_init_read_errors=False): - - self.config = config - self.output = config['output'] - - self.proxies = {} - - if config['proxy']: - self.proxies['http'] = config['proxy'] - elif os.getenv('http_proxy'): - self.proxies['http'] = os.getenv('http_proxy') - - if self.proxies: - proxy_handler = urllib2.ProxyHandler(self.proxies) - opener = urllib2.build_opener(proxy_handler) - urllib2.install_opener(opener) - - self.urls = [i.strip() for i in config['overlays'].split('\n') if len(i)] - - paths = [self.filepath(i) + '.xml' for i in self.urls] - - if config['nocheck']: - ignore = 2 - else: - ignore = 0 - - #quiet = int(config['quietness']) < 3 - - DbBase.__init__(self, config, paths=paths, ignore=ignore, - ignore_init_read_errors=ignore_init_read_errors) - - # overrider - def _broken_catalog_hint(self): - return 'Try running "sudo layman -f" to re-fetch that file' - - def cache(self): - ''' - Copy the remote overlay list to the local cache. - - >>> import tempfile - >>> here = os.path.dirname(os.path.realpath(__file__)) - >>> tmpdir = tempfile.mkdtemp(prefix="laymantmp_") - >>> cache = os.path.join(tmpdir, 'cache') - >>> myoptions = {'overlays' : - ... ['file://' + here + '/tests/testfiles/global-overlays.xml'], - ... 'cache' : cache, - ... 'nocheck' : 'yes', - ... 'proxy' : None} - >>> from layman.config import OptionConfig - >>> config = OptionConfig(myoptions) - >>> config.set_option('quietness', 3) - >>> a = RemoteDB(config) - >>> a.cache() - (True, True) - >>> b = fileopen(a.filepath(config['overlays'])+'.xml') - >>> b.readlines()[24] - ' A collection of ebuilds from Gunnar Wrobel [wrobel@gentoo.org].\\n' - - >>> b.close() - >>> os.unlink(a.filepath(config['overlays'])+'.xml') - - >>> a.overlays.keys() - [u'wrobel', u'wrobel-stable'] - - >>> import shutil - >>> shutil.rmtree(tmpdir) - ''' - has_updates = False - # succeeded reset when a failure is detected - succeeded = True - for url in self.urls: - - filepath = self.filepath(url) - mpath = filepath + '.xml' - tpath = filepath + '.timestamp' - - # check when the cache was last updated - # and don't re-fetch it unless it has changed - request = urllib2.Request(url) - opener = urllib2.build_opener() - opener.addheaders = [('User-Agent', 'Layman-' + VERSION)] - - if os.path.exists(tpath): - with fileopen(tpath,'r') as previous: - timestamp = previous.read() - request.add_header('If-Modified-Since', timestamp) - - if not self.check_path([mpath]): - continue - - try: - connection = opener.open(request) - # py2, py3 compatibility, since only py2 returns keys as lower() - headers = dict((x.lower(), x) for x in connection.headers.keys()) - if 'last-modified' in headers: - timestamp = connection.headers[headers['last-modified']] - elif 'date' in headers: - timestamp = connection.headers[headers['date']] - else: - timestamp = None - except urllib2.HTTPError, e: - if e.code == 304: - self.output.info('Remote list already up to date: %s' - % url, 4) - self.output.info('Last-modified: %s' % timestamp, 4) - else: - self.output.error('RemoteDB.cache(); HTTPError was:\n' - 'url: %s\n%s' - % (url, str(e))) - succeeded = False - continue - except IOError, error: - self.output.error('RemoteDB.cache(); Failed to update the ' - 'overlay list from: %s\nIOError was:%s\n' - % (url, str(error))) - succeeded = False - continue - else: - if url.startswith('file://'): - quieter = 1 - else: - quieter = 0 - self.output.info('Fetching new list... %s' % url, 4 + quieter) - if timestamp is not None: - self.output.info('Last-modified: %s' % timestamp, 4 + quieter) - # Fetch the remote list - olist = connection.read() - - # Create our storage directory if it is missing - if not os.path.exists(os.path.dirname(mpath)): - try: - os.makedirs(os.path.dirname(mpath)) - except OSError, error: - raise OSError('Failed to create layman storage direct' - + 'ory ' + os.path.dirname(mpath) + '\n' - + 'Error was:' + str(error)) - - # Before we overwrite the old cache, check that the downloaded - # file is intact and can be parsed - try: - self.read(olist, origin=url) - except Exception, error: - raise IOError('Failed to parse the overlays list fetched fr' - 'om ' + url + '\nThis means that the download' - 'ed file is somehow corrupt or there was a pr' - 'oblem with the webserver. Check the content ' - 'of the file. Error was:\n' + str(error)) - - # the folowing is neded for py3 only - if sys.hexversion >= 0x3000000 and hasattr(olist, 'decode'): - olist = olist.decode("UTF-8") - # Ok, now we can overwrite the old cache - try: - out_file = fileopen(mpath, 'w') - out_file.write(olist) - out_file.close() - - if timestamp is not None: - out_file = fileopen(tpath, 'w') - out_file.write(str(timestamp)) - out_file.close() - - has_updates = True - - except Exception, error: - raise IOError('Failed to temporarily cache overlays list in' - ' ' + mpath + '\nError was:\n' + str(error)) - self.output.debug("RemoteDB.cache() returning: has_updates, succeeded" - " %s, %s" % (str(has_updates), str(succeeded)), 4) - return has_updates, succeeded - - - def filepath(self, url): - '''Return a unique file name for the url.''' - - base = self.config['cache'] - - self.output.debug('Generating cache path.', 6) - url_encoded = encoder(url, "UTF-8") - - return base + '_' + hashlib.md5(url_encoded).hexdigest() - - - def check_path(self, paths, hint=True): - '''Check for sufficient privileges''' - self.output.debug('RemoteDB.check_path; paths = ' + str(paths), 8) - is_ok = True - for path in paths: - if os.path.exists(path) and not os.access(path, os.W_OK): - if hint: - self.output.warn( - 'You do not have permission to update the cache (%s).' - % path) - import getpass - if getpass.getuser() != 'root': - self.output.warn('Hint: You are not root.\n') - is_ok = False - return is_ok #=============================================================================== # |