[Za-pm] oop

Spike spikeh at mweb.co.za
Fri Jun 6 04:49:33 CDT 2003


At 2003/06/06 10:55 AM, Sean Carte wrote:
>Aha! I'm using $ARGV[0] where you're using @ARGV:
I did that too :-(


I have written a object orientated perl module called Mailsend.pl.
It give a very simple interface to sendmail and allows you to send HTML 
formatted mail or plain or HTML and plain (multipart) and most importantly 
attachments.
The attachments bit is what makes it really usefully - attaching a file in 
send mail is horrible and with this module you can write a simple perl 
script to allow you to send attachments from the command line if you want.
It gives you control over things like the priority, from address, etc so 
would also be a good start to a spam machine.

It's not huge and is a very simple example of oop; both how to use it and 
how to write one.

The next step will be to replace sendmail with a built in SMTP engine ...

You can perldoc it for instalation and usage stuff.

<SNIP>

#----------------------------------------------------------------
# Title         : Mailsend.pm
# Author        : Spike spike at mweb.co.za
# Date          : 2003-03-04
#
# Description
# -----------
# This perl Module will provide a simple interface to Sendmail.
# It must be copied to your library path.
# To see a path list type:  "perl -e 'print join("\n", @INC)'"
# Various methods allow a mail to be sent to multiple recipients
# in plain text, html or both, with or without multiple attachments.
# The only obligatory methods Mailsend->new() and  setTo("address").
# If the style is set to html and only a setPlain message body is
# specified the plain text message will be set to html with a non-serif
# font (more readable on screen) and any URLs will be expanded with
# html tags to make them 'clickable'.
# If the style is set to plain and only an html message body is set
# an attempt to convert the html to plain text will be made. Note
# that the results will probably be ugly.
# If no style is set the setStyle will be defaulted to 'both' and
# any necessary conversions made in accordance with the rules above.
# A message with an attachment set with setAttach will have it's style
# set to 'both'. Attachments are base64 encoded.
# A message "priority can be set with setPriority. It can be set to any
# value but values fro 1-5 are supported by most clients. "1" is highest,
# "5" Lowest and "3" is Normal priority.
# Code for subroutine 'old_encode_base64' taken from MIME::Base64
# by Gisle Aas <gisle at ActiveState.com>.
#
# Examples
# --------
# $msg1 = Mailsend->new();
#
# $msg1->setTo('spike at mweb.com, recipient2 at foo.com, ...');
# $msg1->setSubject("$subject");
# $msg1->setFrom('spike at mweb.co.za');
# $msg1->setStyle('plain'); or 'html' or 'both'
# $msg1->setPlain("$plain_message_text")
# #msg1->sethtml("$html_message_code")
# $msg1->setMailprog('/path/to/sendmail');
# $msg1->setReplyto('sender at mweb.com');
# $msg1->setCc('cc_recipient1 at inode.co.za, cc_recipient2 at inode.co.za, ...');
# $msg1->setBcc('bcc_recipient1 at inode.co.za, bcc_recipient2 at inode.co.za, ...');
# $msg1->setAttach('/root/file1, /var/log/file2.txt, /home/me/file3, ...');
# $msg1->setPriority('1') # 1 high to 5 low. 3 normal.
#
#
# Change Control
# ---------------
# Date:  2003-03-o4
# Author: Spike spike at mweb.co.za
# Change: Initial version
#

package Mailsend;

use File::Basename;
use strict;

sub send
{
     my (%self, @attachments, $file, $basefilename, $encoded);

     my $self = shift;
     my ($die, $warn, $rv, $content_type, $message);

     unless (defined $self->{Mailprog})
     {
         $warn .= "No mail program defined\nI shall try and use a default\n";
         chomp($rv = `which sendmail`);
         if ($rv !~ /no sendmail/)
         {
             $self->{Mailprog} = $rv;
             $warn .= "I have set the Mailprog to $rv\n";
         }
         else
         {
             $die .= "I can't find a suitable Mailprog ... quiting\n";
         }
     }

     ($warn) && (print $warn);
     ($die) && (print $die) && (exit 0);

     ($self->{Attach}) && ($self->{Style} = "both");
     ($self->{Style}) || ($self->{Style} = "both");

#-- plain only --#

     if ($self->{Style} =~ m/plain/i)
     {
         $content_type = "text/plain; charset=\"us=ascii\"\n\n";

#-- get some plain content

         if((defined $self->{Html}) && (! defined $self{Plain}))
         {
             $self->{Plain} = makeplain("$self->{Html}");
         }

#-- build and send a plain only

         $message = $self->{Plain};
     }

#-- html only --#

     if ($self->{Style} =~ m/html/i)
     {
         $content_type = 'text/html; charset="us=ascii"';

#-- get some html

         if ((defined $self->{Plain}) && (! defined $self->{Html}))
         {
             $self->{Html} = makehtml("$self->{Plain}");
         }

#-- build and send html only

         $message = $self->{Html};
     }


#-- both --#

     if ($self->{Style} =~ m/Both/i)
     {
         if ((defined $self->{Plain}) && (! defined $self->{Html}))
         {
             $self->{Html} = makehtml("$self->{Plain}");
         }
         if((defined $self->{Html}) && (! defined $self->{Plain}))
         {
             $self->{Plain} = makeplain("$self->{Html}");
         }

         $content_type = 'multipart/alternative;' . 
qq{boundary="BoundaryPoodle"};

         $message = "\n--BoundaryPoodle\nContent-Type: text/plain; 
charset=\"us=ascii\"\n\n$self->{Plain}\n";
         $message .= "\n--BoundaryPoodle\nContent-Type: text/html; 
charset=\"us=ascii\"\n\n$self->{Html}\n";
         #$message = "\n--BoundaryPoodle\nContent-Type: text/plain; 
charset=\"us=ascii\"\nContent-Transfer-Encoding: 7bit\n\n$self->{Plain}\n";
         #$message .= "\n--BoundaryPoodle\nContent-Type: text/html; 
charset=\"us=ascii\"\nContent-Transfer-Encoding: 7bit\n\n$self->{Html}\n";
         $message .= "\n--BoundaryPoodle--\n";
     }

#-- attach--#

     if ($self->{Attach})
     {
         my $debug = $self->{Attach};
         @attachments = split(',',$self->{Attach});
         $content_type = 'multipart/mixed; ' . qq{boundary="mmBoundaryPoodle"};
         $content_type .= "\n\n--mmBoundaryPoodle\n";
         $content_type .= 'Content-Type: multipart/alternative; ' . 
qq{boundary="BoundaryPoodle"\n};

         foreach $file (@attachments)
         {
             chomp($file);
             $file =~ s/^\s+//g;
             $file =~ s/\s+$//g;

             $basefilename = basename($file);

             (-e "$file") || die(qq(I can't find file $file\n));

             local($/) = undef;
             open(FILE, "$file") or die "$!";
             $encoded = old_encode_base64(<FILE>);


             $message .= "--mmBoundaryPoodle";
             $message .= "\nContent-Type: application/octet-stream; 
name=\"$basefilename\"";
             $message .= "\nContent-Transfer-Encoding: base64";
             $message .= "\nContent-Disposition: attachment; 
filename=\"$basefilename\"";
             $message .= "\n\n$encoded";
             close FILE;
         }
         $message .= "--mmBoundaryPoodle--";
     }

     my $full_message = qq{From: $self->{From}\n};
     $full_message .= qq{To: $self->{To}\n};
     ($self->{Replyto}) && ($full_message .= qq{Reply-To: $self->{Replyto}\n});
     ($self->{Cc})      && ($full_message .= qq{Cc: $self->{Cc}\n});
     ($self->{Bcc})     && ($full_message .= qq{Bcc: $self->{Bcc}\n});
     ($self->{Subject}) && ($full_message .= qq{Subject: $self->{Subject}\n});
     $full_message .= "Mime-Version: 1.0\n";
     ($self->{Priority}) && ($full_message .= qq{X-Priority: 
$self->{Priority}\n});
     $full_message .= "Content-Type: $content_type\n";
     $full_message .= $message;

     open(SENDMAIL, "|$self->{Mailprog} -oi -t");
     print SENDMAIL "$full_message";
     close SENDMAIL;
}

# constructor #

sub new
{
     my $class = shift;
     my $self = {};

     return bless $self, $class;
}

# methods #

sub setStyle{
     my $self = shift;
     my $style = shift;
     $self->{Style} = $style
}

sub setPriority{
     my $self = shift;
     my $priority = shift;
     $self->{Priority} = $priority;
}


sub setHtml{
     my $self = shift;
     my $html = shift;
     $self->{Html} = $html;
}

sub setPlain{
     my $self = shift;
     my $plain = shift;
     $self->{Plain} = $plain;
}

sub setAttach{
     my $self = shift;
     my $attach = shift;
     $self->{Attach} = $attach;
}

sub setSubject{
     my $self = shift;
     my $subject = shift;
     $self->{Subject} = $subject;
}

sub setTo{
     my $self = shift;
     my $to = shift;
     $self->{To} = $to;
}

sub setFrom{
     my $self = shift;
     my $from = shift;
     $self->{From} = $from;
}

sub setCc{
     my $self = shift;
     my $cc = shift;
     $self->{Cc} = $cc;
}

sub setBcc{
     my $self = shift;
     my $bcc = shift;
     $self->{Bcc} = $bcc;
}

sub setMailprog{
     my $self = shift;
     my $mailprog = shift;
     $self->{Mailprog} = $mailprog;
}

sub setReplyto{
     my $self = shift;
     my $replyto = shift;
     $self->{Replyto} = $replyto;
}

sub makehtml
{
     my $body = shift;

     $body =~ s/ftp:\S+/<A HREF="$&">$&<\/A>/gs;
     $body =~ s/http:\S+/<A HREF="$&">$&<\/A>/gs;
     $body =~ s/https:\S+/<A HREF="$&">$&<\/A>/gs;
     my $htmlbody = "<PRE><font face=\"Arial, Helvetica, sans-serif\"> 
$body <\/font><\/PRE>";

     return $htmlbody
}

sub makeplain
{
     my ($line, $plaintext, @plain);

     my $html = shift;

     my @HTML = split(/(<[^>]*>)/, $html);

     foreach $line (@HTML)
     {
         $line =~ s/\n//g;
         $line =~ s/^\s+//g;
         $line =~ s/\s+$//g;
         $line =~ 
s/<\s*HR*>/-----------------------------------------------------------\n/i;
         ($line =~ m#<\s*/TD>#i) && push(@plain, "      ");
         ($line =~ m#<\s*/TR>#i) && push(@plain, "\n");
         ($line =~ m#<\s*TABLE>#i) && push(@plain, "\n");
         ($line =~ m#<\s*BR>#i) && push(@plain, "\n");
         ($line =~ m#<\s*/DIV>#i) && push(@plain, "\n\n");
         ($line =~ m#<\s*/P>#i) && push(@plain, "\n\n");
         ($line =~ m#<*>#) && (next);
         push(@plain, "$line");
     }

     $plaintext = join(' ', @plain);
     return $plaintext;

}

sub old_encode_base64 ($;$)
{
     my $res = "";
     my $eol = $_[1];
     $eol = "\n" unless defined $eol;
     pos($_[0]) = 0;                          # ensure start at the beginning

     $res = join '', map( pack('u',$_)=~ /^.(\S*)/, ($_[0]=~/(.{1,45})/gs));

     $res =~ tr|` -_|AA-Za-z0-9+/|;               # `# help emacs
     # fix padding at the end
     my $padding = (3 - length($_[0]) % 3) % 3;
     $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
     # break encoded string into lines of no more than 76 characters each
     if (length $eol) {
         $res =~ s/(.{1,76})/$1$eol/g;
     }
     return $res;
}


1;

__END__

=head1 NAME

Mailsend.pm

=head1 SYNOPSIS


  $msg1 = Mailsend->new();


  $msg1->setTo('spike at mweb.com, recipient2 at foo.com, ...');


  $msg1->setSubject("$subject");


  $msg1->setFrom('spike at mweb.co.za');


  $msg1->setStyle('plain'); or 'html' or 'both'


  $msg1->setPlain("$plain_message_text")


  #msg1->sethtml("$html_message_code")


  $msg1->setMailprog('/path/to/sendmail');


  $msg1->setReplyto('sender at mweb.com');


  $msg1->setCc('cc_recipient1 at inode.co.za,
                cc_recipient2 at inode.co.za,
                ...');


  $msg1->setBcc('bcc_recipient1 at inode.co.za,
                 bcc_recipient2 at inode.co.za,
                 ...');


  $msg1->setAttach('/root/file1, /var/log/file2.txt,
                    /home/me/file3, ...');


  $msg1->setPriority('1') # 1 high to 5 low. 3 normal.


  $msg1->send();

=head1 DESCRIPTION


This perl Module will provide a simple interface to Sendmail.
It must be copied to your library path.
To see a path list type:  "perl -e 'print join("\n", @INC)'"

Various methods allow a mail to be sent to multiple recipients
in plain text, html or both, with or without multiple attachments.
The only obligatory methods Mailsend->new() and  setTo("address")
and send().

If the style is set to html and only a setPlain message body is
specified the plain text message will be set to html with a non-serif
font (more readable on screen) and any URLs will be expanded with
html tags to make them 'clickable'.

If the style is set to plain and only an html message body is set
an attempt to convert the html to plain text will be made. Note
that the results will probably be ugly.

If no style is set the setStyle will be defaulted to 'both' and
any necessary conversions made in accordance with the rules above.

A message with an attachment set with setAttach will have it's style
set to 'both'. Attachments are base64 encoded.

A message "priority can be set with setPriority. It can be set to any
value but values fro 1-5 are supported by mosr clients. "1" is highest,
"5" Lowest and "3" is Normal priority.

Code for subroutine 'old_encode_base64' taken from MIME::Base64
by Gisle Aas <gisle at ActiveState.com>.


=cut


<SNIP>








Spike Hodge

UNIX Programmer
M-Web Technology
021 596 8496
082 901 5265

Click here and make M-Web your homepage
http://homepage.mweb.co.za 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.pm.org/pipermail/za-pm/attachments/20030606/1560f8c3/attachment.htm


More information about the Za-pm mailing list