Stanza IM: 25 дней спустя

То, что еще месяц назад казалось дикой идеей — было реализовано. На волне увлечения OpenCode — сделал свой jabber-клиент.

Да, базовые вещи были сделаны намного раньше, но у меня не было времени на заметки в блог для «неделю спустя», потом пилил более-менее крупные фичи и снова не было времени на блог, а сейчас ждать еще 3 дня для отсылки к одноименному фильму — нет желания 🙂

Так или иначе, теперь есть Stanza IM. Целиком и полностью написан в OpenCode под моим чутким руководством. Название — легкая модификация одного из вариантов, предложенного гуглоИИ. Кстати, как оказалось, «станза» — вполне популярное слово и не в контексте jabber’а. А еще существует полурабочий сайт-визитка https://stanza.im какого-то француза (и там даже есть какой-то старенький Prosody) — ну да пофиг.

Клиент — микс идей из Jabbim, Psi и Gajim.

Jabbim — был когда-то такой клиент от чешских разработчиков (которые jabber.cz и у которых еще Jabber Disk с галереей на Ruby). Python2 + Qt4. Хоть и пробовал его более 15 лет назад — остались положительные воспоминания о его внешнем виде (в целом, софт на Qt обычно неплохо выглядит);  как минимум, были такие на тот момент. Захотелось использовать отдельные наработки по интерфейсу. Опять же, Python — т.е., клиент не надо компилировать, можно сразу запускать и видеть изменения в процессе разработки. В свою очередь, мы уже имеем связку Python + GTK в виде Gajim, пусть будет разнообразие.

Psi очень хорош в плане внешнего вида, разнообразных фич и удобства интерфейса. Но не хватает современных фич — звонки, MAM, вот это вот все; а впрягаться в его разработку я пока не готов, так что Stanza IM в некотором роде может быть для меня и тестовым полигоном, чтобы понимать, что и как вообще работает в jabber-клиенте. Хотя в Psi в последние дни тоже начались определенные подвижки, радует.

Ну и Gajim… Современный вариант мне не нравится. Из положительных моментов — в нем есть некоторые современные фишки (MAM, OMEMO, реакции). В теории можно было бы взять старую версию (до переделки интерфейса) и пробовать пилить ее, но надо ли? Поэтому позаимствовал только отдельные идеи — на сейчас это то, как выглядят реакции (и кнопки в сообщениях), шапки и PEP-менеджер.

Так как я постоянно пользуюсь Psi и он очень привычен и удобен — многие диалоги в клиенте срисованы с него. Т.е., Станза в некотором роде — такой себе допиленный по фичам Psi на Python’е с нотками Gajim’а 🙂

По планам сначала было взять за основу исходники Jabbim и пытаться делать что-то вокруг них, но, во-первых, его даже запустить было проблематично на свежих дистрибутивах, а во-вторых, делать какие-то мелкие правки, чтобы хоть как-то заработало на старом стеке ИИ отговорил. В итоге с него взяли только иконки, а Jabbim я в итоге запустил на виртуалке с Debian 7, чтобы посмотреть еще раз на интерфейс.

Ну а дальше пошла активная работа над фичами. Одно из первых, что реализовал — поддержка MAM. Больная тема для меня на Psi, за которую давно уже висит приличная награда для желающих в топике конференции разработчиков.

В Станзе получилось все реализовать за несколько дней и примерно 15$ затрат на OpenCode. Часть работ (тогда и в дальнейшем) я старался делать на бесплатных моделях, но на сейчас, когда проект уже разросся — работаю в основном с платным DeepSeek 4.1. Затрат немного (по сравнению с выполняемой работой) — на сейчас потратил 89$, зато нет страданий из-за постоянно переполняющегося контекста. Да, 200к контекста на бесплатных моделях сейчас маловато, либо надо сильно дробить задачу. На 1M я могу «просто работать».

На сейчас я имею клиент с плюс-минус привычным стилем и диалогами с такими фичами:

  • MAM
  • Звонки
  • Групповые звонки (!)
  • Реакции
  • Ответы
  • Модерация сообщений
  • Нормально работающий Message Styling
    …и прочие полезные фишки, как, например:

    • предпросмотр медиафайлов
    • просмотр геолокации — и с live-режимом!
    • нормально работающие уведомления и синхронизация сообщений

По стилю — уже относительно недавно решил использовать еще одну фишку из Jabbim’а: вкладки в главном окне. На сейчас там ростер / закладки / события. Потенциально — заметки, работа с транспортами, форумы/блоги и так далее.

