erkennen, wenn ein neues mail im pop3 fach liegt

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
tao
User
Beiträge: 15
Registriert: Sonntag 12. November 2006, 21:34
Wohnort: basel
Kontaktdaten:

hallo zusammen,

ich arbeite gerade an einem neuen projekt, und bin gerade ziehmlich hilflos!
es geht um folgendes:
ich habe einen pop3 account und das mailprogramm thunderbird. thunderbird verbindet sich in einem regelmässigen interval mit meiner mailbox und schaut ob da was neues reingekommen ist.
ich will etwas scripten, was zwischen thunderbird und mailserver ist und die daten dort abfängt, prüft und dann über pySerial ein signal an ein microcontroller-board sendet, was dann mehrere servos steuert.
hat jemand einen tip für mich was sich da am besten eignet? muss ich mehr nach proxy oder nach sniffer suchen? kann man das mit python bewerkstelligen?

besten dank für euere antworten jetzt schon!
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Du kannst auch direkt mit Python (über das Modul `popilb`) auf das POP3-Postfach zugreifen.

Mit einem IMAP-Postfach ließe sich das ganze zeitnäher realisieren. Der Server kann eine Art Push zum Client machen und ihn direkt über neu eintreffende Mails informieren. IIRC muss dazu aber eine Verbindung dauerhaft bestehen, und irgendwie hatte das Kommando IDLE da was mit zu tun. Aber wer suchet, der findet.
Benutzeravatar
tiax
User
Beiträge: 152
Registriert: Samstag 23. Juli 2005, 17:28
Kontaktdaten:

Alternativ könntest du deine mails statt mit Thunderbird direkt auch mit getmail abholen, mit pycmail filtern und in ein lokales Maildir eintragen lassen - das kann Thunderbird unter Linux dann auch verarbeiten.

