2 import os
, sys
, popen2
, tempfile
, shutil
3 import pygtk
; pygtk
.require('2.0')
5 from StringIO
import StringIO
8 from zeroinstall
.injector
.policy
import Policy
9 from zeroinstall
.injector
.iface_cache
import iface_cache
11 zero2desktop_uri
= "http://0install.net/2007/interfaces/Zero2Desktop.xml"
13 gladefile
= os
.path
.join(os
.path
.dirname(__file__
), 'zero2desktop.glade')
15 def try_interface(uri
):
17 launcher
= processes
.PipeThroughCommand(
18 ["0launch", "-d", "-g", "--", uri
],
22 except processes
.ChildError
, ex
:
23 if '(256)' not in str(ex
):
26 rox
.report_exception()
31 template
= """[Desktop Entry]
32 # This file was generated by zero2desktop.
33 # See the Zero Install project for details: http://0install.net
40 Categories=Application;%s
45 tree
= gtk
.glade
.XML(gladefile
, 'main')
46 self
.window
= tree
.get_widget('main')
50 self
.window
.set_response_sensitive(gtk
.RESPONSE_OK
, bool(text
))
51 uri
= tree
.get_widget('interface_uri')
52 about
= tree
.get_widget('about')
53 icon
= tree
.get_widget('icon')
54 category
= tree
.get_widget('category')
56 uri
.set_text('http://rox.sourceforge.net/2005/interfaces/ROX-Filer')
57 uri
.connect('changed', set_uri_ok
)
60 nb
= tree
.get_widget('notebook1')
62 def update_details_page():
63 iface
= iface_cache
.get_interface(uri
.get_text())
64 about
.set_text('%s - %s' % (iface
.get_name(), iface
.summary
))
65 icon_path
= iface_cache
.get_icon_path(iface
)
68 # Icon format must be PNG (to avoid attacks)
69 loader
= gtk
.gdk
.PixbufLoader('png')
71 loader
.write(file(icon_path
).read())
74 icon_pixbuf
= loader
.get_pixbuf()
76 print >>sys
.stderr
, "Failed to load cached PNG icon: %s" % ex
78 icon
.set_from_pixbuf(icon_pixbuf
)
80 #update_details_page()
84 iface
= iface_cache
.get_interface(uri
.get_text())
85 tmpdir
= tempfile
.mkdtemp(prefix
= 'zero2desktop-')
87 desktop_name
= os
.path
.join(tmpdir
, 'zeroinstall-%s.desktop' % iface
.get_name().lower())
88 desktop
= file(desktop_name
, 'w')
89 desktop
.write(template
% (iface
.get_name(), iface
.summary
,
90 iface_cache
.get_icon_path(iface
),
92 category
.get_active_text()))
94 status
= os
.spawnlp(os
.P_WAIT
, 'xdg-desktop-menu', 'xdg-desktop-menu', 'install', desktop_name
)
98 box
= gtk
.MessageDialog(self
.window
, gtk
.DIALOG_MODAL
, gtk
.MESSAGE_ERROR
, gtk
.BUTTONS_OK
,
99 'Failed to run xdg-desktop-menu (error code %d)' % status
)
103 self
.window
.destroy()
105 def response(box
, resp
):
106 if resp
== gtk
.RESPONSE_OK
:
107 page
= nb
.get_current_page()
109 iface
= uri
.get_text()
110 self
.window
.set_sensitive(False)
111 child
= popen2
.Popen3(['0launch',
112 '--gui', '--download-only',
114 child
.tochild
.close()
115 def output_ready(src
, cond
):
116 got
= os
.read(src
.fileno(), 100)
118 status
= child
.wait()
119 self
.window
.set_sensitive(True)
121 update_details_page()
125 gobject
.io_add_watch(child
.fromchild
,
126 gobject
.IO_IN | gobject
.IO_HUP
,
134 self
.window
.connect('response', response
)
137 main
.window
.connect('destroy', lambda box
: gtk
.main_quit())