]>
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/Python/2.5/',
28 '/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/',
29 '/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/',
30 '/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/',
34 # The files that match one of the items in this list will only be
35 # removed if the last installation of wxPython on the system is being
37 COMMON_FILES
= [ '/usr/local/bin/*',
44 class AccessError(Exception):
47 class ReceiptError(Exception):
51 class InstalledReceipt(object):
52 def __init__(self
, rcptPath
):
53 self
.rcptPath
= rcptPath
54 self
.rsrcPath
= os
.path
.join(rcptPath
, RSRCDIR
)
55 bf
= glob
.glob(os
.path
.join(self
.rsrcPath
, "*.bom"))
59 print "WARNING: Unable to find %s/*.bom" % self
.rsrcPath
64 def findMetaData(self
):
65 # TODO: Make this be able to also look at Info.plist files
66 infoFiles
= glob
.glob(os
.path
.join(self
.rsrcPath
, "*.info"))
68 # there should be only one
69 infoFile
= infoFiles
[0]
71 for line
in open(infoFile
, "r").readlines():
73 if line
and line
[0] != '#':
75 self
.mdata
[ls
[0]] = line
[len(ls
[0])+1:]
77 print "WARNING: Unable to find %s/*.info" % self
.rsrcPath
81 def getFileList(self
):
82 p
= os
.popen("lsbom -s %s" % self
.bomFile
, "r")
85 data
= filter(lambda s
: s
!='' and s
!='.', data
.split('\n'))
86 loc
= self
.mdata
['DefaultLocation']
87 return [loc
+item
for item
in data
]
90 def walkFiles(self
, handleFile
, handleDir
):
92 names
= self
.getFileList()
96 name
= os
.path
.abspath(name
)
97 if os
.path
.isdir(name
):
105 for prefix
in PREFIXES
:
106 if dir.startswith(prefix
):
110 # Finally, remove the Receipts package, bottom-up
111 for dirpath
, dirname
, filenames
in os
.walk(self
.rcptPath
, False):
112 for name
in filenames
:
113 name
= os
.path
.join(dirpath
, name
)
117 # wxaddons should be always kept as the user may have installed
118 # third-party modules seperate from wxpython.
119 def testWxaddons(self
, name
):
120 for prefix
in PREFIXES
:
121 if name
.startswith(prefix
+ "wxaddons"):
125 def testCommon(self
, name
):
126 for cmn
in COMMON_FILES
:
127 if fnmatchcase(name
, cmn
) or fnmatchcase(os
.path
.basename(name
), cmn
):
134 if os
.path
.exists(name
):
135 if not self
.lastInstall
and self
.testCommon(name
):
137 if self
.testWxaddons(name
):
139 print "Will remove:", name
140 self
.walkFiles(show
, show
)
143 def testUninstallAccess(self
):
145 if os
.path
.exists(name
):
146 if not self
.lastInstall
and self
.testCommon(name
):
148 if not os
.access(name
, os
.W_OK
):
149 raise AccessError(name
)
150 self
.walkFiles(testFile
, testFile
)
153 def doUninstall(self
):
154 def removeFile(name
):
155 if os
.path
.exists(name
):
156 if not self
.lastInstall
and self
.testCommon(name
):
158 if self
.testWxaddons(name
):
160 print "Removing:", name
163 print "Removing:", name
164 if os
.path
.exists(name
) and not self
.testWxaddons(name
):
165 hasFiles
= os
.listdir(name
)
166 if hasFiles
: # perhaps some stale symlinks, or .pyc files
167 for file in hasFiles
:
168 os
.unlink(os
.path
.join(name
, file))
172 self
.testUninstallAccess()
173 except AccessError
, e
:
174 print "UNABLE TO UNINSTALL!\nNo permission to remove: ", e
.args
[0]
177 self
.walkFiles(removeFile
, removeDir
)
184 for name
in glob
.glob(os
.path
.join(RCPTDIR
, "wxPython*")):
186 ir
= InstalledReceipt(name
)
189 pass # just skip it...
194 # Just in case a Python < 2.3 is used to run this
198 def enumerate(sequence
):
199 return zip(range(len(sequence
)), sequence
)
203 if len(sys
.argv
) > 1 and sys
.argv
[1] == "-doit":
204 inst
= cPickle
.loads(urllib
.unquote(sys
.argv
[2]))
209 installed
= findInstalled()
212 print "*** No wxPython installations found! ***"
213 raw_input("Press RETURN...")
216 for i
, inst
in enumerate(installed
):
217 print " %2d. %-40s %s" % (i
+1, inst
.mdata
["Title"], inst
.mdata
["Version"])
220 ans
= raw_input("Enter the number of the install to examine or 'Q' to quit: ")
221 if ans
in ['Q', 'q']:
223 inst
= installed
[int(ans
) - 1]
224 inst
.lastInstall
= len(installed
) == 1
231 Description: %(Description)s
234 ans
= raw_input("(U)ninstall, (S)how what will be removed, or (Q)uit? [u,s,q] ")
235 if ans
in ['Q', 'q']:
238 elif ans
in ['S', 's']:
241 elif ans
in ['U', 'u']:
243 print "Launching uninstaller with sudo, please enter your password if prompted:"
244 os
.system("sudo %s -doit %s" %
246 urllib
.quote(cPickle
.dumps(inst
))))
250 if __name__
== '__main__':