"""
A simple non-interactive policy.
This module provides a simple policy that will select, download and run a suitable set of
implementations. It is not interactive. This is the policy used when you run B{0launch -c}, and
is also the policy used to run the injector's GUI.
"""
# Copyright (C) 2006, Thomas Leonard
# See the README file for details, or visit http://0install.net.
import os
from logging import debug, info
from zeroinstall.injector import model, policy, run, handler
from zeroinstall import NeedDownload
class AutoPolicy(policy.Policy):
__slots__ = ['allow_downloads', 'download_only', 'dry_run']
def __init__(self, interface_uri, download_only = False, dry_run = False, src = False):
policy.Policy.__init__(self, interface_uri, handler.Handler(), src = src)
self.dry_run = dry_run
self.allow_downloads = not dry_run
self.download_only = download_only
self.dry_run = dry_run
def need_download(self):
"""Decide whether we need to download anything (but don't do it!)
@return: true if we MUST download something (interfaces or implementations)
@rtype: bool
@postcondition: if we return False, self.stale_feeds contains any feeds which SHOULD be updated
"""
old = self.allow_downloads
self.allow_downloads = False
try:
try:
self.recalculate(fetch_stale_interfaces = False)
debug("Recalculated: ready = %s; %d stale feeds", self.ready, len(self.stale_feeds))
if not self.ready: return False
self.start_downloading_impls()
except NeedDownload:
return True
return False
finally:
self.allow_downloads = old
def begin_iface_download(self, interface, force = False):
if self.dry_run or not self.allow_downloads:
raise NeedDownload(interface.uri)
else:
policy.Policy.begin_iface_download(self, interface, force)
def start_downloading_impls(self):
for iface, impl in self.get_uncached_implementations():
debug("start_downloading_impls: for %s get %s", iface, impl)
source = self.get_best_source(impl)
if not source:
raise model.SafeException("Implementation " + impl.id + " of "
"interface " + iface.get_name() + " cannot be "
"downloaded (no download locations given in "
"interface!)")
self.begin_impl_download(impl, source)
def begin_archive_download(self, download_source, success_callback, force = False):
if self.dry_run or not self.allow_downloads:
raise NeedDownload(download_source.url)
return policy.Policy.begin_archive_download(self, download_source, success_callback, force = force)
def execute(self, prog_args, main = None, wrapper = None):
self.start_downloading_impls()
self.handler.wait_for_downloads()
if not self.download_only:
run.execute(self, prog_args, dry_run = self.dry_run, main = main, wrapper = wrapper)
else:
info("Downloads done (download-only mode)")
def recalculate_with_dl(self):
self.recalculate()
while self.handler.monitored_downloads:
self.handler.wait_for_downloads()
self.recalculate()
def download_and_execute(self, prog_args, refresh = False, main = None):
self.recalculate_with_dl()
if refresh:
self.refresh_all(False)
self.recalculate_with_dl()
if not self.ready:
raise model.SafeException("Can't find all required implementations:\n" +
'\n'.join(["- %s -> %s" % (iface, self.implementation[iface])
for iface in self.implementation]))
self.execute(prog_args, main = main)
syntax highlighted by Code2HTML, v. 0.9.1