pop3 emailbody durchsuchen
Norbert
- perl
Hi,
wie durchsuche ich den emailbody einer mail nach Begriffen, die in einer seperaten Datei stehen, um die Mail dann ggf. zu löschen.
Hier mein Versuch: (der entscheidende Teil steht zwischen den #####)
Der Rest des Scriptes ist ein Beispielscript zm Modul Net::Pop3.
Danke für Hilfe
Norbert
P.S: Wichtig wäre auch noch, daß das Script nicht alle weiteren Begriffe durchforstet, wenn bereits dererste ein Treffer wäre.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#! /usr/bin/perl
#use strict;
use CGI::Carp qw(fatalsToBrowser);
use Net::POP3;
print "Content-type: text/html\n\n";
print qq~<HTML><BODY><P>~;
my $host = "pop";
my $user = "";
my $pw = "";
my $pop3;
$pop3 = Net::POP3->new($host) || die("Kein Kontakt zu $host. $!");
my $nom; # number of messages
$nom = $pop3->login($user,$pw);
unless (defined $nom) { die("$user: Auth failed $!"); }
if ($nom > 0) {
my $msgno;
print qq~<TABLE BORDER="1">~;
foreach $msgno ( sort { $a <=> $b } keys %{$pop3->list()}) {
$mailnummer=neu;
my $subject;
my $from;
# Komplette Mail holen (Head und Body)
my $Lines = $pop3->get($msgno);
my $x;
for ($x = 0; $x <= $#$Lines; $x++) {
# Header abklappern
# Absender und Betreff einsammeln
$subject = $1 if ($Lines->[$x] =~ m/^Subject:\s+(.*)/i);
$from = $1 if ($Lines->[$x] =~ m/^From:\s+(.*)/i);
# Header und Body sind gemäss RFC durch
# eine Leerzeile getrennt.
# Raus, wenn Leerzeile
last if ($Lines->[$x] =~ m/^\s*$/);
}
unless (defined $subject) {$subject = "Kein Betreff";}
$subject =~ s/</</g;
$subject =~ s/>/>/g;
unless (defined $from) { $from = "Kein Absender";}
$from =~ s/</</g;
$from =~ s/>/>/g;
print qq~<TR><TH>Nr.</TH><TH>Absender</TH><TH>Betreff</TH><TH>Status</TH></TR>~;
###############################################################################
open(MAIN3,"./body.txt") || die $!;
@main3 = <MAIN3>;
close(MAIN3);
$x += 1;
foreach (@main3) {
$_=$text;
for (; $x <= $#$Lines; $x++) {
if ($Lines->[$x] =~ m/$text/) {
$pop3->delete($msgno);
print qq~<TR><TD>$msgno</TD><TD>$from</TD><TD>$subject</TD><TD>gel(b)</TD></TR>~;
}
}
}
###############################################################################
print qq~<TR><TD>$msgno</TD><TD>$from</TD><TD>$subject</TD><TD>behalten</TD></TR>~;
print qq~<TR><TD COLSPAN="4">~;
# $x besteht noch aus der
# obigen for-Schleife.
# Wir fangen mit der ersten Zeile
# nach dem Header an, vermutlich der Body
$x += 1;
for (; $x <= $#$Lines; $x++) {
$Lines->[$x] =~ s/</</g;
$Lines->[$x] =~ s/>/>/g;
$Lines->[$x] =~ s/\n/<BR>/g;
print $Lines->[$x];
}
# Wird auch ausgeben, wenn die Nachricht leer ist.
print "<BR>";
print qq~</TD></TR>~;
}
print qq~</TABLE>~;
} else { print qq~<H1>Sorry, no Mail</H1>~; }
print qq~</BODY></HTML>~;
$pop3->quit();
}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Halihallo Norbert
Der Rest des Scriptes ist ein Beispielscript zm Modul Net::Pop3.
Nein, es ist ein Beispielscript zum Modul Net::POP3. Net::Pop3 kenne ich nicht.
Danke für Hilfe
Keine Hilfe ohne Frage.
#! /usr/bin/perl
nix Abstand. #!/usr/bin/perl
#use strict;
Das gehört nicht ausgequotet! - Das soll da rein.
use CGI::Carp qw(fatalsToBrowser);
use Net::POP3;
Aha!
print "Content-type: text/html\n\n";
Korrekter wäre:
print "Content-Type: text/html\015\012\015\012";
oder header über CGI-Modul. Aber funktionieren tut es manchmal...
print qq~<HTML><BODY><P>~;
Hm, kann mir mal wer sagen, warum das so "Inn" ist? - Interessiert mich wirklich.
---
Rest lasse ich mal aus...
Viele Grüsse
Philipp
...das Du Dich hier als so super oberkluger Schlaumeier aufspielen mußt? Kompensierst Du damit was?
Na, mir egal, zum Glück ist ja nicht jeder hier so. :-)
Schöne Grüße
Norbert
Halihallo Norbert
...das Du Dich hier als so super oberkluger Schlaumeier aufspielen mußt? Kompensierst Du damit was?
Du bestimmt nicht, denn als oberkluger Schlaumeier[1] hättest du eine konkrete Frage
gestellt und von mir mit grosser Wahrscheinlichkeit eine selbst von dir als nützlich
klassifizierte Antwort erhalten. :-)
Genug der Flames:
Was ist deine Frage/Problem? - Bisher sehe ich ein ziemlich grosses Stück Code ohne
Frage, lediglich ein Hinweis auf eine Frage, die so allgemein formuliert ist, dass ich
sie mit einem "foreach (@words) {if ($mail_body =~ /$_/i) {$delete_it=1; break; }}" zu
beantworten pflegen würde. Du musst präziser werden! - Dein Problem einkreisen und dann,
wenn es keine allzugrossen Umstände macht (*g*), auch nur den relevanten Code posten.
Viele Grüsse
Philipp
Ok, 2. Versuch:
wie durchsuche ich (mit dem Modul Net::POP3) den emailbody einer mail nach Begriffen, die in einer seperaten Datei stehen, um die Mail dann ggf. zu löschen???????
Nur, der Code bleibt derselbe!
open(MAIN3,"./body.txt") || die $!;
@main3 = <MAIN3>;
close(MAIN3);
Nun hab ich die relevanten Begriffe in @main3.
Aber dann:
$x += 1;
foreach (@main3) {
for (; $x <= $#$Lines; $x++) {
if ($Lines->[$x] =~ m/$_/i) {
$pop3->delete($msgno);
}
}
}
Das wäre das, was ich selber anzubieten hab. Aber im Versuch tats das eben nicht. Außerdem möchte ich, daß nach dem ersten gefundenen Begriff nicht mehr weiter gesucht wird, weil die Mail ja dann quasi schon gelöscht ist. Quasi aber eben nur, weil sie ganz real erst dann gelöscht wird, wenn $pop3->quit(); gelaufen ist.
Und zum besseren Verständnis des Gesamtscriptes hatte ich halt den Scriptrest auch mal gepostet und den relevanten Teil zwischen die ###########-Linien gesetzt.
Das hab ich aber auch so beschrieben, oder?
Gruß
Norbert
Halihallo Norbert
Nur, der Code bleibt derselbe!
Das ist mir schon klar. Nur: Bemühe dich bitte das nächste mal gleich den relevanten
Code zu posten und deine Frage klar zu formulieren. Wir sind weder Hellseher, noch haben
wir grosse Lust uns durch A4 Seiten Code zu wälzen. Ich glaube das kannst du verstehen,
oder?
Inhalt öffnen, Inhalt einlesen, wieder schliessen
open(MAIN3,"./body.txt") || die $!;
@main3 = <MAIN3>;
close(MAIN3);
Nun hab ich die relevanten Begriffe in @main3.
Hm. Fast: die relevanten Begriffe und ein Zeilenumbruch.
chomp @main3;
entfernt diese.
foreach (@main3) {
for (; $x <= $#$Lines; $x++) {
Das würde ich der logik halber umkehren. Zuerst über alle Zeilen der Mail iterieren
und jeweils eine Zeile mit allen Stopwords (@main3) vergleichen, so macht es IMHO mehr
Sinn, obwohl das andere natürlich auch geht.
if ($Lines->[$x] =~ m/$_/i) {
Tja, hier ist der Fehler wohl bemerkbar geworden. Wenn die Begriffe in @main3 alle noch
ein Zeilenumbruch enthalten, wird es hier nur wahr, wenn der Begriff am Ende der Zeile
stünde.
Das wäre das, was ich selber anzubieten hab. Aber im Versuch tats das eben nicht.
Dann musst du schrittweise reduzieren, bis du den Fehler findest. Erstelle Debug-Ausgaben
von Variablen oder Schritten in Kontrollstrukturen, so findet man den Fehler oftmals
selber sehr schnell.
Außerdem möchte ich, daß nach dem ersten gefundenen Begriff nicht mehr weiter gesucht wird, weil die Mail ja dann quasi schon gelöscht ist. Quasi aber eben nur, weil sie ganz real erst dann gelöscht wird, wenn $pop3->quit(); gelaufen ist.
Du hast etwas in der Art:
foreach (@lines_of_body) {
foreach my $stop_word (@stopwords) {
if ($_ =~ m/$stop_word/i) { $pop->delete; }
}
}
Was hälst du von:
foreach (@lines_of_body) {
my $delete_status = 0;
foreach my $stop_word (@stopwords) {
if ($_ =~ m/$stop_word/i) { $pop->delete; $delete_status=1; break; }
}
if ($delete_status == 1) {break;}
}
Und zum besseren Verständnis des Gesamtscriptes hatte ich halt den Scriptrest auch mal gepostet und den relevanten Teil zwischen die ###########-Linien gesetzt.
Ich neige gar dazu dir recht zu geben. Nur zuoft fehlt der globale Kontext und lokal
(im kleinen Teilcode) lassen sich einige Fehler nicht erkennen.
Das hab ich aber auch so beschrieben, oder?
Nicht ganz. Du hattest gar keine Frage gestellt, bzw. sie derart offen gelassen, dass
ich zumindest nicht gewusst hatte, was du eigentlich von uns erwartest.
Wenn ich dich kurz zittieren darf:
"wie durchsuche ich den emailbody einer mail nach Begriffen, die in einer seperaten Datei stehen, um die Mail dann ggf. zu löschen.
Hier mein Versuch: (der entscheidende Teil steht zwischen den #####)"
OK, wir wissen dass du den E-Mail Body nach Begriffen durchsuchen möchtest und die Mail
ggf. löschen willst. Dann kommt ein "Hier mein Versuch:" und ein Rattenschwanz an Code.
Wo war die Frage? - Was wolltest du wissen? - Oder wolltest du uns nur dein Script
vorstellen?
Ich hoffe du verstehst jetzt, warum ich erst nicht so richtig auf dein Problem einge-
gangen bin, ich wusste nicht welches... Du darfst das nicht mit deinen Augen sehen, klar
kennst du dein Problem, wir nicht. Uns musst du es mit gezielten Fragen zeigen.
Viele Grüsse
Philipp
Hi Philip,
Hm. Fast: die relevanten Begriffe und ein Zeilenumbruch.
chomp @main3;
entfernt diese.
Aha, das bringt mich schonmal weiter.
Tja, hier ist der Fehler wohl bemerkbar geworden. Wenn die Begriffe in @main3 alle noch
ein Zeilenumbruch enthalten, wird es hier nur wahr, wenn der Begriff am Ende der Zeile
stünde.
Klar!
Dann musst du schrittweise reduzieren, bis du den Fehler findest. Erstelle Debug-Ausgaben
von Variablen oder Schritten in Kontrollstrukturen, so findet man den Fehler oftmals
selber sehr schnell.
Jaja, aber alle mir bekannten Möglichkeiten hatte ich schon ausgeschöpft. Ich kenn halt nicht alle...
Was hälst du von:
foreach (@lines_of_body) {
my $delete_status = 0;
foreach my $stop_word (@stopwords) {
if ($_ =~ m/$stop_word/i) { $pop->delete; $delete_status=1; break; }
}
if ($delete_status == 1) {break;}
}
Ja, gemauso hat ich mir das auch gedacht, leider kannte ich den break-Befehl nicht. Ich hatte da mit last gewurschtelt, aber da das Script eh nicht funtzte, weiß ich auch nicht, ob last gelaufen wäre.
Und zum besseren Verständnis des Gesamtscriptes hatte ich halt den Scriptrest auch mal gepostet und den relevanten Teil zwischen die ###########-Linien gesetzt.
Ich neige gar dazu dir recht zu geben. Nur zuoft fehlt der globale Kontext und lokal
(im kleinen Teilcode) lassen sich einige Fehler nicht erkennen.
Siehste mal. Sag ich doch.
Das hab ich aber auch so beschrieben, oder?
Nicht ganz. Du hattest gar keine Frage gestellt, bzw. sie derart offen gelassen, dass
ich zumindest nicht gewusst hatte, was du eigentlich von uns erwartest.Wenn ich dich kurz zittieren darf:
"wie durchsuche ich den emailbody einer mail nach Begriffen, die in einer seperaten Datei stehen, um die Mail dann ggf. zu löschen.
Fragezeichen vergessen, was? Naja, mir fehlen wohl einige perl-Befehle, Techniken zur Fehlersuche usw., dafür hätte ich ein fehlendes Fragezeichen stillschweigend gedanklich ersetzt und die Frage hinter diesem Satz schon vermutet.
Anyway, nun bin ich der Lösung ja schon sehr nahe und Du hast mir dabei geholfen.
Danke, vüll Jröß und bess demnähst (das war kölnische Mundart)
Norbert
Halihallo Norbert
Dann musst du schrittweise reduzieren, bis du den Fehler findest. Erstelle Debug-Ausgaben
von Variablen oder Schritten in Kontrollstrukturen, so findet man den Fehler oftmals
selber sehr schnell.Jaja, aber alle mir bekannten Möglichkeiten hatte ich schon ausgeschöpft. Ich kenn halt nicht alle...
OK, hier muss ich nochmal etwas loswerden: :-)
Besonders am Anfang gilt: "Buttom-Up, nicht Top-Down". Also nicht ein riesen Projekt
basteln (naja, oder einfach mal zwei, drei A4 Seiten eintippen) und dann wie verrückt
nach dem Fehler suchen, sondern gleich wieder alles verwerfen, von Grund auf sich
Schritt für Schritt vorkämpfen und Fehler gleich korrigieren, wenn sie das erste Mal
auftreten. Der Lernerfolg ist tausendmal grösser und am Schluss bringt man es
tatsächlich zum Laufen, anders, wenn man so'n riesen Ding vor sich hat und einfach nicht
weiss wo der Fehler ist und dann hier ins Forum gestürmt kommt (nimms nicht persönlich!).
Glaub mir, ich weiss _genau_ wovon ich spreche, ich lerne soeben C/C++ :-)
Und ich versuche mir die gleichen Grundsätze zu eigen zu machen.
Ja, gemauso hat ich mir das auch gedacht, leider kannte ich den break-Befehl nicht. Ich hatte da mit last gewurschtelt, aber da das Script eh nicht funtzte, weiß ich auch nicht, ob last gelaufen wäre.
Sollte in deinem Kontext die selbe Wirkung gehabt haben.
Näheres über:
perldoc -f break
perldoc -f last
Anyway, nun bin ich der Lösung ja schon sehr nahe und Du hast mir dabei geholfen.
Hoffe du hast es hingekriegt?
Danke, vüll Jröß und bess demnähst (das war kölnische Mundart)
Bitte und bis zum nöchschte mol (schwiizerdütsch)
Viele Grüsse
Philipp
OK, hier muss ich nochmal etwas loswerden: :-)
Besonders am Anfang gilt: "Buttom-Up, nicht Top-Down".
Hi Philipp,
hab ich ja gemacht, jedenfalls fast :-)
weiss wo der Fehler ist und dann hier ins Forum gestürmt kommt (nimms nicht persönlich!).
Keine Sorge. Jedenfalls habe ich zuvor stundenlang selber gesucht, eh ich hier gepostet hatte. Es gibt ja auch solche, die gleich den anderen die die Fehlersuche aufdrücken wollen.
Anyway, nun bin ich der Lösung ja schon sehr nahe und Du hast mir dabei geholfen.
Hoffe du hast es hingekriegt?
Jausi, hab ich. Zwar letztlich dann doch nicht mit dem break-Befehl (warum auch immer), aber hier kommt die entscheidende Stelle:
open(MAIN3,"./body.txt") || die $!;
@main3 = <MAIN3>;
chomp @main3;
close(MAIN3);
$x += 1;
for (; $x <= $#$Lines; $x++) {
push (@lines_of_body,$Lines->[$x]);
}
foreach (@lines_of_body) {
last if ($mailnummer eq "alt");
my $delete_status = 0;
foreach my $stop_word (@main3) {
if ($_ =~ m/$stop_word/i) {
$pop3->delete($msgno);
$delete_status=1;
$mailnummer=alt;
$gel_durch_body=1;
print qq~<TR><TD>$msgno</TD><TD>$from</TD><TD>$subject</TD><TD>gel(b)</TD></TR>~;
last;
}
}
}
} # end mailnumer=alt?
Diesmal ohne Gesamtkontext, aber ich glaube, Du kannst Dir inzwischen denken, wie was hier gemeint ist, gelle?
Also, vielen Dank zu Dir in die Schweiz für die Hilfe, endlich kann ich den Spammern ein Schnippchen schlagen :-)))
Danke, vüll Jröß und bess demnähst (das war kölnische Mundart)
Bitte und bis zum nöchschte mol (schwiizerdütsch)
Jausi, bis zum nöchschste mol :-)
Grüße Norbert