nuxeo-localizer
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Nuxeo-localizer] problems rewriting strings in the MessageCatalog


From: Juan David Ibáñez Palomar
Subject: Re: [Nuxeo-localizer] problems rewriting strings in the MessageCatalog
Date: Tue, 23 Jul 2002 12:17:21 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020610 Debian/1.0.0-1



Attached are two files that should solve your problem, if they don't
just tell me.


Luistxo Fernandez wrote:

Problems in the new MessageCatalog interface

I want to change a string message in a given language. To search for it, I have 
to uncheck the 'Only untranslated messages' option, and search for the string.

My string´s msgid is 'Udala'. So, I search for 'Udala' and it happens that there are 3 matches...
Ondarroako Udala
Udala
Udalaren kredituak

The interface lets me only change the first string. When I click in the 2nd option, which 
is the one I want to edit, it says "There aren't messages".

It appears to me that that click makes the situation go back to the "only 
untranstaled messages" option, so that already translated messages disappear...

Luistxo



_______________________________________________
Nuxeo-localizer mailing list
address@hidden
http://mail.freesoftware.fsf.org/mailman/listinfo/nuxeo-localizer




--
J. David Ibáñez, http://www.j-david.net
Software Engineer / Ingénieur Logiciel / Ingeniero de Software


Initialize variables
" method="post"> "> "> "> "> ">

">

"> ">
"> "> "> checked>
"> ">
0"> "><< ">>>
bgcolor="yellow" bgcolor="#DDDDDD"> ">
There aren't messages.
# Localizer, Zope product that provides internationalization services
# Copyright (C) 2000-2002  Juan David Ibáñez Palomar <address@hidden>

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

"""
This module provides the MessageCatalog base class, which
provides message catalogs for the web.
"""
__version__ = "$Revision: 1.23 $"

# Python
import re, time
from types import StringType
from urllib import quote

# Zope
from Globals import  MessageDialog, PersistentMapping, InitializeClass, \
     get_request
from AccessControl import ClassSecurityInfo
from OFS.SimpleItem import SimpleItem
from OFS.ObjectManager import ObjectManager

# Localizer
from LocalFiles import LocalDTMLFile
from zgettext import parse_po_file
from Utils import charsets, languages, lang_negotiator
from LanguageManager import LanguageManager
import Gettext


_ = Gettext.translation(globals())
N_ = Gettext.dummy



manage_addMessageCatalogForm = LocalDTMLFile('ui/MC_add', globals())
def manage_addMessageCatalog(self, id, title, languages, REQUEST=None):
    """ """
    self._setObject(id, MessageCatalog(id, title, languages))

    if REQUEST is not None:
        return self.manage_main(self, REQUEST)


# Empty header information for PO files, the default
empty_po_header = {'last_translator_name': '',
                   'last_translator_email': '',
                   'language_team': '',
                   'charset': ''}



