From 2643650aecf4771f574c6fbbe1e9b4b20e1d9a15 Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Tue, 18 May 2010 20:37:49 +0100 Subject: [PATCH] Prefer known languages, but a bad match is better than nothing --- tests/Langs.xml | 6 +++--- tests/testreader.py | 2 +- tests/testsolver.py | 17 +++++++++++++++-- zeroinstall/injector/model.py | 5 +++-- zeroinstall/injector/solver.py | 28 ++++++++++++++-------------- 5 files changed, 36 insertions(+), 22 deletions(-) diff --git a/tests/Langs.xml b/tests/Langs.xml index 09416e6..d2bacba 100644 --- a/tests/Langs.xml +++ b/tests/Langs.xml @@ -24,13 +24,13 @@ - + - + @@ -40,7 +40,7 @@ - + diff --git a/tests/testreader.py b/tests/testreader.py index 94a59a6..c5a139e 100755 --- a/tests/testreader.py +++ b/tests/testreader.py @@ -255,7 +255,7 @@ class TestReader(BaseTest): self.assertEquals('fr', iface.implementations['sha1=124'].langs) self.assertEquals('fr en_GB', iface.implementations['sha1=234'].langs) - self.assertEquals(None, iface.implementations['sha1=345'].langs) + self.assertEquals('', iface.implementations['sha1=345'].langs) if __name__ == '__main__': unittest.main() diff --git a/tests/testsolver.py b/tests/testsolver.py index ad78bc8..cd7cece 100755 --- a/tests/testsolver.py +++ b/tests/testsolver.py @@ -144,30 +144,43 @@ class TestSolver(BaseTest): iface = iface_cache.get_interface('http://foo/Langs.xml') reader.update(iface, 'Langs.xml') + # 1 is the oldest, but the only one in our language binary_arch = arch.get_architecture(None, 'arch_1') s.solve('http://foo/Langs.xml', binary_arch) assert s.ready self.assertEquals('sha1=1', s.selections[iface].id) + # 6 is the newest, and close enough, even though not + # quite the right locale binary_arch = arch.get_architecture(None, 'arch_2') s.solve('http://foo/Langs.xml', binary_arch) assert s.ready - self.assertEquals('sha1=4', s.selections[iface].id) + self.assertEquals('sha1=6', s.selections[iface].id) + # 9 is the newest, although 7 is a closer match binary_arch = arch.get_architecture(None, 'arch_3') s.solve('http://foo/Langs.xml', binary_arch) assert s.ready - self.assertEquals('sha1=8', s.selections[iface].id) + self.assertEquals('sha1=9', s.selections[iface].id) + # 11 is the newest we understand binary_arch = arch.get_architecture(None, 'arch_4') s.solve('http://foo/Langs.xml', binary_arch) assert s.ready self.assertEquals('sha1=11', s.selections[iface].id) + # 13 is the newest we understand binary_arch = arch.get_architecture(None, 'arch_5') s.solve('http://foo/Langs.xml', binary_arch) assert s.ready self.assertEquals('sha1=13', s.selections[iface].id) + + # We don't understand any, so pick the newest + s.langs = ['es_ES'] + binary_arch = arch.get_architecture(None, 'arch_2') + s.solve('http://foo/Langs.xml', binary_arch) + assert s.ready + self.assertEquals('sha1=6', s.selections[iface].id) finally: locale.setlocale(locale.LC_ALL, '') diff --git a/zeroinstall/injector/model.py b/zeroinstall/injector/model.py index df88b94..e9933ea 100644 --- a/zeroinstall/injector/model.py +++ b/zeroinstall/injector/model.py @@ -394,6 +394,7 @@ class Implementation(object): @ivar user_stability: the stability as set by the user @type upstream_stability: [insecure | buggy | developer | testing | stable | packaged | preferred] @ivar langs: natural languages supported by this package + @type langs: str @ivar requires: interfaces this package depends on @type requires: [L{Dependency}] @ivar main: the default file to execute when running as a program @@ -426,7 +427,7 @@ class Implementation(object): self.version = None self.released = None self.download_sources = [] - self.langs = None + self.langs = "" self.machine = None self.bindings = [] @@ -768,7 +769,7 @@ class ZeroInstallFeed(object): impl.main = item_main impl.released = item_attrs.get('released', None) - impl.langs = item_attrs.get('langs', None) + impl.langs = item_attrs.get('langs', '') size = item.getAttribute('size') if size: diff --git a/zeroinstall/injector/solver.py b/zeroinstall/injector/solver.py index 62adaaa..6efb895 100644 --- a/zeroinstall/injector/solver.py +++ b/zeroinstall/injector/solver.py @@ -101,7 +101,9 @@ class Solver(object): raise NotImplementedError("Abstract") class SATSolver(Solver): - """Converts the problem to a set of pseudo-boolean constraints and uses a PB solver to solve them.""" + """Converts the problem to a set of pseudo-boolean constraints and uses a PB solver to solve them. + @ivar langs: the preferred languages (e.g. ["es_ES", "en"]). Initialised to the current locale. + @type langs: str""" def __init__(self, network_use, iface_cache, stores, extra_restrictions = None): """ @param network_use: how much use to make of the network @@ -120,12 +122,23 @@ class SATSolver(Solver): self.help_with_testing = False self.extra_restrictions = extra_restrictions or {} + self.langs = [locale.getlocale()[0] or 'en'] + def compare(self, interface, b, a, arch): """Compare a and b to see which would be chosen first. Does not consider whether the implementations are usable (check for that yourself first). @param interface: The interface we are trying to resolve, which may not be the interface of a or b if they are from feeds. @rtype: int""" + + # Languages we understand come first + a_langs = (a.langs or 'en').split() + b_langs = (b.langs or 'en').split() + main_langs = set(l.split('_')[0] for l in self.langs) + r = cmp(any(l.split('_')[0] in main_langs for l in a_langs), + any(l.split('_')[0] in main_langs for l in b_langs)) + if r: return r + a_stab = a.get_stability() b_stab = b.get_stability() @@ -264,19 +277,6 @@ class SATSolver(Solver): if impl.machine == 'src': return _("Source code") return _("Unsupported machine type") - if impl.langs: - lang_found = False - current_locale = locale.getlocale()[0] - for lang in impl.langs.split(): - if '_' not in lang: - current_lang = current_locale.split('_')[0] - else: - current_lang = current_locale - if lang == current_lang: - lang_found = True - break - if not lang_found: - return _("Unsupported language") return None def usable_feeds(iface, arch): -- 2.11.4.GIT