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')
27 parser
.add_option("", "--with-store", help=_("add an implementation cache"), action
='append', metavar
='DIR')
29 parser
.disable_interspersed_args()
31 (options
, args
) = parser
.parse_args(args
)
35 logger
= logging
.getLogger()
36 if options
.verbose
== 1:
37 logger
.setLevel(logging
.INFO
)
39 logger
.setLevel(logging
.DEBUG
)
42 # Must fork before importing gtk, or ATK dies
44 # We exit, so our parent can call waitpid and unblock.
46 # The grandchild continues...
48 if options
.with_store
:
49 from zeroinstall
import zerostore
50 for x
in options
.with_store
:
51 iface_cache
.stores
.stores
.append(zerostore
.Store(os
.path
.abspath(x
)))
56 print "0launch-gui (zero-install) " + gui
.version
57 print "Copyright (C) 2009 Thomas Leonard"
58 print _("This program comes with ABSOLUTELY NO WARRANTY,"
59 "\nto the extent permitted by law."
60 "\nYou may redistribute copies of this program"
61 "\nunder the terms of the GNU Lesser General Public License."
62 "\nFor more information about these matters, see the file named COPYING.")
66 if gtk
.gdk
.get_display() is None:
67 print >>sys
.stderr
, "Failed to connect to display. Aborting."
70 if not hasattr(gtk
, 'combo_box_new_text'):
75 cache_explorer
= cache
.CacheExplorer()
77 cache_explorer
.window
.set_cursor(gtk
.gdk
.Cursor(gtk
.gdk
.WATCH
))
79 cache_explorer
.populate_model()
80 cache_explorer
.window
.set_cursor(None)
84 handler
= gui
.GUIHandler()
88 # Once we separate configuration from Policy, this hack can go away
89 class DummyPolicy(Policy
):
90 def recalculate(fetch_stale_interfaces
= True):
92 def solve_with_downloads(force
= False):
94 box
= preferences
.show_preferences(DummyPolicy('http://localhost/dummy', handler
))
95 box
.connect('destroy', gtk
.main_quit
)
99 interface_uri
= args
[0]
105 import mainwindow
, dialog
108 if options
.before
or options
.not_before
:
109 restrictions
.append(model
.VersionRangeRestriction(model
.parse_version(options
.before
),
110 model
.parse_version(options
.not_before
)))
112 widgets
= dialog
.Template('main')
114 policy
= Policy(interface_uri
, handler
, src
= bool(options
.source
))
115 policy
.target_arch
= arch
.get_architecture(options
.os
, options
.cpu
)
116 root_iface
= iface_cache
.get_interface(interface_uri
)
117 policy
.solver
.extra_restrictions
[root_iface
] = restrictions
118 policy
.solver
.record_details
= True
120 window
= mainwindow
.MainWindow(policy
, widgets
, download_only
= bool(options
.download_only
))
121 handler
.mainwindow
= window
124 window
.set_message(options
.message
)
126 root
= iface_cache
.get_interface(policy
.root
)
127 window
.browser
.set_root(root
)
129 window
.window
.connect('destroy', lambda w
: handler
.abort_all_downloads())
132 window
.use_systray_icon()
136 force_refresh
= bool(options
.refresh
)
138 window
.refresh_button
.set_sensitive(False)
139 window
.browser
.set_update_icons(force_refresh
)
141 solved
= policy
.solve_with_downloads(force
= force_refresh
)
143 if not window
.systray_icon
:
147 window
.refresh_button
.set_sensitive(True)
149 except Exception, ex
:
150 window
.report_exception(ex
)
152 if window
.systray_icon
and window
.systray_icon
.get_visible() and \
153 window
.systray_icon
.is_embedded():
155 window
.systray_icon
.set_tooltip(_('Downloading updates for %s') % root_iface
.get_name())
156 window
.run_button
.set_active(True)
158 # Should already be reporting an error, but
159 # blink it again just in case
160 window
.systray_icon
.set_blinking(True)
162 yield dialog
.ButtonClickedBlocker(window
.refresh_button
)
165 handler
.wait_for_blocker(main())