CPAN: Email-Text auslesen

Beitrag lesen

=pod

Dieses Posting ist gleichzeitig ein funktionierendes Perlprogramm. Bitte in UTF-8 abspeichern. Führ - mich - aus! (Ich liebe Literate Programming als Lehrwerkzeug; mehr dazu in der Wikipedia.)

Ich ignoriere dein Posting mit dem Workaround. Du lernst mehr, wenn ich auf dieses hier eingehe.

Betrachten wir zunächst die Synopse von LNet::POP3:

my $msg = $pop->get($msgnum);

Die Methode get liefert eine Mail-Nachricht als String zurück. Mangels POP3-Account für Testzwecke konnte ich das nicht ausprobieren. Angenommen, eine Nachricht sei dann:

=cut

use 5.010; use utf8; # Ordnung muss sein.
my $message = <<'LOLINTERNET';
Subject: Foobar =?UTF-8?B?4pi6?=
From: foo@example.com
To: bar@example.net,
 =?UTF-8?B?SGVyciDDm8Oxw6zDp8O4xJHhuJ0g?=quux@example.org
Cc: baz@example.com
Date: Thu, 1 Jan 1970 00:00:00 +0000
In-Reply-To: msgid@example.net
References: msgid@example.net
Message-Id: msgid@example.com
Mime-Version: 1.0
Content-Type: multipart/alternative;
 boundary="=_limes"

--=_limes
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Hallo Welt! ♡

--=_limes
Content-Type: application/x-perl;
 name="foo.pl"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="foo.pl"

Ceci n'est pas une programme.

--=_limes--
LOLINTERNET

=pod

Die weitaus besten Werkzeuge zum Zerlegen liefert ohne Zweifel das PEP. Lhttp://emailproject.perl.org/

=cut

use Email::MIME qw();
my $parsed = Email::MIME->new($message);

=pod

Dies ist objektorientierte Programmierung. Wenn du ein bares Objekt C<print>en willst, tust du es falsch. Unter Stringifizierung gibt's, den Typen (meist geC<bless>ter Hashrefs, wie du gezeigt hast) und die Hexadresse, wo's im Speicher liegt. Objekte muss man sich mit speziellen Dumpern anschauen. Ich empfehle L<Data::Dump::Streamer>, den König unter den Dumpern.

=cut

use DDS; Dump $parsed;

$Email_MIME1 = bless( {

#                  body     => \do { my $v = '' },
#                  body_raw => "--=_limes\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encod".
#         "ing: 8bit\n\nHallo Welt! \x{2661}\n\n--=_limes\nContent-Type: application/x-perl;\n n".
#         "ame="foo.pl"\nContent-Transfer-Encoding: 7bit\nContent-Disposition: attach".
#         "ment;\n filename="foo.pl"\n\nCeci n'est pas une programme.\n\n--=_limes--\n",
#                  ct       => {
#                                attributes => { boundary => '=_limes' },
#                                composite  => 'alternative',
#                                discrete   => 'multipart'
#                              },
#                  header   => bless( {
#                                headers => [
#                                             'Subject',
#                                             'Foobar =?UTF-8?B?4pi6?=',
#                                             'From',
#                                             'foo@example.com',
#                                             'To',
#                                             'bar@example.net, =?UTF-8?B?SGVyciDDm8Oxw6zDp8O4xJHhuJ0g?=quux@example.org',
#                                             'Cc',
#                                             'baz@example.com',
#                                             'Date',
#                                             'Thu, 1 Jan 1970 00:00:00 +0000',
#                                             'In-Reply-To',
#                                             'msgid@example.net',
#                                             'References',
#                                             'msgid@example.net',
#                                             'Message-Id',
#                                             'msgid@example.com',
#                                             'Mime-Version',
#                                             '1.0',
#                                             'Content-Type',
#                                             'multipart/alternative; boundary="=_limes"'
#                                           ],
#                                mycrlf  => "\n"
#                              }, 'Email::MIME::Header' ),
#                  mycrlf   => "\n",
#                  parts    => [
#                                bless( {
#                                  body     => \do { my $v = "Hallo Welt! \x{2661}\n\n" },
#                                  body_raw => "Hallo Welt! \x{2661}\n\n",
#                                  ct       => {
#                                                attributes => { charset => 'UTF-8' },
#                                                composite  => 'plain',
#                                                discrete   => 'text'
#                                              },
#                                  header   => bless( {
#                                                headers => [
#                                                             'Content-Type',
#                                                             'text/plain; charset=UTF-8',
#                                                             'Content-Transfer-Encoding',
#                                                             '8bit'
#                                                           ],
#                                                mycrlf  => "\n"
#                                              }, 'Email::MIME::Header' ),
#                                  mycrlf   => "\n",
#                                  parts    => []
#                                }, 'Email::MIME' ),
#                                bless( {
#                                  body     => \do { my $v = "Ceci n'est pas une programme.\n\n" },
#                                  body_raw => "Ceci n'est pas une programme.\n\n",
#                                  ct       => {
#                                                attributes => { name => 'foo.pl' },
#                                                composite  => 'x-perl',
#                                                discrete   => 'application'
#                                              },
#                                  header   => bless( {
#                                                headers => [
#                                                             'Content-Type',
#                                                             'application/x-perl; name="foo.pl"',
#                                                             'Content-Transfer-Encoding',
#                                                             '7bit',
#                                                             'Content-Disposition',
#                                                             'attachment; filename="foo.pl"'
#                                                           ],
#                                                mycrlf  => "\n"
#                                              }, 'Email::MIME::Header' ),
#                                  mycrlf   => "\n",
#                                  parts    => []
#                                }, 'Email::MIME' )
#                              ]
#                }, 'Email::MIME' );

=pod

Allerdings ist es Pfuibäh, mittels einfacher Dereferenzierung auf die Innereien zuzugreifen. Jemand kann gewiss einen passenden Link dazu beisteuern, warum.

Ein Blick in die Doku von LEmail::MIME verrät dann wieder, was man mit der Objektinstanz machen kann. Die MIME-Parts hattest du ja schon. Du interessierst dich aber nur für die, die normaler Text sind.

=cut

for my $part ($parsed->parts) { # $part ist wieder vom Typ Email::MIME
    next unless $part->content_type ~~ m|\A text/plain|msx;
    $part->body_str; # liefert dekodierten Inhalt als Textstring zurück

womöglich möchtest du ihn nach STDOUT schreiben, z.B. für ein CGI-Programm?

use Encode qw(encode_utf8); say encode_utf8 $part->body_str;

}

=pod

Wenn dir dieses Posting gefallen hat, bewerte es als hilfreich.

=cut