products/CPSRSS

changeset 142:4862ac6484e0

Updated *.po files to increase the quality of the 'po' files fix #595
author gdelaroch
date Mon, 30 May 2005 16:02:19 +0000
parents 7f5e5ecf4f7b
children 735ea46d7b1e
files i18n/de.po i18n/en.po i18n/eu.po i18n/fr.po i18n/nl.po i18n/ro.po tests/test_po.py
diffstat 7 files changed, 132 insertions(+), 49 deletions(-) [+]
line diff
     1.1 --- a/i18n/de.po
     1.2 +++ b/i18n/de.po
     1.3 @@ -13,7 +13,7 @@
     1.4  "Last-Translator: gh <georg.hennemann@dhl.com>\n"
     1.5  "Language-Team: de <rheinland@dzug.org>\n"
     1.6  "MIME-Version: 1.0\n"
     1.7 -"Content-Type: text/plain; charset=UTF-8\n"
     1.8 +"Content-Type: text/plain; charset=ISO-8859-15\n"
     1.9  "Content-Transfer-Encoding: 8bit\n"
    1.10  "Plural-Forms: nplurals=1; plural=0;\n"
    1.11  "Language-Code: de\n"
     2.1 --- a/i18n/en.po
     2.2 +++ b/i18n/en.po
     2.3 @@ -10,7 +10,7 @@
     2.4  "Last-Translator: emmanuel <epietriga@nuxeo.com>\n"
     2.5  "Language-Team: francais <fr@li.org>\n"
     2.6  "MIME-Version: 1.0\n"
     2.7 -"Content-Type: text/plain; charset=UTF-8\n"
     2.8 +"Content-Type: text/plain; charset=ISO-8859-15\n"
     2.9  "Content-Transfer-Encoding: 8bit\n"
    2.10  "Plural-Forms: nplurals=1; plural=0;\n"
    2.11  "Preferred-encodings: utf-8 latin1\n"
     3.1 --- a/i18n/eu.po
     3.2 +++ b/i18n/eu.po
     3.3 @@ -12,7 +12,7 @@
     3.4  "Last-Translator: Aitzol Naberan BurgaƱa <anaberan@codesyntax.com>\n"
     3.5  "Language-Team: Euskara <eu@li.org>\n"
     3.6  "MIME-Version: 1.0\n"
     3.7 -"Content-Type: text/plain; charset=UTF-8\n"
     3.8 +"Content-Type: text/plain; charset=ISO-8859-15\n"
     3.9  "Content-Transfer-Encoding: 8bit\n"
    3.10  "X-Generator: KBabel 1.3\n"
    3.11  "Language-Code: eu\n"
     4.1 --- a/i18n/fr.po
     4.2 +++ b/i18n/fr.po
     4.3 @@ -10,7 +10,7 @@
     4.4  "Last-Translator: emmanuel <epietriga@nuxeo.com>\n"
     4.5  "Language-Team: francais <fr@li.org>\n"
     4.6  "MIME-Version: 1.0\n"
     4.7 -"Content-Type: text/plain; charset=UTF-8\n"
     4.8 +"Content-Type: text/plain; charset=ISO-8859-15\n"
     4.9  "Content-Transfer-Encoding: 8bit\n"
    4.10  "Plural-Forms: nplurals=1; plural=0;\n"
    4.11  "Preferred-encodings: utf-8 latin1\n"
     5.1 --- a/i18n/nl.po
     5.2 +++ b/i18n/nl.po
     5.3 @@ -10,7 +10,7 @@
     5.4  "Last-Translator: emmanuel <epietriga@nuxeo.com>\n"
     5.5  "Language-Team: francais <fr@li.org>\n"
     5.6  "MIME-Version: 1.0\n"
     5.7 -"Content-Type: text/plain; charset=UTF-8\n"
     5.8 +"Content-Type: text/plain; charset=ISO-8859-15\n"
     5.9  "Content-Transfer-Encoding: 8bit\n"
    5.10  "Plural-Forms: nplurals=1; plural=0;\n"
    5.11  "Preferred-encodings: utf-8 latin1\n"
     6.1 --- a/i18n/ro.po
     6.2 +++ b/i18n/ro.po
     6.3 @@ -10,7 +10,7 @@
     6.4  "Language-Team:  <en@li.org>\n"
     6.5  "MIME-Version: 1.0\n"
     6.6  "Plural-Forms: nplurals=1; plural=0;\n"
     6.7 -"Content-Type: text/plain; charset=ISO-8859-2\n"
     6.8 +"Content-Type: text/plain; charset=ISO-8859-15\n"
     6.9  "Content-Transfer-Encoding: 8bit\n"
    6.10  "Preferred-encodings: utf-8 latin1\n"
    6.11  "X-Generator: KBabel 1.9.1\n"
     7.1 --- a/tests/test_po.py
     7.2 +++ b/tests/test_po.py
     7.3 @@ -1,3 +1,25 @@
     7.4 +# (C) Copyright 2005 Nuxeo SARL <http://nuxeo.com>
     7.5 +# (C) Copyright 2005 Unilog <http://unilog.com>
     7.6 +# Authors:
     7.7 +# M.-A. Darche <madarche@nuxeo.com>
     7.8 +# G. de la Rochemace <gdelaroch@unilog.com>
     7.9 +#
    7.10 +# This program is free software; you can redistribute it and/or modify
    7.11 +# it under the terms of the GNU General Public License version 2 as published
    7.12 +# by the Free Software Foundation.
    7.13 +#
    7.14 +# This program is distributed in the hope that it will be useful,
    7.15 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.16 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.17 +# GNU General Public License for more details.
    7.18 +#
    7.19 +# You should have received a copy of the GNU General Public License
    7.20 +# along with this program; if not, write to the Free Software
    7.21 +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
    7.22 +# 02111-1307, USA.
    7.23 +#
    7.24 +# $Id: BaseBox.py 7293 2005-04-03 23:09:11Z janguenot $
    7.25 +
    7.26  """Unit tests for .po files
    7.27  
    7.28  Adapted from plone-i18n
    7.29 @@ -7,7 +29,7 @@
    7.30  http://cvs.sourceforge.net/viewcvs.py/plone-i18n/i18n/tests/
    7.31  """
    7.32  
    7.33 -import os, os.path, sys
    7.34 +import os, os.path, sys, re
    7.35  
    7.36  if __name__ == '__main__':
    7.37      execfile(os.path.join(sys.path[0], 'framework.py'))
    7.38 @@ -53,8 +75,9 @@
    7.39  
    7.40  
    7.41  def getPoPath():
    7.42 +    product_name = __name__.split('.')[0]
    7.43      import Products
    7.44 -    product_file = getattr(Products, 'CPSRSS').__file__
    7.45 +    product_file = getattr(Products, product_name).__file__
    7.46      product_path = os.path.dirname(product_file)
    7.47      po_path = os.path.join(product_path, 'i18n')
    7.48      return po_path
    7.49 @@ -63,75 +86,135 @@
    7.50  def getPotFiles():
    7.51      po_path = getPoPath()
    7.52      po_files = [f for f in os.listdir(po_path) if f.endswith('.pot')]
    7.53 -    #print po_files
    7.54      return po_files
    7.55  
    7.56  
    7.57  def getPoFiles():
    7.58      po_path = getPoPath()
    7.59      po_files = [f for f in os.listdir(po_path) if f.endswith('.po')]
    7.60 -    #print po_files
    7.61      return po_files
    7.62  
    7.63  
    7.64 +
    7.65 +# DOTALL: Make the "." special character match any character at all, including a
    7.66 +# newline; without this flag, "." will match anything except a newline.
    7.67 +#
    7.68 +# for example:
    7.69 +#
    7.70 +# msgid "button_back"
    7.71 +# msgstr ""
    7.72 +#
    7.73 +# returns 'button_back'
    7.74 +#
    7.75 +MSGID_REGEXP = re.compile('msgid "(.*?)".*?msgstr "', re.DOTALL)
    7.76 +
    7.77  class TestPOT(ZopeTestCase.ZopeTestCase):
    7.78 -    potFile = None
    7.79 +    pot_filename = None
    7.80  
    7.81      def testNoDuplicateMsgId(self):
    7.82          """Check that there are no duplicate msgid:s in the pot files"""
    7.83 -        cmd = 'grep ^msgid %s/../i18n/%s|sort|uniq -d' % (
    7.84 -            _TESTS_PATH, potFile)
    7.85 -        status = commands.getstatusoutput(cmd)
    7.86 -        assert len(status[1]) == 0, "Duplicate msgid:s were found in the files %s :\n\n%s" \
    7.87 -                                     % (potFile, status[1])
    7.88  
    7.89 +        pot = self.pot_filename
    7.90 +        
    7.91 +        file = open(os.path.join(getPoPath(), pot), 'r')
    7.92 +        file_content = file.read()
    7.93 +        file.close()
    7.94 +
    7.95 +        # Check for duplicate msgids
    7.96 +        matches = re.finditer(MSGID_REGEXP, file_content)
    7.97 +        
    7.98 +        msgids = []
    7.99 +
   7.100 +        for match in matches:
   7.101 +            msgid = match.group(0)
   7.102 +            if msgid in msgids:
   7.103 +                assert 0, "Duplicate msgid:s were found in the file %s :\n\n%s" \
   7.104 +                       % (pot, msgid)
   7.105 +            else:
   7.106 +                msgids.append(msgid)
   7.107 +
   7.108 +
   7.109 +# DOTALL: Make the "." special character match any character at all, including a
   7.110 +# newline; without this flag, "." will match anything except a newline.
   7.111 +#
   7.112 +# #, fuzzy
   7.113 +# msgid ""
   7.114 +# msgstr ""
   7.115 +#
   7.116 +FUZZY_HEADER_ENTRY_REGEXP = re.compile('#, fuzzy\nmsgid ""\nmsgstr ""',
   7.117 +                                       re.DOTALL)
   7.118 +
   7.119 +# IGNORECASE: Perform case-insensitive matching; expressions like [A-Z] will
   7.120 +# match lowercase letters, too. This is not affected by the current locale.
   7.121 +#
   7.122 +# MULTILINE: When specified, the pattern character "^" matches at the beginning
   7.123 +# of the string and at the beginning of each line (immediately following each
   7.124 +# newline); and the pattern character "$" matches at the end of the string and
   7.125 +# at the end of each line (immediately preceding each newline). By default, "^"
   7.126 +# matches only at the beginning of the string, and "$" only at the end of the
   7.127 +# string and immediately before the newline (if any) at the end of the string.
   7.128 +#
   7.129 +# Check the charset:
   7.130 +#
   7.131 +# for example
   7.132 +#
   7.133 +# "Content-Type: text/plain; charset=ISO-8859-15\n"
   7.134 +#
   7.135 +CHARSET_REGEXP = re.compile('^"Content-Type: text/plain; charset=ISO-8859-15',
   7.136 +                            re.MULTILINE | re.IGNORECASE)
   7.137  
   7.138  class TestPoFile(ZopeTestCase.ZopeTestCase):
   7.139 -    poFile = None
   7.140 +    po_filename = None
   7.141  
   7.142      def testPoFile(self):
   7.143 -        po = self.poFile
   7.144 -        poName = po
   7.145 +        po = self.po_filename
   7.146 +
   7.147 +        po_name = po
   7.148          file = open(os.path.join(getPoPath(), po), 'r')
   7.149 +        file_content = file.read()
   7.150 +        file.seek(0)
   7.151          try:
   7.152              lines = file.readlines()
   7.153          except IOError, msg:
   7.154 -            self.fail('Can\'t read po file %s:\n%s' % (poName,msg))
   7.155 +            self.fail('Can\'t read po file %s:\n%s' % (po_name, msg))
   7.156          file.close()
   7.157  
   7.158          # Checking that the .po file has a non-fuzzy header entry, so that it
   7.159          # cannot be deleted by error.
   7.160 -        cmd = """grep -B 1 'msgid ""' %s/../i18n/%s|grep fuzzy""" % (
   7.161 -            _TESTS_PATH, poName)
   7.162 -        #print "cmd = %s" % cmd
   7.163 -        statusoutput = commands.getstatusoutput(cmd)
   7.164 -        #print "status = %s" % statusoutput[0]
   7.165 -        #print "output = %s" % statusoutput[1]
   7.166 -        self.assert_(statusoutput[0] != 0,
   7.167 -                     "Fuzzy header entry found in file %s! "
   7.168 -                     "Remove the fuzzy flag on this entry.\n\n%s"
   7.169 -                     % (poName, statusoutput[1]))
   7.170 +        match_fuzzy = re.findall(FUZZY_HEADER_ENTRY_REGEXP, file_content)
   7.171 +     
   7.172 +        match_charset = re.findall(CHARSET_REGEXP, file_content)
   7.173 +
   7.174 +        if len(match_fuzzy) != 0:
   7.175 +            assert 0, "Fuzzy header entry found in file %s! " \
   7.176 +               "Remove the fuzzy flag on this entry.\n\n" \
   7.177 +               % po_name
   7.178 + 
   7.179 +        if len(match_charset) != 1:
   7.180 +            assert 0, "Invalide charset found in file %s! \n the correct " \
   7.181 +               "line is : 'Content-Type: text/plain; charset=ISO-8859-15'\n\n" \
   7.182 +               % po_name
   7.183  
   7.184          try:
   7.185              mo = Msgfmt(lines)
   7.186          except PoSyntaxError, msg:
   7.187              self.fail('PoSyntaxError: Invalid po data syntax in file %s:\n%s' \
   7.188 -                      % (poName, msg))
   7.189 +                      % (po_name, msg))
   7.190          except SyntaxError, msg:
   7.191              self.fail('SyntaxError: Invalid po data syntax in file %s \
   7.192 -                      (Can\'t parse file with eval():\n%s' % (poName, msg))
   7.193 +                      (Can\'t parse file with eval():\n%s' % (po_name, msg))
   7.194          except Exception, msg:
   7.195              self.fail('Unknown error while parsing the po file %s:\n%s' \
   7.196 -                      % (poName, msg))
   7.197 +                      % (po_name, msg))
   7.198  
   7.199          try:
   7.200              tro = GNUTranslations(mo.getAsFile())
   7.201              #print "tro = %s" % tro
   7.202          except UnicodeDecodeError, msg:
   7.203 -            self.fail('UnicodeDecodeError in file %s:\n%s' % (poName, msg))
   7.204 +            self.fail('UnicodeDecodeError in file %s:\n%s' % (po_name, msg))
   7.205          except PoSyntaxError, msg:
   7.206              self.fail('PoSyntaxError: Invalid po data syntax in file %s:\n%s' \
   7.207 -                      % (poName, msg))
   7.208 +                      % (po_name, msg))
   7.209  
   7.210          domain = tro._info.get('domain', None)
   7.211          #print "domain = %s" % domain
   7.212 @@ -145,7 +228,7 @@
   7.213  
   7.214          self.failIf(language_old, 'The file %s has the old style language flag \
   7.215                                     set to %s. Please remove it!' \
   7.216 -                                  % (poName, language_old))
   7.217 +                                  % (po_name, language_old))
   7.218  
   7.219          self.failUnless(language, 'Po file %s has no language!' % po)
   7.220  
   7.221 @@ -158,7 +241,7 @@
   7.222          self.failUnless(fileLang == language,
   7.223              'The file %s has the wrong name or wrong language code. \
   7.224               expected: %s, got: %s' % \
   7.225 -             (poName, language, fileLang))
   7.226 +             (po_name, language, fileLang))
   7.227  
   7.228          # i18n completeness chart generation mechanism relies on case sensitive
   7.229          # Language-Code and Language-Name.
   7.230 @@ -167,7 +250,7 @@
   7.231                            '"Domain: ',
   7.232                            ]:
   7.233              cmd = """grep '%s' %s/../i18n/%s""" % (
   7.234 -                meta_info, _TESTS_PATH, poName)
   7.235 +                meta_info, _TESTS_PATH, po_name)
   7.236              #print "cmd = %s" % cmd
   7.237              statusoutput = commands.getstatusoutput(cmd)
   7.238              #print "status = %s" % statusoutput[0]
   7.239 @@ -176,37 +259,37 @@
   7.240                           "Wrong case used for metadata in file %s! "
   7.241                           "Check that your metadata is "
   7.242                           "Language-Code, Language-Name and Domain.\n\n%s"
   7.243 -                         % (poName, statusoutput[1]))
   7.244 +                         % (po_name, statusoutput[1]))
   7.245  
   7.246  
   7.247  class TestMsg(ZopeTestCase.ZopeTestCase):
   7.248 -    poFile = None
   7.249 -    potFile = None
   7.250 +    po_filename = None
   7.251 +    pot_filename = None
   7.252  
   7.253      def checkMsgExists(self,po,template):
   7.254          """Check that each existing message is translated and
   7.255             that there are no extra messages."""
   7.256 -        cmd='LC_ALL=C msgcmp --directory=%s/../i18n %s %s' % (
   7.257 -            _TESTS_PATH, po,template)
   7.258 +        cmd = 'LC_ALL=C msgcmp --directory=%s/../i18n %s %s' % (
   7.259 +            TESTS_PATH, po,template)
   7.260          status = commands.getstatusoutput(cmd)
   7.261          if status[0] != 0:
   7.262              return status
   7.263          return None
   7.264  
   7.265  
   7.266 -tests=[]
   7.267 -for potFile in getPotFiles():
   7.268 +tests = []
   7.269 +for pot_filename in getPotFiles():
   7.270      class TestOnePOT(TestPOT):
   7.271 -        potFile = potFile
   7.272 +        pot_filename = pot_filename
   7.273      tests.append(TestOnePOT)
   7.274  
   7.275 -for poFile in getPoFiles():
   7.276 +for po_filename in getPoFiles():
   7.277      class TestOneMsg(TestMsg):
   7.278 -        poFile = poFile
   7.279 +        po_filename = po_filename
   7.280      tests.append(TestOneMsg)
   7.281  
   7.282      class TestOnePoFile(TestPoFile):
   7.283 -        poFile = poFile
   7.284 +        po_filename = po_filename
   7.285      tests.append(TestOnePoFile)
   7.286  
   7.287