Category: |
E-Mail Programs |
Author/Contact Info |
Kyle Krom (buckaduck) |
Description: |
This Win32 program extracts all email messages from your Lotus Notes account, and saves the text and all of the attachments to your hard drive.
Some of this code was based on the excellent program getnotes.pl |
# This program extracts email messages from a
# Lotus Notes account.
#
# Email messages will be saved in directories
# named for the mail folder they're stored in.
# All of these directories will be stored
# under a new top-level directory named
# "C:\temp\mail" by default, but this can be
# overridden with the -d flag.
#
# For each email message, a subdirectory will
# be created, containing the text and attachments
# for that message. These subdirectories are
# currently named by sequential numbers instead of
# by their subject titles. That's on my TODO list
# to fix; it shouldn't be too hard.
#
# Some folders in the Notes mail database are not
# really mail folders, so I try to skip them.
# Currently I skip all folders whose names are in
# parentheses (except for Inbox), and the folders
# in the array @badlist. You can customize @badlist
# as necessary.
#
# By default, Lotus Notes will open the email
# database for the PC's default user. To access
# the email for a different user: open Notes
# and switch to another userid first; then run
# this program while Notes is still open.
use strict;
use English;
use warnings;
use vars qw($opt_d $opt_v);
use Getopt::Std;
use Win32::OLE;
# Command-line options:
# -d dirname Save everything under the directory "dirname"
# -v Verbose reporting of progress
getopt("d");
# Define a directory to store the results
my $dir = $opt_d || 'C:/temp/mail';
mkdir ($dir, 0755) or die "Can't make $dir: $!";
# Define a list of "Normal" folders to skip
my @badlist = ('_Archiving', 'Archiving\\Age of Documents',
'Discussion Threads', 'Events');
# Auto-print carriage returns
$OUTPUT_RECORD_SEPARATOR = "\n";
# Open the email database in Lotus Notes
# (To use another person's email database, switch to
# their userid in Notes before running this program)
my $notes = Win32::OLE->new('Notes.NotesSession')
or die "Can't open Lotus Notes";
my $database = $notes->GetDatabase("","");
$database->OpenMail;
# Verify the server connection
print "Connected to ", $database->{Title},
" on ", $database->{Server} if $opt_v;
# Loop over all of the folders
foreach my $viewname (GetViews($database)) {
# Get the object for this View
print "Checking folder $viewname...";
my $view = $database->GetView($viewname);
# Create a subdirectory to store the messages in
$viewname =~ tr/()$//d;
$viewname =~ s(\\)(.)g;
my $path = "$dir/$viewname";
mkdir ($path, 0755)
or die "Can't make directory $path: $!";
chdir ($path);
# Get the first document in the folder
my $num = 1;
my $doc = $view->GetFirstDocument;
next unless $doc;
GetInfo($num, $path, $doc);
# Get the remaining documents in the folder
while ($doc = $view->GetNextDocument($doc)) {
$num++;
GetInfo($num, $path, $doc);
}
}
sub GetInfo {
my ($num, $path, $doc) = @_;
print "Processing message $num" if $opt_v;
# Create a new subdirectory based on the message number
my $subdir = sprintf("%02d",$num);
mkdir ($subdir, 0755)
or die "Can't make $subdir subdirectory: $!";
# Write the contents of the message to a file
open (TEXTFILE, ">$subdir/message.txt")
or die "Can't create $subdir message file: $!";
print TEXTFILE "From: ", $doc->{From}->[0];
print TEXTFILE "Subject: ", $doc->{Subject}->[0];
print TEXTFILE $doc->{Body};
close TEXTFILE;
# Save attachments as files, if any
my $array_ref = $doc->{'$FILE'};
foreach my $attachment (@$array_ref) {
if ($attachment) {
ExtractAttachment($doc, "$path/$subdir", $attachment);
}
}
}
sub ExtractAttachment {
my ($doc, $path, $filename) = @_;
print "Extracting attachment $filename" if $opt_v;
# Get a Windows-friendly pathname for the file
$path = "$path/$filename";
$path =~ tr/\//\\/;
# Save the attachment to a file
my $attachment = $doc->GetAttachment($filename);
$attachment->ExtractFile($path);
}
sub GetViews {
my ($database) = @_;
my @views = ();
# Loop through all of the views in this database
my $array_ref = $database->{Views};
foreach my $view (@$array_ref) {
my $name = $view->{Name};
# We only want folders if it's the Inbox
# or a normal folder name with no parentheses
if (($name eq '($Inbox)') or ($name !~ /\(.+\)/)) {
# Add the folder name to the @views list
# if it's not in the @badlist
push(@views, $name) unless (grep { $name eq $_ } @badlist);
}
}
return @views;
}
|
Re: Store Lotus Notes Email
by NateTut (Deacon) on Dec 10, 2004 at 00:53 UTC
|
Thanks to buckaduck for this lifesaver of a script. Our Notes setup here automagically deletes messages over 90 days weekly. Now I can save them off in a usuable & portable format.
I have made some modest changes to the script.
UPDATE:
The script now saves messages with the same or related (FW & RE) to the same directory.
Here is my version:
# This program extracts email messages from a
# Lotus Notes account.
#
# Email messages will be saved in directories
# named for the mail folder they're stored in.
# All of these directories will be stored
# under a new top-level directory named
# "C:\temp\mail" by default, but this can be
# overridden with the -d flag.
#
# For each email message, a subdirectory will
# be created, containing the text and attachments
# for that message. These subdirectories are
# currently named by sequential numbers instead of
# by their subject titles. That's on my TODO list
# to fix; it shouldn't be too hard.
#
# Some folders in the Notes mail database are not
# really mail folders, so I try to skip them.
# Currently I skip all folders whose names are in
# parentheses (except for Inbox), and the folders
# in the array @badlist. You can customize @badlist
# as necessary.
#
# By default, Lotus Notes will open the email
# database for the PC's default user. To access
# the email for a different user: open Notes
# and switch to another userid first; then run
# this program while Notes is still open.
#
# Original by Kyle Krom (buckaduck)
#
# Tweaked by Doug Marsh (NateTut)
#
# Added Default Directory of "My Documents\Notes2Files"
# Added 'All by Purge Date', 'Stationery' to the @badlist
# Added an Exception for (Sent)
# Remove extraneous LFs from message.txt
# Message Directories are now named for $Subject
# Multiple Messages with the same or Related Subjects (i.e. FW & RE) a
+re
# now stored to the same folder.
# Tweaked some prints
#
use strict;
use English;
use warnings;
use vars qw($opt_d $opt_v);
use charnames ':full';
use Getopt::Std;
use Win32::OLE;
use Win32;
# Command-line options:
# -d dirname Save everything under the directory "dirname"
# -v Verbose reporting of progress
getopt("d");
# Define a directory to store the results
my $dir = $opt_d || Win32::GetFolderPath(Win32::CSIDL_PERSONAL) . '\\N
+otes2Files';
if(-d $dir)
{
print("Directory: $dir already exists.\nPlease choose another direc
+tory or remove $dir.\n");
exit(1);
}
mkdir ($dir, 0755) or die "Can't make $dir: $!";
print("Saving Lotus Notes Mail in: $dir\\\n");
# Define a list of "Normal" folders to skip
my @badlist = ('_Archiving', 'Archiving\\Age of Documents',
'Discussion Threads', 'Events', 'All by Purge Date', 'S
+tationery');
# Auto-print carriage returns
$OUTPUT_RECORD_SEPARATOR = "\n";
# Open the email database in Lotus Notes
# (To use another person's email database, switch to
# their userid in Notes before running this program)
my $notes = Win32::OLE->new('Notes.NotesSession')
or die "Can't open Lotus Notes";
my $database = $notes->GetDatabase("","");
$database->OpenMail;
# Verify the server connection
print "Connected to ", $database->{Title},
" on ", $database->{Server} if $opt_v;
# Loop over all of the folders
foreach my $viewname (GetViews($database)) {
# Get the object for this View
print "Saving Messages in folder $viewname...";
my $view = $database->GetView($viewname);
# Create a subdirectory to store the messages in
$viewname =~ tr/()$//d;
$viewname =~ s(\\)(.)g;
my $path = "$dir/$viewname";
mkdir ($path, 0755)
or die "Can't make directory $path: $!";
chdir ($path);
# Get the first document in the folder
my $num = 1;
my $doc = $view->GetFirstDocument;
next unless $doc;
GetInfo($num, $path, $doc);
# Get the remaining documents in the folder
while ($doc = $view->GetNextDocument($doc)) {
$num++;
GetInfo($num, $path, $doc);
}
}
sub GetInfo {
my ($num, $path, $doc) = @_;
print "Processing message $num" if $opt_v;
# Create a new subdirectory based on the message number
my $Cleaned_Subject = $doc->{Subject}->[0];
while($Cleaned_Subject =~ s/[^A-z0-9\$%'`\-\@{}~!#()&_^ ]/\-/g)
{
;
}
$Cleaned_Subject =~ s/^\s*//;
$Cleaned_Subject =~ s/\s*$//;
$Cleaned_Subject =~ s/\\//;
$Cleaned_Subject =~ s/\s+/\-/g;
my $subdir = $Cleaned_Subject;
$subdir =~ s/^RE\-//i;
$subdir =~ s/^FW\-//i;
$subdir =~ s/^\-//i;
if($subdir eq '')
{
$subdir = 'No_Subject';
}
if(! -d $subdir)
{
mkdir ($subdir, 0755) or warn "Can't make \[$subdir\] subdirector
+y: $!";
}
# Write the contents of the message to a file
my $FileName = sprintf("%04d_Message.txt", $num);
open (TEXTFILE, ">$subdir/$FileName") or warn "Can't create \[$subdi
+r/$FileName\] file: $!";
print TEXTFILE "From: ", $doc->{From}->[0];
print TEXTFILE "Subject: ", $doc->{Subject}->[0];
my $NewBody = $doc->{Body};
$NewBody =~ s/\x0D\n/\n/g;
print TEXTFILE $NewBody;
close TEXTFILE;
# Save attachments as files, if any
my $array_ref = $doc->{'$FILE'};
foreach my $attachment (@$array_ref) {
if ($attachment) {
ExtractAttachment($doc, "$path/$subdir", $attachment);
}
}
}
sub ExtractAttachment {
my ($doc, $path, $filename) = @_;
print "Extracting attachment $filename" if $opt_v;
# Get a Windows-friendly pathname for the file
$path = "$path/$filename";
$path =~ tr/\//\\/;
# Save the attachment to a file
my $attachment = $doc->GetAttachment($filename);
eval { $attachment->ExtractFile($path) };
if($?)
{
print("Error Saving Attachment:$filename:$?:$!:$@:$^E\n");
}
}
sub GetViews {
my ($database) = @_;
my @views = ();
# Loop through all of the views in this database
my $array_ref = $database->{Views};
foreach my $view (@$array_ref) {
my $name = $view->{Name};
# We only want folders if it's the Inbox or Sent
# or a normal folder name with no parentheses
if (($name eq '($Inbox)') or ($name eq '($Sent)') or ($name !~ /\(
+.+\)/))
{
# Add the folder name to the @views list
# if it's not in the @badlist
push(@views, $name) unless (grep { $name eq $_ } @badlist);
}
}
return @views;
}
Doug | [reply] [d/l] |
|
These are some awesome improvements! I'm glad we could help each other.
| [reply] |
|
The Attachments seemed not to be saving off... I get no message warnings using the newer code... but when I print that ExtractFile message anyways it says something about: No such file or directory.
I tried hard coding the path and it still doesn't save off the attachments.
Any ideas?
| [reply] |
|
|
|
|
|
Re: Store Lotus Notes Email
by Anonymous Monk on Sep 25, 2003 at 16:28 UTC
|
Source Code? What do i do with it?!
I need to store or convert all of my Lotus Notes (R5) email so I can read it in Outlook or otherwise text.
If this will do it -- what do I do with this code?
Please help! | [reply] |
|
To use this program as written you need a PC with Perl and Lotus Notes installed, and it should already be configured so that you are able to login to Lotus Notes and read your mail.
You don't need to compile the source code, or anything like that. Just save this code to a file (e.g. "get_mail.pl") and run it from a Windows command prompt:
perl get_mail.pl .
Some command line options are described in the source code comments.
If Lotus Notes isn't already running, it will launch automatically.
| [reply] [d/l] |
|
Can I store emails in html version?
| [reply] |
|
|
|
Hello to all of you, I'm trying to extract my notes messages to txt files before migrating to outlook. However,Perl is not installed on my machine. I would like to know if there's a solution for people like me who only have Lotus on their desktop.
| [reply] |
|
|
Export the email and save it as a *.eml - that should save it into a format that can be opened in Outlook.
| [reply] |
|
Does this work on LN .nsf files?
| [reply] |
|
|