Pycmail und getmail sind beidein Python geschrieben und mit pycmail kannst du bei einer neuen mail dann auch externe scripte aufrufen lassen
Ne invoces expellere non possis
[url=xmpp://florian@florianheinle.de]xmpp:florian@florianheinle.de[/url]
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

tao hat geschrieben:ich will etwas scripten, was zwischen thunderbird und mailserver ist und die daten dort abfängt
Hallo tao!

Leider schreibst du nicht mehr über deine Umgebung.

Wenn du Linux benutzt, dann kannst du z.B. mit ``procmail`` ein Programm ausführen lassen, wenn ein Email ankommt. Du könntest den Mail-Server veranlassen, die Email an ein Programm weiterzugeben. (z.B per Alias-Mechanismus)

Dann könntest du ein einfaches Python-Programm schreiben, welches mit den Daten, die vom Mail-Server oder von procmail kommen, etwas macht.

Unter Windows würde ich den Jana Server einsetzen. Der Jana Server kann als lokaler POP-Server oder IMAP-Server arbeiten. Dieser holt z.B. die Emails alle paar Minuten vom Provider ab und stellt diese in ein lokales Postfach. Dieses Postfach kann dann von Thunderbird abgefragt werden.
Der große Vorteil des Jana Servers ist in deinem Fall der, dass bei Emailempfang ein Programm aufgerufen werden kann. Dieses Programm wird mit dem Pfad zur Email-Textdatei gefüttert. So kannst du vom Jana Server ein Python-Programm aufrufen lassen und hast zusätzlich noch den Vorteil eines lokalen IMAP-Servers.

Wenn du dir das selber programmieren möchtest, dann empfehle ich dir das Python-Modul ``poplib`` und ``smtplib``. Mit poplib holst du dir die Email ab und mit smtplib könntest du die Email an ein anderes Postfach weiterschicken. Den Thunderbird stellst du dann so ein, dass er die Emails von dem Postfach holt, an das du die Emails weitersendest.

Das sind einige der Möglichkeiten, die du hast. Allerdings kommt es im Endeffekt darauf an, was du brauchst und wie du das umsetzen möchtest.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
tao
User
Beiträge: 15
Registriert: Sonntag 12. November 2006, 21:34
Wohnort: basel
Kontaktdaten:

wow, das ging ja schnell!

leider arbeite ich nicht auf einem linux oder windows, sondern auf einem mac. die poplib kenne ich und sie macht gute dienste! es ist mir auch bereits gelungen ein einfaches e-mail programm zu schreiben, dass sich bei meinem server anmeldet und die nachrichten holt.
procmail höhrt sich interessant an! ich werd da mal in schauen, ob diese library auch auf mac den gewünschten effect hat.
am ende ist es mein ziel ein programm zu haben, dass vom anwender sehr wenig abfordert. es soll möglichst plug and play mässig laufen, also ohne neukonfigurierung von seinem mailprogramm oder konfigurierung des pythonprogramms.
ich weiss, dass dies warscheinlich eine utopie ist, aber mein ziel soll es mal sein das maximum zu erreichen.

danke für die tipps leute ich werd mich mal an euere vorschläge hängen und nachlesen was die einzelnen lib's genau können und in wiefern sie für mich was taugen.

mfg
tao
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Die von tiax angesprochenen getmail und pycmail sind in Python geschrieben und daher auch problemlos unter Mac OS X lauffähig.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
tao
User
Beiträge: 15
Registriert: Sonntag 12. November 2006, 21:34
Wohnort: basel
Kontaktdaten:

hy leute,

ich hatte endlich zeit daran rumzufummeln. hier mal, was ich bis jetzt zusammen gescriptet habe...

Code: Alles auswählen

#!/usr/bin/python
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
import socket, thread
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
thunderHost = 'localhost'                 
thunderPort = 5000
#
serverHost = 'pop.gmx.ch'
serverPort = 110 #standart port für pop3
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.bind((thunderHost, thunderPort))
s.listen(1)
#
t = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
t.connect((serverHost, serverPort))
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
def dataExchange(conn,addr):
    while 1:
        data = conn.recv(1024)
        data01 = t.recv(1024)
       
        if data or data01:
            conn.send(data01)
            t.send(data)
            print data
            print data01
    
        if not data01: break
        if not data: break

    conn.close()
    t.close()
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
def listener():
    while 1:
        conn, addr = s.accept()
        thread.start_new(dataExchange,(conn,addr))
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
listener()
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
eigentlich ist es jetzt ein man-in-the-middle, der auf meinen localhost läuft.
thunderbird ist so eingestellt, dass es auf localhost port 5000 höhrt und alles was passiert ist die umleitung auf gmx.
leider will das ganze so noch nicht! wenn ich es mit telnet probiere klappt alles, aber ich merke, dass die antworten vom server immer versetzt zu spät kommen.
da thunderbird dumm ist und immer einen korrekten request erwartet, bricht es die verbindung immer ab.
wie kann ich diese verspätete antwort des server korregieren, oder hat jemand eine ahnung an was das liegen könnte???

lg
tao
BlackJack

Ich sehe da ein Problem das Du die Verbindung zum POP3-Server nur einmal öffnest. Wenn mehrere Anfragen kommen, dann gehen die alle über die gleiche Verbindung und können leichtes Chaos verursachen, oder!?
tao
User
Beiträge: 15
Registriert: Sonntag 12. November 2006, 21:34
Wohnort: basel
Kontaktdaten:

hm BlackJack,

ich bin nicht ganz sicher was du mit mehreren anfragen meinst, wie gesagt über telnet funkitonieren alle anfragen super, nur das ich sie manuell mache. thunderbird macht auch keine anderen abfragen wie ich, denn eigentlich ist alles im pop3 protokoll vorgegeben. ich muss nur schauen, dass die umleitung richtig funktioniert, was sie eben nicht tut! der server sollte beim anmelden eine nachricht an den client senden.
<+OK GMX StreamProxy Ready (1225454354@435436)>
ca in dem stiel sieht das aus. das macht er auch, aber erst wenn vom client aus den ersten befehl (USER xxxx) geschickt habe. darauf sollte er aber antworten: <+OK can I have your passwort pleas?>. da so der ablauf einer standart pop3 verbindung nicht eingehalten wird, funktioniert das ganze mit thunderbird nicht.

meinst du, dass ich jedesmal, wenn mein programm einen socket mit dem client aufbaut erst den server connecten soll???

lg
alessandro
BlackJack

Wenn zwei Programme gleichzeitig auf Port 5000 gehen, kommunizieren beide über das gleiche `t` mit dem Server. Das gibt auf jeden Fall Probleme.
tao
User
Beiträge: 15
Registriert: Sonntag 12. November 2006, 21:34
Wohnort: basel
Kontaktdaten:

sorry, kann sein, dass ich es nicht ganz verstehe,
javascript:emoticon(':wink:')
aber in dem script greifen nicht zwei programme auf den gleichen port zu, so wie ich das jetzt gerade sehe.
tut mir leid das kapiere ich jetzt wirlich nicht. 't' ist ja nur eine verbindung zum server und gibt lediglich die daten weiter die es von 'conn' bekommt und schickt die daten, die es vom server hat an 'conn' weiter.
vielleicht reden wir vom selben und versteh dich nicht so ganz, könntest du noch einen konkreteren erklärungsversuch starten?
wär super lieb von dir, bin gerad etwas ratlos!

danke für deine antwort
tao
Benutzeravatar
Blattlaus
User
Beiträge: 55
Registriert: Donnerstag 24. August 2006, 08:55

Könntest du mal die Ausgabe des Scriptes auf der Console posten, die es ausgibt, wenn du per Thunderbird zu connecten Versuchst?
Am besten fügst du vor "print data" und "print data01" noch ein "From server"/"From client" ein.

Ich hab den Verdacht das da irgendwo ein Socket blockiert/zu lange wartet und der deswegen aus dem Tritt kommt.
tao
User
Beiträge: 15
Registriert: Sonntag 12. November 2006, 21:34
Wohnort: basel
Kontaktdaten:

also wenn ich es im terminal aufrufe gibt er folgendes aus:

<
80-219-135-200:~ admin$ python /Users/admin/Desktop/proxy01.py
from client:
from server: +OK GMX POP3 StreamProxy ready <15593.1163680941@mp035>
>

und thunderbird sagt: Zeitüberschreitung bei verbindung mit server 127.0.0.1

eigentlich sollte, sobald der client sich anmeldet, also der socket zustande kommt, er die nachricht des server erhalten, damit er die befehle schickt.

hab jetzt die prozedur wiederhohlt und dann meint er:

<
Unhandled exception in thread started by <function dataExchange at 0x4dd30>
Traceback (most recent call last):
File "/Users/admin/Desktop/proxy01.py", line 21, in dataExchange
data01 = t.recv(1024)
File "/Library/Frameworks/Python.framework/Versions/2.4//lib/python2.4/socket.py", line 144, in _dummy
raise error(EBADF, 'Bad file descriptor')
socket.error: (9, 'Bad file descriptor')
>

also hat er sich erst beim zweiten mal aufgehängt oder blockiert??
BlackJack

tao hat geschrieben:sorry, kann sein, dass ich es nicht ganz verstehe,
javascript:emoticon(':wink:')
aber in dem script greifen nicht zwei programme auf den gleichen port zu, so wie ich das jetzt gerade sehe.
Nicht auf den gleichen Port sondern auf die gleiche Verbindung zum Server.
tut mir leid das kapiere ich jetzt wirlich nicht. 't' ist ja nur eine verbindung zum server und gibt lediglich die daten weiter die es von 'conn' bekommt und schickt die daten, die es vom server hat an 'conn' weiter. vielleicht reden wir vom selben und versteh dich nicht so ganz, könntest du noch einen konkreteren erklärungsversuch starten?
Programm eins verbindet sich mit port 5000 und bekommt ein `conn` Objekt. Programm zwei verbindet sich lokal mit port 5000 und bekommt auch ein (neues) `conn` Objekt. Beide kommunizieren aber über das *gleiche* `t` mit dem POP3-Server! Das gibt Chaos. Der POP3-Server erhält mitten in der Kommunikation mit dem einen Mailclient auch Anfragen vom anderen, über den gleichen Kanal. Und bei den Antworten vom Server ist es reine Glückssache welcher der beiden Threads, welche Bruchstücke von den Antworten verarbeitet.

Ausserdem ist es äusserst fraglich ob GMX die Verbindung lange offen hält. Du öffnest die ja und dann wartest Du erstmal gemütlich darauf, dass sich jemand auf Port 5000 meldet. Stell Dir mal vor jeder würde morgens eine stehende Verbindung zu GMX aufmachen, nur so auf Vorrat. :-)
BlackJack

