# -*- coding: ISO-8859-1 -*-
#
# $Id: Tracker.py 18265 2006-01-21 03:05:25Z hannosch $
#
__version__ = "$Id: Tracker.py 18265 2006-01-21 03:05:25Z hannosch $"[11:-2]
__author__ = "Gilles Lenfant <gilles.lenfant@ingeniweb.com>"

import time
from AccessControl import ClassSecurityInfo
from Globals import InitializeClass

# Template of .po / .pot file header
PO_HEADER_TPL = """# Generated by PlacelessTranslationService tracker
msgid ""
msgstr ""
"Project-Id-Version: YOUR PROJECT HERE\\n"
"POT-Creation-Date: %(date)s\\n"
"Last-Translator: YOUR NAME HERE <your@mail.here>\\n"
"Language-Team:  YOUR ORGANISATION HERE\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=utf-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Plural-Forms: nplurals=1; plural=0;\\n"
"Language-code: %(language)s\\n"
"Language-name: %(languagename)s\\n"
"Preferred-encodings: ascii latin1 utf-8\\n"
"Domain: %(domain)s\\n"

"""

class Tracker:
    """Provides all services for tracking missing messages on domains
    """

    # FIXME: Replace this with real security assertions
    __allow_access_to_unprotected_subobjects__ = 1    
    
    security = ClassSecurityInfo()

    def __init__(self):
        """Constructor
        """
        self.mode = False # Off
        self.domain = ''
        self.cleanup()
        return

    def cleanup(self):
        """Resetting the content
        """
        # All msgids for current domain
        self.msgids = []
        # Indexes in self.msgids for various languages
        self.by_language = {}

    def recordFailure(self, domain, msgid, language):
        """Must be called at each failing translation request
        """
        # Don't do anything in following cases
        if ((not self.mode)
            or (domain != self.domain)):
            return

        if msgid not in self.msgids:
            self.msgids.append(msgid)
        position = self.msgids.index(msgid)
        positions = self.by_language.get(language)
        if positions:
            if not position in positions:
                self.by_language[language].append(position)
        else:
            self.by_language[language] = [position]
        return

    def availableLanguages(self):
        """For what languages the messages are recorded
        """
        languages = self.by_language.keys()
        languages.sort()
        return languages

    def availableMsgids(self, language=None):
        """Sorted msgids for a language or all nalguages if not provided
        """
        if language:
            msgids = [self.msgids[x] for x in self.by_language[language]]
            msgids.sort()
        else:
            msgids = self.msgids[:]
            msgids.sort()
        return msgids

    def potFile(self, stream, language=None):
        """The raw text of the .po or .pot file
        """
        self.potHeader(stream, language=language)
        for msgid in self.availableMsgids(language=language):
            stream.write('msgid "%s"\n' % msgid)
            stream.write('msgstr ""\n\n')
        return
        
    def potHeader(self, stream, language=None):
        """Formats the .po / .pot header
        """
        global PO_HEADER_TPL
        if not language:
            language = 'any'
        date = time.strftime("%Y-%m-%d %H:%M")
        # FIXME: should change to a real language name (needs a dict)
        languagename = language
        domain = self.domain
        stream.write(PO_HEADER_TPL % locals())
        return

    def manage_tracker(self, pts, REQUEST):
        """Actions from the ZMI management tab "Tracker"
        """
        form = REQUEST.form
        message = ''
        if form.has_key('button.setdomain'):
            # Domain has changed
            new_domain = form['domain'].strip()
            if new_domain != self.domain:
                self.domain = new_domain
                self.mode = True
                self.cleanup()
                message = "Domain changed and tracker reset."
            else:
                message = "No change..."

        elif form.has_key('button.togglemode'):
            # Toggling mode
            self.mode = not self.mode
            if self.mode:
                message = "Tracking is ON"
            else:
                message = "Tracking is OFF"

        elif form.has_key('button.download.pot'):
            # Download for the whole .pot
            REQUEST.RESPONSE.setHeader('Content-Type', 'text/plain')
            REQUEST.RESPONSE.setHeader('Content-Disposition',
                                       'attachment; filename=%s.pot' % self.domain)
            self.potFile(REQUEST.RESPONSE)
            return

        elif form.has_key('button.view.pot'):
            # View the whole .pot
            REQUEST.RESPONSE.setHeader('Content-Type', 'text/plain')
            self.potFile(REQUEST.RESPONSE)
            return

        elif form.has_key('button.clear'):
            # Cleanup all
            self.cleanup()
            message = "Removed recorded msgids"

        else:
            button_dl_po = [k for k in form.keys() if k.startswith('button.download.po.')]
            button_view_po = [k for k in form.keys() if k.startswith('button.view.po.')]

            if len(button_dl_po):
                # Download .po for a language
                button_dl_po = button_dl_po[0]
                language = button_dl_po.split('.')[-1]
                REQUEST.RESPONSE.setHeader('Content-Type', 'text/plain')
                REQUEST.RESPONSE.setHeader('Content-Disposition',
                                           'attachment; filename=%s-%s.po' % (self.domain, language))
                self.potFile(REQUEST.RESPONSE, language=language)
                return

            elif len(button_view_po):
                # View a .po for a language
                button_view_po = button_view_po[0]
                language = button_view_po.split('.')[-1]
                REQUEST.RESPONSE.setHeader('Content-Type', 'text/plain')
                self.potFile(REQUEST.RESPONSE, language=language)
                return

        return pts.manage_trackerForm(pts, REQUEST, manage_tabs_message=message)

InitializeClass(Tracker)

global_tracker = Tracker()
