Allow specifying the interface in add-feed
[zeroinstall.git] / zeroinstall / cmd / add_feed.py
blob7b4080276e6ae67cde450e18c41dae3c404be6f7
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 from zeroinstall import SafeException, _
9 from zeroinstall.support import tasks
10 from zeroinstall.cmd import UsageError
11 from zeroinstall.injector import model, writer
12 from zeroinstall.injector.policy import Policy
14 syntax = "[INTERFACE] NEW-FEED"
16 def add_options(parser):
17 parser.add_option("-o", "--offline", help=_("try to avoid using the network"), action='store_true')
19 def find_feed_import(iface, feed_url):
20 for f in iface.extra_feeds:
21 if f.uri == feed_url:
22 return f
23 return None
25 def handle(config, options, args, add_ok = True, remove_ok = False):
26 if options.offline:
27 config.network_use = model.network_offline
29 if len(args) == 2:
30 iface = config.iface_cache.get_interface(model.canonical_iface_uri(args[0]))
31 feed_url = args[1]
33 if find_feed_import(iface, feed_url):
34 raise SafeException(_('Interface %(interface)s already has feed %(feed)s') %
35 {'interface': iface.uri, 'feed': feed_url})
37 feed = config.iface_cache.get_feed(feed_url)
38 if not feed:
39 blocker = config.fetcher.download_and_import_feed(feed_url, config.iface_cache)
40 tasks.wait_for_blocker(blocker)
42 iface.extra_feeds.append(model.Feed(feed_url, arch = None, user_override = True))
43 writer.save_interface(iface)
44 return
45 elif len(args) != 1:
46 raise UsageError()
48 x = args[0]
50 print _("Feed '%s':") % x + '\n'
51 x = model.canonical_iface_uri(x)
52 policy = Policy(x, config = config)
54 feed = config.iface_cache.get_feed(x)
55 if policy.network_use != model.network_offline and policy.is_stale(feed):
56 blocker = config.fetcher.download_and_import_feed(x, config.iface_cache)
57 tasks.wait_for_blocker(blocker)
59 candidate_interfaces = policy.get_feed_targets(x)
60 assert candidate_interfaces
61 interfaces = []
62 for i in range(len(candidate_interfaces)):
63 iface = candidate_interfaces[i]
64 if find_feed_import(iface, x):
65 if remove_ok:
66 print _("%(index)d) Remove as feed for '%(uri)s'") % {'index': i + 1, 'uri': iface.uri}
67 interfaces.append(iface)
68 else:
69 if add_ok:
70 print _("%(index)d) Add as feed for '%(uri)s'") % {'index': i + 1, 'uri': iface.uri}
71 interfaces.append(iface)
72 if not interfaces:
73 if remove_ok:
74 raise SafeException(_("%(feed)s is not registered as a feed for %(interface)s") %
75 {'feed': x, 'interface': candidate_interfaces[0]})
76 else:
77 raise SafeException(_("%(feed)s already registered as a feed for %(interface)s") %
78 {'feed': x, 'interface': candidate_interfaces[0]})
79 print
80 while True:
81 try:
82 i = raw_input(_('Enter a number, or CTRL-C to cancel [1]: ')).strip()
83 except KeyboardInterrupt:
84 print
85 raise SafeException(_("Aborted at user request."))
86 if i == '':
87 i = 1
88 else:
89 try:
90 i = int(i)
91 except ValueError:
92 i = 0
93 if i > 0 and i <= len(interfaces):
94 break
95 print _("Invalid number. Try again. (1 to %d)") % len(interfaces)
96 iface = interfaces[i - 1]
97 feed_import = find_feed_import(iface, x)
98 if feed_import:
99 iface.extra_feeds.remove(feed_import)
100 else:
101 iface.extra_feeds.append(model.Feed(x, arch = None, user_override = True))
102 writer.save_interface(iface)
103 print '\n' + _("Feed list for interface '%s' is now:") % iface.get_name()
104 if iface.extra_feeds:
105 for f in iface.extra_feeds:
106 print "- " + f.uri
107 else:
108 print _("(no feeds)")