[Zope3-checkins] CVS: Zope3/src/zope/app/services/translation - filters.py:1.1 configure.zcml:1.4 gettextexportfilter.py:NONE gettextimportfilter.py:NONE

Stephan Richter srichter@cbu.edu
Tue, 25 Mar 2003 13:22:07 -0500


Update of /cvs-repository/Zope3/src/zope/app/services/translation
In directory cvs.zope.org:/tmp/cvs-serv24080/src/zope/app/services/translation

Modified Files:
	configure.zcml 
Added Files:
	filters.py 
Removed Files:
	gettextexportfilter.py gettextimportfilter.py 
Log Message:
Made LocalTranslationService work again. Refactored all Filters to simple
filters.py module. Reactivated XML-RPC interface.


=== Added File Zope3/src/zope/app/services/translation/filters.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Translation Service Message Export and Import Filters

$Id: filters.py,v 1.1 2003/03/25 18:21:35 srichter Exp $
"""
import time, re
from types import StringTypes

from zope.i18n.interfaces import IMessageExportFilter
from zope.i18n.interfaces import IMessageImportFilter
from zope.i18n.interfaces import IWriteTranslationService


class GettextExportFilter:

    __implements__ =  IMessageExportFilter
    __used_for__ = IWriteTranslationService


    def __init__(self, service):
        self.service = service

    def exportMessages(self, domains, languages):
        'See IMessageExportFilter'

        if isinstance(domains, StringTypes):
            domain = domains
        elif len(domains) == 1:
            domain = domains[0]
        else:
            raise TypeError, \
                  'Only one domain at a time is supported for gettext export.'

        if isinstance(languages, StringTypes):
            language = languages
        elif len(languages) == 1:
            language = languages[0]
        else:
            raise TypeError, \
                'Only one language at a time is supported for gettext export.'

        dt = time.time()
        dt = time.localtime(dt)
        dt = time.strftime('%Y/%m/%d %H:%M', dt)
        output = _file_header %(dt, language.encode('UTF-8'),
                                domain.encode('UTF-8'))
        service = self.service

        for msgid in service.getMessageIdsOfDomain(domain):
            msgstr = service.translate(domain, msgid,
                                       target_language=language)
            msgstr = msgstr.encode('UTF-8')
            msgid = msgid.encode('UTF-8')
            output += _msg_template %(msgid, msgstr)

        return output



class GettextImportFilter:

    __implements__ =  IMessageImportFilter
    __used_for__ = IWriteTranslationService


    def __init__(self, service):
        self.service = service

    def importMessages(self, domains, languages, file):
        'See IMessageImportFilter'

        if isinstance(domains, StringTypes):
            domain = domains
        elif len(domains) == 1:
            domain = domains[0]
        else:
            raise TypeError, \
                  'Only one domain at a time is supported for gettext export.'

        if isinstance(languages, StringTypes):
            language = languages
        elif len(languages) == 1:
            language = languages[0]
        else:
            raise TypeError, \
                'Only one language at a time is supported for gettext export.'

        result = parseGetText(file.readlines())[3]
        headers = parserHeaders(''.join(result[('',)][1]))
        del result[('',)]
        charset = extractCharset(headers['content-type'])
        service = self.service
        for msg in result.items():
            msgid = unicode(''.join(msg[0]), charset)
            msgid = msgid.replace('\\n', '\n')
            msgstr = unicode(''.join(msg[1][1]), charset)
            msgstr = msgstr.replace('\\n', '\n')
            service.addMessage(domain, msgid, msgstr, language)



def extractCharset(header):
    charset = header.split('charset=')[-1]
    return charset.lower()


def parserHeaders(headers_text):
    headers = {}
    for line in headers_text.split('\\n'):
        name = line.split(':')[0]
        value = ''.join(line.split(':')[1:])
        headers[name.lower()] = value

    return headers


def parseGetText(content):
    # The regular expressions
    com = re.compile('^#.*')
    msgid = re.compile(r'^ *msgid *"(.*?[^\\]*)"')
    msgstr = re.compile(r'^ *msgstr *"(.*?[^\\]*)"')
    re_str = re.compile(r'^ *"(.*?[^\\])"')
    blank = re.compile(r'^\s*$')

    trans = {}
    pointer = 0
    state = 0
    COM, MSGID, MSGSTR = [], [], []
    while pointer < len(content):
        line = content[pointer]
        #print 'STATE:', state
        #print 'LINE:', line, content[pointer].strip()
        if state == 0:
            COM, MSGID, MSGSTR = [], [], []
            if com.match(line):
                COM.append(line.strip())
                state = 1
                pointer = pointer + 1
            elif msgid.match(line):
                MSGID.append(msgid.match(line).group(1))
                state = 2
                pointer = pointer + 1
            elif blank.match(line):
                pointer = pointer + 1
            else:
                raise 'ParseError', 'state 0, line %d\n' % (pointer + 1)
        elif state == 1:
            if com.match(line):
                COM.append(line.strip())
                state = 1
                pointer = pointer + 1
            elif msgid.match(line):
                MSGID.append(msgid.match(line).group(1))
                state = 2
                pointer = pointer + 1
            elif blank.match(line):
                pointer = pointer + 1
            else:
                raise 'ParseError', 'state 1, line %d\n' % (pointer + 1)

        elif state == 2:
            if com.match(line):
                COM.append(line.strip())
                state = 2
                pointer = pointer + 1
            elif re_str.match(line):
                MSGID.append(re_str.match(line).group(1))
                state = 2
                pointer = pointer + 1
            elif msgstr.match(line):
                MSGSTR.append(msgstr.match(line).group(1))
                state = 3
                pointer = pointer + 1
            elif blank.match(line):
                pointer = pointer + 1
            else:
                raise 'ParseError', 'state 2, line %d\n' % (pointer + 1)

        elif state == 3:
            if com.match(line) or msgid.match(line):
                # print "\nEn", language, "detected", MSGID
                trans[tuple(MSGID)] = (COM, MSGSTR)
                state = 0
            elif re_str.match(line):
                MSGSTR.append(re_str.match(line).group(1))
                state = 3
                pointer = pointer + 1
            elif blank.match(line):
                pointer = pointer + 1
            else:
                raise 'ParseError', 'state 3, line %d\n' % (pointer + 1)

    # the last also goes in
    if tuple(MSGID):
        trans[tuple(MSGID)] = (COM, MSGSTR)

    return COM, MSGID, MSGSTR, trans


_file_header = '''
msgid ""
msgstr ""
"Project-Id-Version: Zope 3\\n"
"PO-Revision-Date: %s\\n"
"Last-Translator: Zope 3 Gettext Export Filter\\n"
"Zope-Language: %s\\n"
"Zope-Domain: %s\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
'''

_msg_template = '''
msgid "%s"
msgstr "%s"
'''


=== Zope3/src/zope/app/services/translation/configure.zcml 1.3 => 1.4 ===
--- Zope3/src/zope/app/services/translation/configure.zcml:1.3	Mon Dec 30 21:52:05 2002
+++ Zope3/src/zope/app/services/translation/configure.zcml	Tue Mar 25 13:21:35 2003
@@ -5,13 +5,15 @@
    xmlns:gts="http://namespaces.zope.org/gts">
 
 <!-- Register the Translation Service as a content object -->
-<content class="zope.app.services.translation.translationservice.TranslationService">
+<content 
+  class="zope.app.services.translation.translationservice.TranslationService">
    <factory id="TranslationService" permission="zope.ManageServices" />
    <require permission="zope.Public"
        interface="zope.i18n.interfaces.ITranslationService" />
    <require permission="zope.ManageServices"
        interface="zope.app.interfaces.container.IContainer" />
-   <implements interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
+   <implements 
+       interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
 </content>
 
 <browser:icon name="zmi_icon" for="zope.i18n.interfaces.ITranslationService"
@@ -25,26 +27,29 @@
 
   <require permission="zope.ManageServices"
       attributes="setMessage getMessageIds" />
-  <implements interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
+  <implements 
+      interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
+  <implements 
       interface="zope.i18n.interfaces.IWriteMessageCatalog" />
-
-
 </content>
 
-<factory component="zope.app.services.translation.messagecatalog.MessageCatalog" id="Message Catalog"/>
+<factory 
+     component="zope.app.services.translation.messagecatalog.MessageCatalog" 
+     id="Message Catalog"/>
+
+<include package=".xmlrpc" />
 
 <!-- Setup Export and Import Filters -->
-<adapter factory="zope.app.services.translation.gettextexportfilter.GettextExportFilter"
+<adapter 
+    factory="zope.app.services.translation.filters.GettextExportFilter"
     for="zope.i18n.interfaces.IWriteTranslationService"
     provides="zope.i18n.interfaces.IMessageExportFilter" />
 
-<adapter factory="zope.app.services.translation.gettextimportfilter.GettextImportFilter"
+<adapter factory="zope.app.services.translation.filters.GettextImportFilter"
     for="zope.i18n.interfaces.IWriteTranslationService"
     provides="zope.i18n.interfaces.IMessageImportFilter" />
 
 <gts:registerTranslations directory="./locale" />
 <gts:defaultLanguages languages="en" />
-
-<include package=".Views" />
 
 </zopeConfigure>

=== Removed File Zope3/src/zope/app/services/translation/gettextexportfilter.py ===

=== Removed File Zope3/src/zope/app/services/translation/gettextimportfilter.py ===