KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Хэл Фултон - Программирование на языке Ruby

Хэл Фултон - Программирование на языке Ruby

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Хэл Фултон, "Программирование на языке Ruby" бесплатно, без регистрации.
Перейти на страницу:

У объекта SMTP есть метод экземпляра sendmail, который обычно и занимается всеми деталями отправки сообщения. Он принимает три параметра:

• source — строка или массив (или любой объект, у которого есть итератор each, возвращающий на каждой итерации одну строку);

• sender — строка, записываемая в поле «from» сообщения;

• recipients — строка или массив строк, описывающие одного или нескольких получателей.

Вот пример отправки сообщения с помощью методов класса:

require 'net/smtp'


msg = <<EOF

Subject: Разное

... пришла пора

Подумать о делах:

О башмаках, о сургуче,

Капусте, королях.

И почему, как суп в котле,

Кипит вода в морях.

EOF


Net::SMTP.start("smtp-server.fake.com") do |smtp|

 smtp.sendmail msg, ' [email protected]', ' [email protected]'

end

Поскольку в начале строки находится слово Subject:, то получатель сообщения увидит тему Разное.

Имеется также метод экземпляра start, который ведет себя практически так же, как метод класса. Поскольку почтовый сервер определен в методе new, то задавать его еще и в методе start не нужно. Поэтому этот параметр пропускается, а остальные не отличаются от параметров, передаваемых методу класса. Следовательно, сообщение можно послать и с помощью объекта SMTP:

require 'net/smtp'


msg = <<EOF

Subject: Ясно и логично

"С другой стороны, - добавил Тарарам, -

если все так и было, то все именно так и было.

Если же все было бы так, то все не могло бы быть

не так. Но поскольку все было не совсем так, все

было совершенно не так. Ясно и логично!"

EOF


smtp = Net::SMTP.new("smtp-server.fake.com")

smtp.start

smtp.sendmail msg, ' [email protected]', ' [email protected]'

Если вы еще не запутались, добавим, что метод экземпляра может принимать ещё и блок:

require 'net/smtp'


msg = <<EOF

Subject: Моби Дик

Зовите меня Измаил.

EOF


addressees = [' [email protected]', ' [email protected]']

smtp = Net::SMTP.new("smtp-server.fake.com")

smtp.start do |obj|

 obj.sendmail msg, ' [email protected]', addressees

end

Как видно из примера, объект, переданный в блок (obj), не обязан называться так же, как объект, от имени которого вызывается метод (smtp). Кроме того, хочу подчеркнуть: несколько получателей можно представить в виде массива строк.

Существует еще метод экземпляра со странным названием ready. Он похож на sendmail, но есть и важные различия. Задаются только отправитель и получатели, тело же сообщения конструируется с помощью объекта adapter класса Net::NetPrivate::WriteAdapter, у которого есть методы write и append. Адаптер передается в блок, где может использоваться произвольным образом[17]:

require "net/smtp"


smtp = Net::SMTP.new("smtp-server.fake1.com")


smtp.start


smtp.ready(" [email protected]", " [email protected]") do |obj|

 obj.write "Пошли вдвоем, пожалуй.rn"

 obj.write "Уж вечер небо навзничью распялоrn"

 obj.write "Как пациента под ножом наркоз... rn"

end

Отметим, что пары символов «возврат каретки», «перевод строки» обязательны (если вы хотите разбить сообщение на строчки). Читатели, знакомые с деталями протокола, обратят внимание на то, что сообщение «завершается» (добавляется точка и слово «QUIT») без нашего участия.

Можно вместо метода write воспользоваться оператором конкатенации:

smtp.ready(" [email protected]", " [email protected]") do |obj|

 obj << "В гостиной разговаривают тетиrn"

 obj << "О Микеланджело Буонаротти.rn"

end

И еще одно небольшое усовершенствование: мы добавим метод puts, который вставит в сообщение символы перехода на новую строку:

class Net::NetPrivate::WriteAdapter

 def puts(args)

  args << "rn"

  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.

18.2.6. Кодирование и декодирование вложений

Для вложения в почтовое сообщение или в сообщение, отправляемое в конференцию, файл обычно кодируется. Как правило, применяется кодировка base64, для работы с которой служит метод pack с аргументом m:

bin = File.read("new.gif")

str = [bin].pack("m")     # str закодирована.


orig = str.unpack("m")[0] # orig == bin

Старые почтовые клиенты работали с кодировкой uuencode/uudecode. В этом случае вложение просто добавляется в конец текста сообщения и ограничивается строками begin и end, причем в строке begin указываются также разрешения на доступ к файлу (которые можно и проигнорировать) и имя файла. Аргумент u метода pack позволяет представить строку в кодировке uuencode. Пример:

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*