Fixed namespace prefix generation for elements
[zeroinstall.git] / zeroinstall / injector / policy.py
blobc22e3fbcc569d8d289a0cabe9f64a203c17a3192
1 """
2 This class brings together a L{solve.Solver} to choose a set of implmentations, a
3 L{fetch.Fetcher} to download additional components, and the user's configuration
4 settings.
5 """
7 # Copyright (C) 2009, Thomas Leonard
8 # See the README file for details, or visit http://0install.net.
10 from zeroinstall import _
11 from logging import info
13 from zeroinstall import SafeException
14 from zeroinstall.injector import driver
15 from zeroinstall.injector.model import Interface, Implementation, network_offline
16 from zeroinstall.injector.config import load_config
18 class Policy(object):
19 """@deprecated: Use Driver instead."""
20 __slots__ = ['driver']
22 help_with_testing = property(lambda self: self.config.help_with_testing,
23 lambda self, value: setattr(self.config, 'help_with_testing', bool(value)))
25 network_use = property(lambda self: self.config.network_use,
26 lambda self, value: setattr(self.config, 'network_use', value))
28 freshness = property(lambda self: self.config.freshness,
29 lambda self, value: setattr(self.config, 'freshness', str(value)))
31 target_arch = property(lambda self: self.driver.target_arch,
32 lambda self, value: setattr(self.driver, 'target_arch', value))
34 implementation = property(lambda self: self.solver.selections)
36 ready = property(lambda self: self.solver.ready)
37 config = property(lambda self: self.driver.config)
38 requirements = property(lambda self: self.driver.requirements)
40 # (was used by 0test)
41 handler = property(lambda self: self.config.handler,
42 lambda self, value: setattr(self.config, 'handler', value))
45 def __init__(self, root = None, handler = None, src = None, command = -1, config = None, requirements = None):
46 """
47 @param requirements: Details about the program we want to run
48 @type requirements: L{requirements.Requirements}
49 @param config: The configuration settings to use, or None to load from disk.
50 @type config: L{config.Config}
51 Note: all other arguments are deprecated (since 0launch 0.52)
52 """
53 if requirements is None:
54 from zeroinstall.injector.requirements import Requirements
55 requirements = Requirements(root)
56 requirements.source = bool(src) # Root impl must be a "src" machine type
57 if command == -1:
58 if src:
59 command = 'compile'
60 else:
61 command = 'run'
62 requirements.command = command
63 else:
64 assert root == src == None
65 assert command == -1
67 if config is None:
68 config = load_config(handler)
69 else:
70 assert handler is None, "can't pass a handler and a config"
72 self.driver = driver.Driver(config = config, requirements = requirements)
74 @property
75 def fetcher(self):
76 return self.config.fetcher
78 @property
79 def watchers(self):
80 return self.driver.watchers
82 @property
83 def solver(self):
84 return self.driver.solver
86 def save_config(self):
87 self.config.save_globals()
89 def usable_feeds(self, iface):
90 """Generator for C{iface.feeds} that are valid for our architecture.
91 @rtype: generator
92 @see: L{arch}"""
93 a = self.driver.target_arch
94 if iface.uri != self.root:
95 # note: assumes that only the root arch may be different (e.g. if using --source)
96 a = a.child_arch
97 return self.config.iface_cache.usable_feeds(iface, a)
99 def is_stale(self, feed):
100 """@deprecated: use IfaceCache.is_stale"""
101 return self.config.iface_cache.is_stale(feed, self.config.freshness)
103 def get_implementation_path(self, impl):
104 """Return the local path of impl.
105 @rtype: str
106 @raise zeroinstall.zerostore.NotStored: if it needs to be added to the cache first."""
107 assert isinstance(impl, Implementation)
108 return impl.local_path or self.config.stores.lookup_any(impl.digests)
110 def get_implementation(self, interface):
111 """Get the chosen implementation.
112 @type interface: Interface
113 @rtype: L{model.Implementation}
114 @raise SafeException: if interface has not been fetched or no implementation could be
115 chosen."""
116 assert isinstance(interface, Interface)
118 try:
119 return self.implementation[interface]
120 except KeyError:
121 raise SafeException(_("No usable implementation found for '%s'.") % interface.uri)
123 def get_cached(self, impl):
124 """Check whether an implementation is available locally.
125 @type impl: model.Implementation
126 @rtype: bool
128 return impl.is_available(self.config.stores)
130 def get_uncached_implementations(self):
131 return self.driver.get_uncached_implementations()
133 def refresh_all(self, force = True):
134 """Start downloading all feeds for all selected interfaces.
135 @param force: Whether to restart existing downloads."""
136 return self.solve_with_downloads(force = True)
138 def get_feed_targets(self, feed):
139 """@deprecated: use IfaceCache.get_feed_targets"""
140 return self.config.iface_cache.get_feed_targets(feed)
142 def solve_with_downloads(self, force = False, update_local = False):
143 return self.driver.solve_with_downloads(force, update_local)
145 def solve_and_download_impls(self, refresh = False, select_only = False):
146 return self.driver.solve_and_download_impls(refresh, select_only)
148 def need_download(self):
149 return self.driver.need_download()
151 def download_uncached_implementations(self):
152 return self.driver.download_uncached_implementations()
154 def download_icon(self, interface, force = False):
155 """Download an icon for this interface and add it to the
156 icon cache. If the interface has no icon or we are offline, do nothing.
157 @return: the task doing the import, or None
158 @rtype: L{tasks.Task}"""
159 if self.network_use == network_offline:
160 info("Not downloading icon for %s as we are off-line", interface)
161 return
163 return self.fetcher.download_icon(interface, force)
165 def get_interface(self, uri):
166 """@deprecated: use L{iface_cache.IfaceCache.get_interface} instead"""
167 import warnings
168 warnings.warn("Policy.get_interface is deprecated!", DeprecationWarning, stacklevel = 2)
169 return self.config.iface_cache.get_interface(uri)
171 @property
172 def command(self):
173 return self.requirements.command
175 @property
176 def root(self):
177 return self.requirements.interface_uri
179 _config = None
180 def get_deprecated_singleton_config():
181 global _config
182 if _config is None:
183 _config = load_config()
184 return _config