Что: b10a0aa678fd8759885c9af0d9abba7bafd88efb Когда: 2022-02-17 22:39:04+03:00 ------------------------------------------------------------------------ Темы: go mail redo zsh ------------------------------------------------------------------------ Сделал собственный newsfeeds aggregator http://www.feeder.stargrave.org/ http://www.feeder.stargrave.org/Usage.html Видимо не давал моей голове покоя sfeed (571ce0c3d2c17e5562ff41866ae4948c701cf54b) и я проснулся с мыслью о том что надобно или написать свой или понять что это отнюдь не тривиальная задача. В итоге получилось гораздо проще чем ожидал, причём работает существенно быстрее Newsboat при парсинге/индексации за счёт распараллеливания. Вовсю переиспользуются существующие инструменты. curl, как оказалось, прекрасно умеет самостоятельно отправлять If-Modified-Since и ETag заголовки, храня эту информацию в отдельном для ETag-а файле и mtime. Прекрасно поддерживает сжатый Content-Encoding, в том числе Zstandard. Хранить сообщения из feed-ов я решил в Maildir-ах и использовать MUA в качестве интерфейса для этого. Каждый feed это отдельная директория, по совместительству Maildir, в которой и состояние для скачивания curl-ом хранится. Использую github.com/mmcdole/gofeed библиотеку для парсинга всевозможных форматов. Поддерживает даже JSON, которого в Newsboat не было. Она просто выплёвывает простые структуры идентичные для любых форматов feed-ов, из которой я руками формирую почтовые MIME сообщения. Тело сообщений -- только HTML. Ибо даже я в своих feed-ах его использую для простоты. Названия файлов для писем: SHA512/2(title+date). Изначально вообще использовал дату обновления/публикация для имён, но, оказалось, очень много feed-ов вообще не несут никакой информации о датах. А ещё могут иметь одну и ту же дату для кучи разных записей. Честно выставляю mtime и для файлов и для Maildir директорий, чтобы MUA понимал когда последний раз были сообщения в feed-е. Всё попадает в new/, что в Mutt-е честно будет показываться с флагом "N". Всё что не прочтённое, но уже и не новое, будет old-ом ("O"). feed2mdir утилита умеет ограничивать кол-во обрабатываемых записей. Удалять старые записи тривиально можно сортировкой по mtime и отсеканию ненужного множества файлов (rm *(om[101,-1])). Распараллеливать скачивание можно либо через redo, либо через parallel: $ parallel "redo {}/feed.download" ::: feeds/* $ parallel "redo {}/feed.parse" ::: feeds/* С redo вышла засада: сама по себе команда redo выполняет цели без распараллеливания, последовательно, чтобы можно было написать: redo lib install clean. Так делает не только goredo. Но redo-ifchange делает проверку на "надо ли это вообще собирать", а так как явно зависимостей никаких нет, то он ничего выполнять и не будет. Я добавил в goredo "-f" флаг для redo-ifchange, но вообще думаю что redo тут наверное вообще излишен. Честно для tracking-а зависимостей он использует для решения надо ли запускать feed2mdir и для пересборки mutt.rc файла, если список feed-ов и их названий поменялся. Но то, что feed.download, feed.parse, feed.clean являются виртуальными целями, как будто присутствующими в директории -- мне эстетически нравится. Mutt запускается в режиме броузера почтовых ящиков. Для всего этого дела автоматически генерируется mutt.rc, в котором все feed-и прописаны в качестве почтовых ящиков с человеческими названиями. Сортировка по дате, быстрый переход к списку feed-ов/ящиков, компактные форматы index-ов, отображение авторов, категорий и ссылок новостей в виде X--заголовков сообщений. Можно запускать (что я и делаю) mu index для индексации этого всего и добавлены макросы в Mutt для быстрого вызова поиска и просмотра результатов. Так как в результатах поиска мешанина из элементов разных feed-ов, то названия feed-ов в этом индексе тоже отображаются. Я привык в Newsboat нажимать "A" для помечания всех элементов текущего feed-а прочтёнными -- легко было написать аналогичный макрос и для Mutt. В общем всё это получилось шустро работающим, сильно гибким из-за куда более мощных инструментов. Я думал что подвохов будет гораздо больше. Хотя по сути то самое главное это парсинг и раскладывание в БД: это делается на Go. redo скорее не нужен будет -- можно будет заменить только parallel. ------------------------------------------------------------------------ оставить комментарий: mailto:comment@blog.stargrave.org?subject=Re:%20%D0%A1%D0%B4%D0%B5%D0%BB%D0%B0%D0%BB%20%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9%20newsfeeds%20aggregator%20%28b10a0aa678fd8759885c9af0d9abba7bafd88efb%29 ------------------------------------------------------------------------ Сгенерирован: SGBlog 0.34.0