| 
									
										
										
										
											1997-04-29 14:45:19 +00:00
										 |  |  | """Utility functions for copying files.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | XXX The functions here don't copy the data fork or other metadata on Mac. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											1990-10-13 19:23:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-03-31 18:55:40 +00:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											1999-02-23 23:07:51 +00:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											1997-04-29 14:45:19 +00:00
										 |  |  | import stat | 
					
						
							| 
									
										
										
										
											1990-10-13 19:23:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def copyfile(src, dst): | 
					
						
							| 
									
										
										
										
											1997-04-29 14:45:19 +00:00
										 |  |  |     """Copy data from src to dst""" | 
					
						
							| 
									
										
										
										
											1997-04-29 14:06:46 +00:00
										 |  |  |     fsrc = None | 
					
						
							|  |  |  |     fdst = None | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         fsrc = open(src, 'rb') | 
					
						
							|  |  |  |         fdst = open(dst, 'wb') | 
					
						
							|  |  |  |         while 1: | 
					
						
							|  |  |  |             buf = fsrc.read(16*1024) | 
					
						
							|  |  |  |             if not buf: | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |             fdst.write(buf) | 
					
						
							| 
									
										
										
										
											1997-04-29 14:06:46 +00:00
										 |  |  |     finally: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if fdst: | 
					
						
							|  |  |  |             fdst.close() | 
					
						
							|  |  |  |         if fsrc: | 
					
						
							|  |  |  |             fsrc.close() | 
					
						
							| 
									
										
										
										
											1990-10-13 19:23:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def copymode(src, dst): | 
					
						
							| 
									
										
										
										
											1997-04-29 14:45:19 +00:00
										 |  |  |     """Copy mode bits from src to dst""" | 
					
						
							| 
									
										
										
										
											1997-04-29 14:06:46 +00:00
										 |  |  |     st = os.stat(src) | 
					
						
							| 
									
										
										
										
											1997-04-29 14:45:19 +00:00
										 |  |  |     mode = stat.S_IMODE(st[stat.ST_MODE]) | 
					
						
							| 
									
										
										
										
											1997-04-29 14:06:46 +00:00
										 |  |  |     os.chmod(dst, mode) | 
					
						
							| 
									
										
										
										
											1990-10-13 19:23:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def copystat(src, dst): | 
					
						
							| 
									
										
										
										
											1997-04-29 14:45:19 +00:00
										 |  |  |     """Copy all stat info (mode bits, atime and mtime) from src to dst""" | 
					
						
							| 
									
										
										
										
											1997-04-29 14:06:46 +00:00
										 |  |  |     st = os.stat(src) | 
					
						
							| 
									
										
										
										
											1997-04-29 14:45:19 +00:00
										 |  |  |     mode = stat.S_IMODE(st[stat.ST_MODE]) | 
					
						
							| 
									
										
										
										
											1998-10-02 03:16:08 +00:00
										 |  |  |     os.utime(dst, (st[stat.ST_ATIME], st[stat.ST_MTIME])) | 
					
						
							| 
									
										
										
										
											1999-01-14 00:42:00 +00:00
										 |  |  |     os.chmod(dst, mode) | 
					
						
							| 
									
										
										
										
											1997-04-29 14:45:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-10-13 19:23:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def copy(src, dst): | 
					
						
							| 
									
										
										
										
											1997-04-29 14:45:19 +00:00
										 |  |  |     """Copy data and mode bits ("cp src dst").
 | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     The destination may be a directory. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											1997-04-29 14:06:46 +00:00
										 |  |  |     if os.path.isdir(dst): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         dst = os.path.join(dst, os.path.basename(src)) | 
					
						
							| 
									
										
										
										
											1997-04-29 14:06:46 +00:00
										 |  |  |     copyfile(src, dst) | 
					
						
							|  |  |  |     copymode(src, dst) | 
					
						
							| 
									
										
										
										
											1990-10-13 19:23:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def copy2(src, dst): | 
					
						
							| 
									
										
										
										
											1997-04-29 14:45:19 +00:00
										 |  |  |     """Copy data and all stat info ("cp -p src dst").
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The destination may be a directory. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											1997-04-29 14:06:46 +00:00
										 |  |  |     if os.path.isdir(dst): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         dst = os.path.join(dst, os.path.basename(src)) | 
					
						
							| 
									
										
										
										
											1997-04-29 14:06:46 +00:00
										 |  |  |     copyfile(src, dst) | 
					
						
							|  |  |  |     copystat(src, dst) | 
					
						
							| 
									
										
										
										
											1990-10-13 19:23:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-29 14:45:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def copytree(src, dst, symlinks=0): | 
					
						
							|  |  |  |     """Recursively copy a directory tree using copy2().
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The destination directory must not already exist. | 
					
						
							|  |  |  |     Error are reported to standard output. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     If the optional symlinks flag is true, symbolic links in the | 
					
						
							|  |  |  |     source tree result in symbolic links in the destination tree; if | 
					
						
							|  |  |  |     it is false, the contents of the files pointed to by symbolic | 
					
						
							|  |  |  |     links are copied. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     XXX Consider this example code rather than the ultimate tool. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											1997-04-29 14:06:46 +00:00
										 |  |  |     names = os.listdir(src) | 
					
						
							| 
									
										
										
										
											1997-04-29 14:45:19 +00:00
										 |  |  |     os.mkdir(dst) | 
					
						
							| 
									
										
										
										
											1997-04-29 14:06:46 +00:00
										 |  |  |     for name in names: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         srcname = os.path.join(src, name) | 
					
						
							|  |  |  |         dstname = os.path.join(dst, name) | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             if symlinks and os.path.islink(srcname): | 
					
						
							|  |  |  |                 linkto = os.readlink(srcname) | 
					
						
							|  |  |  |                 os.symlink(linkto, dstname) | 
					
						
							|  |  |  |             elif os.path.isdir(srcname): | 
					
						
							|  |  |  |                 copytree(srcname, dstname) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 copy2(srcname, dstname) | 
					
						
							|  |  |  |             # XXX What about devices, sockets etc.? | 
					
						
							|  |  |  |         except (IOError, os.error), why: | 
					
						
							|  |  |  |             print "Can't copy %s to %s: %s" % (`srcname`, `dstname`, str(why)) | 
					
						
							| 
									
										
										
										
											1998-02-06 21:38:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def rmtree(path, ignore_errors=0, onerror=None): | 
					
						
							|  |  |  |     """Recursively delete a directory tree.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     If ignore_errors is set, errors are ignored; otherwise, if | 
					
						
							|  |  |  |     onerror is set, it is called to handle the error; otherwise, an | 
					
						
							|  |  |  |     exception is raised. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     cmdtuples = [] | 
					
						
							|  |  |  |     _build_cmdtuple(path, cmdtuples) | 
					
						
							|  |  |  |     for cmd in cmdtuples: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             apply(cmd[0], (cmd[1],)) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             exc = sys.exc_info() | 
					
						
							|  |  |  |             if ignore_errors: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             elif onerror: | 
					
						
							|  |  |  |                 onerror(cmd[0], cmd[1], exc) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 raise exc[0], (exc[1][0], exc[1][1] + ' removing '+cmd[1]) | 
					
						
							| 
									
										
										
										
											1998-02-06 21:38:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Helper for rmtree() | 
					
						
							|  |  |  | def _build_cmdtuple(path, cmdtuples): | 
					
						
							|  |  |  |     for f in os.listdir(path): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         real_f = os.path.join(path,f) | 
					
						
							|  |  |  |         if os.path.isdir(real_f) and not os.path.islink(real_f): | 
					
						
							|  |  |  |             _build_cmdtuple(real_f, cmdtuples) | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											1998-10-07 13:18:17 +00:00
										 |  |  |             cmdtuples.append((os.remove, real_f)) | 
					
						
							|  |  |  |     cmdtuples.append((os.rmdir, path)) |