]>
Commit | Line | Data |
---|---|---|
61a0bf7c KO |
1 | #---------------------------------------------------------------------- |
2 | # Name: __init__.py | |
3 | # Purpose: Import logic and common functions for wxaddons module | |
4 | # | |
5 | # Author: Kevin Ollivier | |
6 | # | |
7 | # Created: 15-Nov-2006 | |
8 | # RCS-ID: $Id$ | |
9 | # Copyright: (c) 2006 Kevin Ollivier | |
10 | # Licence: wxWindows license | |
11 | #---------------------------------------------------------------------- | |
12 | ||
13 | import sys, os, string | |
14 | import xmlrpclib | |
15 | import __builtin__ | |
16 | import wx | |
17 | ||
18 | domain = 'http://wxpyaddons.wxcommunity.com' | |
19 | builtin_import = __builtin__.__import__ | |
20 | ||
21 | debug = False | |
22 | use_gui = True | |
23 | ||
24 | if use_gui and not wx.App.IsDisplayAvailable(): | |
25 | use_gui = False | |
26 | ||
27 | s = xmlrpclib.Server('%s/xmlrpc-server.php' % domain, verbose=(debug == True)) | |
28 | ||
29 | def version_greater_than_or_equal(version1, version2): | |
30 | """ | |
31 | Checks if version1 >= version2, returning true if so, | |
32 | false if otherwise. | |
33 | """ | |
34 | greater_than = True | |
35 | ||
36 | for index in range(0, len(version1)-1): | |
37 | if version1[index] > version2[index]: | |
38 | greater_than = True | |
39 | break | |
40 | elif version[index] < current_version[index]: | |
41 | greater_than = False | |
42 | break | |
43 | ||
44 | return greater_than | |
45 | ||
46 | def prompt_install(name, version): | |
47 | should_install = False | |
48 | message = "The wxaddon %s is not installed, but was found on the wxaddons site. Would you like to download and install it?" % (name + " " + version) | |
49 | if use_gui: | |
50 | app = wx.PySimpleApp() | |
51 | app.MainLoop() | |
52 | result = wx.MessageBox(message, "Install Dependency?", style=wx.YES_NO) | |
53 | if result == wx.YES: | |
54 | should_install = True | |
55 | else: | |
56 | result = raw_input(message + " [y/n]") | |
57 | if result[0].lower() == "y": | |
58 | should_install = True | |
59 | ||
60 | return should_install | |
61 | ||
62 | def require_addon_version(name, version=[], canBeNewer=True): | |
63 | # Check the install receipt to see if we've got an appropriate version | |
64 | config = wx.Config("wxaddons-receipts") | |
65 | needs_update = True | |
66 | if config.HasGroup(name): | |
67 | config.SetPath(name) | |
68 | current_version = config.Read("version", "0.0").split(".") | |
69 | ||
70 | needs_update = version_greater_than_or_equal(version, current_version) | |
71 | ||
72 | if needs_update: | |
73 | comp_xml = s.getComponent(name) | |
74 | if not comp_xml: | |
75 | raise | |
76 | ||
77 | comp = xmlrpclib.loads(comp_xml)[0][0] | |
78 | comp_version = comp["version"].split(".") | |
79 | ||
80 | update_comp = False | |
81 | if canBeNewer: | |
82 | update_comp = version_greater_than_or_equal(comp_version, version) | |
83 | else: | |
84 | update_comp = (version == comp_version) | |
85 | ||
86 | if update_comp: | |
87 | url = get_url(name, version) | |
88 | should_install = prompt_install(name, comp_version) | |
89 | ||
90 | if should_install: | |
91 | dl_and_install_addon(name, comp_version) | |
92 | ||
93 | def get_url(name, version): | |
94 | url = "" | |
95 | release_xml = s.getReleases(name) | |
96 | if not release_xml: | |
97 | return "" | |
98 | ||
99 | releases = xmlrpclib.loads(release_xml)[0][0] | |
100 | for release in releases: | |
101 | if release['version'] == version: | |
102 | url = release['url'] | |
103 | ||
104 | return url | |
105 | ||
106 | def dl_and_install_addon(name, version, url): | |
107 | installed = True | |
108 | tempdir = None | |
109 | cwd = os.getcwd() | |
110 | ||
111 | # get the package URL | |
112 | url = "http://wxpyaddons.wxcommunity.com/releases/sized_controls-0.5.tar.gz" | |
113 | ||
114 | if use_gui: | |
115 | progress = wx.ProgressDialog("Installing Dependency", | |
116 | "Preparing to install the %s addon module." % name, | |
117 | 4, | |
118 | style=wx.PD_APP_MODAL|wx.PD_SMOOTH) | |
119 | ||
120 | message = "Downloading tarball..." | |
121 | print message | |
122 | if use_gui: progress.Update(1, message) | |
123 | import urllib | |
124 | temp_archive, headers = urllib.urlretrieve(url) | |
125 | ||
126 | message = "Extracting files..." | |
127 | print message | |
128 | if use_gui: progress.Update(2, message) | |
129 | import tempfile | |
130 | tempdir = tempfile.mkdtemp() | |
131 | ||
132 | os.chdir(tempdir) | |
133 | import tarfile | |
134 | tar = tarfile.open(temp_archive, "r:gz") | |
135 | for tarinfo in tar: | |
136 | tar.extract(tarinfo) | |
137 | tar.close() | |
138 | ||
139 | os.chdir(name) | |
140 | ||
141 | message = "Installing %s" % name | |
142 | if use_gui: progress.Update(3, message) | |
143 | # TODO: Add support for modified PYTHONPATH? | |
144 | # Also, do we need admin install support here? | |
145 | retval = os.system(sys.executable + " " + string.join(("setup.py", "install"), " ")) | |
146 | if use_gui: progress.Update(4) | |
147 | ||
148 | if retval == 0: | |
149 | message = "The %s addon was successfully installed." % name | |
150 | print message | |
151 | if use_gui: | |
152 | wx.MessageBox(message, "Installation Successful") | |
153 | else: | |
154 | installed = False | |
155 | ||
156 | # cleanup | |
157 | if use_gui: progress.Destroy() | |
158 | os.chdir(cwd) | |
159 | import shutil | |
160 | shutil.rmtree(tempdir) | |
161 | os.remove(temp_archive) | |
162 | ||
163 | return installed | |
164 | ||
165 | def import_hook(name, globals=None, locals=None, fromlist=None): | |
166 | # Fast path: see if the module has already been imported. | |
167 | try: | |
168 | return builtin_import(name, globals, locals, fromlist) | |
169 | except: | |
170 | if name.startswith("wxaddons"): | |
171 | print "Querying %s for module." % domain | |
172 | try: | |
173 | modname = name.split(".")[1] | |
174 | comp = None | |
175 | comp_xml = s.getComponent(modname) | |
176 | if not comp_xml: | |
177 | raise | |
178 | ||
179 | comp = xmlrpclib.loads(comp_xml)[0][0] | |
180 | url = get_url(comp["name"], comp["version"]) | |
181 | should_install = prompt_install(comp["name"], comp["version"]) | |
182 | ||
183 | if should_install: | |
184 | try: | |
185 | success = dl_and_install_addon(comp["name"], comp["version"], url) | |
186 | if not success: | |
187 | raise | |
188 | except: | |
189 | raise | |
190 | ||
191 | ||
192 | except: | |
193 | raise | |
194 | else: | |
195 | raise | |
196 | ||
197 | def runTests(): | |
198 | import wxaddons.sized_controls | |
199 | import wxaddons.foo_bar | |
200 | import googly | |
201 | ||
202 | __builtin__.__import__ = import_hook | |
203 |