Formulación y Ejecución de la Estrategia Proceso de
4. Cuándo tener un tablero de control estratégico
Up until this point, you’ve seen only the methods and options related to the connection object itself. This means that the e-mail is still sitting on the server waiting to be picked up.
You check for e-mail receipt with the login() method. When you receive mail (the login() method returns more than 0), you have a choice of what to do with the mail. You can obtain a list of messages and their sizes with the list() method, you can retrieve the messages with get(), or you can do both. I’ll show you how to do both. Just be aware that you aren’t required to obtain a list of messages before retrieving them.
Login
Once you’ve created the connection object, you log in to the server by using the login() method. The login() method sends the USER and the PASS commands to the POP3 server, according to the protocol specification. Neither the username nor the password is required. If you don’t pro- vide the password, it will be read using Net::Netrc. If you don’t give the username, the currently logged-in user will be sent as the username. In practice, it’s just as easy and usually cleaner to specify both within the program. Doing so avoids confusion later when you need to migrate the code to a different machine or user, or just have to look at it three years later to debug it.
The basic syntax for the login() method is as follows: $pop3conn->login(username,password);
C H A P T E R 6■ N E T: : TO O L S 111
When login() is called in a numeric context, the result is the number of messages waiting on the server for the user. If there is an error with authentication, the login() method will return undef. Therefore, you can determine if you have messages waiting by using an if/then control statement:
if ($pop3conn->login($username,$password) > 0) { print "You've Got Mail!\n";
}
■Note
Other methods for authentication include apop()andauth(), which provide additional security but also have additional requirements. For more information about these methods, see the Net::POP3doc- umentation at http://search.cpan.org/~gbarr/libnet-1.19/Net/POP3.pm.The user() and pass() methods send the username and password for the connection by sending the POP3 USER and PASS commands. Their arguments are, not surprisingly, the username and the password, respectively. These two methods perform essentially the same functions as the login()method, which also sends the USER and PASS commands to the POP3 server. The login() method returns the number of messages, whereas these two methods do not.
List
The aptly titled list() method returns a list of the messages and their corresponding sizes. Actually, list() can also return the size of an individual message if it’s called with an argument. For the first case, list() returns a reference to a hash. The hash contains the message numbers as keys and their sizes as values. Building on the example shown in the previous section, this code obtains a list of messages and prints their message numbers and sizes:
$msgs = $pop3conn->list(); foreach $msg (keys %$msgs) {
print "Message $msg is $$msgs{$msg} bytes\n"; }
Listing 6-1 (Pop3complete.pl) shows a more complete example. Listing 6-1. Listing POP3 Messages
#!/usr/bin/perl -w use strict; use Net::POP3;
my $username = "user\@example.com"; my $password = "password";
C H A P T E R 6■ N E T: : TO O L S
112
my $pop3conn = Net::POP3->new("mail.example.com", timeout => 30); if ($pop3conn->login($username,$password) > 0) {
print "You've Got Mail!\n"; my $messages = $pop3conn->list(); foreach my $msg (keys %{$messages}) {
print "Message $msg is $messages->{$msg} bytes\n"; }
}
$pop3conn->quit
The quit() method closes the connection. I’ll explain it further in the “Deleting E-Mail and Quitting” section.
The output from the program will be similar to the following, which shows that I happen to have 12 messages in this mailbox:
You've Got Mail! Message 6 is 3353 bytes Message 11 is 4234 bytes Message 3 is 7721 bytes Message 7 is 2385 bytes Message 9 is 1578 bytes Message 12 is 257788 bytes Message 2 is 4700 bytes Message 8 is 1659 bytes Message 1 is 3723 bytes Message 4 is 1312 bytes Message 10 is 1832 bytes Message 5 is 2145 bytes
Get
You actually retrieve the message with the get() method, called with the message number as an argument. The get() method returns a reference to an array of the message itself. You can do as you please with this array reference, including simply printing the messages. Listing 6-2 (Pop3example2.pl) shows an example that retrieves a message and prints it to STDOUT. Listing 6-2. Getting and Printing POP3 Messages
#!/usr/bin/perl -w use strict; use Net::POP3;
my $username = "user\@example.com"; my $password = "password";
my $pop3conn = Net::POP3->new("mail.example.com", timeout => 30); my $nummsgs = $pop3conn->login($username,$password);
C H A P T E R 6■ N E T: : TO O L S 113
if ($nummsgs > 0) {
print "There are $nummsgs messages waiting\n"; my $message = $pop3conn->get(12);
print "@{$message}"; }
$pop3conn->quit;
In this example, the number of messages available is stored in a variable called $nummsgs. Then the $nummsgs variable is checked to see if it’s greater than zero. If it is, the number of mes- sages waiting is printed, followed by message number 12. Note that I already knew how many messages were waiting and merely hard-coded message number 12 into this example. It’s more likely that you’ll want to iterate through each of the messages with a for loop, as shown in Listing 6-3 (Pop3example3.pl).
Listing 6-3. Retrieving Messages with Net::POP3 #!/usr/bin/perl -w
use Net::POP3; use strict;
my $username = "user\@example.com"; my $password = "password";
my $pop3conn = Net::POP3->new("mail.example.com", timeout => 30); my $nummsgs = $pop3conn->login($username,$password);
for (my $i=1;$i<=$nummsgs;$i++) { my $message = $pop3conn->get($i); print "@{$message}";
print "retrieved message $i\n\n\n"; }
$pop3conn->quit;
In this example, each message is retrieved in turn and printed to STDOUT.
■Note
Thegetfh()method performs the same function as get(), but gives a filehandle, which can then be read to retrieve the given message.Along with the get() and list(), a couple other methods stand out as being useful for working with POP3 e-mail: uidl() and top(), which get message IDs and headers, respec- tively. You might also find popstat() useful if you want to know the size of the mailbox.
Uidl
Many POP3 mail clients use the uidl() method to obtain a unique identifier for a given mes- sage. In this way, the program can keep track of which messages have been downloaded, so that they aren’t downloaded multiple times by the same program. This would apply only when
C H A P T E R 6■ N E T: : TO O L S
114
the POP3 client program doesn’t delete the messages after downloading them, since the values obtained from uidl() are message-dependent. Therefore, you wouldn’t use uidl() values if your program deletes the e-mail from the server after downloading it.
In order to take advantage of the values returned from uidl(), the program must keep track of which IDs have been seen, usually across multiple executions of the program. For a Perl program, this would likely mean storing the IDs in an external file, but the IDs could be stored in any valid location that can be accessed from a Perl program, such as a relational database or a DBM hash file.
Like the list() method, uidl() returns the ID for a given message when called with an argument of the message number, and it returns a reference to a hash with the message num- ber as the key and the ID as the value when called with no argument.
Consider the example in Listing 6-4 (Pop3example4.pl), which looks nearly the same as the example for the list() method. This example uses uidl(), and then prints each ID. Listing 6-4. Printing Message IDs
#!/usr/bin/perl -w use Net::POP3; use strict;
my $username = "user\@example.com"; my $password = "password";
my $pop3conn = Net::POP3->new("mail.example.com", timeout => 30); if ($pop3conn->login($username,$password) > 0) {
my $messages = $pop3conn->uidl(); foreach my $msg (keys %{$messages}) {
print "Message $msg is ID: $messages->{$msg}\n"; }
}
$pop3conn->quit;
From here, you could store these IDs for later use or use them within the program, if the program were a long-running process. Here’s typical output from this program:
Message 6 is ID: 5cb794e9ba2c45b2 Message 11 is ID: ac9375c45b8aca77 Message 3 is ID: 822ac7377f459093 Message 7 is ID: 3dadb5032fca6952 Message 9 is ID: e10e0bfe628f74ff Message 12 is ID: 1420b979566679a6 Message 2 is ID: 770a0ebe8ae76b68 Message 8 is ID: b77fbf3630ea720e Message 1 is ID: d0065fbe85999bc3 Message 4 is ID: 2e3331c08c34e0a0 Message 10 is ID: 8d63341d100e1007 Message 5 is ID: b5fc539c28da4afb
C H A P T E R 6■ N E T: : TO O L S 115
Top
The top() method retrieves the header of the message along with, optionally, a number of lines from the body of the message as well. This method is useful to look at the Subject line or From line of an e-mail message for something like spam filtering or just general filtering. Recall the code example given to print each message to STDOUT. Using that code as a base, the example in Listing 6-5 (Pop3example5.pl) uses top() to retrieve the header of the message, and then per- forms a simple grep to look for the Subject line of each message, outputting that to STDOUT. Listing 6-5. Printing Subject Lines
#!/usr/bin/perl -w use Net::POP3; use strict;
my $username = "user\@example.com"; my $password = "password";
my $pop3conn = Net::POP3->new("mail.example.com", timeout => 30); my $nummsgs = $pop3conn->login($username,$password);
for (my $i=1;$i<=$nummsgs;$i++) { my $message = $pop3conn->top($i); print "Message $i: ";
print grep (/^Subject:/, @{$message}); }
$pop3conn->quit;
The output looks something like this: Message 1: Subject: RE: Security consulting Message 2: Subject: Re: Security consulting Message 3: Subject: RE: Security consulting Message 4: Subject: Meeting
Message 5: Subject: RE: Account costs Message 6: Subject: Re: Introduction Message 7: Subject: Re: Web design work Message 8: Subject: Hello
Message 9: Subject: Partners Pub Website Update Message 10: Subject: Perl help!
Message 11: Subject: Re: Perl consulting Message 12: Subject: Files for site
Popstat
The popstat() method gives the number of messages along with the size of the mailbox. These are returned in list context so could be stored in an array or into individual scalars, as in this example:
C H A P T E R 6■ N E T: : TO O L S
116
($messages,$size) = $pop3conn->popstat();
print "There are $messages messages totaling $size bytes\n";