obj.write 'Уж вечер небо навзничью распяло
'
obj.write 'Как пациента под ножом наркоз...
'
end
Отметим, что пары символов «возврат каретки», «перевод строки» обязательны (если вы хотите разбить сообщение на строчки). Читатели, знакомые с деталями протокола, обратят внимание на то, что сообщение «завершается» (добавляется точка и слово «QUIT») без нашего участия.
Можно вместо метода write
воспользоваться оператором конкатенации:
smtp.ready('[email protected]', '[email protected]') do |obj|
obj << 'В гостиной разговаривают тети
'
obj << 'О Микеланджело Буонаротти.
'
end
И еще одно небольшое усовершенствование: мы добавим метод puts
, который вставит в сообщение символы перехода на новую строку:
class Net::NetPrivate::WriteAdapter
def puts(args)
args << '
'
self.write(*args)
end
end
Новый метод позволяет формировать сообщение и так:
smtp.ready('[email protected]', '[email protected]') do |obj|
obj.puts 'Мы были призваны в глухую глубину,'
obj.puts 'В мир дев морских, в волшебную страну,'
obj.puts 'Но нас окликнули - и мы пошли ко дну.'
end
Если всего изложенного вам не хватает, поэкспериментируйте самостоятельно. А если соберетесь написать новый интерфейс к протоколу SMTP, не стесняйтесь.
18.2.5. Взаимодействие с IMAP-сервером
Протокол IMAP нельзя назвать вершиной совершенства, но во многих отношениях он превосходит POP3. Сообщения могут храниться на сервере сколь угодно долго (с индивидуальными пометками «прочитано» и «не прочитано»). Для хранения сообщений можно организовать иерархию папок. Этих возможностей уже достаточно для того, чтобы считать протокол IMAP более развитым, чем POP3.
Для взаимодействия с IMAP-сервером предназначена стандартная библиотека net/imap
. Естественно, вы должны сначала установить соединение с сервером, а затем идентифицировать себя с помощью имени и пароля:
require 'net/imap'
host = 'imap.hogwarts.edu'
user, pass = 'lupin', 'riddikulus'
imap = Net::IMAP.new(host)
begin
imap.login(user, pass)
# Или иначе:
# imap.authenticate('LOGIN', user, pass)
rescue Net::IMAP::NoResponseError
abort 'He удалось аутентифицировать пользователя #{user}'
end
# Продолжаем работу...
imap.logout # Разорвать соединение.
Установив соединение, можно проверить почтовый ящик методом examine; по умолчанию почтовый ящик в IMAP называется INBOX. Метод responses возвращает информацию из почтового ящика в виде хэша массивов (наиболее интересные данные находятся в последнем элементе массива). Показанный ниже код показывает общее число сообщений в почтовом ящике ('EXISTS'
) и число непрочитанных сообщений ('RESENT'
):
imap.examine('INBOX')
total = imap.responses['EXISTS'].last # Всего сообщений.
recent = imap.responses['RECENT'].last # Непрочитанных сообщений.
imap.close # Закрыть почтовый ящик.
Отметим, что метод examine
позволяет только читать содержимое почтового ящика. Если нужно удалить сообщения или произвести какие-то другие изменения, пользуйтесь методом select
.
Почтовые ящики в протоколе IMAP организованы иерархически, как имена путей в UNIX. Для манипулирования почтовыми ящиками предусмотрены методы create
, delete
и rename
:
imap.create('lists')
imap.create('lists/ruby')
imap.create('lists/rails')
imap.create('lists/foobar')
# Уничтожить последний созданный ящик:
imap.delete('lists/foobar')
Имеются также методы list
(получить список всех почтовых ящиков) и lsub
(получить список «активных» ящиков, на которые вы «подписались»). Метод status
возвращает информацию о состоянии ящика.
Метод search
находит сообщения, удовлетворяющие заданному критерию, а метод fetch
возвращает запрошенное сообщение:
msgs = imap.search('ТО','lupin')
msgs.each do |mid|
env = imap.fetch(mid, 'ENVELOPE')[0].attr['ENVELOPE']
puts 'От #{env.from[0].name} #{env.subject}'
end
Команда fetch
в предыдущем примере выглядит так сложно, потому что возвращает массив хэшей. Сам конверт тоже представляет собой сложную структуру; некоторые методы доступа к нему возвращают составные объекты, другие — просто строки.
В протоколе IMAP есть понятия UID (уникального идентификатора) и порядкового номера сообщения. Обычно методы типа fetch
обращаются к сообщениям по номерам, но есть и варианты (например, uid_fetch
) для обращения по UID. У нас нет места объяснять, почему нужны обе системы идентификации, но если вы собираетесь серьезно работать с IMAP, то должны понимать различие между ними (и никогда не путать одну с другой).
Библиотека net/imap
располагает разнообразными средствами для работы с почтовыми ящиками, сообщениями, вложениями и т.д. Дополнительную информацию поищите в онлайновой документации на сайте ruby-doc.org.