Из открытий для себя и просто интересных моментов, а также идей — было такое:

  • Muji. Оказывается, уже лет 17 есть стандарт, позволяющий реализовать групповые аудио и видеозвонки — то, для чего еще месяц назад я бы предложил воспользоваться Mumble или Jitsi Meet. Нет, Mumble хорош в своей нише и если нужна большая конференция — он вне конкуренции, так как в случае с Muji по факту имеем просто несколько параллельных звонков «1 на 1». Но Muji вполне решает задачу созвона 3-5-10 человек без лишнего софта. Про фичу я узнал в описании DinoX — похоже, кто-то за лето начал активно приводить в порядок известный клиент и реализовал там в том числе это. В общем, теперь Muji есть и у меня, и в Monocles mod для мобильных.
  • Спам-репорты и блокировки пользователей. Открыл для себя, что существует «XEP-0191: Blocking Command» и «XEP-0016: Privacy Lists«, при этом они технически могут решать одну проблему — забанить кого-то. И сделано правило совместимости, поэтому когда банишь кого-то через 191 — он показывается и в виде заблокированного в privacy-листах. С одной стороны privacy-листы вроде как устарели и не должны использоваться, с другой — предоставляют более гибкий механизм по блокировкам. Так что у меня реализованы оба механизма. А еще разобрался с репортами в «XEP-0377: Blocking Command Reports» — мне уже раньше приходили жалобы на спамеров с моего сервера вида
    SPAM/ABUSE REPORT -----------------Reported JID: crazycarderf@linuxoid.inA user on our service has reported a message originating from the above JID on your server.

    The reported message was sent at: 2024-10-07T15:40:21Z

    -- This message contains also machine-readable payloads, including XEP-0377, in case you want to automate handling of these reports. You can receive these reports to a different address by setting 'spam-report-addresses' in your server contact info configuration. For more information, see https://xmppbl.org/reports/

    Теперь я знаю, как это работает. В клиенте реализован XEP-0377 — по факту это тот же 191, но с дополнительным блоком. И выяснилось, что штатно сервер уведомления на такое не шлет. В ejabberd средств для уведомлений вообще нет, в Prosody надо ставить и включать mod_spam_reporting + mod_report_forward — именно они дают такое сообщение. Вот что рассказал про это гуглоИИ:

    Репорты на пользователей

    Чтобы успешно протестировать генерацию и получение спам-репортов, важно понимать одну техническую деталь: сам по себе ejabberd из коробки не превращает внутренний XEP-0377-запрос от клиента в уведомление для администратора.

    Когда ваш подконтрольный пользователь нажимает в клиенте «Заблокировать и пожаловать на спам», происходит следующее:

    * Клиент шлет на свой сервер ejabberd XML-станзу блокировки с элементом <report xmlns=»urn:xmpp:reporting:1″ reason=»spam»/>.
    * Модуль mod_blocking обрабатывает этот запрос: он успешно заносит спамера в черный список (блокирует трафик).
    * И всё. На этом встроенная логика mod_blocking заканчивается. ejabberd сам по себе не знает, куда дальше пересылать текстовое уведомление или XML-жалобу, если ему это явно не объяснить.

    То, что вы видели ранее от удаленных серверов — это результат работы специальных скриптов пересылки (Forwarding) на тех серверах (например, аналога модуля mod_report_forward из мира Prosody, который умеет автоматически брать репорт из XEP-0377, смотреть XEP-0157-контакты целевого сервера и слать туда жалобу).
    Чтобы ваша схема заработала и вы получили репорт, вам нужно настроить перехват этого события на вашем сервере ejabberd 26.7.

    [свернуть]

    Раз уж у меня есть тест-сервер на Prosody — протестировал там. И да — все работает.
  • Заметки на стороне сервера. В планах реализовать это, по факту имеем: ряд плюс-минус старых клиентов с кастомным namespace на базе старого стандарта, но более-менее совместимых между собой. Это Psi, Tkabber, Gtalk, Miranda (ее адрес и используется в namespace — вероятно, от нее все и пошло), Monocles mod. И есть современный стандарт «PEP native bookmarks», который по факту используется только для закладок на конференции и который можно было бы использовать для заметок, но… поддержки именно таких заметок нигде нет. Поэтому если и делать что-то новое — то скооперировавшись с другими разработчиками.
  • Из интересных идей и открытий — сегодня узнал, что в jabber’e таки можно задавать приоритеты у сообщений. Есть «XEP-0131: Stanza Headers and Internet Metadata«. А еще есть «XEP-0145: Annotations» — заметки о пользователе. Можно скомбинировать одно с другим (или вместо 0145 использовать популярный вариант с PEP) и хранить настройки приоритета сообщений для контакта на стороне сервера. А дальше в клиенте по-разному обрабатывать сообщения с разными приоритетами: например, не показывать OSD для низкоприоритетных, обрабатывать как обычно средний приоритет и, например, не скрывать уведомлений для сообщений от «важных» контактов.

Работа продолжается. На сейчас из крупных задач — вникнуть и реализовать OMEMO, потом все это активно допиливать и полировать. Буду обновлять пост по ходу дела.

Добавить комментарий