Как разобрать файл почтового ящика в Ruby?

У Ruby gem rmail есть методы для разбора файла почтового ящика на локальном диске. К сожалению, этот драгоценный камень сломался (в Ruby 2.0.0). Это может не быть исправлено, потому что люди переходят на гем mail.

Gem mail имеет метод Mail.read('filename.txt'), но он анализирует только первое сообщение в почтовом ящике.

Этот гем и встроенный Net::IMAP заполонили сеть руководствами по доступу к почтовым ящикам через imap.

Итак, есть ли способ разобрать старый добрый файл без imap? Как единственный рубист в моей группе, я предпочел бы не ставить себя в неловкое положение, прибегая к http://docs.python.org/2/library/mailbox.html.

Или, что еще хуже, PHP imap_open('/var/mail/www-data', ...) -- если бы только Net::IMAP.new принимал такие имена файлов.


person Camille Goudeseune    schedule 03.05.2013    source источник
comment
Буквальный файл почтового ящика? Разве не все перешли на Maildir до того, как дискотека угасла?   -  person tadman    schedule 03.05.2013
comment
Ага, именно так. ‹ударяет бедром, указывает указательным пальцем вверх›   -  person Camille Goudeseune    schedule 03.05.2013


Ответы (3)


Хорошей новостью является то, что формат Mbox действительно чертовски прост, хотя именно из-за этой простоты его в конечном итоге и заменили. . Анализ большого файла почтового ящика для извлечения одного сообщения не особенно эффективен.

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

Пример отправной точки:

def parse_message(message)
  Mail.new(message)

  do_other_stuff!
end

message = nil

while (line = STDIN.gets)
  if (line.match(/\AFrom /))
    parse_message(message) if (message)
    message = ''
  else
    message << line.sub(/^\>From/, 'From')
  end
end

Суть в том, что каждое сообщение начинается с "From ", где пробел после него является ключевым. Заголовки будут определены как From:, и любая строка, начинающаяся с ">From", будет рассматриваться как "From". Именно такие вещи делают этот метод кодирования действительно неадекватным, но если Maildir не подходит, это то, что вам нужно сделать.

person tadman    schedule 03.05.2013
comment
Быстрый просмотр рассматриваемых почтовых ящиков подтверждает, что /^From /, а не /From: / действительно разделяет сообщения. - person Camille Goudeseune; 03.05.2013

Вы можете использовать tmail для для анализа почтовых ящиков, но он был заменен на mail, но я не могу найти класс, который его заменяет. Так что, возможно, вы захотите продолжить работу с tmail.

РЕДАКТИРОВАТЬ: как указал @tadman, он не должен работать с ruby ​​​​1.9. Однако вы можете портировать этот класс (и поместить его на github для использования всеми остальными :-))

person fotanus    schedule 03.05.2013
comment
По моему опыту, tmail действительно не работает в 1.9.x. Он устарел в пользу mail. - person tadman; 03.05.2013

Формат mbox максимально прост. Это просто объединение всех сообщений, разделенных пустой строкой. Первая строка каждого сообщения начинается с пяти символов «От кого»; когда сообщения добавляются в файл, любая строка, начинающаяся с «От», имеет префикс >, поэтому вы можете надежно использовать тот факт, что строка начинается с «От», как индикатор того, что это начало сообщения.

Конечно, поскольку это старый формат и он никогда не был стандартизирован, существует множество вариантов. Один вариант использует заголовок Content-Length для определения длины сообщения, и в некоторых реализациях этого варианта не удается вставить «>». Однако я думаю, что это редкость на практике.

Большая проблема с форматом mbox заключается в том, что почтовые агенты должны изменять файл на месте; следовательно, каждая реализация имеет некоторую процедуру блокировки. Конечно, там нет никакой стандартизации, поэтому вам нужно следить за другими процессами, модифицирующими почтовый ящик, пока вы его читаете. На практике многие почтовые системы решили эту проблему, используя вместо этого формат maildir, в котором почтовый ящик фактически является каталогом, а каждое сообщение представляет собой отдельный файл.

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

person rici    schedule 03.05.2013