This is roughly a copy of the above program but demonstrates how to iterate over mails and grep for a regular expression in the mail body.
It shows how to open a MailItem for display and user interaction.
#!perl
use 5.020;
use feature 'signatures';
no warnings 'experimental::signatures';
use Getopt::Long;
use File::Basename 'dirname';
use File::Spec;
use Win32::OLE 'in';
use Win32::OLE::Const 'Microsoft Outlook';
use Win32::OLE::Variant;
use Scalar::Util 'blessed';
system('chcp 65001 >NUL:');
binmode STDOUT, ':encoding(UTF-8)';
GetOptions(
'quick' => \my $quick_run,
'mailbox|mb=s' => \my $mailbox,
'start-folders|f=s' => \my @start_folder,
'open|o' => \my $do_open,
'print|p' => \my $do_print,
);
=head1 NAME
outlook-grep.pl - grep für Outlook
=head1 SYNOPSIS
perl outlook-grep.pl -o some-regular-expression --mailbox "#MAGIC-MA
+ILBOX"
=cut
my $outlook = Win32::OLE->GetActiveObject('Outlook.Application')
|| Win32::OLE->new('Outlook.Application', 'Quit');
my $namespace = $outlook->GetNamespace("MAPI")
or die "Couldn't get MAPI namespace?!";
if( ! @start_folder ) {
push @start_folder, 'Posteingang';
}
@start_folder = map {
find_folder( $_ )
} @start_folder;
my @keywords = @ARGV;
sub progress( $info ) {
local $| = 1;
state $last_progress;
print join "", " " x length($last_progress), "\r", $info, "\r";
$last_progress = $info;
}
sub find_folder($path) {
my $folder = $namespace->Folders->{$mailbox};
for my $el (split /!/, $path) {
progress( $el );
my $next_folder = $folder->Folders->{$el};
if( ! $next_folder ) {
warn "No folder found for '$el' in '$path'";
for( in($folder->Folders) ) {
say "<$_->{Name}>";
};
};
$folder = $next_folder;
};
return $folder;
}
sub in_all_subfolders( $callback, $queue=[] ) {
while( my $folder = shift @$queue ) {
$callback->($folder);
my $folders = $folder->Folders;
my $subfolder = $folders->GetFirst;
while( $subfolder ) {
push @$queue, $subfolder;
$subfolder = $folders->GetNext;
};
}
}
sub found( $mailitem, $where, $options ) {
progress("");
say sprintf "%s (%s)", $mailitem->{Subject}, $where;
$mailitem->Display;
}
sub scan_mails( $folder, $options ) {
my $visual = $folder->{Name};
progress(sprintf "%s", $visual);
my $items = $folder->{Items};
if(! $items) {
#warn sprintf "%s ist leer", $visual;
return ;
}
my $mail = $items->GetFirst;
my $total = $items->Count;
my $count = 0;
while( $mail ) {
$count++;
progress(sprintf "%s (%d/%d)", $visual, $count, $total);
my @places;
push @places, map { [$mail->{$_}, $_] } (qw(Subject HTMLBody))
+;
push @places, map { [$_->Filename, 'Attachment'] } (in( $mail-
+>Attachments));
#use Data::Dumper; warn Dumper $options;
my ($found, $where);
for my $v (@places) {
my ($val,$w) = @$v;
for my $str (@{$options->{ keyword }}) {
if( $val =~ /\Q$str/) {
$found = 1;
$where //= $w;
}
}
}
if( $found ) {
found( $mail, $where, $options );
};
$mail = $items->GetNext;
}
}
my %search_options = (
keyword => \@keywords,
);
in_all_subfolders( sub( $this_folder ) {
scan_mails( $this_folder, \%search_options );
}, \@start_folder);
|