[Python-de] Listen in ein File Object verwandeln

Andreas Grytz agrytz at linux-user.de
Mit Feb 11 15:51:10 CET 2004


On Wed, Aug 13, 2003 at 02:38:43PM +0200, Dinu Gherman wrote:
> Andreas Grytz:
> 
> > ich möchte eine Liste von Strings an eine Funktion übergeben, die aber
> > ein File-Objekt erwartet. Gibt es eine Möglichkeit, die Liste
> > umzuwandeln? Bisher behelfe ich mir dadurch, dass ich die Liste in eine
> > temporäre Datei schreibe und daraus anschließend wieder lese. Das
> > scheint mir nicht sehr elegant.
> 
> Schreibst Du noch, was diese ominoese Funktion mit dem vermeintlichen
> Dateiobjekt anstellt? Fuer mich macht das bisher noch nicht genug Sinn
> fuer eine qualifizierte Antwort! ;-)
> 
Ich hatte mal vor einiger Zeit ein Problem mit einer Liste von Strings,
die ich in ein File-Objekt umwandeln wollte. Das ganze wurde in einem
Skript verwendet, das eine Mailbox in ein XML-Format umwandelt:

formail -ds leser.py < leser.mbx > leser.xml

Mittlerweile ist das Skript einigermaßen fertig und ich hatte ja
versprochen, das mal zu posten. Man kann da sicher noch einiges
verbessern. Vorschläge sind da jederzeit willkommen, aber nicht
vergessen, ich sitze an einer Kiste, auf der noch Python 1.5.2
installiert ist.

Das sollte fast mehr Herausforderung sein, als die Technik selber :)

Gruss,
	Andreas
-- 
Andreas Grytz		| http://www.linuxnewmedia.de
Stefan-George-Ring 24	| Tel:	+49 (0) 89 993411-0
D-81929 München		| Fax:	+49 (0) 89 993411-99
-------------- nächster Teil --------------
#!/usr/bin/python

import sys
import string
import time
import mimetools
import mimify
import quopri
import multifile
import cStringIO
import tempfile
import re

config_dict= {}

msg = mimetools.Message(sys.stdin)

try:
	msg["Subject"]
except KeyError:
	config_dict['subject'] = "No Subject"
else:
	config_dict['subject'] = msg["Subject"]

config_dict['date'] = msg.getdate("Date")
try:
	msg["Message-ID"]
except KeyError:
	try:
		msg["Resent-Message-Id"]
	except KeyError:
		config_dict['id'] = "None"
	else: config_dict['id'] = "id" + msg["Resent-Message-Id"][1:-1]
else: config_dict['id'] = "id" + msg["Message-ID"][1:-1]

config_dict['name'] = msg.getaddr("From")[0]
config_dict['mail'] = msg.getaddr("From")[1]
config_dict['type'] = msg.gettype()
config_dict['encoding'] = string.lower(msg.getencoding())
config_dict['date'] = time.strftime('%Y-%m-%d %H:%M', config_dict['date'])

try:
	msg["In-Reply-To"]
except KeyError:
	config_dict['reference'] = ""
	config_dict['editor'] = config_dict['mail'][0:3]
else:
	config_dict['reference'] = "id" + string.split(msg["In-Reply-To"], ';')[0][1:-1]
	config_dict['editor'] = config_dict['mail'][0:3]

if config_dict['encoding'] == "7bit" or config_dict['encoding'] == "quoted-printable":
	config_dict['name'] = mimify.mime_decode_header(config_dict['name'])
	config_dict['subject'] = mimify.mime_decode_header(re.sub('\n',' ', config_dict['subject']))
if string.find(config_dict['subject'], '=?iso-8859-1?'):
	config_dict['name'] = mimify.mime_decode_header(config_dict['name'])
	config_dict['subject'] = mimify.mime_decode_header(re.sub('\n',' ', config_dict['subject']))

sys.stderr.write("Subject: %(subject)s\n" % config_dict)
sys.stderr.write("ID: %s\n" % config_dict['id'])
sys.stderr.write("Encoding: %s\n\n" % config_dict['encoding'])

