Moved GUI to its own subdir.
[zeroinstall.git] / policy.py
blobff9e43c2f485949f020a0d75179c3486e76a0031
1 from model import *
2 import basedir
3 from namespaces import *
4 import ConfigParser
5 import reader
7 class Policy(object):
8 __slots__ = ['root', 'implementation', 'watchers',
9 'help_with_testing', 'network_use', 'updates']
11 def __init__(self):
12 self.root = None
13 self.implementation = {} # Interface -> Implementation
14 self.watchers = []
15 self.help_with_testing = False
16 self.network_use = network_minimal
17 self.updates = []
19 path = basedir.load_first_config(config_site, config_prog, 'global')
20 if path:
21 config = ConfigParser.ConfigParser()
22 config.read(path)
23 self.help_with_testing = config.getboolean('global',
24 'help_with_testing')
25 self.network_use = config.get('global', 'network_use')
26 assert self.network_use in network_levels
28 def set_root_iterface(self, root):
29 assert isinstance(root, Interface)
30 self.root = root
32 def save_config(self):
33 config = ConfigParser.ConfigParser()
34 config.add_section('global')
36 config.set('global', 'help_with_testing', self.help_with_testing)
37 config.set('global', 'network_use', self.network_use)
39 path = basedir.save_config_path(config_site, config_prog)
40 path = os.path.join(path, 'global')
41 config.write(file(path + '.new', 'w'))
42 os.rename(path + '.new', path)
44 def recalculate(self):
45 self.implementation = {}
46 self.updates = []
47 def process(iface):
48 if not iface.uptodate:
49 reader.update_from_cache(iface)
50 assert iface.uptodate
51 impl = self.get_best_implementation(iface)
52 if impl:
53 self.implementation[iface] = impl
54 for d in impl.dependencies.values():
55 process(d.get_interface())
56 process(self.root)
57 for w in self.watchers: w()
59 def get_best_implementation(self, iface):
60 if not iface.implementations:
61 return None
62 impls = iface.implementations.values()
63 best = impls[0]
64 for x in impls[1:]:
65 if self.compare(iface, x, best) < 0:
66 best = x
67 if self.is_unusable(best):
68 return None
69 return best
71 def compare(self, interface, b, a):
72 a_stab = a.get_stability()
73 b_stab = b.get_stability()
75 # Usable ones come first
76 r = cmp(self.is_unusable(b), self.is_unusable(a))
77 if r: return r
79 # Preferred versions come first
80 r = cmp(a_stab == preferred, b_stab == preferred)
81 if r: return r
83 if self.network_use != network_full:
84 r = cmp(a.get_cached(), b.get_cached())
85 if r: return r
87 # Stability
88 policy = interface.stability_policy
89 if not policy:
90 if self.help_with_testing: policy = testing
91 else: policy = stable
93 if a_stab >= policy: a_stab = preferred
94 if b_stab >= policy: b_stab = preferred
96 r = cmp(a_stab, b_stab)
97 if r: return r
99 r = cmp(a.version, b.version)
100 if r: return r
102 if self.network_use != network_full:
103 r = cmp(a.get_cached(), b.get_cached())
104 if r: return r
106 return cmp(a.path, b.path)
108 def get_ranked_implementations(self, iface):
109 impls = iface.implementations.values()
110 impls.sort(lambda a, b: self.compare(iface, a, b))
111 return impls
113 def is_unusable(self, impl):
114 if impl.get_stability() <= buggy:
115 return True
116 if self.network_use == network_offline and not impl.get_cached():
117 return True
118 return False
120 # Singleton instance used everywhere...
121 policy = Policy()
122 policy.save_config()