MIME::Lite send one email in for loop

A

alexbarham

I am using MIME::Lite to send out an attachment for any image that is
received within each hour. Here is what I have:

use Date::Manip;
use MIME::Lite;
use Net::SMTP;

my $current_time = localtime;

<code that reads directory here>

foreach my $file(@files){
my $lastmodtime = stat($file);
my $currenttime = localtime;
<Date::Manip code to parse dates and extract elapsed hours>
<When I first started, I used -M $file but it kept crashing with some
obscure error, I just reran it and it worked??>
So as it is now:
<@time refers to DateCalc which will return +0:0:WK:DD:HH:MM:SS. I want
the 4th element to grab the elapsed hours)
if ($time[4] < 0.5){
send_message($file);
}

sub send_message{
my $file_name = shift;
my $msg = MIME:Lite->new(
From=>'(e-mail address removed)',
To=>'(e-mail address removed)',
Subject=>$file_name,
Type=>'image/jpeg',
Encoding=>'base64',
Path=>"/root/PERL/test_scripts/$file_name"
(;

MIME::Lite->send('smtp','smtp.myisp.com',Timeout=>60);
$msg->send;
}

The problem I have that only the last email is sent. The first emails
don't get sent. Any ideas as to what could cause this? I am wondering
if I need to rename the MIME::Lite object through each loop iteration
($msg1, $msg2, $msg3 etc...)

Thanks in advance for everyone's help
 
A

A. Sinan Unur

(e-mail address removed) wrote in @g49g2000cwa.googlegroups.com:
my $lastmodtime = stat($file);

perldoc -f stat

As for the rest, please follow the posting guidelines and post a short
script that we can run just by cutting and pasting into an editor.

Sinan
 
G

Gunnar Hjalmarsson

I am using MIME::Lite to send out an attachment for any image that is
received within each hour. Here is what I have:

<code that reads directory here>

The problem I have that only the last email is sent.

And still you didn't include the code that reads the files.

Please follow Sinan's advice.
 
B

Brian Wakem

I am using MIME::Lite to send out an attachment for any image that is
received within each hour. Here is what I have:

use Date::Manip;
use MIME::Lite;
use Net::SMTP;

my $current_time = localtime;

<code that reads directory here>

foreach my $file(@files){
<snip rest>


Follow the advise already given.

I will add one thing though - have a look at what @files actually contains.
 
A

alexbarham

As for the rest, please follow the posting guidelines and post a short
script that we can run just by cutting and pasting into an editor.

While I agree with you that keeping the code short, it is contradictory
to keep it both short and be able to paste it into an editor so that
the the PERL interpretor will run the code. You won't be able to
iterate through the files unless you read the directory. Nor will you
be able to single out the files that are received within the hour
without some kind of calculation using -M or stat. I snipped a lot of
the actual code and just replaced it with my flow of logic. Only
keeping the relevant parts. Namely, the send_message sub, which isn't
sending all the files it should. So I can either leave it as is. Or put
in the entire listing so that you can in fact have the PERL interpretor
run the code. Let me know what will work best.
And still you didn't include the code that reads the files.
I will add one thing though - have a look at what @files actually contains

I put in a statement in the send message sub:

if ($time[4] < 0.5){
send_message($file)
}

sub send_message{
my $file_name = shift;
print $file_name

This outputs all the files that should be included in the send_message
sub however as I stated only the last file is sent via email.

Thank you for the guidance on posting etiquette and I do appreciate
your help on this
 
B

Babacio

While I agree with you that keeping the code short, it is contradictory
to keep it both short and be able to paste it into an editor so that
the the PERL interpretor will run the code.

Is it really impossible to produce a shorter code which reproduces the
same bug ?

When I have a bug somewhere and start to decide that I can't resolve
it myself, I try to produce the shortest possible code which
reproduces it. And 80% of the time, doing this make me find where the
problem actually is.

This guideline is not only for the comodity of readers, it's a general
advice to help us whenever we have a problem.
 
A

A. Sinan Unur

(e-mail address removed) wrote in

[ Please provide the proper attributions when you reply. ]
While I agree with you that keeping the code short, it is
contradictory to keep it both short and be able to paste it into an
editor so that the the PERL interpretor will run the code.

s/PERL/perl/ above.

There is no contradiction. In my reply to you, I also pointed out that
you seemed to be using stat incorrectly. Namely:

(e-mail address removed) wrote in @g49g2000cwa.googlegroups.com:


perldoc -f stat
You won't be able to iterate through the files unless you read the
directory.

So, write a script that reads the directory. I fail to see the problem.
Nor will you be able to single out the files that are received within
the hour without some kind of calculation using -M or stat.

So, use stat correctly, and do whatever calculation you need.
I snipped a lot of the actual code and just replaced it with my
flow of logic. Only keeping the relevant parts.
....

Thank you for the guidance on posting etiquette and I do appreciate
your help on this.

I am skeptical: It does not look like you read the guidelines. They
explain very well the need to post compilable, runnable code. The
problem is in the code. You do not post the code. How do you expect us
to figure out where in the code the problem is?

The original code you posted contained a bunch of obvious syntax errors
as well:

(e-mail address removed) wrote in @g49g2000cwa.googlegroups.com:
my $file_name = shift;
my $msg = MIME:Lite->new(
From=>'(e-mail address removed)',
To=>'(e-mail address removed)',
Subject=>$file_name,
Type=>'image/jpeg',
Encoding=>'base64',
Path=>"/root/PERL/test_scripts/$file_name"
(;

How do you expect people to know what really is causing the problem?

Now, I am doing laundry, and bored, so:

C:\Home\asu1\UseNet\clpmisc> touch -t 200510020000 test.jpg

D:\Home\asu1\UseNet\clpmisc> dir test*.jpg
....
10/02/2005 12:00 AM 0 test.jpg
10/02/2005 12:00 AM 0 test1.jpg
10/02/2005 12:00 AM 0 test2.jpg

D:\Home\asu1\UseNet\clpmisc> cat files.pl
#!/usr/bin/perl

use strict;
use warnings;

use File::Spec::Functions 'catfile';
use MIME::Lite;

my $dir_name = shift || '.';

my @files;
if ( populate($dir_name, \@files) ) {
send_file_by_email($_) for @files;
}

## subs

sub populate {
my ($dir_name, $files_ref) = @_;
$files_ref = [ ] unless defined $files_ref;

opendir my $dir, $dir_name
or die "Cannot open $dir_name";

while (my $file = readdir $dir) {
next unless $file =~ /\.jpe?g$/i;
my $path = catfile $dir_name, $file;
my $mtime = (stat $path)[9];
if ( time() - 3600 > $mtime ) {
push @{ $files_ref }, $path;
}
}

closedir $dir or die "Cannot close $dir_name: $!";
return scalar @{ $files_ref };
}

sub send_file_by_email {
my ($file) = @_;

my $msg = MIME::Lite->new(
From => '(e-mail address removed)',
To =>'(e-mail address removed)',
Subject => $file,
Type =>'image/jpeg',
Encoding =>'base64',
Path => $file,
);

MIME::Lite->send('smtp','smtp.myisp.com', Timeout => 60);
$msg->send
or warn "$file not sent: $@";
return;
}

__END__

D:\Home\asu1\UseNet\clpmisc> files
..\test.jpg not sent: Failed to connect to mail server: Invalid argument
at D:\Home\asu1\UseNet\clpmisc\files.pl line 52
..\test1.jpg not sent: Failed to connect to mail server: Invalid argument
at D:\Home\asu1\UseNet\clpmisc\files.pl line 52
..\test2.jpg not sent: Failed to connect to mail server: Invalid argument
at D:\Home\asu1\UseNet\clpmisc\files.pl line 52

See, it is not that hard.

The problem is, *YOU* are the one who is supposed to put effort into
your question.

Now, I gotta go put my clothes in the dryer.

Sinan
 
G

Gunnar Hjalmarsson

While I agree with you that keeping the code short, it is contradictory
to keep it both short and be able to paste it into an editor so that
the the PERL interpretor will run the code.

Note that you don't need to post the original code. Just write a short
program that reproduces the problem you are having.
I put in a statement in the send message sub:

if ($time[4] < 0.5){
send_message($file)
}

sub send_message{
my $file_name = shift;
print $file_name

This outputs all the files that should be included in the send_message
sub

That's good; it reduces the possible reasons for the problem.
however as I stated only the last file is sent via email.

I tested your sub where @files had been populated with three filenames:

send_message($_) for @files;

and received three messages successfully. I have almost no experience
from using MIME::Lite, but checking for success is always advisable:

$msg->send or die "Couldn't mail $file_name: $!";

If your script still runs without a fatal error, you'd better examine
the mailserver log.
 
A

alexbarham

OK. Thanks for the guidelines both on the netiquette and the script
suggestions.

I re-wrote the script to just simply traverse the directory and email
any jpeg files it finds. That worked. I then made a small change to the
original sript to test the last modified date from less than 0.5 to
greater than 0.5:

if ($time[4] < 0.5){
# send_message($file);
}
TO
if ($time[4] > 0.5){
# send_message($file);
}

I ran the script without calling the send_message sub. By this time the
files were well over an hour old. It output the correct filenames and
correct file age, so that worked. I then ran touch to update the time
stamp on the files. Then I put it back from greater than 0.5 to less
than 0.5 and (although not expecting it too) that also called the
correct file names and file ages. I then took out the # to call the
send_message sub and and I received all 4 emails! I can't really
explain why it works now but now the problem is solved.

Again thanks to everyone for your help
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,744
Latest member
CortneyMcK

Latest Threads

Top