Updated Debian changelog.
[zeroinstall.git] / 0launch
blob810d0b500b3bbe369b241e09f0b8a18f8fdc5a42
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 [signed-interface-files]\n"
11 " %prog --add-feed [local-interface-files]")
12 parser.add_option("-a", "--add-feed", help="add a local feed", action='store_true')
13 parser.add_option("-c", "--console", help="never use GUI", action='store_false', dest='gui')
14 parser.add_option("-d", "--download-only", help="fetch but don't run", action='store_true')
15 parser.add_option("-D", "--dry-run", help="just print actions", action='store_true')
16 parser.add_option("-g", "--gui", help="show graphical policy editor", action='store_true')
17 parser.add_option("-i", "--import", help="import from files, not from the network", action='store_true')
18 parser.add_option("-l", "--list", help="list all known interfaces", action='store_true')
19 parser.add_option("-r", "--refresh", help="refresh all used interfaces", action='store_true')
20 parser.add_option("-v", "--verbose", help="more verbose output", action='count')
21 parser.add_option("-V", "--version", help="display version information", action='store_true')
22 parser.disable_interspersed_args()
24 (options, args) = parser.parse_args()
26 if options.verbose:
27 logger = logging.getLogger()
28 if options.verbose == 1:
29 logger.setLevel(logging.INFO)
30 else:
31 logger.setLevel(logging.DEBUG)
33 if options.list:
34 if len(args) == 0:
35 match = None
36 elif len(args) == 1:
37 match = args[0].lower()
38 else:
39 parser.print_help()
40 sys.exit(1)
41 from zeroinstall.injector.iface_cache import iface_cache
42 for i in iface_cache.list_all_interfaces():
43 if match and match not in i.lower(): continue
44 print i
45 sys.exit(0)
47 if options.version:
48 import zeroinstall
49 print "0launch (zero-install) " + zeroinstall.version
50 print "Copyright (C) 2005 Thomas Leonard"
51 print "This program comes with ABSOLUTELY NO WARRANTY,"
52 print "to the extent permitted by law."
53 print "You may redistribute copies of this program"
54 print "under the terms of the GNU General Public License."
55 print "For more information about these matters, see the file named COPYING."
56 sys.exit(0)
58 if len(args) < 1:
59 if options.gui:
60 args = [namespaces.injector_gui_uri]
61 options.download_only = True
62 else:
63 parser.print_help()
64 sys.exit(1)
66 try:
67 if getattr(options, 'import'):
68 from zeroinstall.injector import gpg, handler
69 from zeroinstall.injector.iface_cache import iface_cache
70 from xml.dom import minidom
71 for x in args:
72 if not os.path.isfile(x):
73 raise model.SafeException("File '%s' does not exist" % x)
74 logging.info("Importing from file '%s'", x)
75 signed_data = file(x)
76 data, sigs = gpg.check_stream(signed_data)
77 doc = minidom.parseString(data.read())
78 uri = doc.documentElement.getAttribute('uri')
79 assert uri
80 new, iface = iface_cache.get_interface(uri)
81 logging.info("Importing information about interface %s", iface)
82 signed_data.seek(0)
83 iface_cache.check_signed_data(iface, signed_data, handler.Handler())
84 sys.exit(0)
86 if getattr(options, 'add_feed'):
87 from zeroinstall.injector import iface_cache, writer
88 from xml.dom import minidom
89 for x in args:
90 x = os.path.realpath(x)
91 if not os.path.isfile(x):
92 raise model.SafeException("File '%s' does not exist" % x)
93 logging.info("Reading interface file '%s'", x)
94 doc = minidom.parse(x)
95 uri = doc.documentElement.getAttribute('uri')
96 if not uri:
97 raise model.SafeException("Missing uri attribute in interface file '%s'" % x)
98 continue
99 new, iface = iface_cache.iface_cache.get_interface(uri)
100 if not iface.name:
101 print "Warning: unknown interface '%s'" % uri
102 if x in iface.feeds:
103 print "Feed '%s' is already registered." % x
104 continue
105 if options.dry_run:
106 print "Would add this file as a feed for '%s'" % iface.get_name()
107 continue
109 iface.feeds.append(x)
110 writer.save_interface(iface)
111 print "Feed list for interface '%s' is now:" % iface.get_name()
112 for f in iface.feeds:
113 print "- " + f
114 sys.exit(0)
116 if args[0].startswith('http:'):
117 iface_uri = args[0]
118 else:
119 iface_uri = os.path.realpath(args[0])
120 if not os.path.isfile(iface_uri):
121 raise model.SafeException("Bad interface name '%s'.\n"
122 "(doesn't start with 'http:', and "
123 "doesn't exist as a local file either)" % args[0])
125 # Singleton instance used everywhere...
126 policy = autopolicy.AutoPolicy(iface_uri,
127 download_only = bool(options.download_only),
128 dry_run = options.dry_run)
130 if options.gui is None and os.environ.get('DISPLAY', None):
131 if options.refresh:
132 options.gui = True
133 else:
134 options.gui = policy.need_download()
135 if options.gui:
136 # If we need to download anything, we might as well
137 # refresh all the interfaces first. Also, this triggers
138 # the 'checking for updates' box, which is non-interactive
139 # when there are no changes to the selection.
140 options.refresh = True
141 logging.info("Need to download; switching to GUI mode")
142 except model.SafeException, ex:
143 print >>sys.stderr, ex
144 sys.exit(1)
146 if options.gui:
147 policy.set_root(namespaces.injector_gui_uri)
149 # Try to start the GUI without using the network.
150 # The GUI can refresh itself if it wants to.
151 policy.freshness = 0
152 policy.network_use = model.network_minimal
154 prog_args = [iface_uri] + args[1:]
155 # Options apply to actual program, not GUI
156 if options.download_only:
157 policy.download_only = False
158 prog_args.insert(0, '--download-only')
159 if options.refresh:
160 options.refresh = False
161 prog_args.insert(0, '--refresh')
162 else:
163 prog_args = args[1:]
165 try:
166 policy.download_and_execute(prog_args, refresh = bool(options.refresh))
167 except model.SafeException, ex:
168 print >>sys.stderr, ex
169 sys.exit(1)
170 except autopolicy.NeedDownload, ex:
171 print ex
172 sys.exit(0)