# copyright 2007 ETH Zurich, DMATL
# author lorenz textor

from Products.Silva.Folder import Folder as SilvaFolder
from Products.Silva.Publication import Publication
from OFS.Folder import Folder
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
from Products.PythonScripts.PythonScript import PythonScript
from Products.SilvaExternalSources.CodeSource import CodeSource

# script which walks through all folders below object obj and fixes non-ascii page templates and python scripts inside code sources

# P R O B L E M
# -> management_page_charset sets the encoding header for the management views
# -> was utf-8 until SilvaExternalSources 0.13, now iso-8859-1(why?)
# -> objects in code sources acquire this setting (e.g. page templates or python scripts)
# -> to work with silva this objects should be utf-8, not iso-8859-1
# solution:
# - edit /Products/SilvaExternalSources/ExternalSource.py (otherwise CodeSources have wrong encoding)
# 	-management_page_charset = 'iso-8859-1'
# 	+management_page_charset = 'UTF-8'

# S O L U T I O N
# -> now we leave SilvaExternalSources source code as it is and do the following:
#       - decode all python scripts and page templates inside code sources with non-ascii characters with utf-8 charset and reencode with iso-8859-1
#       - change "Data encoding" for this code sources to iso-8859-1

def fixTemplatesAndScripts(obj):
    """walks through all folders below object obj and fixes non-ascii page templates and python scripts inside code sources"""
    # obj = context.restrictedTraverse('/silva')

    # get files
    def walk(objects):
        for id,val in objects:
            if isinstance(val,SilvaFolder) or isinstance(val,Publication) or isinstance(val,Folder):
                # step into subfolder
                walk(val.objectItems())
            elif isinstance(val,ZopePageTemplate):
                zpts.append(val)
            elif isinstance(val,PythonScript):
                pyts.append(val)
    
    # scan files
    def test(object):
        content = object.read()
        for char in content:
            if ord(char)>127:
                return True
        return False

    # fix file
    def fix(zpt):
        # check if in codesource
        inCodeSource = False
        pathParts = zpt.absolute_url_path().split('/')
        for i in range(len(pathParts)-2):
            container = obj.restrictedTraverse('/'.join(zpt.absolute_url_path().split('/')[0:-1-i]))
            if isinstance(container,CodeSource):
                inCodeSource = True
                break
        if inCodeSource:
            try:
                zpt.write(zpt.read().decode('utf-8').encode('iso-8859-1'))
                output.append('<p style="color:green">%s (fixed)</p>' % zpt.absolute_url_path())
                container.set_data_encoding('iso-8859-1')
                output.append('<p style="color:green">%s (CodeSource changed to iso-8859-1)</p>' % (container.absolute_url_path()))
            except:
                output.append('<p style="color:red">%s (error while trying to fix)</p>' % zpt.absolute_url_path())
        else:
            output.append('<p style="color:#999">%s (not fixed because not in code source)</p>' % zpt.absolute_url_path())


    zpts = []
    pyts = []
    output = ['<html><head></head><body>']
    walk(obj.objectItems())

    # scan page tamplates
    output.append('<p>Fixing PageTemplates with non-ascii characters<br>------------------------------------------------</p>')
    for zpt in zpts:
        if test(zpt):
            fix(zpt)
    output.append("<p><b>%d PageTemplates scanned.</b></p>" % len(zpts))
    
    # scan python scripts
    output.append('<p>Fixing PythonScripts with non-ascii characters<br>------------------------------------------------</p>')
    for pyt in pyts:
        if test(pyt):
            fix(pyt)
    output.append("<p><b>%d PythonScripts scanned.</b><p>" % len(pyts))
    
    output.append('<p><b>Be sure to test all fixed pages afterwards!</b></p>')
    output.append('</body></html>')
    return ''.join(output)

