From 44be39c6224b34fb188f59462acaeb9ca572a15c Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Tue, 1 Jun 2010 21:03:50 +0100 Subject: [PATCH] Store summaries in all languages and choose the right one when asked --- tests/Local.xml | 7 ++++++- tests/basetest.py | 10 +++++++++- tests/testmodel.py | 30 +++++++++++++++++++++++++++-- zeroinstall/injector/model.py | 45 ++++++++++++++++++++++--------------------- 4 files changed, 66 insertions(+), 26 deletions(-) diff --git a/tests/Local.xml b/tests/Local.xml index 8786612..b062215 100644 --- a/tests/Local.xml +++ b/tests/Local.xml @@ -1,8 +1,13 @@ - Echo Local feed + Local feed (English) + Local feed (English GB) + Fuente local + + English + Español diff --git a/tests/basetest.py b/tests/basetest.py index 3ac8456..be99f4e 100755 --- a/tests/basetest.py +++ b/tests/basetest.py @@ -10,7 +10,7 @@ os.environ['LANGUAGE'] = 'C' sys.path.insert(0, '..') from zeroinstall.injector import qdom -from zeroinstall.injector import iface_cache, download, distro +from zeroinstall.injector import iface_cache, download, distro, model from zeroinstall.zerostore import Store; Store._add_with_helper = lambda *unused: False from zeroinstall import support, helpers from zeroinstall.support import basedir @@ -33,6 +33,14 @@ def test_execvp(prog, args): os.execvp = test_execvp +test_locale = (None, None) +assert model.locale +class TestLocale: + LC_MESSAGES = 0 + def getlocale(self, x): + return test_locale +model.locale = TestLocale() + class BaseTest(unittest.TestCase): def setUp(self): warnings.resetwarnings() diff --git a/tests/testmodel.py b/tests/testmodel.py index 181ab1f..7025aad 100755 --- a/tests/testmodel.py +++ b/tests/testmodel.py @@ -1,7 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import basetest from basetest import BaseTest, empty_feed -import sys +import sys, os, locale from xml.dom import minidom import unittest from StringIO import StringIO @@ -9,6 +10,8 @@ from StringIO import StringIO sys.path.insert(0, '..') from zeroinstall.injector import model, qdom, iface_cache +mydir = os.path.dirname(__file__) + class TestModel(BaseTest): def testLevels(self): assert model.network_offline in model.network_levels @@ -90,12 +93,35 @@ class TestModel(BaseTest): assert main_feed.get_metadata('a', 'a') == [] assert e.getAttribute('foo') == 'bar' + def testLocale(self): + local_path = os.path.join(mydir, 'Local.xml') + dom = qdom.parse(open(local_path)) + feed = model.ZeroInstallFeed(dom, local_path = local_path) + self.assertEquals("Local feed", feed.summary) + self.assertEquals("English", feed.description) + + self.assertEquals(4, len(feed.summaries)) + self.assertEquals(2, len(feed.descriptions)) + + try: + basetest.test_locale = ('es_ES', 'UTF8') + + self.assertEquals("Fuente local", feed.summary) + self.assertEquals(u"Español", feed.description) + + basetest.test_locale = ('fr_FR', 'UTF8') + + self.assertEquals("Local feed", feed.summary) + self.assertEquals("English", feed.description) + finally: + basetest.test_locale = (None, None) + def testStabPolicy(self): i = model.Interface('http://foo') self.assertEquals(None, i.stability_policy) i.set_stability_policy(model.buggy) self.assertEquals(model.buggy, i.stability_policy) - + def testImpl(self): i = model.Interface('http://foo') a = model.ZeroInstallImplementation(i, 'foo', None) diff --git a/zeroinstall/injector/model.py b/zeroinstall/injector/model.py index 816e0eb..c18fecd 100644 --- a/zeroinstall/injector/model.py +++ b/zeroinstall/injector/model.py @@ -68,6 +68,12 @@ def _join_arch(osys, machine): if osys == machine == None: return None return "%s-%s" % (osys or '*', machine or '*') +def _best_language_match(options): + (language, encoding) = locale.getlocale(locale.LC_MESSAGES) + return (options.get(language, None) or + options.get(language.split('_', 1)[0], None) or + options.get(None, None)) + class Stability(object): """A stability rating. Each implementation has an upstream stability rating and, optionally, a user-set rating.""" @@ -610,8 +616,10 @@ class ZeroInstallFeed(object): @ivar implementations: Implementations in this feed, indexed by ID @type implementations: {str: L{Implementation}} @ivar name: human-friendly name - @ivar summary: short textual description - @ivar description: long textual description + @ivar summaries: short textual description (in various languages, since 0.49) + @type summaries: {str: str} + @ivar descriptions: long textual description (in various languages, since 0.49) + @type descriptions: {str: str} @ivar last_modified: timestamp on signature @ivar last_checked: time feed was last successfully downloaded and updated @ivar feeds: list of elements in this feed @@ -621,7 +629,7 @@ class ZeroInstallFeed(object): @ivar metadata: extra elements we didn't understand """ # _main is deprecated - __slots__ = ['url', 'implementations', 'name', 'description', 'summary', + __slots__ = ['url', 'implementations', 'name', 'descriptions', 'summaries', 'last_checked', 'last_modified', 'feeds', 'feed_for', 'metadata'] def __init__(self, feed_element, local_path = None, distro = None): @@ -634,8 +642,8 @@ class ZeroInstallFeed(object): assert feed_element self.implementations = {} self.name = None - self.summary = None - self.description = "" + self.summaries = {} # { lang: str } + self.descriptions = {} # { lang: str } self.last_modified = None self.feeds = [] self.feed_for = set() @@ -665,17 +673,6 @@ class ZeroInstallFeed(object): "You can get a newer version from http://0install.net") % {'min_version': min_injector_version, 'version': version}) - def language_matches(nodelang): - (language, encoding) = locale.getlocale(locale.LC_MESSAGES) - if nodelang == None: - return True - if language == None: - return False - if nodelang.find('_') != -1: - return nodelang == language - else: - return language.startswith(nodelang + "_") - for x in feed_element.childNodes: if x.uri != XMLNS_IFACE: self.metadata.append(x) @@ -683,13 +680,9 @@ class ZeroInstallFeed(object): if x.name == 'name': self.name = x.content elif x.name == 'description': - lang = x.attrs.get("http://www.w3.org/XML/1998/namespace lang", None) - if language_matches(lang): - self.description = x.content + self.descriptions[x.attrs.get("http://www.w3.org/XML/1998/namespace lang", None)] = x.content elif x.name == 'summary': - lang = x.attrs.get("http://www.w3.org/XML/1998/namespace lang", None) - if language_matches(lang): - self.summary = x.content + self.summaries[x.attrs.get("http://www.w3.org/XML/1998/namespace lang", None)] = x.content elif x.name == 'feed-for': feed_iface = x.getAttribute('interface') if not feed_iface: @@ -927,6 +920,14 @@ class ZeroInstallFeed(object): """Return a list of interface metadata elements with this name and namespace URI.""" return [m for m in self.metadata if m.name == name and m.uri == uri] + @property + def summary(self): + return _best_language_match(self.summaries) + + @property + def description(self): + return _best_language_match(self.descriptions) + class DummyFeed(object): """Temporary class used during API transition.""" last_modified = None -- 2.11.4.GIT