[Python-checkins] python/dist/src/Lib/plat-mac pimp.py, 1.27.4.1,
1.27.4.2
jackjansen at users.sourceforge.net
jackjansen at users.sourceforge.net
Thu Jun 3 09:07:42 EDT 2004
Update of /cvsroot/python/python/dist/src/Lib/plat-mac
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26052
Modified Files:
Tag: release23-maint
pimp.py
Log Message:
Backport of 1.31-1.34:
- Added a downloader using urllib2 in stead of curl, based on code
donated by Kevin Ollivier. This is now the default downloader.
- Added a watcher mechanism, whereby downloaders and unpackers (and,
later builders) can give status feedback to the user. When running
pimp as a command line tool in verbose mode print this output.
- Force option should be applied to a single package, not recursively
to its dependencies. Fixes #733819.
- Don't use "dict" as a variable, it shadows the builtin. Spotted by
Bob Ippolito.
Two issues spotted by Ronald OUssoren:
- there were no accessor functions for the global per-database fields
- packages and their dependencies were installed in order in stead
of in reverse order.
Index: pimp.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/pimp.py,v
retrieving revision 1.27.4.1
retrieving revision 1.27.4.2
diff -C2 -d -r1.27.4.1 -r1.27.4.2
*** pimp.py 28 Feb 2004 23:21:50 -0000 1.27.4.1
--- pimp.py 3 Jun 2004 13:07:39 -0000 1.27.4.2
***************
*** 26,29 ****
--- 26,30 ----
import tempfile
import shutil
+ import time
__all__ = ["PimpPreferences", "PimpDatabase", "PimpPackage", "main",
***************
*** 48,94 ****
def getDefaultDatabase(experimental=False):
! if experimental:
! status = "exp"
! else:
! status = "prod"
!
! major, minor, micro, state, extra = sys.version_info
! pyvers = '%d.%d' % (major, minor)
! if state != 'final':
! pyvers = pyvers + '%s%d' % (state, extra)
!
! longplatform = distutils.util.get_platform()
! osname, release, machine = longplatform.split('-')
! # For some platforms we may want to differentiate between
! # installation types
! if osname == 'darwin':
! if sys.prefix.startswith('/System/Library/Frameworks/Python.framework'):
! osname = 'darwin_apple'
! elif sys.prefix.startswith('/Library/Frameworks/Python.framework'):
! osname = 'darwin_macpython'
! # Otherwise we don't know...
! # Now we try various URLs by playing with the release string.
! # We remove numbers off the end until we find a match.
! rel = release
! while True:
! url = DEFAULT_PIMPDATABASE_FMT % (PIMP_VERSION, status, pyvers, osname, rel, machine)
! try:
! urllib2.urlopen(url)
! except urllib2.HTTPError, arg:
! pass
! else:
! break
! if not rel:
! # We're out of version numbers to try. Use the
! # full release number, this will give a reasonable
! # error message later
! url = DEFAULT_PIMPDATABASE_FMT % (PIMP_VERSION, status, pyvers, osname, release, machine)
! break
! idx = rel.rfind('.')
! if idx < 0:
! rel = ''
! else:
! rel = rel[:idx]
! return url
def _cmd(output, dir, *cmditems):
--- 49,95 ----
def getDefaultDatabase(experimental=False):
! if experimental:
! status = "exp"
! else:
! status = "prod"
!
! major, minor, micro, state, extra = sys.version_info
! pyvers = '%d.%d' % (major, minor)
! if state != 'final':
! pyvers = pyvers + '%s%d' % (state, extra)
!
! longplatform = distutils.util.get_platform()
! osname, release, machine = longplatform.split('-')
! # For some platforms we may want to differentiate between
! # installation types
! if osname == 'darwin':
! if sys.prefix.startswith('/System/Library/Frameworks/Python.framework'):
! osname = 'darwin_apple'
! elif sys.prefix.startswith('/Library/Frameworks/Python.framework'):
! osname = 'darwin_macpython'
! # Otherwise we don't know...
! # Now we try various URLs by playing with the release string.
! # We remove numbers off the end until we find a match.
! rel = release
! while True:
! url = DEFAULT_PIMPDATABASE_FMT % (PIMP_VERSION, status, pyvers, osname, rel, machine)
! try:
! urllib2.urlopen(url)
! except urllib2.HTTPError, arg:
! pass
! else:
! break
! if not rel:
! # We're out of version numbers to try. Use the
! # full release number, this will give a reasonable
! # error message later
! url = DEFAULT_PIMPDATABASE_FMT % (PIMP_VERSION, status, pyvers, osname, release, machine)
! break
! idx = rel.rfind('.')
! if idx < 0:
! rel = ''
! else:
! rel = rel[:idx]
! return url
def _cmd(output, dir, *cmditems):
***************
*** 110,113 ****
--- 111,176 ----
return child.wait()
+ class PimpDownloader:
+ """Abstract base class - Downloader for archives"""
+
+ def __init__(self, argument,
+ dir="",
+ watcher=None):
+ self.argument = argument
+ self._dir = dir
+ self._watcher = watcher
+
+ def download(self, url, filename, output=None):
+ return None
+
+ def update(self, str):
+ if self._watcher:
+ return self._watcher.update(str)
+ return True
+
+ class PimpCurlDownloader(PimpDownloader):
+
+ def download(self, url, filename, output=None):
+ self.update("Downloading %s..." % url)
+ exitstatus = _cmd(output, self._dir,
+ "curl",
+ "--output", filename,
+ url)
+ self.update("Downloading %s: finished" % url)
+ return (not exitstatus)
+
+ class PimpUrllibDownloader(PimpDownloader):
+
+ def download(self, url, filename, output=None):
+ output = open(filename, 'wb')
+ self.update("Downloading %s: opening connection" % url)
+ keepgoing = True
+ download = urllib2.urlopen(url)
+ if download.headers.has_key("content-length"):
+ length = long(download.headers['content-length'])
+ else:
+ length = -1
+
+ data = download.read(4096) #read 4K at a time
+ dlsize = 0
+ lasttime = 0
+ while keepgoing:
+ dlsize = dlsize + len(data)
+ if len(data) == 0:
+ #this is our exit condition
+ break
+ output.write(data)
+ if int(time.time()) != lasttime:
+ # Update at most once per second
+ lasttime = int(time.time())
+ if length == -1:
+ keepgoing = self.update("Downloading %s: %d bytes..." % (url, dlsize))
+ else:
+ keepgoing = self.update("Downloading %s: %d%% (%d bytes)..." % (url, int(100.0*dlsize/length), dlsize))
+ data = download.read(4096)
+ if keepgoing:
+ self.update("Downloading %s: finished" % url)
+ return keepgoing
+
class PimpUnpacker:
"""Abstract base class - Unpacker for archives"""
***************
*** 117,121 ****
def __init__(self, argument,
dir="",
! renames=[]):
self.argument = argument
if renames and not self._can_rename:
--- 180,185 ----
def __init__(self, argument,
dir="",
! renames=[],
! watcher=None):
self.argument = argument
if renames and not self._can_rename:
***************
*** 123,130 ****
--- 187,200 ----
self._dir = dir
self._renames = renames
+ self._watcher = watcher
def unpack(self, archive, output=None, package=None):
return None
+ def update(self, str):
+ if self._watcher:
+ return self._watcher.update(str)
+ return True
+
class PimpCommandUnpacker(PimpUnpacker):
"""Unpack archives by calling a Unix utility"""
***************
*** 174,178 ****
--- 244,250 ----
for member in members:
if member in skip:
+ self.update("Skipping %s" % member.name)
continue
+ self.update("Extracting %s" % member.name)
tf.extract(member, self._dir)
if skip:
***************
*** 215,218 ****
--- 287,294 ----
self.buildDir = buildDir
self.pimpDatabase = pimpDatabase
+ self.watcher = None
+
+ def setWatcher(self, watcher):
+ self.watcher = watcher
def setInstallDir(self, installDir=None):
***************
*** 283,286 ****
--- 359,363 ----
self._packages = []
self.preferences = prefs
+ self._url = ""
self._urllist = []
self._version = ""
***************
*** 288,291 ****
--- 365,374 ----
self._description = ""
+ # Accessor functions
+ def url(self): return self._url
+ def version(self): return self._version
+ def maintainer(self): return self._maintainer
+ def description(self): return self._description
+
def close(self):
"""Clean up"""
***************
*** 302,314 ****
self._urllist.append(url)
fp = urllib2.urlopen(url).fp
! dict = plistlib.Plist.fromFile(fp)
# Test here for Pimp version, etc
if included:
! version = dict.get('Version')
if version and version > self._version:
sys.stderr.write("Warning: included database %s is for pimp version %s\n" %
(url, version))
else:
! self._version = dict.get('Version')
if not self._version:
sys.stderr.write("Warning: database has no Version information\n")
--- 385,397 ----
self._urllist.append(url)
fp = urllib2.urlopen(url).fp
! plistdata = plistlib.Plist.fromFile(fp)
# Test here for Pimp version, etc
if included:
! version = plistdata.get('Version')
if version and version > self._version:
sys.stderr.write("Warning: included database %s is for pimp version %s\n" %
(url, version))
else:
! self._version = plistdata.get('Version')
if not self._version:
sys.stderr.write("Warning: database has no Version information\n")
***************
*** 316,323 ****
sys.stderr.write("Warning: database version %s newer than pimp version %s\n"
% (self._version, PIMP_VERSION))
! self._maintainer = dict.get('Maintainer', '')
! self._description = dict.get('Description', '').strip()
! self._appendPackages(dict['Packages'])
! others = dict.get('Include', [])
for url in others:
self.appendURL(url, included=1)
--- 399,407 ----
sys.stderr.write("Warning: database version %s newer than pimp version %s\n"
% (self._version, PIMP_VERSION))
! self._maintainer = plistdata.get('Maintainer', '')
! self._description = plistdata.get('Description', '').strip()
! self._url = url
! self._appendPackages(plistdata['Packages'])
! others = plistdata.get('Include', [])
for url in others:
self.appendURL(url, included=1)
***************
*** 362,366 ****
for pkg in self._packages:
packages.append(pkg.dump())
! dict = {
'Version': self._version,
'Maintainer': self._maintainer,
--- 446,450 ----
for pkg in self._packages:
packages.append(pkg.dump())
! plistdata = {
'Version': self._version,
'Maintainer': self._maintainer,
***************
*** 368,372 ****
'Packages': packages
}
! plist = plistlib.Plist(**dict)
plist.write(pathOrFile)
--- 452,456 ----
'Packages': packages
}
! plist = plistlib.Plist(**plistdata)
plist.write(pathOrFile)
***************
*** 429,439 ****
"""Class representing a single package."""
! def __init__(self, db, dict):
self._db = db
! name = dict["Name"]
! for k in dict.keys():
if not k in ALLOWED_KEYS:
sys.stderr.write("Warning: %s: unknown key %s\n" % (name, k))
! self._dict = dict
def __getitem__(self, key):
--- 513,523 ----
"""Class representing a single package."""
! def __init__(self, db, plistdata):
self._db = db
! name = plistdata["Name"]
! for k in plistdata.keys():
if not k in ALLOWED_KEYS:
sys.stderr.write("Warning: %s: unknown key %s\n" % (name, k))
! self._dict = plistdata
def __getitem__(self, key):
***************
*** 583,590 ****
if scheme == 'manual':
return "Please download package manually and save as %s" % self.archiveFilename
! if _cmd(output, self._db.preferences.downloadDir,
! "curl",
! "--output", self.archiveFilename,
! self._dict['Download-URL']):
return "download command failed"
if not os.path.exists(self.archiveFilename) and not NO_EXECUTE:
--- 667,674 ----
if scheme == 'manual':
return "Please download package manually and save as %s" % self.archiveFilename
! downloader = PimpUrllibDownloader(None, self._db.preferences.downloadDir,
! watcher=self._db.preferences.watcher)
! if not downloader.download(self._dict['Download-URL'],
! self.archiveFilename, output):
return "download command failed"
if not os.path.exists(self.archiveFilename) and not NO_EXECUTE:
***************
*** 615,619 ****
return "unknown extension for archive file: %s" % filename
self.basename = filename[:-len(ext)]
! unpacker = unpackerClass(arg, dir=self._db.preferences.buildDir)
rv = unpacker.unpack(self.archiveFilename, output=output)
if rv:
--- 699,704 ----
return "unknown extension for archive file: %s" % filename
self.basename = filename[:-len(ext)]
! unpacker = unpackerClass(arg, dir=self._db.preferences.buildDir,
! watcher=self._db.preferences.watcher)
rv = unpacker.unpack(self.archiveFilename, output=output)
if rv:
***************
*** 824,828 ****
for package in packages:
if not package in self._todo:
! self._todo.insert(0, package)
def _prepareInstall(self, package, force=0, recursive=1):
--- 909,913 ----
for package in packages:
if not package in self._todo:
! self._todo.append(package)
def _prepareInstall(self, package, force=0, recursive=1):
***************
*** 845,849 ****
for pkg, descr in prereqs:
if pkg:
! self._prepareInstall(pkg, force, recursive)
else:
self._curmessages.append("Problem with dependency: %s" % descr)
--- 930,934 ----
for pkg, descr in prereqs:
if pkg:
! self._prepareInstall(pkg, False, recursive)
else:
self._curmessages.append("Problem with dependency: %s" % descr)
***************
*** 880,887 ****
! def _run(mode, verbose, force, args, prefargs):
"""Engine for the main program"""
prefs = PimpPreferences(**prefargs)
rv = prefs.check()
if rv:
--- 965,974 ----
! def _run(mode, verbose, force, args, prefargs, watcher):
"""Engine for the main program"""
prefs = PimpPreferences(**prefargs)
+ if watcher:
+ prefs.setWatcher(watcher)
rv = prefs.check()
if rv:
***************
*** 980,983 ****
--- 1067,1075 ----
sys.exit(1)
+ class _Watcher:
+ def update(self, msg):
+ sys.stderr.write(msg + '\r')
+ return 1
+
try:
opts, args = getopt.getopt(sys.argv[1:], "slifvdD:Vu:")
***************
*** 990,993 ****
--- 1082,1086 ----
verbose = 0
prefargs = {}
+ watcher = None
for o, a in opts:
if o == '-s':
***************
*** 1013,1016 ****
--- 1106,1110 ----
if o == '-v':
verbose = 1
+ watcher = _Watcher()
if o == '-D':
prefargs['installDir'] = a
***************
*** 1022,1026 ****
print 'Pimp version %s; module name is %s' % (PIMP_VERSION, __name__)
else:
! _run(mode, verbose, force, args, prefargs)
# Finally, try to update ourselves to a newer version.
--- 1116,1120 ----
print 'Pimp version %s; module name is %s' % (PIMP_VERSION, __name__)
else:
! _run(mode, verbose, force, args, prefargs, watcher)
# Finally, try to update ourselves to a newer version.
More information about the Python-checkins
mailing list