]>
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-pacakges/',
28 '/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-pacakges/',
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):
46 class InstalledReceipt(object):
47 def __init__(self
, rcptPath
):
48 self
.rcptPath
= rcptPath
49 self
.rsrcPath
= os
.path
.join(rcptPath
, RSRCDIR
)
50 self
.bomFile
= glob
.glob(os
.path
.join(self
.rsrcPath
, "*.bom"))[0]
54 def findMetaData(self
):
55 # TODO: Make this be able to also look at Info.plist files
56 infoFile
= glob
.glob(os
.path
.join(self
.rsrcPath
, "*.info"))[0]
58 for line
in open(infoFile
, "r").readlines():
60 if line
and line
[0] != '#':
62 self
.mdata
[ls
[0]] = line
[len(ls
[0])+1:]
65 def getFileList(self
):
66 p
= os
.popen("lsbom -s %s" % self
.bomFile
, "r")
69 data
= filter(lambda s
: s
!='' and s
!='.', data
.split('\n'))
70 loc
= self
.mdata
['DefaultLocation']
71 return [loc
+item
for item
in data
]
74 def walkFiles(self
, handleFile
, handleDir
):
76 names
= self
.getFileList()
80 name
= os
.path
.abspath(name
)
81 if os
.path
.isdir(name
):
89 for prefix
in PREFIXES
:
90 if dir.startswith(prefix
):
94 # Finally, remove the Receipts package, bottom-up
95 for dirpath
, dirname
, filenames
in os
.walk(self
.rcptPath
, False):
96 for name
in filenames
:
97 name
= os
.path
.join(dirpath
, name
)
102 def testCommon(self
, name
):
103 for cmn
in COMMON_FILES
:
104 if fnmatchcase(name
, cmn
) or fnmatchcase(os
.path
.basename(name
), cmn
):
111 if os
.path
.exists(name
):
112 if not self
.lastInstall
and self
.testCommon(name
):
114 print "Will remove:", name
115 self
.walkFiles(show
, show
)
118 def testUninstallAccess(self
):
120 if os
.path
.exists(name
):
121 if not self
.lastInstall
and self
.testCommon(name
):
123 if not os
.access(name
, os
.W_OK
):
124 raise AccessError(name
)
125 self
.walkFiles(testFile
, testFile
)
128 def doUninstall(self
):
129 def removeFile(name
):
130 if os
.path
.exists(name
):
131 if not self
.lastInstall
and self
.testCommon(name
):
133 print "Removing:", name
136 print "Removing:", name
137 if os
.path
.exists(name
):
138 hasFiles
= os
.listdir(name
)
139 if hasFiles
: # perhaps some stale symlinks, or .pyc files
140 for file in hasFiles
:
141 os
.unlink(os
.path
.join(name
, file))
145 self
.testUninstallAccess()
146 except AccessError
, e
:
147 print "UNABLE TO UNINSTALL!\nNo permission to remove: ", e
.args
[0]
150 self
.walkFiles(removeFile
, removeDir
)
157 for name
in glob
.glob(os
.path
.join(RCPTDIR
, "wxPython*")):
158 ir
= InstalledReceipt(name
)
164 # Just in case a Python < 2.3 is used to run this
168 def enumerate(sequence
):
169 return zip(range(len(sequence
)), sequence
)
173 if len(sys
.argv
) > 1 and sys
.argv
[1] == "-doit":
174 inst
= cPickle
.loads(urllib
.unquote(sys
.argv
[2]))
179 installed
= findInstalled()
182 print "*** No wxPython installations found! ***"
183 raw_input("Press RETURN...")
186 for i
, inst
in enumerate(installed
):
187 print " %d. %s \t%s" % (i
+1, inst
.mdata
["Title"], inst
.mdata
["Version"])
190 ans
= raw_input("Enter the number of the install to examine or 'Q' to quit: ")
191 if ans
in ['Q', 'q']:
193 inst
= installed
[int(ans
) - 1]
194 inst
.lastInstall
= len(installed
) == 1
201 Description: %(Description)s
204 ans
= raw_input("(U)ninstall, (S)how what will be removed, or (Q)uit? [u,s,q] ")
205 if ans
in ['Q', 'q']:
208 elif ans
in ['S', 's']:
211 elif ans
in ['U', 'u']:
213 print "Launching uninstaller with sudo, please enter your password if prompted:"
214 os
.system("sudo %s -doit %s" %
216 urllib
.quote(cPickle
.dumps(inst
))))
220 if __name__
== '__main__':