tao hat geschrieben:und thunderbird sagt: Zeitüberschreitung bei verbindung mit server 127.0.0.1

eigentlich sollte, sobald der client sich anmeldet, also der socket zustande kommt, er die nachricht des server erhalten, damit er die befehle schickt.
Die ersten beiden Zeilen in der ``while``-Schleife funktionieren so nicht. `recv()` ist blockierend. Wenn Du immer in einer festen Reihenfolge blockierend von den beiden Sockets liest, dann läufst Du immer Gefahr, das Du bei einer "Seite" landest die auf Daten wartet und erst dann wieder was sendet. Und schon gibt's 'ne Verklemmung. Du solltest mit `select.select()` arbeiten.
hab jetzt die prozedur wiederhohlt und dann meint er:

<
Unhandled exception in thread started by <function dataExchange at 0x4dd30>
Traceback (most recent call last):
File "/Users/admin/Desktop/proxy01.py", line 21, in dataExchange
data01 = t.recv(1024)
File "/Library/Frameworks/Python.framework/Versions/2.4//lib/python2.4/socket.py", line 144, in _dummy
raise error(EBADF, 'Bad file descriptor')
socket.error: (9, 'Bad file descriptor')
>

also hat er sich erst beim zweiten mal aufgehängt oder blockiert??
Nein Du hast `t` geschlossen und versuchst jetzt etwas von einer geschlossenen Verbindung zu empfangen.
tao
User
Beiträge: 15
Registriert: Sonntag 12. November 2006, 21:34
Wohnort: basel
Kontaktdaten:

