]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/distrib/mac/uninstall_wxPython.py
3 This script will search for installed versions of wxPython on OSX and
4 allow the user to choose one to uninstall. It then will use the
5 metadata stored about the installed package to remove all the files
6 associated with that install.
8 Only the files installed by the main Installer Package will be
9 removed. This includes the Python modules and the wxWidgets shared
10 libraries. If you also installed the demo or docs by dragging them out
11 of the disk image, then you will need to drag them to the Trash
16 from fnmatch
import fnmatchcase
17 import cPickle
, urllib
19 RCPTDIR
= "/Library/Receipts"
20 RSRCDIR
= "Contents/Resources"
22 # Only completly clean out dirs that have one of these as a prefix.
23 # We do this because the file list returned from lsbom will include /,
24 # /usr, /usr/local, etc.
25 PREFIXES
= [ '/Library/Python/2.3/',
26 '/Library/Python/2.4/',
27 '/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/',
28 '/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/',
32 # The files that match one of the items in this list will only be
33 # removed if the last installation of wxPython on the system is being
35 COMMON_FILES
= [ '/usr/local/bin/*',
42 class AccessError(Exception):
45 class ReceiptError(Exception):
49 class InstalledReceipt(object):
50 def __init__(self
, rcptPath
):
51 self
.rcptPath
= rcptPath
52 self
.rsrcPath
= os
.path
.join(rcptPath
, RSRCDIR
)
53 bf
= glob
.glob(os
.path
.join(self
.rsrcPath
, "*.bom"))
57 print "WARNING: Unable to find %s/*.bom" % self
.rsrcPath
62 def findMetaData(self
):
63 # TODO: Make this be able to also look at Info.plist files
64 infoFiles
= glob
.glob(os
.path
.join(self
.rsrcPath
, "*.info"))
66 # there should be only one
67 infoFile
= infoFiles
[0]
69 for line
in open(infoFile
, "r").readlines():
71 if line
and line
[0] != '#':
73 self
.mdata
[ls
[0]] = line
[len(ls
[0])+1:]
75 print "WARNING: Unable to find %s/*.info" % self
.rsrcPath
79 def getFileList(self
):
80 p
= os
.popen("lsbom -s %s" % self
.bomFile
, "r")
83 data
= filter(lambda s
: s
!='' and s
!='.', data
.split('\n'))
84 loc
= self
.mdata
['DefaultLocation']
85 return [loc
+item
for item
in data
]
88 def walkFiles(self
, handleFile
, handleDir
):
90 names
= self
.getFileList()
94 name
= os
.path
.abspath(name
)
95 if os
.path
.isdir(name
):
103 for prefix
in PREFIXES
:
104 if dir.startswith(prefix
):
108 # Finally, remove the Receipts package, bottom-up
109 for dirpath
, dirname
, filenames
in os
.walk(self
.rcptPath
, False):
110 for name
in filenames
:
111 name
= os
.path
.join(dirpath
, name
)
116 def testCommon(self
, name
):
117 for cmn
in COMMON_FILES
:
118 if fnmatchcase(name
, cmn
) or fnmatchcase(os
.path
.basename(name
), cmn
):
125 if os
.path
.exists(name
):
126 if not self
.lastInstall
and self
.testCommon(name
):
128 print "Will remove:", name
129 self
.walkFiles(show
, show
)
132 def testUninstallAccess(self
):
134 if os
.path
.exists(name
):
135 if not self
.lastInstall
and self
.testCommon(name
):
137 if not os
.access(name
, os
.W_OK
):
138 raise AccessError(name
)
139 self
.walkFiles(testFile
, testFile
)
142 def doUninstall(self
):
143 def removeFile(name
):
144 if os
.path
.exists(name
):
145 if not self
.lastInstall
and self
.testCommon(name
):
147 print "Removing:", name
150 print "Removing:", name
151 if os
.path
.exists(name
):
152 hasFiles
= os
.listdir(name
)
153 if hasFiles
: # perhaps some stale symlinks, or .pyc files
154 for file in hasFiles
:
155 os
.unlink(os
.path
.join(name
, file))
159 self
.testUninstallAccess()
160 except AccessError
, e
:
161 print "UNABLE TO UNINSTALL!\nNo permission to remove: ", e
.args
[0]
164 self
.walkFiles(removeFile
, removeDir
)
171 for name
in glob
.glob(os
.path
.join(RCPTDIR
, "wxPython*")):
173 ir
= InstalledReceipt(name
)
176 pass # just skip it...
181 # Just in case a Python < 2.3 is used to run this
185 def enumerate(sequence
):
186 return zip(range(len(sequence
)), sequence
)
190 if len(sys
.argv
) > 1 and sys
.argv
[1] == "-doit":
191 inst
= cPickle
.loads(urllib
.unquote(sys
.argv
[2]))
196 installed
= findInstalled()
199 print "*** No wxPython installations found! ***"
200 raw_input("Press RETURN...")
203 for i
, inst
in enumerate(installed
):
204 print " %d. %s \t%s" % (i
+1, inst
.mdata
["Title"], inst
.mdata
["Version"])
207 ans
= raw_input("Enter the number of the install to examine or 'Q' to quit: ")
208 if ans
in ['Q', 'q']:
210 inst
= installed
[int(ans
) - 1]
211 inst
.lastInstall
= len(installed
) == 1
218 Description: %(Description)s
221 ans
= raw_input("(U)ninstall, (S)how what will be removed, or (Q)uit? [u,s,q] ")
222 if ans
in ['Q', 'q']:
225 elif ans
in ['S', 's']:
228 elif ans
in ['U', 'u']:
230 print "Launching uninstaller with sudo, please enter your password if prompted:"
231 os
.system("sudo %s -doit %s" %
233 urllib
.quote(cPickle
.dumps(inst
))))
237 if __name__
== '__main__':