class MessageCatalog(LanguageManager, ObjectManager, SimpleItem):
    """
    Stores messages and their translations...
    """

    meta_type = 'MessageCatalog'

    security = ClassSecurityInfo()


    def manage_options(self):
        """ """
        options = (
            {'label': N_('Messages'), 'action': 'manage_messages',
             'help': ('Localizer', 'MC_messages.stx')},
            {'label': N_('Properties'), 'action': 'manage_propertiesForm'},
            {'label': N_('Import/Export'), 'action': 'manage_importExport',
             'help': ('Localizer', 'MC_importExport.stx')}) \
            + LanguageManager.manage_options \
            + SimpleItem.manage_options

        r = []
        for option in options:
            option = option.copy()
            option['label'] = _(option['label'])
            r.append(option)

        return r


    def __init__(self, id, title, languages):
        self.id = id

        self.title = title

        # Language Manager data
        self._languages = tuple(languages)
        self._default_language = languages[0]

        # Here the message translations are stored
        self._messages = PersistentMapping()

        # Data for the PO files headers
        self._po_headers = PersistentMapping()
        for lang in self._languages:
            self._po_headers[lang] = empty_po_header


    security.declarePublic('get_language_name')
    def get_language_name(self, id):
        """ """
        return languages[id]

    security.declarePublic('get_url')
    def get_url(self, url, batch_start, batch_size, regex, lang, empty, **kw):
        """ """

        params = []
        for key, value in kw.items():
            params.append('%s=%s' % (key, quote(value)))

        params.extend(['batch_start:int=%d' % batch_start,
                       'batch_size:int=%d' % batch_size,
                       'regex=%s' % quote(regex)])

        if lang:
            params.append('lang=%s' % lang)

        return url + '?' + '&amp;'.join(params)

    security.declarePublic('filter')
    def filter(self, lang=None, empty=0, regex='',
               batch_start=0, batch_size=15):
        """
        For the management interface, allows to filter the messages to show.
        """
        regex = regex.strip()

        try:
            regex = re.compile(regex)
        except:
            regex = re.compile('')

        r = [ (m, t) for m, t in self._messages.items()
              if regex.search(m)
                 and (not empty or not t.get(lang, '').strip()) ]
        r.sort()

        n = len(r)

        while batch_start >= n:
            batch_start = batch_start - batch_size

        return {'entries': r[batch_start:batch_start+batch_size],
                'nentries': n, 'batch_start': batch_start}


    security.declareProtected('Manage messages', 'get_translations')
    def get_translations(self, message):
        """ """
        return self._messages[message]


    security.declarePublic('hasmsg')
    def hasmsg(self, message):
        """ """
        return self._messages.has_key(message)

    # Here only for backawards compatibility (CMFLocalizer uses it)
    hasLS = hasmsg


    security.declareProtected('Manage messages', 'manage_messages')
    manage_messages = LocalDTMLFile('ui/MC_messages', globals())

    security.declareProtected('Manage messages', 'manage_editMessage')
    def manage_editMessage(self, message, language, translation,
                           REQUEST=None, RESPONSE=None):
        """Modifies a message."""
        self._messages[message][language] = translation

        if REQUEST is not None:
            url = self.get_url(REQUEST.URL1 + '/manage_messages',
                               REQUEST['batch_start'], REQUEST['batch_size'],
                               REQUEST['regex'], REQUEST.get('lang', ''),
                               REQUEST.get('empty', 0),
                               manage_tabs_message=_('Saved changes.'))
            RESPONSE.redirect(url)

    security.declareProtected('Manage messages', 'manage_delMessage')
    def manage_delMessage(self, message, REQUEST=None, RESPONSE=None):
        """ """
        del self._messages[message]

        if REQUEST is not None:
            url = self.get_url(REQUEST.URL1 + '/manage_messages',
                               REQUEST['batch_start'], REQUEST['batch_size'],
                               REQUEST['regex'], REQUEST.get('lang', ''),
                               REQUEST.get('empty', 0),
                               manage_tabs_message=_('Saved changes.'))
            RESPONSE.redirect(url)



    security.declarePublic('gettext')
    def gettext(self, message, lang=None, add=1):
        """Returns the message translation from the database if available."""

        if type(message) is not StringType:
            raise TypeError, 'only strings can be translated.'

        # Add it if it's not in the dictionary
        if add and not self._messages.has_key(message) and message.strip():
            self._messages[message] = PersistentMapping()

        # Get the string
        if self._messages.has_key(message):
            m = self._messages[message]

            if lang is None:
                # Builds the list of available languages
                # should the empty translations be filtered?
                available_languages = list(self._languages)

                # Get the language!
                lang = lang_negotiator(available_languages)

                # Is it None? use the default
                if lang is None:
                    lang = self._default_language

            if lang is not None:
                return m.get(lang, None) or message

        return message

    __call__ = gettext


    # Properties management
    security.declareProtected('View management screens',
                              'manage_propertiesForm')
    manage_propertiesForm = LocalDTMLFile('ui/MC_properties', globals())

    security.declareProtected('View management screens', 'manage_properties')
    def manage_properties(self, title, REQUEST=None, RESPONSE=None):
        """Change the Message Catalog properties."""

        self.title = title

        if RESPONSE is not None:
            RESPONSE.redirect('manage_propertiesForm')


    # Properties management screen
    security.declareProtected('View management screens', 'get_po_header')
    def get_po_header(self, lang):
        """ """

        # For backwards compatibility
        if not hasattr(self.aq_base, '_po_headers'):
            self._po_headers = PersistentMapping()

        return self._po_headers.get(lang, empty_po_header)

    security.declareProtected('View management screens', 'update_po_header')
    def update_po_header(self, lang,
                         last_translator_name, last_translator_email,
                         language_team, charset,
                         REQUEST=None, RESPONSE=None):
        """ """

        self._po_headers[lang] = {'last_translator_name': last_translator_name,
                                  'last_translator_email': 
last_translator_email,
                                  'language_team': language_team,
                                  'charset': charset}

        if RESPONSE is not None:
            RESPONSE.redirect('manage_propertiesForm')


    # Import/export management screen
    security.declarePublic('get_charsets')
    def get_charsets(self):
        """ """
        return charsets[:]

    security.declareProtected('View management screens', 'manage_importExport')
    manage_importExport = LocalDTMLFile('ui/MC_importExport', globals())

    security.declarePublic('manage_export')
    def manage_export(self, x, REQUEST=None, RESPONSE=None):
        """
        Exports the content of the message catalog either to a template
        file (locale.pot) or to an language specific PO file (<x>.po).
        """

        # Get the PO header info
        header = self.get_po_header(x)
        last_translator_name = header['last_translator_name']
        last_translator_email = header['last_translator_email']
        language_team = header['language_team']
        charset = header['charset']

        # PO file header, empty message.
        po_revision_date = time.strftime('%Y-%m-%d %H:%m+%Z',
                                         time.gmtime(time.time()))
        pot_creation_date = po_revision_date
        last_translator = '%s <%s>' % (last_translator_name,
                                       last_translator_email)

        if x == 'locale.pot':
            language_team = 'LANGUAGE <address@hidden>'
        else:
            language_team = '%s <%s>' % (x, language_team)

        r = ['msgid ""',
             'msgstr "Project-Id-Version: %s\\n"' % self.title,
             '"POT-Creation-Date: %s\\n"' % pot_creation_date,
             '"PO-Revision-Date: %s\\n"' % po_revision_date,
             '"Last-Translator: %s\\n"' % last_translator,
             '"Language-Team: %s\\n"' % language_team,
             '"MIME-Version: 1.0\\n"',
             '"Content-Type: text/plain; charset=%s\\n"' % charset,
             '"Content-Transfer-Encoding: 8bit\\n"',
             '', '']


        # Get the messages, and perhaps its translations.
        d = {}
        if x == 'locale.pot':
            filename = x
            for k in self._messages.keys():
                d[k] = ""
        else:
            filename = '%s.po' % x
            for k, v in self._messages.items():
                try:
                    d[k] = v[x]
                except KeyError:
                    d[k] = ""

        # Generate the file
        quote_esc = re.compile(r'"')
        for k, v in d.items():
            r.append('msgid ""')
            for line in k.split('\n'):
                r.append('"%s\\n"' % quote_esc.sub('\\"', line))
            r.append('msgstr ""')
            for line in v.split('\n'):
                r.append('"%s\\n"' %  quote_esc.sub('\\"', line))
            r.append('')



        for k, v in d.items():
            r.append('msgid "%s"' % k)
            r.append('msgstr "%s"' % v)
            r.append('')


        if RESPONSE is not None:
            RESPONSE.setHeader('Content-type','application/data')
            RESPONSE.setHeader('Content-Disposition',
                               'inline;filename=%s' % filename)

        return '\n'.join(r)

    security.declareProtected('Manage messages', 'manage_import')
    def manage_import(self, lang, file, REQUEST=None, RESPONSE=None):
        """ """
        messages = self._messages

        if type(file) is StringType:
            content = file.split('\n')
        else:
            content = file.readlines()

        d = parse_po_file(content)

        for k, v in d.items():
            k = ''.join(k)
            if k.strip():
                if not messages.has_key(k):
                    messages[k] = PersistentMapping()
                messages[k][lang] = ''.join(v[1])

        if REQUEST is not None:
            RESPONSE.redirect('manage_messages')


    def objectItems(self, spec=None):
        """ """

        for lang in self._languages:
            if not hasattr(self.aq_base, lang):
                self._setObject(lang, POFile(lang))

        r = MessageCatalog.inheritedAttribute('objectItems')(self, spec)
        return r


    # Language stuff
    security.declarePublic('get_path_for_cookies')
    def get_path_for_cookies(self):
        """
        Returns the path that will be used to set the LOCALIZER_LANGUAGE
        cookie. Used from the LanguageManager.
        """

        return self.aq_parent.absolute_url()



class POFile(SimpleItem):
    """ """

    security = ClassSecurityInfo()

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

    security.declareProtected('FTP access', 'manage_FTPget')
    def manage_FTPget(self):
        """ """

        return self.manage_export(self.id)

    security.declareProtected('Manage messages', 'PUT')
    def PUT(self, REQUEST, RESPONSE):
        """ """

        body = REQUEST['BODY']
        self.manage_import(self.id, body)
        RESPONSE.setStatus(204)
        return RESPONSE


InitializeClass(MessageCatalog)
InitializeClass(POFile)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]