Add a feature to prompt to install wxaddon modules that are not yet on the user's system. Developers can also require a certain version (or minimal version) of a module so that users get prompted to upgrade old modules.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@43457 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Name: __init__.py
|
||||
# Purpose: Import logic and common functions for wxaddons module
|
||||
#
|
||||
# Author: Kevin Ollivier
|
||||
#
|
||||
# Created: 15-Nov-2006
|
||||
# RCS-ID: $Id$
|
||||
# Copyright: (c) 2006 Kevin Ollivier
|
||||
# Licence: wxWindows license
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
import sys, os, string
|
||||
import xmlrpclib
|
||||
import __builtin__
|
||||
import wx
|
||||
|
||||
domain = 'http://wxpyaddons.wxcommunity.com'
|
||||
builtin_import = __builtin__.__import__
|
||||
|
||||
debug = False
|
||||
use_gui = True
|
||||
|
||||
if use_gui and not wx.App.IsDisplayAvailable():
|
||||
use_gui = False
|
||||
|
||||
s = xmlrpclib.Server('%s/xmlrpc-server.php' % domain, verbose=(debug == True))
|
||||
|
||||
def version_greater_than_or_equal(version1, version2):
|
||||
"""
|
||||
Checks if version1 >= version2, returning true if so,
|
||||
false if otherwise.
|
||||
"""
|
||||
greater_than = True
|
||||
|
||||
for index in range(0, len(version1)-1):
|
||||
if version1[index] > version2[index]:
|
||||
greater_than = True
|
||||
break
|
||||
elif version[index] < current_version[index]:
|
||||
greater_than = False
|
||||
break
|
||||
|
||||
return greater_than
|
||||
|
||||
def prompt_install(name, version):
|
||||
should_install = False
|
||||
message = "The wxaddon %s is not installed, but was found on the wxaddons site. Would you like to download and install it?" % (name + " " + version)
|
||||
if use_gui:
|
||||
app = wx.PySimpleApp()
|
||||
app.MainLoop()
|
||||
result = wx.MessageBox(message, "Install Dependency?", style=wx.YES_NO)
|
||||
if result == wx.YES:
|
||||
should_install = True
|
||||
else:
|
||||
result = raw_input(message + " [y/n]")
|
||||
if result[0].lower() == "y":
|
||||
should_install = True
|
||||
|
||||
return should_install
|
||||
|
||||
def require_addon_version(name, version=[], canBeNewer=True):
|
||||
# Check the install receipt to see if we've got an appropriate version
|
||||
config = wx.Config("wxaddons-receipts")
|
||||
needs_update = True
|
||||
if config.HasGroup(name):
|
||||
config.SetPath(name)
|
||||
current_version = config.Read("version", "0.0").split(".")
|
||||
|
||||
needs_update = version_greater_than_or_equal(version, current_version)
|
||||
|
||||
if needs_update:
|
||||
comp_xml = s.getComponent(name)
|
||||
if not comp_xml:
|
||||
raise
|
||||
|
||||
comp = xmlrpclib.loads(comp_xml)[0][0]
|
||||
comp_version = comp["version"].split(".")
|
||||
|
||||
update_comp = False
|
||||
if canBeNewer:
|
||||
update_comp = version_greater_than_or_equal(comp_version, version)
|
||||
else:
|
||||
update_comp = (version == comp_version)
|
||||
|
||||
if update_comp:
|
||||
url = get_url(name, version)
|
||||
should_install = prompt_install(name, comp_version)
|
||||
|
||||
if should_install:
|
||||
dl_and_install_addon(name, comp_version)
|
||||
|
||||
def get_url(name, version):
|
||||
url = ""
|
||||
release_xml = s.getReleases(name)
|
||||
if not release_xml:
|
||||
return ""
|
||||
|
||||
releases = xmlrpclib.loads(release_xml)[0][0]
|
||||
for release in releases:
|
||||
if release['version'] == version:
|
||||
url = release['url']
|
||||
|
||||
return url
|
||||
|
||||
def dl_and_install_addon(name, version, url):
|
||||
installed = True
|
||||
tempdir = None
|
||||
cwd = os.getcwd()
|
||||
|
||||
# get the package URL
|
||||
url = "http://wxpyaddons.wxcommunity.com/releases/sized_controls-0.5.tar.gz"
|
||||
|
||||
if use_gui:
|
||||
progress = wx.ProgressDialog("Installing Dependency",
|
||||
"Preparing to install the %s addon module." % name,
|
||||
4,
|
||||
style=wx.PD_APP_MODAL|wx.PD_SMOOTH)
|
||||
|
||||
message = "Downloading tarball..."
|
||||
print message
|
||||
if use_gui: progress.Update(1, message)
|
||||
import urllib
|
||||
temp_archive, headers = urllib.urlretrieve(url)
|
||||
|
||||
message = "Extracting files..."
|
||||
print message
|
||||
if use_gui: progress.Update(2, message)
|
||||
import tempfile
|
||||
tempdir = tempfile.mkdtemp()
|
||||
|
||||
os.chdir(tempdir)
|
||||
import tarfile
|
||||
tar = tarfile.open(temp_archive, "r:gz")
|
||||
for tarinfo in tar:
|
||||
tar.extract(tarinfo)
|
||||
tar.close()
|
||||
|
||||
os.chdir(name)
|
||||
|
||||
message = "Installing %s" % name
|
||||
if use_gui: progress.Update(3, message)
|
||||
# TODO: Add support for modified PYTHONPATH?
|
||||
# Also, do we need admin install support here?
|
||||
retval = os.system(sys.executable + " " + string.join(("setup.py", "install"), " "))
|
||||
if use_gui: progress.Update(4)
|
||||
|
||||
if retval == 0:
|
||||
message = "The %s addon was successfully installed." % name
|
||||
print message
|
||||
if use_gui:
|
||||
wx.MessageBox(message, "Installation Successful")
|
||||
else:
|
||||
installed = False
|
||||
|
||||
# cleanup
|
||||
if use_gui: progress.Destroy()
|
||||
os.chdir(cwd)
|
||||
import shutil
|
||||
shutil.rmtree(tempdir)
|
||||
os.remove(temp_archive)
|
||||
|
||||
return installed
|
||||
|
||||
def import_hook(name, globals=None, locals=None, fromlist=None):
|
||||
# Fast path: see if the module has already been imported.
|
||||
try:
|
||||
return builtin_import(name, globals, locals, fromlist)
|
||||
except:
|
||||
if name.startswith("wxaddons"):
|
||||
print "Querying %s for module." % domain
|
||||
try:
|
||||
modname = name.split(".")[1]
|
||||
comp = None
|
||||
comp_xml = s.getComponent(modname)
|
||||
if not comp_xml:
|
||||
raise
|
||||
|
||||
comp = xmlrpclib.loads(comp_xml)[0][0]
|
||||
url = get_url(comp["name"], comp["version"])
|
||||
should_install = prompt_install(comp["name"], comp["version"])
|
||||
|
||||
if should_install:
|
||||
try:
|
||||
success = dl_and_install_addon(comp["name"], comp["version"], url)
|
||||
if not success:
|
||||
raise
|
||||
except:
|
||||
raise
|
||||
|
||||
|
||||
except:
|
||||
raise
|
||||
else:
|
||||
raise
|
||||
|
||||
def runTests():
|
||||
import wxaddons.sized_controls
|
||||
import wxaddons.foo_bar
|
||||
import googly
|
||||
|
||||
__builtin__.__import__ = import_hook
|
||||
|
||||
|
Reference in New Issue
Block a user