Hallo Forengemeinde, dies ist mein erster Post, und ich hoffe es werden noch mehr werden.
Ich bin seit einem Praktikum bei einer Firma ein echter Python-Fan und bin begeistert von der Einfachheit und Mächtigkeit dieser Sprache. Im Moment schreibe ich gerade ein kleines Skript, welches Emails automatisch in einem Forum postet, also den Text und das Subject extrahiert, und per http-post versendet. Dabei treten zwei Probleme auf.
1. Bekomme ich es nicht hin das "Subject" der Email in den richtigen Zeichensatz zu formatieren, so dass auch Umlaute etc. dargestellt werden können. Ich habe mich schon in der Doku umgesehen, aber so ganz das richtige, scheine ich nicht zu finden. Wie kann man da vorgehen?
2. Schlägt mein Skript momenta fehl, wenn die Email aus mehreren Teilen besteht, deshalb suche ich nach einer eleganten Methode die Anhänge abzuschneiden. Leider stehe ich auch hierbei etwas auf dem Schlauch.
Über Anregungen und Tipps würde ich mich freuen.
Danke und Grüße
fs111
email Modul: zwei Fragen
- strogon14
- User
- Beiträge: 58
- Registriert: Sonntag 23. Februar 2003, 19:34
- Wohnort: Köln
- Kontaktdaten:
Hallo fs111,
das mit den Umlauten kann mehrere Ursachen haben. Da Du keinen Beispielcode von Dir postest, kann ich nur Vermutungen anstellen.
Hast Du:
- die Formularwerte im HTTP-POST mit urllib.quote_plus() behandelt?
- den Subject-Header der Mail mit der email.Header()-Klasse erzeugt?
siehe dazu Kapitel 12.2.5 "Internationalized headers" in der Standard Library Reference
Was das Abschneiden der Attachments angeht, auch hier wäre ein Code-Schnipsel hilfreich, um zu zeigen, was Du versuchst.
Hast Du Kapitel 12.2.13 "Examples" gelesen, insbesondere das letze Beispiel?
Hier ein Vorschlag für ein grundsätzliche Struktur:
Die Funktion process_email(text) wird dann mit dem Text des Body der Mail aufgerufen.
BTW: Allle Beispiel und Dokumentationsverweise beziehen sich auf Python 2.3
HTH, Chris
das mit den Umlauten kann mehrere Ursachen haben. Da Du keinen Beispielcode von Dir postest, kann ich nur Vermutungen anstellen.
Hast Du:
- die Formularwerte im HTTP-POST mit urllib.quote_plus() behandelt?
- den Subject-Header der Mail mit der email.Header()-Klasse erzeugt?
siehe dazu Kapitel 12.2.5 "Internationalized headers" in der Standard Library Reference
Was das Abschneiden der Attachments angeht, auch hier wäre ein Code-Schnipsel hilfreich, um zu zeigen, was Du versuchst.
Hast Du Kapitel 12.2.13 "Examples" gelesen, insbesondere das letze Beispiel?
Hier ein Vorschlag für ein grundsätzliche Struktur:
Code: Alles auswählen
import email
e = email.message_from_file(file('message.eml'))
for part in e.walk():
# Picke dir hier den Teil der Email raus, den du brauchst
if part.get_content_type() == 'text/plain':
process_email(part.get_payload())
BTW: Allle Beispiel und Dokumentationsverweise beziehen sich auf Python 2.3
HTH, Chris
Danke erstmal für Deine Antwort. ich poste hier mal ein wenig Beispielcode, zmindest die Klasse, die das wichtigste erledig:
Code: Alles auswählen
class emailposter:
FORUM_ID = 20
CAT_ID = 4
def __init__(self, message ):
self.msg = message
self.subject=self.createSubject()
# print self.subject
self.message=self.createMessage()
# print self.message
def postMessage(self):
params = urllib.urlencode({'ARCHIVE': '', 'Method_Type': 'Topic',
'Type': '', 'REPLY_ID': '', 'TOPIC_ID': '',
'FORUM_ID': self.FORUM_ID, 'CAT_ID': self.CAT_ID, 'Refer': 'http://www.imit.uni-hildesheim.de/fachschaft/forum2/forum.asp?FORUM_ID=38',
'cookies': 'yes', 'UserName':'nutzer',
'Password':'geheim',
'Subject':self.subject, 'Message': self.message})
headers = {"Content-type": "application/x-www-form-urlencoded",
"Accept": "text/plain"}
conn = httplib.HTTPConnection("www.imit.uni-hildesheim.de:80")
print 'connecting server...'
conn.request("POST", "/fachschaft/forum2/post_info.asp", params, headers)
response = conn.getresponse()
code = response.status, response.reason
# print response.read()
conn.close()
return code
def createSubject(self):
subject = self.msg.get('Subject')
subject = email.Utils.encode_rfc2231(subject)
if len(subject)<49:
return subject
else: return subject[0:49]
def createMessage(self):
mymsg = self.msg
for header in mymsg.keys():
mymsg.__delitem__(header)
return mymsg.as_string()
Mist, verklickt, und nicht eingeloggt. Auf jeden FAlls seiht man jetzt ja ungefähr was da passiert. Das eigentliche posten geht dann so vor sich, dass mein evolution(email-Programm unter Linux) die erhaltene Email über einen Filter in einer Pipe an mein Skript weitergericht wird. Dieses liest dei email ein, erzeugt ein nueses emailposter Objekt (hoffe die Begrifflichkeit stimmt unter Python) und schickt dei Nachricht dann los.
Danke für die Hilfe.
fs111
Danke für die Hilfe.
fs111
- strogon14
- User
- Beiträge: 58
- Registriert: Sonntag 23. Februar 2003, 19:34
- Wohnort: Köln
- Kontaktdaten:
Versuche mal das:
Die Decodierung des Subjects wird von der Message-Klasse übernommen,
die Codierung dann von urllib.urlencode. Wenn es dann mit den Umlauten nicht klappt, solltest Du vielleicht mal eine Beispiel-Mail (mit allen Header) posten.
Code: Alles auswählen
import urllib
class emailposter:
FORUM_ID = 20
CAT_ID = 4
def __init__(self, message):
self.msg = message
# print self.getSubject()
# print self.geteMessage()
def postMessage(self):
params = urllib.urlencode({
'ARCHIVE': '',
'Method_Type': 'Topic',
'Type': '', 'REPLY_ID': '', 'TOPIC_ID': '',
'FORUM_ID': self.FORUM_ID, 'CAT_ID': self.CAT_ID,
'Refer': 'http://www.imit.uni-hildesheim.de/fachschaft/forum2/forum.asp?FORUM_ID=38',
'cookies': 'yes', 'UserName':'nutzer',
'Password': 'geheim',
'Subject': self.getSubject(),
'Message': self.getMessage()})
headers = {"Content-type": "application/x-www-form-urlencoded",
"Accept": "text/plain"}
conn = httplib.HTTPConnection("www.imit.uni-hildesheim.de:80")
print 'connecting server...'
conn.request("POST", "/fachschaft/forum2/post_info.asp",
params, headers)
response = conn.getresponse()
code = response.status, response.reason
# print response.read()
conn.close()
return code
def getSubject(self):
subject = self.msg.get('Subject')
if len(subject)<49:
return subject
else: return subject[0:49]
def getMessage(self):
if self.msg.is_multipart():
for part in self.msg.walk():
# Picke dir hier den Teil der Email raus, den du brauchst
if part.get_content_type() == 'text/plain':
return part.get_payload()
else:
return self.msg.get_payload()
if __name__ == '__main__':
import email, sys
msg_string = sys.stdin.read()
msg = email.message_from_string(msg_string)
e = emailposter(msg)
e.postMessage()
die Codierung dann von urllib.urlencode. Wenn es dann mit den Umlauten nicht klappt, solltest Du vielleicht mal eine Beispiel-Mail (mit allen Header) posten.
Ja Danke, das mit den Anhängen geht jetzt, nur die Umlaute sind immer noch kaputt.
Aus Existenzgründung wird dann "=?ISO-8859-1?Q?Existenzgr=FCndung?=" was sehr unschön ist. Di Subject Zeile, in dieser Email sieht so aus:
fs111
Aus Existenzgründung wird dann "=?ISO-8859-1?Q?Existenzgr=FCndung?=" was sehr unschön ist. Di Subject Zeile, in dieser Email sieht so aus:
Ich will jetzt mal aus Datenschutzrechrlichen Gründen nicht alles posten, hoffe es geht auch soSubject: =?ISO-8859-1?Q?Existenzgr=FCndung?=
fs111
- strogon14
- User
- Beiträge: 58
- Registriert: Sonntag 23. Februar 2003, 19:34
- Wohnort: Köln
- Kontaktdaten:
Das ist die RFC 2047 Kodierung. Du musst die getSubject-Methode noch so erweitern, dass Sie Unicode zurückgibt:fs111 hat geschrieben:Subject: =?ISO-8859-1?Q?Existenzgr=FCndung?=
Code: Alles auswählen
def getSubject(self):
subject = unicode(self.msg.get('Subject'))
...
hmmm, das hat bei mir keinerlei Effekt, das Subject sieht immer noch genauso aus.
Code: Alles auswählen
>>> from email.Header import Header
>>> h = Header('Existenzgründung', 'iso-8859-1')
>>> h
<email.Header.Header instance at 0x00826358>
>>> str(h)
'=?iso-8859-1?q?Existenzgr=81ndung?='
>>> from email.Header import decode_header
>>> decode_header(h)
[('Existenzgr\x81ndung', 'iso-8859-1')]
>>> unicode(h)
u'Existenzgr\x81ndung'
- strogon14
- User
- Beiträge: 58
- Registriert: Sonntag 23. Februar 2003, 19:34
- Wohnort: Köln
- Kontaktdaten:
Ups, das mit 'iso-8859-1' im vorherigen Bespiel aus dem interaktiven Modus ist natürlich Quatsch, da ich das unter Windows gemacht habe. Das 'ü' ist natürlich im Windows-Zeichensatz kodiert (wie auch immer der unter Python heißt), unter ISO-8859-1 wäre es =FC.
Das ändert aber nichts am grundsätzlichen Vorgehen.
Das ändert aber nichts am grundsätzlichen Vorgehen.
irgendwie hat das keinen Effekt:
noch eine Idee?Python 2.2.3 (#1, Oct 15 2003, 23:33:35)
[GCC 3.3.1 20030930 (Red Hat Linux 3.3.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from email.Header import Header, decode_header
>>> h = Header('http://www.w3schools.com/css/default.asp','iso-8859-1')
[1]+ Stopped python
[FS111@Hermes FS111]$ fg
python
>>> h = Header('=?ISO-8859-1?Q?Existenzgr=FCndung?=','iso-8859-1')
>>> h
<email.Header.Header instance at 0x8b5a334>
>>> str(h)
'=?iso-8859-1?q?=3D=3FISO-8859-1=3FQ=3FExistenzgr=3DFCndung=3F=3D?='
>>> decode_header(h)
[('=?ISO-8859-1?Q?Existenzgr=FCndung?=', 'iso-8859-1')]
>>> unicode(h)
u'=?ISO-8859-1?Q?Existenzgr=FCndung?='
Ok, ich habe es jetzt hinbekommen, wenn auch etwas und die Ecke, aber es funktioniert mit beliebig vielen Umlauten/Sonderzeichen im Subject.
Die Funktion sieht jetzt sieht jetzt folgendermaßen aus:
Vielleicht hilft es ja dem einen oder anderen.
Grüße
fs111
Die Funktion sieht jetzt sieht jetzt folgendermaßen aus:
Code: Alles auswählen
def createSubject(self):
subject = self.msg.get('Subject')
array = subject.split()
mysubject = ''
for part in array:
if part.find('?=') != -1:
i = part.find('?Q?')
part = part[i+3:-2]
part = part.replace('=', '%')
part = urllib.unquote(part)
mysubject = mysubject+part+' '
mysubject = mysubject.replace('_', '')
if len(mysubject)<50:
return mysubject
else: return mysubject[0:49]
Grüße
fs111
- strogon14
- User
- Beiträge: 58
- Registriert: Sonntag 23. Februar 2003, 19:34
- Wohnort: Köln
- Kontaktdaten:
Code: Alles auswählen
unicode(h)