Norbert: pop3 emailbody durchsuchen

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>~;
###############################################################################

Inhalt öffnen, Inhalt einlesen, wieder schliessen

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();

}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  1. 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

    1. ...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

      1. 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

        1. 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!

          Inhalt öffnen, Inhalt einlesen, wieder schliessen

          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

          1. 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

            1. 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

              1. 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

                1. 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:

                  Inhalt öffnen, Inhalt einlesen, wieder schliessen

                  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