From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from <gentoo-commits+bounces-340754-garchives=archives.gentoo.org@lists.gentoo.org>) id 1QGIn3-0003yy-SK for garchives@archives.gentoo.org; Sat, 30 Apr 2011 22:37:30 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id D390B1C043; Sat, 30 Apr 2011 22:37:22 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id 928091C043 for <gentoo-commits@lists.gentoo.org>; Sat, 30 Apr 2011 22:37:22 +0000 (UTC) Received: from pelican.gentoo.org (unknown [66.219.59.40]) (using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id E2DC51B402B for <gentoo-commits@lists.gentoo.org>; Sat, 30 Apr 2011 22:37:21 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by pelican.gentoo.org (Postfix) with ESMTP id 3FB5F80507 for <gentoo-commits@lists.gentoo.org>; Sat, 30 Apr 2011 22:37:21 +0000 (UTC) From: "Brian Dolbec" <brian.dolbec@gmail.com> To: gentoo-commits@lists.gentoo.org Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Brian Dolbec" <brian.dolbec@gmail.com> Message-ID: <fcd35daad6e84fdaab69f4bd0c969b80daee590d.dol-sen@gentoo> Subject: [gentoo-commits] proj/layman:master commit in: layman/ X-VCS-Repository: proj/layman X-VCS-Files: layman/api.py layman/db.py X-VCS-Directories: layman/ X-VCS-Committer: dol-sen X-VCS-Committer-Name: Brian Dolbec X-VCS-Revision: fcd35daad6e84fdaab69f4bd0c969b80daee590d Date: Sat, 30 Apr 2011 22:37:21 +0000 (UTC) Precedence: bulk List-Post: <mailto:gentoo-commits@lists.gentoo.org> List-Help: <mailto:gentoo-commits+help@lists.gentoo.org> List-Unsubscribe: <mailto:gentoo-commits+unsubscribe@lists.gentoo.org> List-Subscribe: <mailto:gentoo-commits+subscribe@lists.gentoo.org> List-Id: Gentoo Linux mail <gentoo-commits.gentoo.org> X-BeenThere: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: quoted-printable X-Archives-Salt: X-Archives-Hash: c5e82e12bf842e0257da9a33f4a3c2d6 commit: fcd35daad6e84fdaab69f4bd0c969b80daee590d Author: dol-sen <brian.dolbec <AT> gmail <DOT> com> AuthorDate: Sat Apr 30 22:36:54 2011 +0000 Commit: Brian Dolbec <brian.dolbec <AT> gmail <DOT> com> CommitDate: Sat Apr 30 22:36:54 2011 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=3Dproj/layman.git;a=3D= commit;h=3Dfcd35daa Add checks and code to fetch the new list using 'If-Modified-Since' proto= col. adds saving the 'last-modified' date of the same filename with a .timesta= mp extension. --- layman/api.py | 39 +++++++++++++++------------ layman/db.py | 80 ++++++++++++++++++++++++++++++++++++++++++++-------= ------ 2 files changed, 84 insertions(+), 35 deletions(-) diff --git a/layman/api.py b/layman/api.py index cbb9d99..b71dd72 100644 --- a/layman/api.py +++ b/layman/api.py @@ -120,7 +120,7 @@ class LaymanAPI(object): self._error(ERROR_INTERNAL_ERROR, "Failed to disable repository '"+ovl+"':\n"+str(= e)) results.append(False) - self.get_installed(reload=3DTrue) + self.get_installed(dbreload=3DTrue) if False in results: return False return True @@ -151,7 +151,7 @@ class LaymanAPI(object): self._error(ERROR_INTERNAL_ERROR, "Failed to enable repository '"+ovl+"' : "+str(e= )) results.append(False) - self.get_installed(reload=3DTrue) + self.get_installed(dbreload=3DTrue) if False in results: return False return True @@ -373,47 +373,52 @@ class LaymanAPI(object): def fetch_remote_list(self): """Fetches the latest remote overlay list""" try: - self._get_remote_db().cache() + dbreload =3D self._get_remote_db().cache() + self.output.debug( + 'LaymanAPI.fetch_remote_list(); cache updated =3D %s' + % str(dbreload),8) except Exception as error: self._error('Failed to fetch overlay list!\n Original Error = was: ' + str(error)) return False - self.get_available(reload=3DTrue) + self.get_available(dbreload) return True =20 =20 - def get_available(self, reload=3DFalse): + def get_available(self, dbreload=3DFalse): """returns the list of available overlays""" - if self._available_ids is None or reload: - self._available_ids =3D self._get_remote_db(reload).list_ids= () + self.output.info('LaymanAPI.get_available() dbreload =3D %s' + % str(dbreload)) + if self._available_ids is None or dbreload: + self._available_ids =3D self._get_remote_db(dbreload).list_i= ds() return self._available_ids[:] or ['None'] =20 =20 - def get_installed(self, reload=3DFalse): + def get_installed(self, dbreload=3DFalse): """returns the list of installed overlays""" - if self._installed_ids is None or reload: - self._installed_ids =3D self._get_installed_db(reload).list_= ids() + if self._installed_ids is None or dbreload: + self._installed_ids =3D self._get_installed_db(dbreload).lis= t_ids() return self._installed_ids[:] =20 =20 - def _get_installed_db(self, reload=3DFalse): + def _get_installed_db(self, dbreload=3DFalse): """returns the list of installed overlays""" - if not self._installed_db or reload: + if not self._installed_db or dbreload: self._installed_db =3D DB(self.config) return self._installed_db =20 =20 - def _get_remote_db(self, reload=3DFalse): + def _get_remote_db(self, dbreload=3DFalse): """returns the list of installed overlays""" - if self._available_db is None or reload: + if self._available_db is None or dbreload: self._available_db =3D RemoteDB(self.config) return self._available_db =20 =20 def reload(self): """reloads the installed and remote db's to the data on disk""" - result =3D self.get_available(reload=3DTrue) - result =3D self.get_installed(reload=3DTrue) + result =3D self.get_available(dbreload=3DTrue) + result =3D self.get_installed(dbreload=3DTrue) =20 =20 def _error(self, message): @@ -423,7 +428,7 @@ class LaymanAPI(object): """ self._error_messages.append(message) if self.report_errors: - print(message, file=3Dstderr) + print(message, file=3Dself.config['stderr']) =20 =20 def get_errors(self): diff --git a/layman/db.py b/layman/db.py index d078e46..3498223 100644 --- a/layman/db.py +++ b/layman/db.py @@ -24,7 +24,9 @@ __version__ =3D "$Id: db.py 309 2007-04-09 16:23:38Z wr= obel $" # #-----------------------------------------------------------------------= -------- =20 -import os, os.path, urllib2, hashlib +import os, os.path +import urllib2 +import hashlib =20 from layman.utils import path, delete_empty_directory from layman.dbbase import DbBase @@ -243,7 +245,7 @@ class RemoteDB(DbBase): =20 self.urls =3D [i.strip() for i in config['overlays'].split('\n'= ) if len(i)] =20 - paths =3D [self.path(i) for i in self.urls] + paths =3D [self.filepath(i) + '.xml' for i in self.urls] =20 if config['nocheck']: ignore =3D 2 @@ -283,22 +285,45 @@ class RemoteDB(DbBase): >>> a.overlays.keys() [u'wrobel', u'wrobel-stable'] ''' + has_updates =3D False for url in self.urls: =20 - mpath =3D self.path(url) + filepath =3D self.filepath(url) + mpath =3D filepath + '.xml' + tpath =3D filepath + '.timestamp' =20 - # Check for sufficient privileges - if os.path.exists(mpath) and not os.access(mpath, os.W_OK): - self.output.warn('You do not have permission to update t= he cache (%s).' % mpath) - import getpass - if getpass.getuser() !=3D 'root': - self.output.warn('Hint: You are not root.\n') + # check when the cache was last updated + # and don't re-fetch it unless it has changed + request =3D urllib2.Request(url) + opener =3D urllib2.build_opener() + opener.addheaders =3D [('User-Agent', 'Layman-2.0-git')] + + if os.path.exists(tpath): + with open(tpath,'r') as previous: + last_time =3D previous.read() + request.add_header('If-Modified-Since', last_time) + + if not self.check_path([mpath]): continue =20 try: - + connection =3D opener.open(request) + timestamp =3D connection.headers['last-modified'] + except urllib2.HTTPError as e: + if e.getcode() =3D=3D 304: + self.output.info('Remote list already up to date: %s= ' + % url) + else: + self.output.info('RemoteDB.cache(); HTTPError was:\n= %s' + % str(e)) + continue + except IOError as error: + self.output.warn('Failed to update the overlay list from= : ' + + url + '\nError was:\n' + str(error)) + else: + self.output.info('Fetching new list...') # Fetch the remote list - olist =3D urllib2.urlopen(url).read() + olist =3D connection.read() =20 # Create our storage directory if it is missing if not os.path.exists(os.path.dirname(mpath)): @@ -326,24 +351,43 @@ class RemoteDB(DbBase): out_file.write(olist) out_file.close() =20 + out_file =3D open(tpath, 'w') + out_file.write(timestamp) + out_file.close() + + has_updates =3D True + except Exception as error: raise IOError('Failed to temporarily cache overlays = list in' ' ' + mpath + '\nError was:\n' + str(e= rror)) + return has_updates =20 =20 - except IOError as error: - self.output.warn('Failed to update the overlay list from= : ' - + url + '\nError was:\n' + str(error)) - - def path(self, url): + def filepath(self, url): '''Return a unique file name for the url.''' =20 base =3D self.config['cache'] =20 self.output.debug('Generating cache path.', 6) =20 - return base + '_' + hashlib.md5(url).hexdigest() + '.xml' - + return base + '_' + hashlib.md5(url).hexdigest() + + + def check_path(self, paths, hint=3DTrue): + '''Check for sufficient privileges''' + self.output.debug('RemoteDB.check_path; paths =3D ' + str(paths)= , 8) + is_ok =3D 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).' + % mpath) + import getpass + if getpass.getuser() !=3D 'root': + self.output.warn('Hint: You are not root.\n') + is_ok =3D False + return is_ok =20 #=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D #