# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc.
#
# 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.

"""Decorate a message by sticking the header and footer around it.
"""

import string
# --- Imported --- #
import StringIO
import mimetools
import fileinput
import multifile
import re
# --- Imported --- #

from Mailman import mm_cfg
from Mailman import Utils
from Mailman.Logging.Syslog import syslog


# --- Imported --- #
# For HTML bodies, replace newlines with <BR>
def HTMLheader(header, footer):
	ret = ["", ""]
	new_header = string.replace(header, "\r\n", "<BR>")
	new_header = string.replace(new_header, "\n", "<BR>")
	new_footer = string.replace(footer, "\r\n", "<BR>")
	new_footer = string.replace(new_footer, "\n", "<BR>")
	ret[0] = new_header
	ret[1] = new_footer
	return ret

# Returns the current body, and the rest of the e-mail in a table
def next_boundary(text, boundary):
	ret = ["", ""]
	expr = "--" + boundary
	result = re.search(expr, text)
	if result != None:
		ret[0] = text[result.end()+1:]

		result = re.search(expr, ret[0])
		if result != None:
			if ret[0][result.end()+1:result.end()+2] != "--":
				ret[1] = ret[0][result.start():]

			ret[0] = ret[0][:result.start()]
			return ret
		return ret
	return ret

# Here is the main procedure
def multiprocess(stream, header, footer, content):
	new_stream = stream

	data = StringIO.StringIO()

	# If the e-mail is multipart, go on...
	if content[1:10] == "ultipart/":
		# Find the boundary
		tmp_dat = string.split(content, ';')
		for tmp_prt in tmp_dat:
			if string.find(tmp_prt, 'oundary')>0:
				tmp_bdr = string.split(tmp_prt, '"')
				boundary = tmp_bdr[1]

		body = str(stream)
		# While there are parts, go on...
		while 1:
			# Get next part, and the rest of the e-mail
			ret = next_boundary(body, boundary)
			body = ret[0]
			remaining = ret[1]

			if not len(body):
				break
			if string.strip(body) == "":
				break

			submsg = mimetools.Message(StringIO.StringIO(body))
			mimetype = submsg.gettype()

			old_body = body

			# If part is text/plain...
			if string.lower(mimetype) == "text/plain":
				result = re.search("\r?\n\r?\n", body)
				if result != None:
					body = body[:result.end()] + header + "\r\n" + body[result.end()+1:] + "\r\n" + footer + "\r\n\r\n"
				else:
					body = header + body + footer

				try:
					new_stream = string.replace(new_stream, old_body, body, 1)
				except ValueError:
					old_body = old_body

			# If part is text/html...
			elif string.lower(mimetype) == "text/html":
				fvalue = body

				# Add the header & footer inside <BODY>...</BODY>
				result = re.search("<\s*[Bb][Oo][Dd][Yy]", body)
				if result != None:
					body_tag = result.start()
					result = re.search('>', body[body_tag:])
					if result != None:
						start_tag = body[body_tag:body_tag + result.end()]
				result = re.search("<\s*/\s*[Bb][Oo][Dd][Yy]\s*>", body)
				if result != None:
					end_tag = body[result.start():result.end()]
				new_headers = HTMLheader(header, footer)
				try:
					new_stream = string.replace(new_stream, start_tag, start_tag + new_headers[0], 1)
					new_stream = string.replace(new_stream, end_tag, new_headers[1] + end_tag, 1)
				except ValueError:
					old_body = old_body

			# If part is multipart/* make a recursion...
			elif string.lower(mimetype[1:10]) == "ultipart/":
				subcontent = submsg.getheader('Content-type')
				body = multiprocess(body, header, footer, subcontent)
				new_stream = string.replace(new_stream, old_body, body, 1)

			body = remaining

	else:
		new_stream = header + stream + footer

	return new_stream
# --- Imported --- #

def process(mlist, msg, msgdata):
    if msgdata.get('isdigest'):
        # Digests already have their own header and footers attached.
        return
    d = Utils.SafeDict(mlist.__dict__)
    # Certain attributes are sensitive
    del d['password']
    del d['passwords']
    d['cgiext'] = mm_cfg.CGIEXT
    # interpolate into the header
    try:
        header = string.replace(mlist.msg_header % d, '\r\n', '\n')
    except (ValueError, TypeError), e:
        syslog('error', 'Exception while calculating message header:\n%s' % e)
        header = '[INVALID HEADER]'
    try:
        footer = string.replace(mlist.msg_footer % d, '\r\n', '\n')
    except (ValueError, TypeError), e:
        syslog('error', 'Exception while calculating message footer:\n%s' % e)
        footer = '[INVALID FOOTER]'
# --- Imported --- #
#    msg.body = header + msg.body + footer
    msg.body = multiprocess(msg.body, header, footer, msg.getheader('Content-type'))
# --- Imported --- #
    # Mark the message as dirty so that its text will be forced to disk next
    # time it's queued.
    msgdata['_dirty'] = 1
