]>
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
)
115 # wxaddons should be always kept as the user may have installed
116 # third-party modules seperate from wxpython.
117 def testWxaddons(self
, name
):
118 for prefix
in PREFIXES
:
119 if name
.startswith(prefix
+ "wxaddons"):
123 def testCommon(self
, name
):
124 for cmn
in COMMON_FILES
:
125 if fnmatchcase(name
, cmn
) or fnmatchcase(os
.path
.basename(name
), cmn
):
132 if os
.path
.exists(name
):
133 if not self
.lastInstall
and self
.testCommon(name
):
135 if self
.testWxaddons(name
):
137 print "Will remove:", name
138 self
.walkFiles(show
, show
)
141 def testUninstallAccess(self
):
143 if os
.path
.exists(name
):
144 if not self
.lastInstall
and self
.testCommon(name
):
146 if not os
.access(name
, os
.W_OK
):
147 raise AccessError(name
)
148 self
.walkFiles(testFile
, testFile
)
151 def doUninstall(self
):
152 def removeFile(name
):
153 if os
.path
.exists(name
):
154 if not self
.lastInstall
and self
.testCommon(name
):
156 if self
.testWxaddons(name
):
158 print "Removing:", name
161 print "Removing:", name
162 if os
.path
.exists(name
) and not self
.testWxaddons(name
):
163 hasFiles
= os
.listdir(name
)
164 if hasFiles
: # perhaps some stale symlinks, or .pyc files
165 for file in hasFiles
:
166 os
.unlink(os
.path
.join(name
, file))
170 self
.testUninstallAccess()
171 except AccessError
, e
:
172 print "UNABLE TO UNINSTALL!\nNo permission to remove: ", e
.args
[0]
175 self
.walkFiles(removeFile
, removeDir
)
182 for name
in glob
.glob(os
.path
.join(RCPTDIR
, "wxPython*")):
184 ir
= InstalledReceipt(name
)
187 pass # just skip it...
192 # Just in case a Python < 2.3 is used to run this
196 def enumerate(sequence
):
197 return zip(range(len(sequence
)), sequence
)
201 if len(sys
.argv
) > 1 and sys
.argv
[1] == "-doit":
202 inst
= cPickle
.loads(urllib
.unquote(sys
.argv
[2]))
207 installed
= findInstalled()
210 print "*** No wxPython installations found! ***"
211 raw_input("Press RETURN...")
214 for i
, inst
in enumerate(installed
):
215 print " %2d. %-40s %s" % (i
+1, inst
.mdata
["Title"], inst
.mdata
["Version"])
218 ans
= raw_input("Enter the number of the install to examine or 'Q' to quit: ")
219 if ans
in ['Q', 'q']:
221 inst
= installed
[int(ans
) - 1]
222 inst
.lastInstall
= len(installed
) == 1
229 Description: %(Description)s
232 ans
= raw_input("(U)ninstall, (S)how what will be removed, or (Q)uit? [u,s,q] ")
233 if ans
in ['Q', 'q']:
236 elif ans
in ['S', 's']:
239 elif ans
in ['U', 'u']:
241 print "Launching uninstaller with sudo, please enter your password if prompted:"
242 os
.system("sudo %s -doit %s" %
244 urllib
.quote(cPickle
.dumps(inst
))))
248 if __name__
== '__main__':