3 from optparse
import OptionParser
6 # Ensure stdin, stdout and stderr FDs exist, to avoid confusion
11 fd
= os
.open('/dev/null', os
.O_RDONLY
)
17 parser
= OptionParser(usage
="usage: %prog [options] interface [args]\n"
18 " %prog --list [search-term]\n"
19 " %prog --import [signed-interface-files]\n"
20 " %prog --feed [interface]")
21 parser
.add_option("-c", "--console", help="never use GUI", action
='store_false', dest
='gui')
22 parser
.add_option("-d", "--download-only", help="fetch but don't run", action
='store_true')
23 parser
.add_option("-D", "--dry-run", help="just print actions", action
='store_true')
24 parser
.add_option("-f", "--feed", help="add or remove a feed", action
='store_true')
25 parser
.add_option("-g", "--gui", help="show graphical policy editor", action
='store_true')
26 parser
.add_option("-i", "--import", help="import from files, not from the network", action
='store_true')
27 parser
.add_option("-l", "--list", help="list all known interfaces", action
='store_true')
28 parser
.add_option("-m", "--main", help="name of the file to execute")
29 parser
.add_option("-o", "--offline", help="try to avoid using the network", action
='store_true')
30 parser
.add_option("-r", "--refresh", help="refresh all used interfaces", action
='store_true')
31 parser
.add_option("-v", "--verbose", help="more verbose output", action
='count')
32 parser
.add_option("-V", "--version", help="display version information", action
='store_true')
33 parser
.disable_interspersed_args()
35 (options
, args
) = parser
.parse_args()
38 logger
= logging
.getLogger()
39 if options
.verbose
== 1:
40 logger
.setLevel(logging
.INFO
)
42 logger
.setLevel(logging
.DEBUG
)
44 from zeroinstall
.injector
import model
, download
, autopolicy
, namespaces
50 match
= args
[0].lower()
54 from zeroinstall
.injector
.iface_cache
import iface_cache
55 for i
in iface_cache
.list_all_interfaces():
56 if match
and match
not in i
.lower(): continue
62 print "0launch (zero-install) " + zeroinstall
.version
63 print "Copyright (C) 2005 Thomas Leonard"
64 print "This program comes with ABSOLUTELY NO WARRANTY,"
65 print "to the extent permitted by law."
66 print "You may redistribute copies of this program"
67 print "under the terms of the GNU General Public License."
68 print "For more information about these matters, see the file named COPYING."
73 args
= [namespaces
.injector_gui_uri
]
74 options
.download_only
= True
80 if getattr(options
, 'import'):
81 from zeroinstall
.injector
import gpg
, handler
82 from zeroinstall
.injector
.iface_cache
import iface_cache
83 from xml
.dom
import minidom
85 if not os
.path
.isfile(x
):
86 raise model
.SafeException("File '%s' does not exist" % x
)
87 logging
.info("Importing from file '%s'", x
)
89 data
, sigs
= gpg
.check_stream(signed_data
)
90 doc
= minidom
.parseString(data
.read())
91 uri
= doc
.documentElement
.getAttribute('uri')
93 iface
= iface_cache
.get_interface(uri
)
94 logging
.info("Importing information about interface %s", iface
)
96 iface_cache
.check_signed_data(iface
, signed_data
, handler
.Handler())
99 if getattr(options
, 'feed'):
100 from zeroinstall
.injector
import iface_cache
, writer
101 from xml
.dom
import minidom
103 print "Feed '%s':\n" % x
104 x
= model
.canonical_iface_uri(x
)
105 policy
= autopolicy
.AutoPolicy(x
, download_only
= True, dry_run
= options
.dry_run
)
107 policy
.network_use
= model
.network_offline
108 policy
.recalculate_with_dl()
109 interfaces
= policy
.get_feed_targets(policy
.root
)
110 for i
in range(len(interfaces
)):
111 feed
= interfaces
[i
].get_feed(x
)
113 print "%d) Remove as feed for '%s'" % (i
+ 1, interfaces
[i
].uri
)
115 print "%d) Add as feed for '%s'" % (i
+ 1, interfaces
[i
].uri
)
119 i
= raw_input('Enter a number, or CTRL-C to cancel [1]: ').strip()
120 except KeyboardInterrupt:
122 raise model
.SafeException("Aborted at user request.")
130 if i
> 0 and i
<= len(interfaces
):
132 print "Invalid number. Try again. (1 to %d)" % len(interfaces
)
133 iface
= interfaces
[i
- 1]
134 feed
= iface
.get_feed(x
)
136 iface
.feeds
.remove(feed
)
138 iface
.feeds
.append(model
.Feed(x
, arch
= None, user_override
= True))
139 writer
.save_interface(iface
)
140 print "\nFeed list for interface '%s' is now:" % iface
.get_name()
142 for f
in iface
.feeds
:
148 iface_uri
= model
.canonical_iface_uri(args
[0])
150 # Singleton instance used everywhere...
151 policy
= autopolicy
.AutoPolicy(iface_uri
,
152 download_only
= bool(options
.download_only
),
153 dry_run
= options
.dry_run
)
156 policy
.network_use
= model
.network_offline
158 if options
.gui
is None and os
.environ
.get('DISPLAY', None):
162 options
.gui
= policy
.need_download()
164 # If we need to download anything, we might as well
165 # refresh all the interfaces first. Also, this triggers
166 # the 'checking for updates' box, which is non-interactive
167 # when there are no changes to the selection.
168 options
.refresh
= True
169 logging
.info("Need to download; switching to GUI mode")
170 except model
.SafeException
, ex
:
171 print >>sys
.stderr
, ex
175 policy
.set_root(namespaces
.injector_gui_uri
)
177 # Try to start the GUI without using the network.
178 # The GUI can refresh itself if it wants to.
180 policy
.network_use
= model
.network_offline
182 prog_args
= [iface_uri
] + args
[1:]
183 # Options apply to actual program, not GUI
184 if options
.download_only
:
185 policy
.download_only
= False
186 prog_args
.insert(0, '--download-only')
188 options
.refresh
= False
189 prog_args
.insert(0, '--refresh')
191 prog_args
= ['--main', options
.main
] + prog_args
197 policy
.download_and_execute(prog_args
, refresh
= bool(options
.refresh
), main
= options
.main
)
198 except autopolicy
.NeedDownload
, ex
:
201 except model
.SafeException
, ex
:
202 print >>sys
.stderr
, ex