New release.
[zeroinstall.git] / 0launch
blob31b4b9b0a01ba8098043c5c0cb7549d96dcb6008
1 #!/usr/bin/env python
2 import os, sys
3 from optparse import OptionParser
4 import logging
6 from zeroinstall.injector import model, download, autopolicy, run, namespaces
8 parser = OptionParser(usage="usage: %prog [options] interface [args]\n"
9 " %prog --list [search-term]\n"
10 " %prog --import [interface-files]")
11 parser.add_option("-c", "--console", help="never use GUI", action='store_false', dest='gui')
12 parser.add_option("-d", "--download-only", help="fetch but don't run", action='store_true')
13 parser.add_option("-D", "--dry-run", help="just print actions", action='store_true')
14 parser.add_option("-g", "--gui", help="show graphical policy editor", action='store_true')
15 parser.add_option("-i", "--import", help="import from files, not from the network", action='store_true')
16 parser.add_option("-l", "--list", help="list all known interfaces", action='store_true')
17 parser.add_option("-r", "--refresh", help="refresh all used interfaces", action='store_true')
18 parser.add_option("-v", "--verbose", help="more verbose output", action='count')
19 parser.add_option("-V", "--version", help="display version information", action='store_true')
20 parser.disable_interspersed_args()
22 (options, args) = parser.parse_args()
24 if options.verbose:
25 logger = logging.getLogger()
26 if options.verbose == 1:
27 logger.setLevel(logging.INFO)
28 else:
29 logger.setLevel(logging.DEBUG)
30 hdlr = logging.StreamHandler()
31 fmt = logging.Formatter("%(levelname)s:%(message)s")
32 hdlr.setFormatter(fmt)
33 logger.addHandler(hdlr)
35 if options.list:
36 if len(args) == 0:
37 match = None
38 elif len(args) == 1:
39 match = args[0].lower()
40 else:
41 parser.print_help()
42 sys.exit(1)
43 from zeroinstall.injector.iface_cache import iface_cache
44 for i in iface_cache.list_all_interfaces():
45 if match and match not in i.lower(): continue
46 print i
47 sys.exit(0)
49 if options.version:
50 import zeroinstall
51 print "0launch (zero-install) " + zeroinstall.version
52 print "Copyright (C) 2005 Thomas Leonard"
53 print "This program comes with ABSOLUTELY NO WARRANTY,"
54 print "to the extent permitted by law."
55 print "You may redistribute copies of this program"
56 print "under the terms of the GNU General Public License."
57 print "For more information about these matters, see the file named COPYING."
58 sys.exit(0)
60 if len(args) < 1:
61 if options.gui:
62 args = [namespaces.injector_gui_uri]
63 options.download_only = True
64 else:
65 parser.print_help()
66 sys.exit(1)
68 try:
69 if getattr(options, 'import'):
70 from zeroinstall.injector import gpg, handler
71 from zeroinstall.injector.iface_cache import iface_cache
72 from xml.dom import minidom
73 for x in args:
74 if not os.path.isfile(x):
75 raise model.SafeException("File '%s' does not exist" % x)
76 logging.info("Importing from file '%s'", x)
77 signed_data = file(x)
78 data, sigs = gpg.check_stream(signed_data)
79 doc = minidom.parseString(data.read())
80 uri = doc.documentElement.getAttribute('uri')
81 assert uri
82 new, iface = iface_cache.get_interface(uri)
83 logging.info("Importing information about interface %s", iface)
84 signed_data.seek(0)
85 iface_cache.check_signed_data(iface, signed_data, handler.Handler())
86 sys.exit(0)
88 # Singleton instance used everywhere...
89 policy = autopolicy.AutoPolicy(args[0],
90 download_only = bool(options.download_only),
91 dry_run = options.dry_run)
93 if options.gui is None and os.environ.get('DISPLAY', None):
94 if options.refresh:
95 options.gui = True
96 else:
97 options.gui = policy.need_download()
98 # If we need to download anything, we might as well
99 # refresh all the interfaces first. Also, this triggers
100 # the 'checking for updates' box, which is non-interactive
101 # when there are no changes to the selection.
102 options.refresh = True
103 if options.gui:
104 logging.info("Need to download; switching to GUI mode")
105 except model.SafeException, ex:
106 print >>sys.stderr, ex
107 sys.exit(1)
109 if options.gui:
110 policy.set_root(namespaces.injector_gui_uri)
112 # Try to start the GUI without using the network.
113 # The GUI can refresh itself if it wants to.
114 policy.freshness = 0
115 policy.network_use = model.network_minimal
117 prog_args = args[:]
118 # Options apply to actual program, not GUI
119 if options.download_only:
120 policy.download_only = False
121 prog_args.insert(0, '--download-only')
122 if options.refresh:
123 options.refresh = False
124 prog_args.insert(0, '--refresh')
125 else:
126 prog_args = args[1:]
128 try:
129 policy.download_and_execute(prog_args, refresh = bool(options.refresh))
130 except model.SafeException, ex:
131 print >>sys.stderr, ex
132 sys.exit(1)
133 except autopolicy.NeedDownload, ex:
134 print ex
135 sys.exit(0)