Release 0.13
[0publish-gui.git] / implementation.py
blob3b1f37f0df496cea209f0d4ef143cfd5a8631101
1 from xml.dom import Node
3 import os
4 from rox import g
5 import gtk.glade
7 import main
8 from xmltools import *
10 from zeroinstall.injector import model
11 from zeroinstall.zerostore import NotStored
13 RESPONSE_SAVE_AND_TEST = 1
15 class ImplementationProperties:
16 def __init__(self, feed_editor, element = None, is_group = False):
17 self.feed_editor = feed_editor
18 self.element = element
20 widgets = gtk.glade.XML(main.gladefile, 'version')
22 #attributes = g.ListStore(str, str)
23 #attr_view = widgets.get_widget('attributes')
24 #attr_view.set_model(attributes)
26 #attr_view.append_column(g.TreeViewColumn('Name'))
27 #attr_view.append_column(g.TreeViewColumn('Value'))
29 inherit_arch = widgets.get_widget('inherit_arch')
30 def shade_os_cpu():
31 s = not inherit_arch.get_active()
32 widgets.get_widget('cpu').set_sensitive(s)
33 widgets.get_widget('os').set_sensitive(s)
34 if s:
35 cpu = widgets.get_widget('cpu').get_active_text()
36 else:
37 cpu = None
38 if element:
39 parent = element.parentNode
40 while parent.nodeType == Node.ELEMENT_NODE and not cpu:
41 arch = parent.getAttribute('arch')
42 if arch and '-' in arch:
43 cpu = arch.split('-')[1]
44 parent = parent.parentNode
46 if cpu == 'src':
47 widgets.get_widget('source_frame').show()
48 else:
49 widgets.get_widget('source_frame').hide()
50 command = widgets.get_widget('compile_command')
51 if command.get_text() == '':
52 command.set_text('"$SRCDIR/configure" --prefix="$DISTDIR" && make install')
53 inherit_arch.connect('toggled', lambda cb: shade_os_cpu())
54 widgets.get_widget('cpu').connect('changed', lambda cb: shade_os_cpu())
56 main_menu = widgets.get_widget('main_binary')
57 doc_menu = widgets.get_widget('doc_dir')
59 if element:
60 if element.localName == 'group':
61 is_group = True
62 id = None
63 else:
64 id = element.getAttribute('id')
66 version = element.getAttribute('version') + \
67 (element.getAttribute('version-modifier') or '')
68 widgets.get_widget('version_number').set_text(version)
69 widgets.get_widget('released').set_text(element.getAttribute('released'))
71 widgets.get_widget('compile_command').set_text(element.getAttributeNS(XMLNS_COMPILE, 'command'))
72 widgets.get_widget('compile_binary_main').set_text(element.getAttributeNS(XMLNS_COMPILE, 'binary-main'))
73 widgets.get_widget('compile_binary_lib_mappings').set_text(element.getAttributeNS(XMLNS_COMPILE, 'binary-lib-mappings'))
75 main_binary = element.getAttribute('main')
76 doc_dir = element.getAttribute('doc-dir')
78 stability_menu = widgets.get_widget('stability')
79 stability = element.getAttribute('stability')
80 if stability:
81 i = 0
82 for row in stability_menu.get_model():
83 if row[0].lower() == stability:
84 stability_menu.set_active(i)
85 break
86 i += 1
87 else:
88 stability_menu.set_active(0)
90 main.combo_set_text(widgets.get_widget('license'), element.getAttribute('license'))
91 arch = element.getAttribute('arch')
92 if arch:
93 arch_os, arch_cpu = arch.split('-')
94 main.combo_set_text(widgets.get_widget('os'), arch_os)
95 main.combo_set_text(widgets.get_widget('cpu'), arch_cpu)
96 inherit_arch.set_active(False)
97 else:
98 widgets.get_widget('os').set_active(0)
99 widgets.get_widget('cpu').set_active(0)
101 def ok():
102 self.update_impl(element, widgets)
103 else:
104 released = widgets.get_widget('released')
106 id = '.'
107 if is_group:
108 widgets.get_widget('version_number').set_text('')
109 released.set_text('')
110 else:
111 widgets.get_widget('version_number').set_text('0.1-pre')
112 #released.set_text(time.strftime('%Y-%m-%d'))
114 widgets.get_widget('cpu').set_active(0)
115 widgets.get_widget('os').set_active(0)
116 widgets.get_widget('stability').set_active(0)
117 main_binary = None
118 doc_dir = None
120 def ok():
121 if is_group:
122 element_name = 'group'
123 else:
124 element_name = 'implementation'
125 element = create_element(self.feed_editor.doc.documentElement, element_name)
126 if not is_group:
127 element.setAttribute('id', '.')
128 try:
129 self.update_impl(element, widgets)
130 except:
131 remove_element(element)
132 raise
134 shade_os_cpu()
136 self.is_group = is_group
138 id_label = widgets.get_widget('id_label')
140 if is_group:
141 id_label.set_text('(group)')
142 elif id:
143 id_label.set_text(id)
144 if id.startswith('.') or id.startswith('/'):
145 id_label.set_sensitive(True)
146 else:
147 id_label.set_text('-')
149 def resp(dialog, r):
150 if r in (g.RESPONSE_OK, RESPONSE_SAVE_AND_TEST):
151 ok()
152 self.feed_editor.update_version_model()
153 if r == RESPONSE_SAVE_AND_TEST:
154 is_src = bool(widgets.get_widget('source_frame').flags() & gtk.VISIBLE)
155 self.feed_editor.save(lambda: self.test(element, is_src))
156 else:
157 dialog.destroy()
159 if is_group and element:
160 # Find a cached implementation for getting main
161 for x in child_elements(element):
162 if x.localName == 'implementation' and x.namespaceURI == XMLNS_INTERFACE:
163 id = x.getAttribute('id')
164 try:
165 if id and (id.startswith('.') or id.startswith('/') or main.stores.lookup(id)):
166 break
167 except NotStored, ex:
168 pass
170 if element:
171 feed = feed_editor.get_as_feed()
172 impl = feed.implementations.get(id)
173 cached_impl = (impl.local_path or main.stores.lookup_maybe(impl.digests)) if impl else None
174 elif id.startswith('/') or id.startswith('.'):
175 cached_impl = os.path.abspath(os.path.join(os.path.dirname(feed_editor.pathname), id))
176 else:
177 cached_impl = main.stores.lookup_maybe([id])
179 if cached_impl:
180 possible_mains = []
181 possible_docs = []
182 for (dirpath, dirnames, filenames) in os.walk(cached_impl):
183 relbasedir = dirpath[len(cached_impl) + 1:]
184 for file in filenames:
185 info = os.lstat(os.path.join(dirpath, file))
186 if info.st_mode & 0111:
187 new = os.path.join(relbasedir, file)
188 possible_mains.append(new)
189 for d in dirnames[:]:
190 if d.startswith('.'):
191 dirnames.remove(d)
192 else:
193 possible_docs.append(os.path.join(relbasedir, d))
194 for option in sorted(possible_mains):
195 main_menu.append_text(option)
196 for option in sorted(possible_docs):
197 doc_menu.append_text(option)
199 main.combo_set_text(main_menu, main_binary)
200 main.combo_set_text(doc_menu, doc_dir)
202 dialog = widgets.get_widget('version')
203 dialog.connect('response', resp)
205 def update_impl(self, element, widgets):
206 version = widgets.get_widget('version_number').get_text()
207 released = widgets.get_widget('released').get_text()
208 inherit_arch = widgets.get_widget('inherit_arch')
210 def get_combo(name):
211 widget = widgets.get_widget(name)
212 return widget.get_active_text()
214 cpu = get_combo('cpu')
215 os = get_combo('os')
216 license = get_combo('license')
218 widget = widgets.get_widget('stability')
219 if widget.get_active() == 0:
220 stability = None
221 else:
222 stability = get_combo('stability').lower()
224 if inherit_arch.get_active():
225 arch = None
226 else:
227 arch = os + '-' + cpu
229 main = widgets.get_widget('main_binary').get_active_text()
230 docs = widgets.get_widget('doc_dir').get_active_text()
232 old_id = element.getAttribute('id')
233 if old_id.startswith('/') or old_id.startswith('.'):
234 # Local paths are editable
235 new_id = widgets.get_widget('id_label').get_text()
236 if new_id.startswith('.') or new_id.startswith('/'):
237 element.setAttribute('id', new_id)
238 else:
239 raise Exception('Local IDs must start with "." or "/"')
241 version_modifier = None
242 if version:
243 model.parse_version(version)
244 # Was only needed for very old versions of 0launch:
245 #if '-' in version:
246 # version, version_modifier = version.split('-', 1)
247 # version_modifier = '-' + version_modifier
249 for name, value in [('version', version),
250 ('version-modifier', version_modifier),
251 ('arch', arch),
252 ('main', main),
253 ('doc-dir', docs),
254 ('released', released),
255 ('license', license),
256 ('stability', stability)]:
257 if value:
258 element.setAttribute(name, value)
259 elif element.hasAttribute(name):
260 element.removeAttribute(name)
262 # Source packages
263 if widgets.get_widget('source_frame').flags() & gtk.VISIBLE:
264 compile_command = widgets.get_widget('compile_command').get_text()
265 compile_binary_main = widgets.get_widget('compile_binary_main').get_text()
266 compile_binary_lib_mappings = widgets.get_widget('compile_binary_lib_mappings').get_text()
267 self.feed_editor.doc.documentElement.setAttribute('xmlns:compile', XMLNS_COMPILE)
268 else:
269 compile_command = compile_binary_main = compile_binary_lib_mappings = None
271 for name, value in [('command', compile_command),
272 ('binary-main', compile_binary_main),
273 ('binary-lib-mappings', compile_binary_lib_mappings)]:
274 if value:
275 element.setAttributeNS(XMLNS_COMPILE, 'compile:' + name, value)
276 elif element.hasAttributeNS(XMLNS_COMPILE, name):
277 element.removeAttributeNS(XMLNS_COMPILE, name)
279 def test(self, element, compile):
280 version = None
281 while element:
282 if element.hasAttribute('version'):
283 version = element.getAttribute('version')
284 break
285 element = element.parentNode
286 if element.namespaceURI != XMLNS_INTERFACE:
287 break
288 if element.localName != 'group':
289 break
291 if compile:
292 # TODO: 0compile doesn't allow setting the version
293 self.feed_editor.test_compile([])
294 else:
295 if version:
296 args = ['--not-before', version, '--before', version + '-0-pre9999']
297 else:
298 args = []
299 self.feed_editor.test(args)