javascript:emoticon(':D')
dank an alle die mitgeholfen haben, jetzt hab ich den wichtigsten teil geschaft. thunderbird kann sich über mein programm mit dem gmx server unterhalten.
Die beiden gehen richtig schnell ab, jetzt muss ich nur noch die verbindungen richtig trennen und die string analyse machen.

HIER MAL DER CODE:

Code: Alles auswählen

#!/usr/bin/python
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
import socket, thread
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
thunderHost = 'localhost'                 
thunderPort = 5000
#
serverHost = 'pop.gmx.net'
serverPort = 110
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.bind((thunderHost, thunderPort))
s.listen(1)
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
t = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
def dataExchange01(conn,addr,a):
    t.connect((serverHost, serverPort))
    while 1:
        if a == 0:
            while 1:
                if a == 1: break
                data01 = conn.recv(1024)
                if data01:
                    t.send(data01)
                    print 'from client '+data01
                    a = 1
                if not data01: break
        else:
            while 1:
                if a ==0: break
                data02 = t.recv(1024)
                if data02:
                    conn.send(data02)
                    print 'from server' + data02
                    a = 0
                if not data02: break
    #conn.close()
    #t.close()
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––    
def listener():
    while 1:
        a =1
        conn, addr = s.accept()
        thread.start_new(dataExchange01,(conn,addr,a))
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
listener()
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
#–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
das programm macht bis jetzt eigentlich nix anderes als die vermittlung zwischen mailprogramm und server.
jetzt kann ich ganz leicht die gespräche abfangen und analysieren!

GROSSES DANKE NOCHMALS FÜR ALLE TIP's...
grüsse tao
Antworten