=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