Added a feed for Zero Install itself.
[zeroinstall.git] / zeroinstall / injector / autopolicy.py
blobc455de9e7bf2f01dbf8b27d729285ec446ea990e
1 """
2 A simple non-interactive policy.
4 This module provides a simple policy that will select, download and run a suitable set of
5 implementations. It is not interactive. This is the policy used when you run B{0launch -c}, and
6 is also the policy used to run the injector's GUI.
7 """
9 # Copyright (C) 2006, Thomas Leonard
10 # See the README file for details, or visit http://0install.net.
12 import os
13 from logging import debug, info
15 from zeroinstall.injector import model, policy, run
16 from zeroinstall.injector.handler import Handler
17 from zeroinstall import NeedDownload
19 class AutoPolicy(policy.Policy):
20 __slots__ = ['allow_downloads', 'download_only', 'dry_run']
22 def __init__(self, interface_uri, download_only = False, dry_run = False, src = False, handler = None):
23 """@param handler: (new in 0.30) handler to use, or None to create a L{Handler}"""
24 policy.Policy.__init__(self, interface_uri, handler or Handler(), src = src)
25 self.dry_run = dry_run
26 self.allow_downloads = not dry_run
27 self.download_only = download_only
28 self.dry_run = dry_run
30 def need_download(self):
31 """Decide whether we need to download anything (but don't do it!)
32 @return: true if we MUST download something (interfaces or implementations)
33 @rtype: bool
34 @postcondition: if we return False, self.stale_feeds contains any feeds which SHOULD be updated
35 """
36 old = self.allow_downloads
37 self.allow_downloads = False
38 try:
39 try:
40 self.recalculate(fetch_stale_interfaces = False)
41 debug("Recalculated: ready = %s; %d stale feeds", self.ready, len(self.stale_feeds))
42 if not self.ready: return False
43 self.start_downloading_impls()
44 except NeedDownload:
45 return True
46 return False
47 finally:
48 self.allow_downloads = old
50 def begin_iface_download(self, interface, force = False):
51 if self.dry_run or not self.allow_downloads:
52 raise NeedDownload(interface.uri)
53 else:
54 policy.Policy.begin_iface_download(self, interface, force)
56 def start_downloading_impls(self):
57 for iface, impl in self.get_uncached_implementations():
58 debug("start_downloading_impls: for %s get %s", iface, impl)
59 source = self.get_best_source(impl)
60 if not source:
61 raise model.SafeException("Implementation " + impl.id + " of "
62 "interface " + iface.get_name() + " cannot be "
63 "downloaded (no download locations given in "
64 "interface!)")
65 self.begin_impl_download(impl, source)
67 def begin_archive_download(self, download_source, success_callback, force = False):
68 if self.dry_run or not self.allow_downloads:
69 raise NeedDownload(download_source.url)
70 return policy.Policy.begin_archive_download(self, download_source, success_callback, force = force)
72 def execute(self, prog_args, main = None, wrapper = None):
73 self.start_downloading_impls()
74 self.handler.wait_for_downloads()
75 if not self.download_only:
76 run.execute(self, prog_args, dry_run = self.dry_run, main = main, wrapper = wrapper)
77 else:
78 info("Downloads done (download-only mode)")
80 def recalculate_with_dl(self):
81 self.recalculate()
82 while self.handler.monitored_downloads:
83 self.handler.wait_for_downloads()
84 self.recalculate()
86 def download_and_execute(self, prog_args, refresh = False, main = None):
87 self.recalculate_with_dl()
88 if refresh:
89 self.refresh_all(False)
90 self.recalculate_with_dl()
91 if not self.ready:
92 raise model.SafeException("Can't find all required implementations:\n" +
93 '\n'.join(["- %s -> %s" % (iface, self.implementation[iface])
94 for iface in self.implementation]))
95 self.execute(prog_args, main = main)