1 # Copyright (C) 2009, Thomas Leonard
2 # See the README file for details, or visit http://0install.net.
6 from optparse
import OptionParser
8 from zeroinstall
.injector
import model
, arch
9 from zeroinstall
.injector
.policy
import Policy
10 from zeroinstall
.injector
.iface_cache
import iface_cache
11 from zeroinstall
.support
import tasks
14 parser
= OptionParser(usage
="usage: %prog [options] interface")
15 parser
.add_option("", "--before", help="choose a version before this", metavar
='VERSION')
16 parser
.add_option("", "--cpu", help="target CPU type", metavar
='CPU')
17 parser
.add_option("-c", "--cache", help="show the cache", action
='store_true')
18 parser
.add_option("-d", "--download-only", help="fetch but don't run", action
='store_true')
19 parser
.add_option("", "--message", help="message to display when interacting with user")
20 parser
.add_option("", "--not-before", help="minimum version to choose", metavar
='VERSION')
21 parser
.add_option("", "--os", help="target operation system type", metavar
='OS')
22 parser
.add_option("-r", "--refresh", help="check for updates of all interfaces", action
='store_true')
23 parser
.add_option("-s", "--source", help="select source code", action
='store_true')
24 parser
.add_option("", "--systray", help="download in the background", action
='store_true')
25 parser
.add_option("-v", "--verbose", help="more verbose output", action
='count')
26 parser
.add_option("-V", "--version", help="display version information", action
='store_true')
28 parser
.disable_interspersed_args()
30 (options
, args
) = parser
.parse_args(args
)
34 logger
= logging
.getLogger()
35 if options
.verbose
== 1:
36 logger
.setLevel(logging
.INFO
)
38 logger
.setLevel(logging
.DEBUG
)
41 # Must fork before importing gtk, or ATK dies
43 # We exit, so our parent can call waitpid and unblock.
45 # The grandchild continues...
50 print "0launch-gui (zero-install) " + gui
.version
51 print "Copyright (C) 2007 Thomas Leonard"
52 print "This program comes with ABSOLUTELY NO WARRANTY,"
53 print "to the extent permitted by law."
54 print "You may redistribute copies of this program"
55 print "under the terms of the GNU General Public License."
56 print "For more information about these matters, see the file named COPYING."
60 if gtk
.gdk
.get_display() is None:
61 print >>sys
.stderr
, "Failed to connect to display. Aborting."
64 if not hasattr(gtk
, 'combo_box_new_text'):
69 cache_explorer
= cache
.CacheExplorer()
71 cache_explorer
.window
.set_cursor(gtk
.gdk
.Cursor(gtk
.gdk
.WATCH
))
73 cache_explorer
.populate_model()
74 cache_explorer
.window
.set_cursor(None)
82 interface_uri
= args
[0]
88 import mainwindow
, dialog
91 if options
.before
or options
.not_before
:
92 restrictions
.append(model
.VersionRangeRestriction(model
.parse_version(options
.before
),
93 model
.parse_version(options
.not_before
)))
95 widgets
= dialog
.Template('main')
97 handler
= gui
.GUIHandler()
98 policy
= Policy(interface_uri
, handler
, src
= bool(options
.source
))
99 policy
.target_arch
= arch
.get_architecture(options
.os
, options
.cpu
)
100 root_iface
= iface_cache
.get_interface(interface_uri
)
101 policy
.solver
.extra_restrictions
[root_iface
] = restrictions
102 policy
.solver
.record_details
= True
104 window
= mainwindow
.MainWindow(policy
, widgets
, download_only
= bool(options
.download_only
))
105 handler
.mainwindow
= window
108 window
.set_message(options
.message
)
110 root
= iface_cache
.get_interface(policy
.root
)
111 window
.browser
.set_root(root
)
113 window
.window
.connect('destroy', lambda w
: handler
.abort_all_downloads())
116 window
.use_systray_icon()
120 force_refresh
= bool(options
.refresh
)
122 window
.refresh_button
.set_sensitive(False)
124 solved
= policy
.solve_with_downloads(force
= force_refresh
)
126 if not window
.systray_icon
:
130 window
.refresh_button
.set_sensitive(True)
132 except Exception, ex
:
133 window
.report_exception(ex
)
135 if window
.systray_icon
and window
.systray_icon
.get_visible() and \
136 window
.systray_icon
.is_embedded():
138 window
.systray_icon
.set_tooltip('Downloading updates for %s' % root_iface
.get_name())
139 window
.run_button
.set_active(True)
141 # Should already be reporting an error, but
142 # blink it again just in case
143 window
.systray_icon
.set_blinking(True)
145 yield dialog
.ButtonClickedBlocker(window
.refresh_button
)
148 handler
.wait_for_blocker(main())