Added '0install add-feed' and '0install remove-feed' sub-commands
[zeroinstall/zeroinstall-afb.git] / zeroinstall / cmd / add_feed.py
blob00d69d19f1536b548c7bda3f3fef798394fff1d3
1 """
2 The B{0install add-feed} command-line interface.
3 """
5 # Copyright (C) 2011, Thomas Leonard
6 # See the README file for details, or visit http://0install.net.
8 import os, sys
9 import logging
11 from zeroinstall import cmd, SafeException, _
12 from zeroinstall.cmd import UsageError
13 from zeroinstall.injector import model, writer, handler
14 from zeroinstall.injector.policy import Policy
15 from zeroinstall.injector.iface_cache import iface_cache
17 syntax = "NEW-FEED"
19 def add_options(parser):
20 parser.add_option("-o", "--offline", help=_("try to avoid using the network"), action='store_true')
22 def handle(options, args, add_ok = True, remove_ok = False):
23 if not args: raise UsageError()
25 if os.isatty(1):
26 h = handler.ConsoleHandler()
27 else:
28 h = handler.Handler()
29 h.dry_run = bool(options.dry_run)
31 def find_feed_import(iface, feed_url):
32 for f in iface.extra_feeds:
33 if f.uri == feed_url:
34 return f
35 return None
37 for x in args:
38 print _("Feed '%s':") % x + '\n'
39 x = model.canonical_iface_uri(x)
40 policy = Policy(x, h)
41 if options.offline:
42 policy.network_use = model.network_offline
44 feed = iface_cache.get_feed(x)
45 if policy.network_use != model.network_offline and policy.is_stale(feed):
46 blocker = policy.fetcher.download_and_import_feed(x, iface_cache)
47 print _("Downloading feed; please wait...")
48 h.wait_for_blocker(blocker)
49 print _("Done")
51 candidate_interfaces = policy.get_feed_targets(x)
52 assert candidate_interfaces
53 interfaces = []
54 for i in range(len(candidate_interfaces)):
55 iface = candidate_interfaces[i]
56 if find_feed_import(iface, x):
57 if remove_ok:
58 print _("%(index)d) Remove as feed for '%(uri)s'") % {'index': i + 1, 'uri': iface.uri}
59 interfaces.append(iface)
60 else:
61 if add_ok:
62 print _("%(index)d) Add as feed for '%(uri)s'") % {'index': i + 1, 'uri': iface.uri}
63 interfaces.append(iface)
64 if not interfaces:
65 if remove_ok:
66 raise SafeException(_("%(feed)s is not registered as a feed for %(interface)s") %
67 {'feed': x, 'interface': candidate_interfaces[0]})
68 else:
69 raise SafeException(_("%(feed)s already registered as a feed for %(interface)s") %
70 {'feed': x, 'interface': candidate_interfaces[0]})
71 print
72 while True:
73 try:
74 i = raw_input(_('Enter a number, or CTRL-C to cancel [1]: ')).strip()
75 except KeyboardInterrupt:
76 print
77 raise SafeException(_("Aborted at user request."))
78 if i == '':
79 i = 1
80 else:
81 try:
82 i = int(i)
83 except ValueError:
84 i = 0
85 if i > 0 and i <= len(interfaces):
86 break
87 print _("Invalid number. Try again. (1 to %d)") % len(interfaces)
88 iface = interfaces[i - 1]
89 feed_import = find_feed_import(iface, x)
90 if feed_import:
91 iface.extra_feeds.remove(feed_import)
92 else:
93 iface.extra_feeds.append(model.Feed(x, arch = None, user_override = True))
94 writer.save_interface(iface)
95 print '\n' + _("Feed list for interface '%s' is now:") % iface.get_name()
96 if iface.extra_feeds:
97 for f in iface.extra_feeds:
98 print "- " + f.uri
99 else:
100 print _("(no feeds)")