Чтение почты через Web-интерфейс

Автор: Александр Сухилин Сайт: http://shurick31.narod.ru/
   
   В последнее время довольно популярными стали почтовые системы с Web-интерфейсом. Надо заметить, это довольно удобно, особенно для пользователей, которые выходят в интернет с разных компьютеров.
   
   Для написания такой программы необходима библиотека Mail::POP3Client
   
   Назначение библиотеки очевидно - видно из названия. В ней содержатся методы доступа к почтовому ящику POP3.Простейший набор кода для проверки почтового ящика на наличие сообщений выглядит так:
   
   use Mail::POP3Client;
   $login = "mailuser";
   $password = "parol";
   $mailserver = "mail.server";
   $pop = new Mail::POP3Client( USER => $login,
   PASSWORD => $password,
   HOST => $mailserver );
   print "В вашем почтовом ящике ",$pop->Count()," сообщений.<br>\n";
   
   Все вообщем, просто:
   
   Создать соединение;
   Посчитать количество писем.
   Первый пункт реализуем созданием объекта $pop, второй - вызовом метода Count() этого объекта. Метод Count() еще имеет одну особенность - если он возвращает -1, то соединение не было создано, иными словами, не удалось соединиться с сервером. Если мы в вышеуказанном коде последнюю строчку заменим на
   
   if ($pop->Count() == -1 ) {
   print "Не удалось соединиться с сервером!<br>\n";
   } else {
   print "В вашем почтовом ящике ",$pop->Count()," сообщений.<br>\n";
   }
   
   , то выглядеть наш скрипт будет несколько приличнее (как-никак, обработка нештатной ситуации :). Если этот код заработал, то нужно развивать успех. Итак, методы класса POP3Client:
   
   new( USER => 'user', PASSWORD => 'password', HOST => 'host', PORT => 110, DEBUG => 0, AUTH_MODE => 'BEST', TIMEOUT => 60 )
   Это конструктор класса. Разработчики библиотеки настоятельно рекомендуют пользоваться объекным стилем написания.Аргументы метода следующие:
   
   USER = имя пользователя
   PASSWORD = пароль
   HOST = почтов?й сервер
   PORT = порт
   DEBUG = если этот параметр равен 1, то в STDERR выводится трафик сокета
   AUTH_MODE = допустимые значения:'BEST', 'PASS' and 'APOP'
   TIMEOUT = число по умолчанию - 60 сек.
   Head( MESSAGE_NUMBER )
   Возвращает заголовок письма с номером MESSAGE_NUMBER. Результат = строка или массив, в зависимости от контекста. Поддерживается не всеми POP3 серверами.
   
   Body( MESSAGE_NUMBER )
   Возвращает тело письма с номером MESSAGE_NUMBER. Результат = массив строк или массив, в зависимости от контекста.
   
   Delete( MESSAGE_NUMBER )
   Помечает сообщение на удаление. Удаляется после выполнения команды QUIT. До удаления можно отменить методом Reset.
   
   Close
   Закрыть соединение.
   
   Count
   Возвращает количество сообщений в почтовом ящике.Нет цели подменять этой статьей описание библиотеки, поэтому ограничимся только этими описаниями. В библиотеке Mail::POP3Client методов примерно в 2 раза больше, и прочитать его описание в первоисточнике несколько полезней, тем более, что для начала работы достаточно и вышеперечисленных методов.
   
   Теперь было бы неплохо просмотреть список сообщений на сервере, от кого, тема. Для этого сосчитаем сообщения и в цикле выведем их заголовки:
   
   ....
   print "В вашем почтовом ящике ",$pop->Count(),"сообщений<br>\n";
   for( $i = 1; $i <= $pop->Count(); $i++ ) {
   foreach( $pop->Head( $i ) ) {
   /^(From|Subject):\s+/i && print $_, "<br>\n";
   }
   }
   #закрыть соединение
   $pop-Close();
   
   Если заработала и сия конструкция, значит все делается правильно, и можно переходить к написанию модуля просмотра сообщений. Просмотреть сообщение №КАКОЙ_ТО можно, вытащив его методом Body(№). Поскольку метод нам вернет массив, то обыкновенным циклом foreach просмотрим письмо.
   
   Вот текст процедуры просмотра тела письма:
   
   sub get_body {
   $numb_mess = shift;
   foreach ($pop->Body($numb_mess)) {
   print $_,"<br>\n";
   }
   }
   
   Ну, а дальше - дело вкуса, как выбирать сообщение. Я предлагаю сделать ссылочку на тему письма для просмотра оного. Полный листинг сего "шедевра" расположен ниже:
   
   use Mail::POP3Client;
   print "Content-type:text/html\n\n";
   $login = "mailuser";
   $password = "parol";
   $mailserver = "mail.server";
   # Пробуем прочесть переданные параметры
   # Этот способ работает только с методом GET!!!
   $temp=$ENV{'QUERY_STRING'};
   # Разбор строки параметров
   if ($temp ne '') {
   @pairs=split(/&/,$temp);
   foreach $item(@pairs) {
   ($key,$content)=split (/=/,$item,2);
   # Режем на название ключа и значение.
    # Названия параметров и значения помещаем в хэш
   $data{$key}=$content;
   }
   }
   # Открываем соединение
   $pop = new Mail::POP3Client( USER => $login,
   PASSWORD => $password,
   HOST => $mailserver );
   # Если был передан параметр view со значением, то просматриваем
   # сообщение с номером view
   if ($data{'view'} ne '') {
   &get_body($data{'view'});
   } else { # Не было параметров
   print "В вашем почтовом ящике ",$pop->Count()," сообщений.<br>\n";
   for( $i = 1; $i <= $pop->Count(); $i++ ) {
   foreach( $pop->Head( $i ) ) {
   /^(From|Subject):\s+/i && print
    "<a href="$SCRIPT_NAME?view=$i">",$_, "</a><br>\n";
   }
   }
   #закрыть соединение
   }
   $pop-Close();
   #Процедура просмотра сообщения
   sub get_body {
   $numb_mess = shift;
   foreach ($pop->Body($numb_mess)) {
   print $_,"<br>\n";
   }
   
   }
   
   
   Вот собственно и все. На самом деле я не советую выкладывать сей перл в интернет. Его можно юзать на localhost-е. Почему? Потому что в теле программы находятся значения логинов/паролей, а этого допускать не стоит. Лучше сделать форму с парой полей, и передавать их методом POST этому скрипту. Прочесть строку параметров при передаче методом POST можно кострукцией:
   
    if ($ENV{'REQUEST_METHOD'} eq 'POST') {
   read(STDIN,$temp,$ENV{'CONTENT_LENGTH'});
   }
   
   т.е. читать нужно из стандартного потока ввода. Разбор строки точно такой же, как и в методе GET. Для дальнейшей работы с почтовым ящиком пару логин/пароль можно сохранить в скрытом поле или в cookie с периодом устаревания ,например, пол-часа. Далее, первым делом после печати строки Content-type:text/html\n\n, прочтем этот куки:
   
    $cookie = $ENV{'HTTP_COOKIE'};
   дальше его разбираем, как нам угодно. Я предлагаю следующую реализацию:
   if ($data{'login'} and $data{'password'}) {
   
    # Запомним пароль/логин в куки в виде строки:
   # login::password, время устаревания = 1 час.
   print "Set-Cookie: login=$form{'login'}::$form{'password'};
    expires=+1H;";
   print "Content-type:text/html\n\n";
    # попытка создать соединение с POP3 сервером
   $pop = new Mail::POP3Client( USER => $data{'login'},
   PASSWORD => $data{'password'},
   HOST => $mailserver );
   } else {
   print "Content-type:text/html\n\n";
   $cookie = $ENV{'HTTP_COOKIE'};
    # Разбираем строку, полученную из cookie
   if ($cookie =~ "login") {
   ($nm,$vals) = split(/=/,$cookie);
   ($login,$passwd) = split(/::/,$vals);
   $pop = new Mail::POP3Client( USER => $login,
   PASSWORD => $password,
   HOST => $mailserver );
    # Далее по тексту....
   }
   
   Вот в принципе и все - небольшой простенький mailreader готов. Но есть один существенный недостаток: "Кириллические" тексты зачастую в письме хранятся в виде mime encoded. Поэтому чтобы их прочесть, нужно использовать соответствующие библиотеки или писать свои конвертеры, но это уже другая тема...
   
   

Опубликовано: HTTP://WWW.R-T-F-M.INFO, pauk ©® 2000-2011.
All rights reserved.
При перепечатки ссылка на сайт обязательна.
Мнение администрации сайта не всегда совпадает с мнением автора..