Browse Source

shutil.rmtree() not reliable on Windows

David Rose 16 years ago
parent
commit
6d64fbeb5f
2 changed files with 21 additions and 7 deletions
  1. 18 3
      direct/src/p3d/AppRunner.py
  2. 3 4
      direct/src/p3d/HostInfo.py

+ 18 - 3
direct/src/p3d/AppRunner.py

@@ -12,7 +12,6 @@ runp3d.py for a command-line tool to invoke this module.
 import sys
 import os
 import types
-import shutil
 import __builtin__
 
 if 'VFSImporter' in sys.modules:
@@ -408,7 +407,7 @@ class AppRunner(DirectObject):
         removed all of the packages). """
 
         self.notify.info("Deleting host %s: %s" % (host.hostUrl, host.hostDir))
-        shutil.rmtree(host.hostDir.toOsSpecific(), True)
+        self.rmtree(host.hostDir)
 
         self.sendRequest('forget_package', host.hostUrl, '', '')
         
@@ -561,7 +560,7 @@ class AppRunner(DirectObject):
             else:
                 # If it's an unknown package, just delete it directly.
                 print "Deleting unknown package %s" % (packageData.pathname)
-                shutil.rmtree(packageData.pathname.toOsSpecific(), True)
+                self.rmtree(packageData.pathname())
 
         packages = self.deletePackages(packages)
         if packages:
@@ -606,6 +605,22 @@ class AppRunner(DirectObject):
             else:
                 raise
 
+    def rmtree(self, filename):
+        """ This is like shutil.rmtree(), but it can remove read-only
+        files on Windows.  It receives a Filename, the root directory
+        to delete. """
+        if filename.isDirectory():
+            for child in os.listdir(filename.toOsSpecific()):
+                self.rmtree(Filename(filename, child))
+            try:
+                os.chmod(filename.toOsSpecific(), 777)
+                os.rmdir(filename.toOsSpecific())
+            except OSError:
+                print "could not remove directory %s" % (filename)
+        else:
+            if not filename.unlink():
+                print "could not delete %s" % (filename)
+
     def setSessionId(self, sessionId):
         """ This message should come in at startup. """
         self.sessionId = sessionId

+ 3 - 4
direct/src/p3d/HostInfo.py

@@ -4,7 +4,6 @@ from direct.p3d.PackageInfo import PackageInfo
 from direct.p3d.FileSpec import FileSpec
 from direct.directnotify.DirectNotifyGlobal import directNotify
 import time
-import shutil
 
 class HostInfo:
     """ This class represents a particular download host serving up
@@ -482,10 +481,10 @@ class HostInfo:
         """ Called by deletePackage(), this actually removes the files
         for the indicated package. """
 
-        self.notify.info("Deleting package %s: %s" % (package.packageName, package.getPackageDir()))
-        shutil.rmtree(package.getPackageDir().toOsSpecific(), True)
-
         if self.appRunner:
+            self.notify.info("Deleting package %s: %s" % (package.packageName, package.getPackageDir()))
+            self.appRunner.rmtree(package.getPackageDir())
+
             self.appRunner.sendRequest('forget_package', self.hostUrl, package.packageName, package.packageVersion or '')
 
     def __determineHostDir(self, hostDirBasename, hostUrl):