Don't assume Linux-x86 compatibility by default. Instead, wait for people
[zeroinstall.git] / 0launch
blobae2761ffb3043b45f8b0c6220c0eba2955ee492a
1 #!/usr/bin/env python
2 import os, sys
3 from optparse import OptionParser
4 import logging
6 parser = OptionParser(usage="usage: %prog [options] interface [args]\n"
7 " %prog --list [search-term]\n"
8 " %prog --import [signed-interface-files]\n"
9 " %prog --add-feed [local-interface-files]")
10 parser.add_option("-a", "--add-feed", help="add a local feed", action='store_true')
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("-m", "--main", help="name of the file to execute")
16 parser.add_option("-i", "--import", help="import from files, not from the network", action='store_true')
17 parser.add_option("-l", "--list", help="list all known interfaces", action='store_true')
18 parser.add_option("-r", "--refresh", help="refresh all used interfaces", action='store_true')
19 parser.add_option("-v", "--verbose", help="more verbose output", action='count')
20 parser.add_option("-V", "--version", help="display version information", action='store_true')
21 parser.disable_interspersed_args()
23 (options, args) = parser.parse_args()
25 if options.verbose:
26 logger = logging.getLogger()
27 if options.verbose == 1:
28 logger.setLevel(logging.INFO)
29 else:
30 logger.setLevel(logging.DEBUG)
32 from zeroinstall.injector import model, download, autopolicy, namespaces
34 if options.list:
35 if len(args) == 0:
36 match = None
37 elif len(args) == 1:
38 match = args[0].lower()
39 else:
40 parser.print_help()
41 sys.exit(1)
42 from zeroinstall.injector.iface_cache import iface_cache
43 for i in iface_cache.list_all_interfaces():
44 if match and match not in i.lower(): continue
45 print i
46 sys.exit(0)
48 if options.version:
49 import zeroinstall
50 print "0launch (zero-install) " + zeroinstall.version
51 print "Copyright (C) 2005 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."
57 sys.exit(0)
59 if len(args) < 1:
60 if options.gui:
61 args = [namespaces.injector_gui_uri]
62 options.download_only = True
63 else:
64 parser.print_help()
65 sys.exit(1)
67 try:
68 if getattr(options, 'import'):
69 from zeroinstall.injector import gpg, handler
70 from zeroinstall.injector.iface_cache import iface_cache
71 from xml.dom import minidom
72 for x in args:
73 if not os.path.isfile(x):
74 raise model.SafeException("File '%s' does not exist" % x)
75 logging.info("Importing from file '%s'", x)
76 signed_data = file(x)
77 data, sigs = gpg.check_stream(signed_data)
78 doc = minidom.parseString(data.read())
79 uri = doc.documentElement.getAttribute('uri')
80 assert uri
81 iface = iface_cache.get_interface(uri)
82 logging.info("Importing information about interface %s", iface)
83 signed_data.seek(0)
84 iface_cache.check_signed_data(iface, signed_data, handler.Handler())
85 sys.exit(0)
87 if getattr(options, 'add_feed'):
88 from zeroinstall.injector import iface_cache, writer
89 from xml.dom import minidom
90 for x in args:
91 x = os.path.realpath(x)
92 if not os.path.isfile(x):
93 raise model.SafeException("File '%s' does not exist" % x)
94 logging.info("Reading interface file '%s'", x)
95 doc = minidom.parse(x)
96 uri = doc.documentElement.getAttribute('uri')
97 if not uri:
98 raise model.SafeException("Missing uri attribute in interface file '%s'" % x)
99 continue
100 iface = iface_cache.iface_cache.get_interface(uri)
101 if not iface.name:
102 print "Warning: unknown interface '%s'" % uri
103 if x in iface.feeds:
104 print "Feed '%s' is already registered." % x
105 continue
106 if options.dry_run:
107 print "Would add this file as a feed for '%s'" % iface.get_name()
108 continue
110 iface.feeds.append(x)
111 writer.save_interface(iface)
112 print "Feed list for interface '%s' is now:" % iface.get_name()
113 for f in iface.feeds:
114 print "- " + f
115 sys.exit(0)
117 iface_uri = model.canonical_iface_uri(args[0])
119 # Singleton instance used everywhere...
120 policy = autopolicy.AutoPolicy(iface_uri,
121 download_only = bool(options.download_only),
122 dry_run = options.dry_run)
124 if options.gui is None and os.environ.get('DISPLAY', None):
125 if options.refresh:
126 options.gui = True
127 else:
128 options.gui = policy.need_download()
129 if options.gui:
130 # If we need to download anything, we might as well
131 # refresh all the interfaces first. Also, this triggers
132 # the 'checking for updates' box, which is non-interactive
133 # when there are no changes to the selection.
134 options.refresh = True
135 logging.info("Need to download; switching to GUI mode")
136 except model.SafeException, ex:
137 print >>sys.stderr, ex
138 sys.exit(1)
140 if options.gui:
141 policy.set_root(namespaces.injector_gui_uri)
143 # Try to start the GUI without using the network.
144 # The GUI can refresh itself if it wants to.
145 policy.freshness = 0
146 policy.network_use = model.network_minimal
148 prog_args = [iface_uri] + args[1:]
149 # Options apply to actual program, not GUI
150 if options.download_only:
151 policy.download_only = False
152 prog_args.insert(0, '--download-only')
153 if options.refresh:
154 options.refresh = False
155 prog_args.insert(0, '--refresh')
156 if options.main:
157 prog_args = ['--main', options.main] + prog_args
158 options.main = None
159 else:
160 prog_args = args[1:]
162 try:
163 policy.download_and_execute(prog_args, refresh = bool(options.refresh), main = options.main)
164 except model.SafeException, ex:
165 print >>sys.stderr, ex
166 sys.exit(1)
167 except autopolicy.NeedDownload, ex:
168 print ex
169 sys.exit(0)