Программирование на языке Ruby - [209]
содержит путь к файлу, в котором хранится идентификатор последнего прочитанного из конференции сообщения; эта «информация о состоянии» позволяет избежать дублирования или пропуска сообщений.
Константа >LOOP_FLAG
определяет строку, которой помечаются сообщения, уже прошедшие через шлюз. Тем самым мы препятствуем возникновению бесконечной
рекурсии, а заодно негодованию возмущенных обитателей сети, получивших тысячи копий одного и того же сообщения.
Возникает вопрос: «А как вообще почта поступает в программу >mail2news
?» Ведь она, похоже, читает из стандартного ввода. Автор рекомендует следующую настройку: сначала в файле >.forward
программы >sendmail
вся входящая почта перенаправляется на программу >procmail
. Файл >.procmail
конфигурируется так, чтобы извлекать сообщения, приходящие из списка рассылки, и по конвейеру направлять их программе >mail2news
. Уточнить детали можно в документации, сопровождающей приложение RubyMirror (в архиве RAA). Если вы работаете не в UNIX, то придется изобрести собственную схему конфигурирования.
Ну а все остальное расскажет сам код, приведенный в листингах 18.6 и 18.7.
># 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)
>##
># Простой сценарий для зеркалирования трафика
># из конференции 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. Возможно, вы хотите проверить контрольную сумму и узнать, не изменился ли документ, чтобы послать автоматическое уведомление. А быть может, вы пишете собственный браузер — тогда это первый шаг на пути длиной в тысячу километров.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Сейчас во многих школах, институтах и других учебных заведениях можно встретить компьютеры старого парка, уже отслужившие свое как морально, так и физически. На таких компьютерах можно изучать разве что Dos, что далеко от реалий сегодняшнего дня. К тому же у большинства, как правило, жесткий диск уже в нерабочем состоянии. Но и выбросить жалко, а новых никто не дает. Различные спонсоры, меценаты, бывает, подарят компьютер (один) и радуются, как дети. Спасибо, конечно, большое, но проблемы, как вы понимаете, этот компьютер в общем не решает, даже наоборот, усугубляет, работать на старых уже как-то не хочется, теперь просто есть с чем сравнивать.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.