Mercurial > cpython-lru_cache-weakref
annotate Tools/scripts/ftpmirror.py @ 15842:f6cd36498a50 legacy-trunk
Document extensions to .pth files.
| author | Martin v. Löwis <martin@v.loewis.de> |
|---|---|
| date | Sat, 13 Jan 2001 09:54:41 +0000 |
| parents | 15cbe399a9c3 |
| children | 14a27acc755a |
| rev | line source |
|---|---|
|
4573
73758db2f464
/usr/local/bin/python -> /usr/bin/env python
Guido van Rossum <guido@python.org>
parents:
4544
diff
changeset
|
1 #! /usr/bin/env python |
| 2761 | 2 |
|
7024
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
3 """Mirror a remote ftp subtree into a local directory tree. |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
4 |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
5 usage: ftpmirror [-v] [-q] [-i] [-m] [-n] [-r] [-s pat] |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
6 [-l username [-p passwd [-a account]]] |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
7 hostname [remotedir [localdir]] |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
8 -v: verbose |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
9 -q: quiet |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
10 -i: interactive mode |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
11 -m: macintosh server (NCSA telnet 2.4) (implies -n -s '*.o') |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
12 -n: don't log in |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
13 -r: remove local files/directories no longer pertinent |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
14 -l username [-p passwd [-a account]]: login info (default anonymous ftp) |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
15 -s pat: skip files matching pattern |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
16 hostname: remote host |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
17 remotedir: remote directory (default initial) |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
18 localdir: local directory (default current) |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
19 """ |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
20 |
| 2761 | 21 import os |
| 22 import sys | |
| 23 import time | |
| 24 import getopt | |
| 25 import string | |
| 26 import ftplib | |
| 27 from fnmatch import fnmatch | |
| 28 | |
|
7024
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
29 # Print usage message and exit |
| 2761 | 30 def usage(*args): |
| 31 sys.stdout = sys.stderr | |
| 32 for msg in args: print msg | |
|
7024
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
33 print __doc__ |
| 2761 | 34 sys.exit(2) |
| 35 | |
| 36 verbose = 1 # 0 for -q, 2 for -v | |
| 37 interactive = 0 | |
| 38 mac = 0 | |
| 39 rmok = 0 | |
| 40 nologin = 0 | |
|
3374
0c8821bf6db5
don't die on unreadable files etc.
Guido van Rossum <guido@python.org>
parents:
2761
diff
changeset
|
41 skippats = ['.', '..', '.mirrorinfo'] |
| 2761 | 42 |
|
7024
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
43 # Main program: parse command line and start processing |
| 2761 | 44 def main(): |
| 45 global verbose, interactive, mac, rmok, nologin | |
| 46 try: | |
| 47 opts, args = getopt.getopt(sys.argv[1:], 'a:bil:mnp:qrs:v') | |
| 48 except getopt.error, msg: | |
| 49 usage(msg) | |
| 50 login = '' | |
| 51 passwd = '' | |
| 52 account = '' | |
| 53 for o, a in opts: | |
| 54 if o == '-l': login = a | |
| 55 if o == '-p': passwd = a | |
| 56 if o == '-a': account = a | |
| 57 if o == '-v': verbose = verbose + 1 | |
| 58 if o == '-q': verbose = 0 | |
| 59 if o == '-i': interactive = 1 | |
| 60 if o == '-m': mac = 1; nologin = 1; skippats.append('*.o') | |
| 61 if o == '-n': nologin = 1 | |
| 62 if o == '-r': rmok = 1 | |
| 63 if o == '-s': skippats.append(a) | |
| 64 if not args: usage('hostname missing') | |
| 65 host = args[0] | |
| 66 remotedir = '' | |
| 67 localdir = '' | |
| 68 if args[1:]: | |
| 69 remotedir = args[1] | |
| 70 if args[2:]: | |
| 71 localdir = args[2] | |
| 72 if args[3:]: usage('too many arguments') | |
| 73 # | |
| 74 f = ftplib.FTP() | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
75 if verbose: print 'Connecting to %s...' % `host` |
| 2761 | 76 f.connect(host) |
| 77 if not nologin: | |
| 78 if verbose: | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
79 print 'Logging in as %s...' % `login or 'anonymous'` |
| 2761 | 80 f.login(login, passwd, account) |
| 81 if verbose: print 'OK.' | |
| 82 pwd = f.pwd() | |
| 83 if verbose > 1: print 'PWD =', `pwd` | |
| 84 if remotedir: | |
| 85 if verbose > 1: print 'cwd(%s)' % `remotedir` | |
| 86 f.cwd(remotedir) | |
| 87 if verbose > 1: print 'OK.' | |
| 88 pwd = f.pwd() | |
| 89 if verbose > 1: print 'PWD =', `pwd` | |
| 90 # | |
| 91 mirrorsubdir(f, localdir) | |
| 92 | |
|
7024
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
93 # Core logic: mirror one subdirectory (recursively) |
| 2761 | 94 def mirrorsubdir(f, localdir): |
| 95 pwd = f.pwd() | |
| 96 if localdir and not os.path.isdir(localdir): | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
97 if verbose: print 'Creating local directory', `localdir` |
|
3495
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
98 try: |
|
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
99 makedir(localdir) |
|
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
100 except os.error, msg: |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
101 print "Failed to establish local directory", `localdir` |
|
3495
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
102 return |
| 2761 | 103 infofilename = os.path.join(localdir, '.mirrorinfo') |
| 104 try: | |
| 105 text = open(infofilename, 'r').read() | |
| 106 except IOError, msg: | |
| 107 text = '{}' | |
| 108 try: | |
| 109 info = eval(text) | |
| 110 except (SyntaxError, NameError): | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
111 print 'Bad mirror info in %s' % `infofilename` |
| 2761 | 112 info = {} |
| 113 subdirs = [] | |
| 114 listing = [] | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
115 if verbose: print 'Listing remote directory %s...' % `pwd` |
| 2761 | 116 f.retrlines('LIST', listing.append) |
|
4544
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
117 filesfound = [] |
| 2761 | 118 for line in listing: |
| 119 if verbose > 1: print '-->', `line` | |
| 120 if mac: | |
| 121 # Mac listing has just filenames; | |
| 122 # trailing / means subdirectory | |
| 123 filename = string.strip(line) | |
| 124 mode = '-' | |
| 125 if filename[-1:] == '/': | |
| 126 filename = filename[:-1] | |
| 127 mode = 'd' | |
| 128 infostuff = '' | |
| 129 else: | |
| 130 # Parse, assuming a UNIX listing | |
|
8320
c14e68f591ce
OK, here's a different way to implement the same thing -- this version
Guido van Rossum <guido@python.org>
parents:
8319
diff
changeset
|
131 words = string.split(line, None, 8) |
| 2761 | 132 if len(words) < 6: |
| 133 if verbose > 1: print 'Skipping short line' | |
| 134 continue | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
135 filename = string.lstrip(words[-1]) |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
136 i = string.find(filename, " -> ") |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
137 if i >= 0: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
138 # words[0] had better start with 'l'... |
| 2761 | 139 if verbose > 1: |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
140 print 'Found symbolic link %s' % `filename` |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
141 linkto = filename[i+4:] |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
142 filename = filename[:i] |
|
8320
c14e68f591ce
OK, here's a different way to implement the same thing -- this version
Guido van Rossum <guido@python.org>
parents:
8319
diff
changeset
|
143 infostuff = words[-5:-1] |
| 2761 | 144 mode = words[0] |
| 145 skip = 0 | |
| 146 for pat in skippats: | |
| 147 if fnmatch(filename, pat): | |
| 148 if verbose > 1: | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
149 print 'Skip pattern', `pat`, |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
150 print 'matches', `filename` |
| 2761 | 151 skip = 1 |
| 152 break | |
| 153 if skip: | |
| 154 continue | |
| 155 if mode[0] == 'd': | |
| 156 if verbose > 1: | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
157 print 'Remembering subdirectory', `filename` |
| 2761 | 158 subdirs.append(filename) |
| 159 continue | |
|
4544
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
160 filesfound.append(filename) |
| 2761 | 161 if info.has_key(filename) and info[filename] == infostuff: |
| 162 if verbose > 1: | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
163 print 'Already have this version of',`filename` |
| 2761 | 164 continue |
| 165 fullname = os.path.join(localdir, filename) | |
|
3495
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
166 tempname = os.path.join(localdir, '@'+filename) |
| 2761 | 167 if interactive: |
| 168 doit = askabout('file', filename, pwd) | |
| 169 if not doit: | |
| 170 if not info.has_key(filename): | |
| 171 info[filename] = 'Not retrieved' | |
| 172 continue | |
| 173 try: | |
|
3495
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
174 os.unlink(tempname) |
|
3374
0c8821bf6db5
don't die on unreadable files etc.
Guido van Rossum <guido@python.org>
parents:
2761
diff
changeset
|
175 except os.error: |
|
0c8821bf6db5
don't die on unreadable files etc.
Guido van Rossum <guido@python.org>
parents:
2761
diff
changeset
|
176 pass |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
177 if mode[0] == 'l': |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
178 if verbose: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
179 print "Creating symlink %s -> %s" % ( |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
180 `filename`, `linkto`) |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
181 try: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
182 os.symlink(linkto, tempname) |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
183 except IOError, msg: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
184 print "Can't create %s: %s" % ( |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
185 `tempname`, str(msg)) |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
186 continue |
| 2761 | 187 else: |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
188 try: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
189 fp = open(tempname, 'wb') |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
190 except IOError, msg: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
191 print "Can't create %s: %s" % ( |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
192 `tempname`, str(msg)) |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
193 continue |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
194 if verbose: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
195 print 'Retrieving %s from %s as %s...' % \ |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
196 (`filename`, `pwd`, `fullname`) |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
197 if verbose: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
198 fp1 = LoggingFile(fp, 1024, sys.stdout) |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
199 else: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
200 fp1 = fp |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
201 t0 = time.time() |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
202 try: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
203 f.retrbinary('RETR ' + filename, |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
204 fp1.write, 8*1024) |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
205 except ftplib.error_perm, msg: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
206 print msg |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
207 t1 = time.time() |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
208 bytes = fp.tell() |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
209 fp.close() |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
210 if fp1 != fp: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
211 fp1.close() |
|
3495
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
212 try: |
|
5546
6c07d44a7081
Unlink before rename (for NT).
Guido van Rossum <guido@python.org>
parents:
5532
diff
changeset
|
213 os.unlink(fullname) |
|
6c07d44a7081
Unlink before rename (for NT).
Guido van Rossum <guido@python.org>
parents:
5532
diff
changeset
|
214 except os.error: |
|
6c07d44a7081
Unlink before rename (for NT).
Guido van Rossum <guido@python.org>
parents:
5532
diff
changeset
|
215 pass # Ignore the error |
|
6c07d44a7081
Unlink before rename (for NT).
Guido van Rossum <guido@python.org>
parents:
5532
diff
changeset
|
216 try: |
|
6c07d44a7081
Unlink before rename (for NT).
Guido van Rossum <guido@python.org>
parents:
5532
diff
changeset
|
217 os.rename(tempname, fullname) |
|
3495
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
218 except os.error, msg: |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
219 print "Can't rename %s to %s: %s" % (`tempname`, |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
220 `fullname`, |
|
3495
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
221 str(msg)) |
|
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
222 continue |
| 2761 | 223 info[filename] = infostuff |
| 224 writedict(info, infofilename) | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
225 if verbose and mode[0] != 'l': |
| 2761 | 226 dt = t1 - t0 |
| 227 kbytes = bytes / 1024.0 | |
| 228 print int(round(kbytes)), | |
| 229 print 'Kbytes in', | |
| 230 print int(round(dt)), | |
| 231 print 'seconds', | |
| 232 if t1 > t0: | |
| 233 print '(~%d Kbytes/sec)' % \ | |
| 234 int(round(kbytes/dt),) | |
| 235 print | |
| 236 # | |
|
4544
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
237 # Remove files from info that are no longer remote |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
238 deletions = 0 |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
239 for filename in info.keys(): |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
240 if filename not in filesfound: |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
241 if verbose: |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
242 print "Removing obsolete info entry for", |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
243 print `filename`, "in", `localdir or "."` |
|
4544
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
244 del info[filename] |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
245 deletions = deletions + 1 |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
246 if deletions: |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
247 writedict(info, infofilename) |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
248 # |
| 2761 | 249 # Remove local files that are no longer in the remote directory |
|
3495
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
250 try: |
|
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
251 if not localdir: names = os.listdir(os.curdir) |
|
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
252 else: names = os.listdir(localdir) |
|
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
253 except os.error: |
|
f70dbe608f03
Create files as temp file and move to real location only when complete.
Guido van Rossum <guido@python.org>
parents:
3374
diff
changeset
|
254 names = [] |
| 2761 | 255 for name in names: |
| 256 if name[0] == '.' or info.has_key(name) or name in subdirs: | |
| 257 continue | |
|
4544
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
258 skip = 0 |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
259 for pat in skippats: |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
260 if fnmatch(name, pat): |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
261 if verbose > 1: |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
262 print 'Skip pattern', `pat`, |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
263 print 'matches', `name` |
|
4544
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
264 skip = 1 |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
265 break |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
266 if skip: |
|
8d0b00ed8c2b
Fixed a bug: files that no longer exist remotely would never be
Guido van Rossum <guido@python.org>
parents:
3495
diff
changeset
|
267 continue |
| 2761 | 268 fullname = os.path.join(localdir, name) |
| 269 if not rmok: | |
| 270 if verbose: | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
271 print 'Local file', `fullname`, |
| 2761 | 272 print 'is no longer pertinent' |
| 273 continue | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
274 if verbose: print 'Removing local file/dir', `fullname` |
|
7024
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
275 remove(fullname) |
| 2761 | 276 # |
| 277 # Recursively mirror subdirectories | |
| 278 for subdir in subdirs: | |
| 279 if interactive: | |
| 280 doit = askabout('subdirectory', subdir, pwd) | |
| 281 if not doit: continue | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
282 if verbose: print 'Processing subdirectory', `subdir` |
| 2761 | 283 localsubdir = os.path.join(localdir, subdir) |
| 284 pwd = f.pwd() | |
| 285 if verbose > 1: | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
286 print 'Remote directory now:', `pwd` |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
287 print 'Remote cwd', `subdir` |
| 2761 | 288 try: |
| 289 f.cwd(subdir) | |
| 290 except ftplib.error_perm, msg: | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
291 print "Can't chdir to", `subdir`, ":", `msg` |
| 2761 | 292 else: |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
293 if verbose: print 'Mirroring as', `localsubdir` |
| 2761 | 294 mirrorsubdir(f, localsubdir) |
| 295 if verbose > 1: print 'Remote cwd ..' | |
| 296 f.cwd('..') | |
| 297 newpwd = f.pwd() | |
| 298 if newpwd != pwd: | |
| 299 print 'Ended up in wrong directory after cd + cd ..' | |
| 300 print 'Giving up now.' | |
| 301 break | |
| 302 else: | |
| 303 if verbose > 1: print 'OK.' | |
| 304 | |
|
7024
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
305 # Helper to remove a file or directory tree |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
306 def remove(fullname): |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
307 if os.path.isdir(fullname) and not os.path.islink(fullname): |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
308 try: |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
309 names = os.listdir(fullname) |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
310 except os.error: |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
311 names = [] |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
312 ok = 1 |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
313 for name in names: |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
314 if not remove(os.path.join(fullname, name)): |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
315 ok = 0 |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
316 if not ok: |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
317 return 0 |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
318 try: |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
319 os.rmdir(fullname) |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
320 except os.error, msg: |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
321 print "Can't remove local directory %s: %s" % \ |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
322 (`fullname`, str(msg)) |
|
7024
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
323 return 0 |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
324 else: |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
325 try: |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
326 os.unlink(fullname) |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
327 except os.error, msg: |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
328 print "Can't remove local file %s: %s" % \ |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
329 (`fullname`, str(msg)) |
|
7024
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
330 return 0 |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
331 return 1 |
|
e17fe79305c7
Dangerous feature added: when removing local files (i.e., only when -r
Guido van Rossum <guido@python.org>
parents:
5546
diff
changeset
|
332 |
| 2761 | 333 # Wrapper around a file for writing to write a hash sign every block. |
| 334 class LoggingFile: | |
| 335 def __init__(self, fp, blocksize, outfp): | |
| 336 self.fp = fp | |
| 337 self.bytes = 0 | |
| 338 self.hashes = 0 | |
| 339 self.blocksize = blocksize | |
| 340 self.outfp = outfp | |
| 341 def write(self, data): | |
| 342 self.bytes = self.bytes + len(data) | |
| 343 hashes = int(self.bytes) / self.blocksize | |
| 344 while hashes > self.hashes: | |
| 345 self.outfp.write('#') | |
| 346 self.outfp.flush() | |
| 347 self.hashes = self.hashes + 1 | |
| 348 self.fp.write(data) | |
| 349 def close(self): | |
| 350 self.outfp.write('\n') | |
| 351 | |
| 352 # Ask permission to download a file. | |
| 353 def askabout(filetype, filename, pwd): | |
| 354 prompt = 'Retrieve %s %s from %s ? [ny] ' % (filetype, filename, pwd) | |
| 355 while 1: | |
| 356 reply = string.lower(string.strip(raw_input(prompt))) | |
| 357 if reply in ['y', 'ye', 'yes']: | |
| 358 return 1 | |
| 359 if reply in ['', 'n', 'no', 'nop', 'nope']: | |
| 360 return 0 | |
| 361 print 'Please answer yes or no.' | |
| 362 | |
| 363 # Create a directory if it doesn't exist. Recursively create the | |
| 364 # parent directory as well if needed. | |
| 365 def makedir(pathname): | |
| 366 if os.path.isdir(pathname): | |
| 367 return | |
| 368 dirname = os.path.dirname(pathname) | |
| 369 if dirname: makedir(dirname) | |
| 370 os.mkdir(pathname, 0777) | |
| 371 | |
| 372 # Write a dictionary to a file in a way that can be read back using | |
| 373 # rval() but is still somewhat readable (i.e. not a single long line). | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
374 # Also creates a backup file. |
| 2761 | 375 def writedict(dict, filename): |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
376 dir, file = os.path.split(filename) |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
377 tempname = os.path.join(dir, '@' + file) |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
378 backup = os.path.join(dir, file + '~') |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
379 try: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
380 os.unlink(backup) |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
381 except os.error: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
382 pass |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
383 fp = open(tempname, 'w') |
| 2761 | 384 fp.write('{\n') |
| 385 for key, value in dict.items(): | |
| 386 fp.write('%s: %s,\n' % (`key`, `value`)) | |
| 387 fp.write('}\n') | |
| 388 fp.close() | |
|
8591
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
389 try: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
390 os.rename(filename, backup) |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
391 except os.error: |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
392 pass |
|
2f43b61a98df
Fix by Sjoerd Mullender to support symbolic links and make a backup of
Guido van Rossum <guido@python.org>
parents:
8320
diff
changeset
|
393 os.rename(tempname, filename) |
| 2761 | 394 |
|
14648
15cbe399a9c3
Allow this script to act like a module by only calling main() if
Barry Warsaw <barry@python.org>
parents:
8591
diff
changeset
|
395 |
|
15cbe399a9c3
Allow this script to act like a module by only calling main() if
Barry Warsaw <barry@python.org>
parents:
8591
diff
changeset
|
396 if __name__ == '__main__': |
|
15cbe399a9c3
Allow this script to act like a module by only calling main() if
Barry Warsaw <barry@python.org>
parents:
8591
diff
changeset
|
397 main() |