letter =  """<letter
	id="%(id)s"
	date="%(date)s"
	name="%(name)s"
	mail="%(mail)s"
	subject="%(subject)s"
	month=""
	year=""
	page="">\n\n""" % config_dict

answer =  """<answer
	ref="%(reference)s"
	editor="%(editor)s"
	name="%(name)s"
	mail="%(mail)s"
	subject="%(subject)s">\n\n""" % config_dict

footer_a = "\n</answer>\n\n"
footer_l = "\n</letter>\n\n"

def to_file(mimepart):
	fp = cStringIO.StringIO(string.join(mimepart, ''))
	return fp

def handle_plain(msg, file):
	if config_dict['encoding'] == "quoted-printable":
		file.write(handle_quopri(msg.fp))
	else: file.writelines(msg.fp.readlines())

def handle_quopri(fp):
	decoded = cStringIO.StringIO()
        quopri.decode(fp, decoded)
	body = decoded.getvalue()
	return body

def handle_mixed(msg, boundary):
        multipart = multifile.MultiFile(msg, 0)
	parts = []
        multipart.push(boundary)
	while not multipart.last:
	        parts.append(multipart.readlines())
		multipart.next()
	return parts

def handle_alternative(msg, boundary, file):
	multipart = multifile.MultiFile(msg, 0)
	multipart.push(boundary)
	multipart.next()
	part = multipart.readlines()
	handle_part(part, file)

def handle_base64(msg, part, file):
	if msg.getparam('name'):
		name = msg.getparam('name')
	elif msg.getparam('filename'):
		name = msg.getparam('filename')
	else: name = tempfile.mktemp()

	attachment = open(name, 'w')
	mimetools.decode(part, attachment, msg.getencoding())
	attachment.close()
	file.write("Attachment written to file: %s\n" % name)

def handle_ascii_attachment(part, boundary, file):
	if msg.getparam('name'):
		name = msg.getparam('name')
	elif msg.getparam('filename'):
		name = msg.getparam('filename')
	else: name = tempfile.mktemp()

	attachment = open(name, 'w')
	attachment.write(part)
	attachment.close()
	file.write("Attachment written to file: %s\n" % name)
	
def handle_part(part, file):
	part = to_file(part)
	msg = mimetools.Message(part)
	boundary = msg.getparam('boundary')
	if msg.gettype() == "text/plain":
		if msg.getparam('Content-Disposition') == 'attachment':
			handle_ascii_attachment(part, boundary, file)
		elif msg.getparam('Content-Disposition') != 'attachment':
			if string.lower(msg.getencoding()) == "quoted-printable":
	                	file.write(handle_quopri(part))
	        	else: file.write(part.getvalue())

	elif msg.gettype() == "text/x-vcard":
		pass

	elif msg.gettype() == "text/html":
#		file.write(handle_quopri(part))
		pass

	elif msg.getmaintype() == "multipart" \
		and msg.getsubtype() in ['related', 'alternative']:
		boundary = msg.getparam('boundary')
		parts = handle_mixed(part, boundary)
		for part in parts:
			handle_part(part, file)

	elif msg.getmaintype() == "image":
		handle_base64(msg, part, file)

	elif msg.getmaintype() == "application":
		if msg.getsubtype() in [ 'pdf', 'octet-stream']:
			handle_base64(msg, part, file)
		else: file.write(part.getvalue())
	
	else: file.write("Other Part: %s\n" % msg.gettype())
		

file = sys.stdout

if config_dict['reference']:
	file.write(answer)
else: file.write(letter)

if config_dict['type'] == "text/plain":
	handle_plain(msg, file)

elif msg.getmaintype() == "multipart" \
	and msg.getsubtype() in ['mixed', 'signed']:
	parts = handle_mixed(msg.fp, msg.getparam('boundary'))
	for part in parts:
		handle_part(part, file)
	
elif config_dict['type'] == "multipart/alternative":
	handle_alternative(msg.fp, msg.getparam('boundary'), file)

if config_dict['reference']:
	file.write(footer_a)
else: file.write(footer_l)

file.close()