Вопрос или проблема
У меня довольно большое количество электронных писем на моем почтовом сервере (IMAP), которые содержат вложения (PDF и т. д.). Эти вложения занимают место — место на моем жестком диске на сервере ограничено моей хостинг-компанией — и я пытаюсь вернуть часть этого места, удаляя вложения из писем. (Эти вложения избыточны на почтовом сервере, так как почти все они были загружены или скачаны локально.)
Когда я использовал Windows (давно это было), существовало приложение под названием “IMAPSize”, которое представляло собой почтовый клиент, который можно было использовать для входа на почтовый сервер и манипулирования сообщениями, удаления вложений и т. д. Но я пока не нашел ничего похожего по удобству и выполнению задачи для Unix/Linux (хотя у нас могут быть гораздо лучшие и более надежные решения — я просто не знаю, какие именно).
Я знаком с munpack (установил и использовал его локально) и ripmime, но, по моему мнению, эти программы предназначены для обработки сообщений, когда они хранятся локально, в формате Mbox или MailDir. Я не синхронизирую свои электронные сообщения локально, предпочитая оставлять их на нашем сервере (у меня так много писем, более 100 тысяч в совокупности).
Кроме того, Munpack, кажется, отлично справляется с извлечением вложений, но я не видел способа просто удалить вложения, не уничтожая само сообщение.
У меня есть Horde, Roundcube и SquirrelMail, доступные в виде веб- GUI, но, снова, я не видел способа удалить только вложения.
Кроме того, я ищу решение, которое не требует сложной настройки и конфигурации и т. д. (Возможно, я мечтаю/прошу слишком многого).
Я подумал попробовать следующий подход: использовать offlineimap для загрузки и синхронизации всех моих электронных писем локально, затем, возможно, использовать munpack или ripmime для удаления вложений (если я смогу найти способ сделать это, а не просто извлечь их), а затем повторно синхронизироваться с сервером, и, надеюсь, письма будут на сервере без вложений, но а) не уверен, сработает ли этот подход и 2) опять же, я не хочу загружать десятки тысяч писем локально….
Я уверен, что для меня существует решение (возможно, какой-то тип клиентского GUI приложения, которое позволит мне манипулировать письмами на серверах/удалить вложения; или какой-то другой не слишком сложный подход).
Примечание: я не использую Thunderbird и не хочу его устанавливать или использовать; то же самое и для Wine. Я стараюсь поддерживать свой компьютер очень ‘минимальным’ с легкими приложениями, где это возможно.
Спасибо за указание в нужном направлении.
У меня есть следующий фрагмент perl, который удаляет все вложения из stdin и возвращает stdout, что может быть полезно:
#!/usr/bin/perl -w
use strict;
use Mail::Audit;
use Mail::Audit::Attach qw(Attach);
my $mail = Mail::Audit->new;
my $attachments = $mail->attachments;
foreach (@$attachments)
{
$_->remove;
}
$mail->print();
А затем простой цикл по файлам в вашем Maildir, из которых вы хотите удалить вложения, например:
for filename in <list>
do
./strip.pl < "$filename" > "$filename".lock && mv "$filename".lock "$filename"
rm "$filename".lock
done
Интересной модификацией может быть сначала извлечь вложения и сохранить их отдельно, прежде чем удалять их из писем:
foreach (@$attachments)
{
$_->save("/path/to/attachment/dir");
$_->remove;
}
Но сначала сделайте резервное копирование 😉
Я также пробовал IMAPSize, но его больше не поддерживают, он иногда вылетал и оставлял сообщения, которые, по-видимому, должен был удалить. Также есть приложение Unattach для пользователей GMail, но я не могу за него поручиться.
Чтобы решить проблему для себя, я сделал python-скрипт, который может быть полезен: IMAP Size Reducer
Он работает с одной указанной папкой за запуск. Пока вы знаете, как запускать python-скрипты в командной строке, как войти на сервер (URL, имя пользователя, пароль) и спецификацию IMAP папки (например, “INBOX.Sent”), он должен работать с любой IMAP папкой. (Ваш провайдер может помочь с этими деталями, если это необходимо.)
Вы можете задать “максимальный желаемый размер сообщения” (то есть “если сообщение больше этого размера, удалите вложения, пока оно не станет меньше этого размера”) и “допустимый размер части” (то есть “если отдельная часть сообщения меньше этого размера, не удаляйте ее, независимо от общего размера сообщения”).
Следующие MIME-типы считаются кандидатами на удаление частей:
Anything with Content-Disposition "attachment"
Content-Type image/*
Content-Type audio/*
Content-Type video/*
Content-Type music/*
Content-Type x-music/*
Content-Type application/*
Он не был тщательно протестирован на различных почтовых провайдерах, но у меня хорошо работал. Посмотрите на веб-стране для подробностей по использованию.
Вы можете использовать Thunderbird и дополнение AttachmentExtractor для этого. Просто добавьте свой почтовый аккаунт в Thunderbird и затем запустите AttachmentExtractor. Он может удалить содержимое вложений, сохраняя имя файла вложения в вашем письме.
Вот что у меня получилось, использовав ruby и gem для mail:
# gem install 'mail'
require 'mail'
require 'pathname'
Dir.glob("**/*", File::FNM_DOTMATCH).each do |path|
next unless Pathname.new(path).file?
next unless File.read(path).include?('Message-ID')
mail = Mail.read path
next if mail.attachments.count == 0
mail.without_attachments!
File.write(path, mail.to_s)
end
Удалить вложения на сервере довольно просто, это всего лишь (текстовые) файлы.
– Найдите письма, содержащие вложения (обычно более крупные):
find -P /home/*/mail/*/*/* -mindepth 1 -maxdepth 1 -name "*=*" -size +2M -mtime '+367'
Это работает на сервере WHM с почтовым каталогом на 100%, не тестировалось с mbox
- Цикл по файлам
if grep -e '------=_' ${file};
# содержащие строки …. тогда- разделите письма по общим критериям, например:
csplit --prefix=split4mail2clean. -z ${file} /commonstring/
- определите/найдите в разделенных файлах строки, вложения будут иметь некоторые характерные строки, удалите эти части
- соедините оставшиеся временные разделенные файлы (те, что без характерных вложений) в обратном порядке, чтобы восстановить оригинальное письмо
- повторно установите временные метки модификации
- сделайте другие вещи здесь, если необходимо
Чтобы добиться успеха, вам может понадобиться 3, 4 или больше возможных условий IF и удаляйте, если файл содержит эту строку … Запустите этот скрипт оболочки из временной папки, скорректируйте размеры и другие критерии поиска. Да, у меня есть работающий скрипт, протестированный на около 40000 электронных писем, и он не оставляет вложений в соответствии с заданными критериями поиска и удаления.
Ответ или решение
Удаление вложений из электронных писем на сервере IMAP может быть сложной задачей, особенно если вы хотите сохранить сами сообщения без изменения их структуры. В этом ответе мы рассмотрим, как эффективно удалить вложения с минимальными затратами времени и сил, используя доступные инструменты и сценарии, как на платформе Unix/Linux, так и на Python.
1. Использование локальных инструментов для работы с IMAP
Вам необходимо будет получить доступ к вашему почтовому серверу через IMAP и работать с содержимым сообщений. Один из вариантов – использовать инструмент offlineimap
для синхронизации ваших писем на локальную машину. Это позволит вам работать с файлами непосредственно из базы данных Maildir или Mbox.
2. Удаление вложений с помощью Perl-скрипта
Если вы имеете опыт работы с Perl, вы можете использовать следующий скрипт для удаления всех вложений из сообщений:
#!/usr/bin/perl -w
use strict;
use Mail::Audit;
use Mail::Audit::Attach qw(Attach);
my $mail = Mail::Audit->new;
my $attachments = $mail->attachments;
foreach (@$attachments) {
$_->remove;
}
$mail->print();
После этого можете использовать следующий код для обработки всех файлов в вашей Maildir:
for filename in <list>
do
./strip.pl < "$filename" > "$filename.lock" && mv "$filename.lock" "$filename"
rm "$filename.lock"
done
Этот ввод будет создавать временные файлы, где удаляются вложения. Обязательно создавайте резервные копии перед выполнением.
3. Использование Python для более гибкого подхода
Если вы предпочитаете Python, вы можете написать скрипт, который подключается к вашему IMAP-серверу и удаляет вложения, основываясь на определенных критериях. Пример простого скрипта на Python, который удаляет вложения:
import imaplib
import email
from email.header import decode_header
# Настройка подключения к IMAP
username = "ваш_email"
password = "ваш_пароль"
imap = imaplib.IMAP4_SSL("imap.yourserver.com")
imap.login(username, password)
# Выбор папки
imap.select("INBOX")
# Поиск всех писем
status, messages = imap.search(None, "ALL")
message_numbers = messages[0].split()
for num in message_numbers:
# Получение сообщения
res, msg = imap.fetch(num, "(RFC822)")
msg = email.message_from_bytes(msg[0][1])
if msg.is_multipart():
for part in msg.walk():
if part.get_content_disposition() == 'attachment':
# Удаление вложения (можно дополнительно сохранить)
# Код для удаления вложения здесь
pass
# Закрытие соединения
imap.logout()
Этот скрипт можно настроить для работы с конкретными вложениями на основе формата файла или размера.
4. Советы по работе с графическими интерфейсами
Если вы предпочитаете графические интерфейсы, важно отметить, что большинство существующих веб-клиентов, таких как Roundcube и SquirrelMail, не поддерживают удаление вложений напрямую. Однако вы можете попробовать:
- Thunderbird с плагином AttachmentExtractor: Несмотря на вашу просьбу не использовать Thunderbird, это один из немногих вариантов, который предоставляет интуитивно понятный интерфейс для работы с вложениями.
Заключение
Удаление вложений на сервере IMAP не является тривиальной задачей, но, следуя вышеописанным подходам, вы сможете эффективно справиться с этой задачей, не загружая сервер ненужной информацией. Важно заранее протестировать выбранный метод на небольшой выборке писем, чтобы избежать нежелательных потерь данных. Не забывайте делать резервные копии ваших данных перед выполнением любых манипуляций.