mirror of
https://github.com/python/cpython.git
synced 2025-09-16 21:56:14 +00:00
Fix by Sjoerd Mullender to support symbolic links and make a backup of
.mirrorinfo. Fix by me to call string.lstrip(filename) to cope with a bug in strop.strip() in Python 1.4. Additionally, I changed all print statements that print filenames etc. to put them in backquotes so that it will be more obvious when there's a funny character on one of them (such as a space...).
This commit is contained in:
parent
6c373f758f
commit
a25969620a
1 changed files with 80 additions and 56 deletions
|
@ -18,10 +18,6 @@ remotedir: remote directory (default initial)
|
||||||
localdir: local directory (default current)
|
localdir: local directory (default current)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# XXX To do:
|
|
||||||
# - handle symbolic links
|
|
||||||
# - back up .mirrorinfo before overwriting
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
@ -76,11 +72,11 @@ def main():
|
||||||
if args[3:]: usage('too many arguments')
|
if args[3:]: usage('too many arguments')
|
||||||
#
|
#
|
||||||
f = ftplib.FTP()
|
f = ftplib.FTP()
|
||||||
if verbose: print 'Connecting to %s...' % host
|
if verbose: print 'Connecting to %s...' % `host`
|
||||||
f.connect(host)
|
f.connect(host)
|
||||||
if not nologin:
|
if not nologin:
|
||||||
if verbose:
|
if verbose:
|
||||||
print 'Logging in as %s...' % (login or 'anonymous')
|
print 'Logging in as %s...' % `login or 'anonymous'`
|
||||||
f.login(login, passwd, account)
|
f.login(login, passwd, account)
|
||||||
if verbose: print 'OK.'
|
if verbose: print 'OK.'
|
||||||
pwd = f.pwd()
|
pwd = f.pwd()
|
||||||
|
@ -98,11 +94,11 @@ def main():
|
||||||
def mirrorsubdir(f, localdir):
|
def mirrorsubdir(f, localdir):
|
||||||
pwd = f.pwd()
|
pwd = f.pwd()
|
||||||
if localdir and not os.path.isdir(localdir):
|
if localdir and not os.path.isdir(localdir):
|
||||||
if verbose: print 'Creating local directory', localdir
|
if verbose: print 'Creating local directory', `localdir`
|
||||||
try:
|
try:
|
||||||
makedir(localdir)
|
makedir(localdir)
|
||||||
except os.error, msg:
|
except os.error, msg:
|
||||||
print "Failed to establish local directory", localdir
|
print "Failed to establish local directory", `localdir`
|
||||||
return
|
return
|
||||||
infofilename = os.path.join(localdir, '.mirrorinfo')
|
infofilename = os.path.join(localdir, '.mirrorinfo')
|
||||||
try:
|
try:
|
||||||
|
@ -112,11 +108,11 @@ def mirrorsubdir(f, localdir):
|
||||||
try:
|
try:
|
||||||
info = eval(text)
|
info = eval(text)
|
||||||
except (SyntaxError, NameError):
|
except (SyntaxError, NameError):
|
||||||
print 'Bad mirror info in %s' % infofilename
|
print 'Bad mirror info in %s' % `infofilename`
|
||||||
info = {}
|
info = {}
|
||||||
subdirs = []
|
subdirs = []
|
||||||
listing = []
|
listing = []
|
||||||
if verbose: print 'Listing remote directory %s...' % pwd
|
if verbose: print 'Listing remote directory %s...' % `pwd`
|
||||||
f.retrlines('LIST', listing.append)
|
f.retrlines('LIST', listing.append)
|
||||||
filesfound = []
|
filesfound = []
|
||||||
for line in listing:
|
for line in listing:
|
||||||
|
@ -136,33 +132,35 @@ def mirrorsubdir(f, localdir):
|
||||||
if len(words) < 6:
|
if len(words) < 6:
|
||||||
if verbose > 1: print 'Skipping short line'
|
if verbose > 1: print 'Skipping short line'
|
||||||
continue
|
continue
|
||||||
filename = words[-1]
|
filename = string.lstrip(words[-1])
|
||||||
if string.find(filename, " -> ") >= 0:
|
i = string.find(filename, " -> ")
|
||||||
|
if i >= 0:
|
||||||
|
# words[0] had better start with 'l'...
|
||||||
if verbose > 1:
|
if verbose > 1:
|
||||||
print 'Skipping symbolic link %s' % \
|
print 'Found symbolic link %s' % `filename`
|
||||||
filename
|
linkto = filename[i+4:]
|
||||||
continue
|
filename = filename[:i]
|
||||||
infostuff = words[-5:-1]
|
infostuff = words[-5:-1]
|
||||||
mode = words[0]
|
mode = words[0]
|
||||||
skip = 0
|
skip = 0
|
||||||
for pat in skippats:
|
for pat in skippats:
|
||||||
if fnmatch(filename, pat):
|
if fnmatch(filename, pat):
|
||||||
if verbose > 1:
|
if verbose > 1:
|
||||||
print 'Skip pattern', pat,
|
print 'Skip pattern', `pat`,
|
||||||
print 'matches', filename
|
print 'matches', `filename`
|
||||||
skip = 1
|
skip = 1
|
||||||
break
|
break
|
||||||
if skip:
|
if skip:
|
||||||
continue
|
continue
|
||||||
if mode[0] == 'd':
|
if mode[0] == 'd':
|
||||||
if verbose > 1:
|
if verbose > 1:
|
||||||
print 'Remembering subdirectory', filename
|
print 'Remembering subdirectory', `filename`
|
||||||
subdirs.append(filename)
|
subdirs.append(filename)
|
||||||
continue
|
continue
|
||||||
filesfound.append(filename)
|
filesfound.append(filename)
|
||||||
if info.has_key(filename) and info[filename] == infostuff:
|
if info.has_key(filename) and info[filename] == infostuff:
|
||||||
if verbose > 1:
|
if verbose > 1:
|
||||||
print 'Already have this version of', filename
|
print 'Already have this version of',`filename`
|
||||||
continue
|
continue
|
||||||
fullname = os.path.join(localdir, filename)
|
fullname = os.path.join(localdir, filename)
|
||||||
tempname = os.path.join(localdir, '@'+filename)
|
tempname = os.path.join(localdir, '@'+filename)
|
||||||
|
@ -176,28 +174,41 @@ def mirrorsubdir(f, localdir):
|
||||||
os.unlink(tempname)
|
os.unlink(tempname)
|
||||||
except os.error:
|
except os.error:
|
||||||
pass
|
pass
|
||||||
try:
|
if mode[0] == 'l':
|
||||||
fp = open(tempname, 'wb')
|
if verbose:
|
||||||
except IOError, msg:
|
print "Creating symlink %s -> %s" % (
|
||||||
print "Can't create %s: %s" % (tempname, str(msg))
|
`filename`, `linkto`)
|
||||||
continue
|
try:
|
||||||
if verbose:
|
os.symlink(linkto, tempname)
|
||||||
print 'Retrieving %s from %s as %s...' % \
|
except IOError, msg:
|
||||||
(filename, pwd, fullname)
|
print "Can't create %s: %s" % (
|
||||||
if verbose:
|
`tempname`, str(msg))
|
||||||
fp1 = LoggingFile(fp, 1024, sys.stdout)
|
continue
|
||||||
else:
|
else:
|
||||||
fp1 = fp
|
try:
|
||||||
t0 = time.time()
|
fp = open(tempname, 'wb')
|
||||||
try:
|
except IOError, msg:
|
||||||
f.retrbinary('RETR ' + filename, fp1.write, 8*1024)
|
print "Can't create %s: %s" % (
|
||||||
except ftplib.error_perm, msg:
|
`tempname`, str(msg))
|
||||||
print msg
|
continue
|
||||||
t1 = time.time()
|
if verbose:
|
||||||
bytes = fp.tell()
|
print 'Retrieving %s from %s as %s...' % \
|
||||||
fp.close()
|
(`filename`, `pwd`, `fullname`)
|
||||||
if fp1 != fp:
|
if verbose:
|
||||||
fp1.close()
|
fp1 = LoggingFile(fp, 1024, sys.stdout)
|
||||||
|
else:
|
||||||
|
fp1 = fp
|
||||||
|
t0 = time.time()
|
||||||
|
try:
|
||||||
|
f.retrbinary('RETR ' + filename,
|
||||||
|
fp1.write, 8*1024)
|
||||||
|
except ftplib.error_perm, msg:
|
||||||
|
print msg
|
||||||
|
t1 = time.time()
|
||||||
|
bytes = fp.tell()
|
||||||
|
fp.close()
|
||||||
|
if fp1 != fp:
|
||||||
|
fp1.close()
|
||||||
try:
|
try:
|
||||||
os.unlink(fullname)
|
os.unlink(fullname)
|
||||||
except os.error:
|
except os.error:
|
||||||
|
@ -205,13 +216,13 @@ def mirrorsubdir(f, localdir):
|
||||||
try:
|
try:
|
||||||
os.rename(tempname, fullname)
|
os.rename(tempname, fullname)
|
||||||
except os.error, msg:
|
except os.error, msg:
|
||||||
print "Can't rename %s to %s: %s" % (tempname,
|
print "Can't rename %s to %s: %s" % (`tempname`,
|
||||||
fullname,
|
`fullname`,
|
||||||
str(msg))
|
str(msg))
|
||||||
continue
|
continue
|
||||||
info[filename] = infostuff
|
info[filename] = infostuff
|
||||||
writedict(info, infofilename)
|
writedict(info, infofilename)
|
||||||
if verbose:
|
if verbose and mode[0] != 'l':
|
||||||
dt = t1 - t0
|
dt = t1 - t0
|
||||||
kbytes = bytes / 1024.0
|
kbytes = bytes / 1024.0
|
||||||
print int(round(kbytes)),
|
print int(round(kbytes)),
|
||||||
|
@ -229,7 +240,7 @@ def mirrorsubdir(f, localdir):
|
||||||
if filename not in filesfound:
|
if filename not in filesfound:
|
||||||
if verbose:
|
if verbose:
|
||||||
print "Removing obsolete info entry for",
|
print "Removing obsolete info entry for",
|
||||||
print filename, "in", localdir or "."
|
print `filename`, "in", `localdir or "."`
|
||||||
del info[filename]
|
del info[filename]
|
||||||
deletions = deletions + 1
|
deletions = deletions + 1
|
||||||
if deletions:
|
if deletions:
|
||||||
|
@ -248,8 +259,8 @@ def mirrorsubdir(f, localdir):
|
||||||
for pat in skippats:
|
for pat in skippats:
|
||||||
if fnmatch(name, pat):
|
if fnmatch(name, pat):
|
||||||
if verbose > 1:
|
if verbose > 1:
|
||||||
print 'Skip pattern', pat,
|
print 'Skip pattern', `pat`,
|
||||||
print 'matches', name
|
print 'matches', `name`
|
||||||
skip = 1
|
skip = 1
|
||||||
break
|
break
|
||||||
if skip:
|
if skip:
|
||||||
|
@ -257,10 +268,10 @@ def mirrorsubdir(f, localdir):
|
||||||
fullname = os.path.join(localdir, name)
|
fullname = os.path.join(localdir, name)
|
||||||
if not rmok:
|
if not rmok:
|
||||||
if verbose:
|
if verbose:
|
||||||
print 'Local file', fullname,
|
print 'Local file', `fullname`,
|
||||||
print 'is no longer pertinent'
|
print 'is no longer pertinent'
|
||||||
continue
|
continue
|
||||||
if verbose: print 'Removing local file/dir', fullname
|
if verbose: print 'Removing local file/dir', `fullname`
|
||||||
remove(fullname)
|
remove(fullname)
|
||||||
#
|
#
|
||||||
# Recursively mirror subdirectories
|
# Recursively mirror subdirectories
|
||||||
|
@ -268,18 +279,18 @@ def mirrorsubdir(f, localdir):
|
||||||
if interactive:
|
if interactive:
|
||||||
doit = askabout('subdirectory', subdir, pwd)
|
doit = askabout('subdirectory', subdir, pwd)
|
||||||
if not doit: continue
|
if not doit: continue
|
||||||
if verbose: print 'Processing subdirectory', subdir
|
if verbose: print 'Processing subdirectory', `subdir`
|
||||||
localsubdir = os.path.join(localdir, subdir)
|
localsubdir = os.path.join(localdir, subdir)
|
||||||
pwd = f.pwd()
|
pwd = f.pwd()
|
||||||
if verbose > 1:
|
if verbose > 1:
|
||||||
print 'Remote directory now:', pwd
|
print 'Remote directory now:', `pwd`
|
||||||
print 'Remote cwd', subdir
|
print 'Remote cwd', `subdir`
|
||||||
try:
|
try:
|
||||||
f.cwd(subdir)
|
f.cwd(subdir)
|
||||||
except ftplib.error_perm, msg:
|
except ftplib.error_perm, msg:
|
||||||
print "Can't chdir to", subdir, ":", msg
|
print "Can't chdir to", `subdir`, ":", `msg`
|
||||||
else:
|
else:
|
||||||
if verbose: print 'Mirroring as', localsubdir
|
if verbose: print 'Mirroring as', `localsubdir`
|
||||||
mirrorsubdir(f, localsubdir)
|
mirrorsubdir(f, localsubdir)
|
||||||
if verbose > 1: print 'Remote cwd ..'
|
if verbose > 1: print 'Remote cwd ..'
|
||||||
f.cwd('..')
|
f.cwd('..')
|
||||||
|
@ -308,14 +319,14 @@ def remove(fullname):
|
||||||
os.rmdir(fullname)
|
os.rmdir(fullname)
|
||||||
except os.error, msg:
|
except os.error, msg:
|
||||||
print "Can't remove local directory %s: %s" % \
|
print "Can't remove local directory %s: %s" % \
|
||||||
(fullname, str(msg))
|
(`fullname`, str(msg))
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
os.unlink(fullname)
|
os.unlink(fullname)
|
||||||
except os.error, msg:
|
except os.error, msg:
|
||||||
print "Can't remove local file %s: %s" % \
|
print "Can't remove local file %s: %s" % \
|
||||||
(fullname, str(msg))
|
(`fullname`, str(msg))
|
||||||
return 0
|
return 0
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
@ -360,12 +371,25 @@ def makedir(pathname):
|
||||||
|
|
||||||
# Write a dictionary to a file in a way that can be read back using
|
# Write a dictionary to a file in a way that can be read back using
|
||||||
# rval() but is still somewhat readable (i.e. not a single long line).
|
# rval() but is still somewhat readable (i.e. not a single long line).
|
||||||
|
# Also creates a backup file.
|
||||||
def writedict(dict, filename):
|
def writedict(dict, filename):
|
||||||
fp = open(filename, 'w')
|
dir, file = os.path.split(filename)
|
||||||
|
tempname = os.path.join(dir, '@' + file)
|
||||||
|
backup = os.path.join(dir, file + '~')
|
||||||
|
try:
|
||||||
|
os.unlink(backup)
|
||||||
|
except os.error:
|
||||||
|
pass
|
||||||
|
fp = open(tempname, 'w')
|
||||||
fp.write('{\n')
|
fp.write('{\n')
|
||||||
for key, value in dict.items():
|
for key, value in dict.items():
|
||||||
fp.write('%s: %s,\n' % (`key`, `value`))
|
fp.write('%s: %s,\n' % (`key`, `value`))
|
||||||
fp.write('}\n')
|
fp.write('}\n')
|
||||||
fp.close()
|
fp.close()
|
||||||
|
try:
|
||||||
|
os.rename(filename, backup)
|
||||||
|
except os.error:
|
||||||
|
pass
|
||||||
|
os.rename(tempname, filename)
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue