Программирование на языке Ruby - [209]

Шрифт
Интервал

содержит путь к файлу, в котором хранится идентификатор последнего прочитанного из конференции сообщения; эта «информация о состоянии» позволяет избежать дублирования или пропуска сообщений.

Константа >LOOP_FLAG определяет строку, которой помечаются сообщения, уже прошедшие через шлюз. Тем самым мы препятствуем возникновению бесконечной

рекурсии, а заодно негодованию возмущенных обитателей сети, получивших тысячи копий одного и того же сообщения.

Возникает вопрос: «А как вообще почта поступает в программу >mail2news?» Ведь она, похоже, читает из стандартного ввода. Автор рекомендует следующую настройку: сначала в файле >.forward программы >sendmail вся входящая почта перенаправляется на программу >procmail. Файл >.procmail конфигурируется так, чтобы извлекать сообщения, приходящие из списка рассылки, и по конвейеру направлять их программе >mail2news. Уточнить детали можно в документации, сопровождающей приложение RubyMirror (в архиве RAA). Если вы работаете не в UNIX, то придется изобрести собственную схему конфигурирования.

Ну а все остальное расскажет сам код, приведенный в листингах 18.6 и 18.7.

Листинг 18.6. Перенаправление почты в конференцию

># mail2news: Принимает почтовое сообщение и отправляет

># его в конференцию.


>require "nntp"

>include NNTP


>require "params"


># Прочитать сообщение, выделив из него заголовок и тело.

># Пропускаются только определенные заголовки.


>HEADERS = %w{From Subject References Message-ID

> Content-Type Content-Transfer-Encoding Date}


>allowed_headers = Regexp.new(%{^(#{HEADERS.join("|")}):})


># Прочитать заголовок. Допускаются только некоторые заголовки.

># Добавить строки Newsgroups и X-rubymirror.


>head = "Newsgroups: #{Params::NEWSGROUP}\n"

>subject = "unknown"

>while line = gets

> exit if line /^#{Params::LOOP_FLAG}/о # Такого не должно быть!

> break if line =~ /^s*$/

> next if line =~ /^\s/

> next unless line =~ allowed_headers


> # Вырезать префикс [ruby-talk:nnnn] из темы, прежде чем

> # отправлять в конференцию.

> if line =~ /^Subject:\s*(.*)/

>  subject = $1


>  # Следующий код вырезает специальный номер ruby-talk

>  # из начала сообщения в списке рассылки, перед тем

>  # как отправлять его новостному серверу.

>  line.sub!(/\[ruby-talk:(\d+)\]\s*/, '')

>  subject = "[#$1] #{line}"

>  head << "X-ruby-talk: #$1\n"

> end

> head << line

>end


>head << "#{Params::LOOP_FLAG}\n"


>body = ""

>while line = gets

> body << line

>end


>msg = head + "\n" + body

>msg.gsub!(/\r?\n/, "\r\n")


>nntp = NNTPIO.new(Params::NEWS_SERVER)

>raise "Failed to connect" unless nntp.connect

>nntp.post(msg)

Листинг 18.7. Перенаправление конференции в почту

>##

># Простой сценарий для зеркалирования трафика

># из конференции comp.lang.ruby в список рассылки ruby-talk.

>#

># Вызывается периодически (скажем, каждые 20 минут).

># Запрашивает у новостного сервера все сообщения с номером,

># большим номера последнего сообщения, полученного

># в прошлый раз. Если таковые есть, то читает сообщения,

># отправляет их в список рассылки и запоминает номер последнего.


>require 'nntp'

>require 'net/smtp'

>require 'params'


>include NNTP


>##

# ># Отправить сообщения в список рассылки. Сообщение должно

># быть отправлено участником списка, хотя в строке From:

># может стоять любой допустимый адрес.

>#


>def send_mail(head, body)

> smtp = Net::SMTP.new

> smtp.start(Params::SMTP_SERVER)

> smtp.ready(Params::MAIL_SENDER, Params::MAILING_LIST) do |a|

>  a.write head

>  a.write "#{Params::LOOP_FLAG}\r\n"

>  a.write "\r\n"

>  a.write body

> end

>end


>##

># Запоминаем идентификатор последнего прочитанного из конференции

># сообщения.


>begin

> last_news = File.open(Params::LAST_NEWS_FILE) {|f| f.read}.to_i

>rescue

> last_news = nil

>end


>##

># Соединяемся с новостным сервером и получаем номера сообщений

># из конференции comp.lang.ruby.

>#

>nntp = NNTPIО.new(Params::NEWS_SERVER)

>raise "Failed to connect" unless nntp.connect

>count, first, last = nntp.set_group(Params::NEWSGROUP)


>##

># Если номер последнего сообщения не был запомнен раньше,

># сделаем это сейчас.


>if not last_news

> last_news = last

>end


>##

># Перейти к последнему прочитанному ранее сообщению

># и попытаться получить следующие за ним. Это может привести

># к исключению, если сообщения с указанным номером

># не существует, но мы не обращаем на это внимания.

>begin

> nntp.set_stat(last_news)

>rescue

>end


>##

># Читаем все имеющиеся сообщения и отправляем каждое

># в список рассылки.

>new_last = last_news

>begin

> loop do

>  nntp.set_next

>  head = ""

>  body = ""

>  new_last, = nntp.get_head do |line|

>   head << line

>  end


>  # He посылать сообщения, которые программа mail2news

>  # уже отправляла в конференцию ранее (иначе зациклимся).

>  next if head =~ %r{^X-rubymirror:}


>  nntp.get_body do |line|

>   body << line

>  end


>  send_mail(head, body)

> end

>rescue

>end


>##

>#И записать в файл новую отметку.


>File.open(Params::LAST_NEWS_FILE, "w") do |f|

> f.puts new_last

>end unless new_last == last_news

18.2.8. Получение Web-страницы с известным URL

Пусть нам нужно получить HTML-документ из Web. Возможно, вы хотите проверить контрольную сумму и узнать, не изменился ли документ, чтобы послать автоматическое уведомление. А быть может, вы пишете собственный браузер — тогда это первый шаг на пути длиной в тысячу километров.


Рекомендуем почитать
Графика DirectX в Delphi

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Вторая жизнь старых компьютеров

Сейчас во многих школах, институтах и других учебных заведениях можно встретить компьютеры старого парка, уже отслужившие свое как морально, так и физически. На таких компьютерах можно изучать разве что Dos, что далеко от реалий сегодняшнего дня. К тому же у большинства, как правило, жесткий диск уже в нерабочем состоянии. Но и выбросить жалко, а новых никто не дает. Различные спонсоры, меценаты, бывает, подарят компьютер (один) и радуются, как дети. Спасибо, конечно, большое, но проблемы, как вы понимаете, этот компьютер в общем не решает, даже наоборот, усугубляет, работать на старых уже как-то не хочется, теперь просто есть с чем сравнивать.


DirectX 8. Начинаем работу с DirectX Graphics

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.