О проекте

Главная страницаПост
main screenchat screen

Lemmy это аналог таких сайтов как Reddit, Lobste.rs, Raddle, или Hacker News: вы подписываетесь на форумы, которые вас интересуют , размещаете ссылки и дискутируете, затем голосуете и комментируете их. Однако за кулисами всё совсем по-другому; любой может легко запустить сервер, и все эти серверы объединены (например электронная почта) и подключены к одной вселенной, именуемой Федиверс.

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

Основная цель - создать легко размещаемую, децентрализованную альтернативу Reddit и другим агрегаторам ссылок, вне их корпоративного контроля и вмешательства.

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

Примечание: API-интерфейсы WebSocket и HTTP в настоящее время нестабильны

Почему назвали Lemmy (рус.Лемми)??

Содержит

Возможности

  • Открытое программное обеспечение, Лицензия AGPL.
  • Возможность самостоятельного размещения, простота развёртывания.
  • Понятый и удобный интерфейс для мобильных устройств.
    • Для регистрации требуется минимум: имя пользователя и пароль!
    • Поддержка аватара пользователя.
    • Обновление цепочек комментариев в реальном времени.
    • Полный подсчёт голосов (+/-) как в старом reddit.
    • Темы, включая светлые, темные и солнечные..
    • Эмодзи с поддержкой автозаполнения. Напечатайте :
    • Упоминание пользователя тегом @, Упоминание сообщества тегом !.
    • Интегрированная загрузка изображений как в сообщениях, так и в комментариях.
    • Сообщение может состоять из заголовка и любой комбинации собственного текста, URL-адреса или чего-либо еще.
    • Уведомления, ответы на комментарии и когда вас отметили.
    • Уведомления могут быть отправлены на электронную почту.
    • i18n / поддержка интернационализации.
    • RSS / Atom ленты для Все, Подписок, Входящих, Пользователь, and Сообщества.
  • Поддержка кросс-постинга.
    • Поиск похожих постов при создании новых. Отлично подходит для вопросов / ответов сообществ.
  • Возможности модерации.
    • Журналы (Логи) Публичной Модерации.
    • Можно прикреплять посты в топ сообщества.
    • Оба и администраторы сайта и модераторы сообщества, могут назначать других модераторов.
    • Можно блокировать, удалять и восстанавливать сообщения и комментарии.
    • Можно банить и разблокировать пользователей в сообществе и на сайте.
    • Можно передавать сайт и сообщества другим.
  • Можно полностью стереть ваши данные, удалив все посты и комментарии.
  • NSFW (аббр. Небезопасный/неподходящий для работы) пост / поддерживается сообществом.
  • Высокая производительность.
    • Сервер написан на rust.
    • Фронтэнд (клиентская сторона пользовательского интерфейса) всего ~80kB архив gzipp.
    • Фронтэнд (клиентская сторона пользовательского интерфейса) не использует javascript (только-чтение).
    • Поддерживается архитектура arm64 / устройства Raspberry Pi.

Цели

  • Придумать имя / кодовое назание.
  • Иметь сообщества.
  • Должны иметь цепочки комментариев.
  • Должна быть федерируемой: ссылаться и следовать за сообществами из/на других инстансах.
  • Постоянно обновляться: иметь панель для новых комментариев справа и основную панель для полного просмотра с развёртыванием.
    • Использовать веб-сокеты для публикации / создавать собственный инстанс.

Вопросы

  • Как должно работать голосование? Должны ли мы вернуться к старому способу отображения подсчёта голосов вверх или вниз? Или просто счёт?
  • Определитесь с технологией, которая будет использоваться
    • Бэкэнд: Actix, Diesel.
    • Фронтэнд: inferno, typescript или bootstrap как сейчас.
  • Должен ли быть разрешены боты?
  • Должны быть комментарии / статистика голосований, или в духе чата, например как в flowchat?.
    • Двухпанельная модель - Правая панель для комментариев в реальном времени, левая часть для просмотра актуальной древовидной структуры.
    • Просмотр с мобильных устройств, разрешить переключаться между ними. По умолчанию?

Источники / Потенциальные библиотеки

Тренды / Лучшее / Лучший алгоритм Сортировки

Цели

  • В течение дня новые сообщения и комментарии должны быть вверху, чтобы за них можно было проголосовать.
  • Примерно через день или более того фактор времени должен исчезнуть.
  • Использовать логарифмическую шкалу, так как голоса имеют тенденцию к снежному кому, и поэтому первые 10 голосов так же важны, как и следующие сотни.

Реализации

Reddit

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

Hacker News

Хотя намного превосходит реализацию Reddit по снижению оценок с течением времени, Алгоритм ранжирования Hacker News всё же не использует логарифмическую шкалу для оценок.

Lemmy

Уравновешивает эффект снежного кома голосов с течением времени с помощью логарифмической шкалы. Сводит на нет неотъемлемое преимущество ранних комментариев, но при этом гарантирует, что голоса по-прежнему имеют значение в долгосрочной перспективе, не разрушая старые популярные комментарии.

Rank = ScaleFactor * log(Max(1, 3 + Score)) / (Time + 2)^Gravity

Score = Upvotes - Downvotes
Time = time since submission (in hours)
Gravity = Decay gravity, 1.8 is default
  • В Lemmy такой же алгоритм Классификатор как наверху, разделяя на два: Активный, и Лучший.
    • Активный использует голосование за публикацию и время последнего комментария (ограничено двумя днями).
    • Лучший использует голоса за публикацию и время опубликования.
  • Используйте Макс (1, балл), чтобы убедиться, что на все комментарии влияет замедление времени.
  • Прибавьте 3 балла, чтобы все, у кого меньше 3 голосов против, выглядили новыми. В противном случае все новые комментарии останутся нулевыми, внизу.
  • Знаки и абв оценки необходимы для работы с журналом отрицательных оценок.
  • Масштабный коэффициент 10k получает ранг в целочисленной форме.

График ранга за 24 часа, баллов 1, 5, 10, 100, 1000 с масштабным коэффициентом 10k.

Подсчёты Активных Пользователей

Lemmy также показывает количество * активных пользователей * для вашего сайта и его сообществ. Они подсчитываются в течение последнего дня, недели, месяца и полугодия и кэшируются при запуске lemmy и каждый час.

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

Путеводитель по Lemmy

Начните печатать...

  • @a_user_name для получения списка пользователей.
  • !a_community для получения списка сообществ.
  • :emoji для получения списка эмодзи.

Сортировка

Применяется как к сообщениям, так и к комментариям

ТипОписание
АктивностьСортировка на основе оценки подсчёта баллов со времени последнего комментария
ПопулярныеСортировка на основе оценки подсчёта баллов с даты создания поста.
НовыеНовинки.
Наиболее КомментируемыеПосты с наибольшим количеством комментариев.
Новые КомментарииПосты снаибольшим колличеством комментариев, Т.е. сортировка в стиле форума.
ЛучшиеС наивысшим количеством баллов заданный период времени.

Детали можно посмотреть по ссылке Посты и оценка комментариев в деталях.

Модерация / Администрирование

Все действия модераторов и администраторов над комментариями и постами пользователей осуществляются посредством нажатия на More 3-точечную иконку.

Сюда входят:

  • Добавление / Удаление модераторов и админов.
  • Удаление / Восстановление комментариев.
  • Банить / Разбанивать пользователей.

Все действия администратора в сообществах выполняются на боковой панели сообщества. На текущий момент возможно только Удаление / Восстановление сообществ.

Путеводитель по Markdown

НаберитеИли… Получите
*Курсив*_Курсив_Курсив
**Жирный**__Жирный__Жирный шрифт
# Заголовок 1Заголовок 1
=========

Заголовок 1

## Заголовок 2Заголовок 2
---------
Заголовок 2
[Ссылка](http://a.com)[Ссылка][1]

[1]: http://b.org
Ссылка
![Изображение](http://url/a.png)![Изображение][1]

[1]: http://url/b.jpg
Markdown
> Цитата
Цитата
* Списки
* Списки
* Списки
- Списки
- Списки
- Списки
* Списки
* Списки
* Списки
1. Один
2. Два
3. Три
1) Один
2) Два
3) Три
1. Один
2. Два
3. Три
Подчёркивания
---
Подчёркивания
***
Подчёркивания

`Инлайн код` с обратными кавычкамиИнлайн код с обратными кавычками
```
# блок кода
print '3 кавычки или'
отбить 'отступ 4 пробела'
```
····# блок кода
····отбить '3 кавычки или'
····отбить 'отступ 4 пробела'
# блок кода
print '3 кавычки или'
отбить 'отступ 4 пробела'
::: спрятать спойлер или материал nsfw
внести сюда
:::
спрятанный или nsfw материал

внести сюда

~подстрочный~ текстSome подстрочный текст
^надстрочный^ текстSome надстрочный текст

CommonMark Tutorial

Информация для администраторов

Информация для администраторов интсанса Lemmy и тех кто хочет запустить собственный сервер.

Установка

У Lemmy есть два основных метода установки: вручную с помощью Docker и автоматизированная с помощью Ansible. Мы рекомендуем использовать Ansible, потому что он упрощает установку, а также упрощает обновление.

Другие методы установки

В некоторых случаях может потребоваться использовать различные методы установки. Но мы этого не рекомендуем и не сможем оказать поддержку для них.

Установка Docker

Убедитесь в наличии установленных docker и docker-compose (>=1.24.0) . В Ubunu, просто запустите apt install docker-compose docker.io. Далее,

# создайте папку для файлов lemmy. путь не имеет значения, размещайте файлы где угодно
mkdir /lemmy
cd /lemmy

# загрузите кнфигурацию по умолчанию
wget https://raw.githubusercontent.com/LemmyNet/lemmy/main/docker/prod/docker-compose.yml
wget https://raw.githubusercontent.com/LemmyNet/lemmy/main/docker/lemmy.hjson
wget https://raw.githubusercontent.com/LemmyNet/lemmy/main/docker/iframely.config.local.js

# Установите корректные разрешения для каталога pictrs
mkdir -p volumes/pictrs
sudo chown -R 991:991 volumes/pictrs

Откройте docker-compose.yml, и убедитесь в наличии LEMMY_EXTERNAL_HOST для lemmy-ui это позволит установить корректный host.

- LEMMY_INTERNAL_HOST=lemmy:8536
- LEMMY_EXTERNAL_HOST=your-domain.com
- LEMMY_HTTPS=false

Если хотите установить другой пароль для БД, вы также должны изменить его в docker-compose.yml перед первым запуском.

После этого, загляните Кофигурационный файл под названием lemmy.hjson, и настройте его, в частности hostname, и возможно пароль БД. Затем запустите:

docker-compose up -d

Вы можете войти в lemmy-ui через http://localhost:1235

Для того чтобы сделать Lemmy доступным в сети, вам необходимо настроить reverse proxy, например Nginx. Пример конфигурации nginx, could be setup with:

wget https://raw.githubusercontent.com/LemmyNet/lemmy/main/ansible/templates/nginx.conf
# Replace the {{ vars }}
# The default lemmy_port is 8536
# The default lemmy_ui_port is 1235
sudo mv nginx.conf /etc/nginx/sites-enabled/lemmy.conf

Вам также необходимо настроить TLS, например с Let's Encrypt. После этого перезапустите Nginx для подгрузки конфигурации.

Обновление

Для обновления до новой версии, вы можете изменить версию вручнуюy в docker-compose.yml. Как альтернатива, получите последнюю версию из нашего репозитария git:

wget https://raw.githubusercontent.com/LemmyNet/lemmy/main/docker/prod/docker-compose.yml
docker-compose up -d

Установка Ansible

Это то же самое, что и установка Docker, за исключением того, что Ansible обрабатывает всё это автоматически. Он также выполняет некоторые дополнительные действия, такие как настройка TLS и электронной почты для вашего экземпляра Lemmy.

Прежде всего вам нужны установка Ansible на ваш локальный компьютер. Вам также необходимо будет установить Docker SDK для Python используя pip install docker (больше информации в документации Ansible).

Затем запустите следующую команду на вашем локальном компьютере:

git clone https://github.com/LemmyNet/lemmy.git
cd lemmy/ansible/
cp inventory.example inventory
nano inventory # enter your server, domain, contact email
# If the command below fails, you may need to comment out this line
# In the ansible.cfg file:
# interpreter_python=/usr/bin/python3
ansible-playbook lemmy.yml --become

Для обновления до новой версии, просто запустите следующее в локальном репозитарии Lemmy:

git pull origin main
cd ansible
ansible-playbook lemmy.yml --become

Другие методы установки

Отказ от ответственности: эти методы установки не рекомендуются разработчиками Lemmy. Если у вас возникнут проблемы, вам нужно решать их самостоятельно или спросить соответствующих авторов. Если вы заметили какие-либо ошибки Lemmy в установленном таким образом экземпляре, укажите это в отчете об ошибке.

Установка Lemmy без Docker

Изначальная инструкция по установке Lemmy, не полагаясь на Docker.

https://lemmy.ca/post/1066

Установка на Amazon Web Services (AWS)

Здесь содержатся необходимые определения инфраструктуры для развертывания Lemmy в AWS используя их Cloud Development Kit.

https://github.com/jetbridge/lemmy-cdk

Конфигурация

Конфигурация основана на файле config.hjson. Этот файл также содержит документацию по всем доступным параметрам. В инструкциях по установке рассказывается, как изменить настройки по умолчанию.

Файл config.hjson находится в config/config.hjson. Чтобы изменить расположение по умолчанию, вы можете установить переменную среды LEMMY_CONFIG_LOCATION.

Дополнительная переменная среды LEMMY_DATABASE_URL доступна, который можно использовать со строкой подключения PostgreSQL, например postgres://lemmy:password@lemmy_db:5432/lemmy, передача всех деталей подключения сразу.

Если контейнер Docker не используется, вручную создайте базу данных, указанную выше, выполнив следующие команды:

cd server
./db-init.sh

Federation

Lemmy использует протокол ActivityPub (стандарт W3C) для обеспечения федерации между различными серверами (часто называемыми инстансами). Это очень похоже на то, как работает электронная почта. Например, если вы используете gmail.com, то вы можете отправлять письма не только другим пользователям gmail.com, но и yahoo.com, yandex.ru и так далее. Для этого в электронной почте используется протокол SMTP, поэтому ActivityPub можно рассматривать как «SMTP для социальных сетей». Количество различных действий, возможных в социальных сетях (публикация, комментарий, лайк, публикация и т. Д.), Означает, что ActivityPub намного сложнее, чем SMTP.

Как и в случае с электронной почтой, федерация ActivityPub происходит только между серверами. Итак, если вы зарегистрированы на enterprise.lemmy.ml, вы подключаетесь только к API enterprise.lemmy.ml, в то время как сервер берет на себя отправку и прием данных от других экземпляров (например voyager.lemmy.ml). Большим преимуществом этого подхода является то, что обычному пользователю не нужно ничего делать, чтобы использовать федерацию. Фактически, если вы используете Lemmy, вы, вероятно, уже используете его. Один из способов подтвердить это - зайти в сообщество или в профиль пользователя. Если ты на enterprise.lemmy.ml и вы видите пользователя вроде @nutomic@voyager.lemmy.ml, или такое сообщество, как !main@ds9.lemmy.ml, тогда они федерированы, то есть они используют инстанс, отличный от вашего.

Один из способов воспользоваться преимуществами федерации - открыть другой инстанст, например ds9.lemmy.ml, и просмотреть его. Если вы видите интересное сообщество, сообщение или пользователя, с которым хотите взаимодействовать, просто скопируйте его URL и вставьте его в поиск своего собственного экземпляра. Ваш инстанс будет подключаться к другому (при условии, что это разрешено списком разрешений / блокировок) и напрямую отображать удаленный контент для вас, чтобы вы могли следить за сообществом или комментировать сообщение. Вот несколько примеров рабочих примеров:

  • !main@lemmy.ml (Сообщество)
  • @nutomic@lemmy.ml (Пользователь)
  • https://lemmy.ml/c/programming (Сообщество)
  • https://lemmy.ml/u/nutomic (Пользователь)
  • https://lemmy.ml/post/123 (Пост)
  • https://lemmy.ml/comment/321 (Комментарий)

Вы можете увидеть список связанных экземпляров, перейдя по ссылке «Инстансы» внизу любой страницы Lemmy.

Получение сообществ

При первом поиске сообщества сначала выбирается 20 сообщений. Только если хотя бы один пользователь на вашем экземпляре подписывается на удаленное сообщество, сообщество будет отправлять обновления на ваш экземпляр. Обновления включают:

  • Новые сообщения, комментарии
  • Голосования
  • Публикации, редактирования и удаление комментариев
  • Действия модераторов

Вы можете скопировать URL-адрес сообщества из адресной строки браузера и вставить его в поле поиска. Подождите несколько секунд, пост появится внизу. На данный момент нет индикатора загрузки для поиска, поэтому подождите несколько секунд, если он показывает «нет результатов».

Получение постов

Вставьте URL-адрес публикации в поле поиска вашего экземпляра Lemmy. Подождите несколько секунд, пока не появится сообщение. Это также приведёт к получению профиля сообщества и профиля создателя сообщения.

Получение сообщений

Если вы найдете интересный комментарий под сообщением на другом инстансе, вы можете найти под комментарием в трехточечном меню символ ссылки. Скопируйте эту ссылку. Это выглядит как https://lemmy.ml/post/56382/ comment/40796. Удалите часть post/XXX и поместите её в строку поиска. В этом примере выполните поиск по запросу https://lemmy.ml/comment/40796. Этот комментарий, все родительские комментарии, пользователи и сообщество, а также соответствующая публикация извлекаются из удаленного экземпляра, если они не известны локально.

Родственные комментарии не загружаются! Если вам нужно больше комментариев к более старым сообщениям, вам нужно найти каждый из них, как описано выше.

Решения проблем

Различные проблемы, которые могут возникнуть на новом инстансе и способы их решения.

Многие функции Lemmy зависят от правильной конфигурации reverse proxy. Убедитесь, что ваш, эквивалентен нашему конфигурационному файлу nginx.

Главное

Журналы

При возникновении проблем с интерфейсом проверьте браузерную консоль для любых сообщениях об ошибки.

Для журналов сервера запустите docker-compose logs -f lemmy в вашей инсталяционной папке. Вы также можете запустить docker-compose logs -f lemmy lemmy-ui pictrs для получения журнала от различных сервисов.

Если этого недостаточно, попробуйте изменить строку RUST_LOG=error в docker-compose.yml на RUST_LOG=info или RUST_LOG=verbose, затем сделайте docker-compose restart lemmy.

Создание пользователя с правами администратора не работает

Убедитесь, что websocket работает правильно, проверив консоль браузера на наличие ошибок. В nginx для этого важны следующие заголовки:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Ошибка ограничения скорости, когда на сайт заходят множество пользователей

Убедитесь, что заголовки X-Real-IP и X-Forwarded-For отправляются в Lemmy посредством reverse proxy. В противном случае он будет считать все действия в соответствии с ограничением скорости IP-адреса обратного прокси-сервера. В nginx это должно выглядеть так:

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Федерация

Другие инстансы не могут получать локальные объекты (сообщество, пост и т.д.)

Ваш reverse proxy (например nginx) должен пересылать запросы с заголовком Accept: application/activity+json в бэкэнд. Это обрабатывается следующими строками:

set $proxpass "http://0.0.0.0:{{ lemmy_ui_port }}";
if ($http_accept = "application/activity+json") {
set $proxpass "http://0.0.0.0:{{ lemmy_port }}";
}
if ($http_accept = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") {
set $proxpass "http://0.0.0.0:{{ lemmy_port }}";
}
proxy_pass $proxpass;

Вы можете проверить, что он работает правильно, выполнив следующие команды, все они должны возвращать действительный JSON:

curl -H "Accept: application/activity+json" https://your-instance.com/u/some-local-user
curl -H "Accept: application/activity+json" https://your-instance.com/c/some-local-community
curl -H "Accept: application/activity+json" https://your-instance.com/post/123 # the id of a local post
curl -H "Accept: application/activity+json" https://your-instance.com/comment/123 # the id of a local comment

Получение удаленных объектов работает, но публикации/комментирование в удаленных сообществах не успешны.

Проверьте это федерация разрешена в обоих случаях.

Также убедитесь, что на вашем сервере установлено точное время. Действия подписываются меткой времени и будут отброшены, если она отключена более чем на 10 секунд.

Резервное копирование и восстановление

Docker и Ansible

При использовании docker или ansible, должен быть создан каталог volumes , содержащий обе базы данных, и все изображения. Скопируйте этот каталог в новый инстанс для восстановления ваших данных.

Инкрементное резервное копирование базы данных

Для инкрементного резервного копирование БД в .sql файл, вы можете запустить:

docker-compose exec postgres pg_dumpall -c -U lemmy >  lemmy_dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql

Пример сценария резервного копирования

#!/bin/sh
# DB Backup
ssh MY_USER@MY_IP "docker-compose exec postgres pg_dumpall -c -U lemmy" >  ~/BACKUP_LOCATION/INSTANCE_NAME_dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql

# Volumes folder Backup
rsync -avP -zz --rsync-path="sudo rsync" MY_USER@MY_IP:/LEMMY_LOCATION/volumes ~/BACKUP_LOCATION/FOLDERNAME

Восстановление БД

Если вам необходимо восстановить из pg_dumpall файла, для начала необходимо очистить уже существующую БД

# Сбросьте существующую БД
docker exec -i FOLDERNAME_postgres_1 psql -U lemmy -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"

# Восстановите БД из резервного .sql 
cat db_dump.sql  |  docker exec -i FOLDERNAME_postgres_1 psql -U lemmy # restores the db

# Возможно при импортировании БД, вам понадобится установить новый пароль, отличающийся от предыдущего.
docker exec -i FOLDERNAME_postgres_1 psql -U lemmy -c "alter user lemmy with password 'bleh'"

Изменение вашего доменного имени

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

Зайдите в psql вашего docker :

docker-compose exec postgres psql -U lemmy

-- Post
update post set ap_id = replace (ap_id, 'old_domain', 'new_domain');
update post set url = replace (url, 'old_domain', 'new_domain');
update post set body = replace (body, 'old_domain', 'new_domain');
update post set thumbnail_url = replace (thumbnail_url, 'old_domain', 'new_domain');

-- Comments
update comment set ap_id = replace (ap_id, 'old_domain', 'new_domain');
update comment set content = replace (content, 'old_domain', 'new_domain');

-- User
update user_ set actor_id = replace (actor_id, 'old_domain', 'new_domain');
update user_ set inbox_url = replace (inbox_url, 'old_domain', 'new_domain');
update user_ set shared_inbox_url = replace (shared_inbox_url, 'old_domain', 'new_domain');
update user_ set avatar = replace (avatar, 'old_domain', 'new_domain');

-- Community
update community set actor_id = replace (actor_id, 'old_domain', 'new_domain');
update community set followers_url = replace (followers_url, 'old_domain', 'new_domain');
update community set inbox_url = replace (inbox_url, 'old_domain', 'new_domain');
update community set shared_inbox_url = replace (shared_inbox_url, 'old_domain', 'new_domain');

Больше информации

  • https://stackoverflow.com/questions/24718706/backup-restore-a-dockerized-postgresql-database

Федерация

Обзор Федерации

Этот документ предназначен для всех, кто хочет знать, как работает федерация Lemmy, не вдаваясь в технические подробности. Он предназначен для предоставления общего принципа работы федерации ActivityPub в Lemmy. Если вы сами реализуете ActivityPub и хотите быть совместимым с Lemmy, прочтите наши ActivityPub API outline.

Соглашения документации

Чтобы не усложнять, иногда вы можете увидеть вещи в формате Create/Note или Delete/Event или Undo/Follow. То, что перед косой чертой - это Activity, а то, что после косой черты - это объект внутри Activity в свойстве object. Итак, это следует читать следующим образом:

  • Create / Note: действие Create, содержащее Note в поле object.
  • Delete / Event: действие Delete, содержащее Event в поле object
  • Undo / Follow: действие Undo, содержащее Follow в поле object

В Lemmy мы используем определенные термины для обозначения элементов ActivityPub. По сути, это наши конкретные реализации хорошо известных концепций ActivityPub:

  • Сообщество: Group
  • Пользователь: Person
  • Пост: Page
  • Комментарий: Note

Этот документ состоит из трех основных разделов:

  • Философия федерации излагает общую модель того, как это должно быть федеративным
  • Действия пользователя описывает, какие действия может предпринять Пользователь для взаимодействия
  • Активность сообщества описывает, что Сообщество делает в ответ на определенные действия Пользователя.

Философия федерации

Основным действующим лицом в «Lemmy» является Сообщество. Каждое сообщество находится в единственном экземпляре и состоит из списка сообщений и списка подписчиков. Основное взаимодействие заключается в том, что Пользователь отправляет пост или комментарий, связанный с публикацией или комментарием в сообществе, который затем аннонсируется об этом всем подписчикам.

В каждом Сообществе есть определенный Пользователь-создатель, который отвечает за установку правил, назначение модераторов и удаление контента, нарушающего правила.

Помимо модерации на уровне сообщества, у каждого экземпляра есть набор пользователей-администраторов, которые имеют право выполнять удаление и блокировку на уровне всего сайта.

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

Пользователи могут не подписываться друг на друга, или не следовать за каким либо сообществом.

Наша реализация федерации уже завершена, но на данном этапе, мы не совсем сосредоточились на соблюдении спецификации ActivityPub. В связи с этим, Lemmy, пока, несовместима с реализациями, которые должны давать возможность отправлять и получать рабочую активность. Это то, что мы планируем исправить в ближайшем будущем. Проверить #698 обзор наших несоответствий.

Действия пользователя

Следовать за сообществом

На каждой странице сообщества есть кнопка «Подписаться». Нажатие на нее запускает действие Follow, которое будет отправлено пользователем в почтовый ящик сообщества. Сообщество автоматически ответит на почтовый ящик пользователя действием Accept/Follow. Он также добавит пользователя в свой список подписчиков и предоставит пользователю информацию о сообщениях и комментариях в Сообществе.

Отписаться от Сообщества

После подписки на сообщество кнопка «Подписаться» заменяется на «Отписаться». При нажатии на нее в почтовый ящик Сообщества отправляется действие Accept/Follow. Сообщество удаляет пользователя из списка подписчиков и больше не отправляет ему никаких действий.

Создать пост

Когда пользователь создает новое сообщение в определённом сообществе, оно отправляется как Create/Page в входящие Сообщества.

Создать комментарий

Когда новый комментарий создается для сообщения, идентификатор сообщения и родительский идентификатор комментария (если он существует) указывается в поле in_reply_to. Это позволяет привязать его к нужному посту и построить дерево комментариев. Затем он отправляется во входящие сообщения сообщества как Create/Note

Экземпляр-источник также сканирует комментарий на предмет упоминания любого пользователя и отправляет Create/Note этим Пользователям.

Редактировать Пост

Изменение содержания существующей публикации. Может быть выполнено только создавшим его пользователем.

Редактировать комментарий

Изменение содержания существующего комментария. Может быть выполнено только создавшим его пользователем.

Нравится и Не нравится

Пользователям могут нравится или не нравится любые сообщения или комментарии. Они отправляются Like/Page, Dislike/Note и т.д. в ящик Сообщества.

Удаление

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

Удаления

Модераторы могут удалять сообщения и комментарии из своих сообществ. Администраторы могут удалять любые сообщения или комментарии со всего сайта. Сообщества также могут быть удалены администраторами. Затем элемент скрывается от всех пользователей.

Об удалении сообщается всем подписчикам Сообщества, поэтому они вступают в силу и там. Исключение составляют случаи, когда администратор удаляет элемент из Сообщества, размещенного в другом экземпляре. В этом случае удаление вступает в силу только локально.

Отмена предыдущего действия

Мы ничего не удаляем из нашей базы данных, просто скрываем это от пользователей. Удаленные или удаленные Сообщества/Сообщения/Комментарии имеют кнопку «восстановить». Эта кнопка Undo генерирует восстановление оригинала удалённой активности как объекта, такого как Undo/Remove/Post или Undo/Delete/Community.

Нажатие кнопки "нравится" за публикацию/комментарий, за которую уже проголосовали (или кнопку "не нравится" для публикации/комментария, за которую уже проголосовали), также генерирует сообщение как Undo. В этом случае Undo/Like/Post или Undo/Dislike/Comment.

Создать личное сообщение

В профилях пользователей есть кнопка «Отправить сообщение», которая открывает диалоговое окно, позволяющее отправить личное сообщение этому пользователю. Отправляется как Create/Note во Входящие пользователя. Личные сообщения могут быть адресованы только одному,конкретному Пользователю.

Редактирование личного сообщения

Update/Note изменяет текст предыдущего отправленного сообщения.

Удалить личное сообщение

Delete/Note удаляет личное сообщение.

Восстановить личное сообщение

Undo/Delete/Note возвращает удалённое личное сообщение.

Активность Сообщества

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

Подтверждение подписки

Если Сообщество получает Follow активность, это автоматически активирует ответ Accept/Follow. И добавляет Пользователя в список подписавшихся.

Не следовать

Однажды получив Undo/Follow, Сообщество удаляет Пользователя из списка подписчиков.

Уведомление

Если Сообщество получает какие-либо действия, связанные с публикациями или комментариями (Создать, Обновить, Нравится, Не нравится, Удалить, Убрать, Отменить), оно Уведомляет об этом своих подписчикам. В связи с этим, Уведомление создаётся как действие , и принимается как объект активности. Таким образом, следующие экземпляры будут в курсе любых действий в сообществах, за которыми они следят.

Удалить Сообщество

Если создатель или администратор удаляет Сообщество, это отправляет Delete/Group всем его подписчикам.

Источники ActivityPub

Официальные документы

Пояснения

Примеры и Библиотеки

Протокол Федерации в Lemmy

Протокол Lemmy (или протокол Lemmy Federation) - это строгое подмножество протокола ActivityPub. Любое отклонение от протокола ActivityPub является ошибкой в Lemmy или в этой документации (или в обоих).

Этот документ предназначен для разработчиков, знакомых с протоколами ActivityPub и ActivityStreams. Он дает подробное описание моделей акторов, объектов и действий, используемых Lemmy.

Прежде чем читать это, взгляните на наш Обзор федерации, чтобы получить представление о том, как федерация Lemmy работает на высшем уровне.

Lemmy еще не во всех отношениях следует спецификации ActivityPub. Например, мы не устанавливаем допустимый контекст, указывающий на наши поля контекста. Мы также игнорируем такие поля, как «inbox», «outbox» или «endpoints» для удалённых участников и предполагаем, что все принадлежит Lemmy. Для обзора девиаций прочтите #698. Они будут исправлены в ближайшее время.

Lemmy также не очень гибкий, когда речь идет о входящих действиях и объектах. Они должны быть в точности идентичны приведенным ниже примерам. Такие вещи, как наличие массива вместо одного значения или идентификатора объекта вместо полного объекта, приведут к ошибке.

В следующих таблицах «обязательный» означает, будет ли Lemmy принимать входящие действия без этого поля. Сам Lemmy всегда будет включать все непустые поля.

Аннотация

{
    "@context": [
        "https://www.w3.org/ns/activitystreams",
        {
            "moderators": "as:moderators",
            "sc": "http://schema.org#",
            "stickied": "as:stickied",
            "sensitive": "as:sensitive",
            "pt": "https://join.lemmy.ml#",
            "comments_enabled": {
                "type": "sc:Boolean",
                "id": "pt:commentsEnabled"
            }
        },
        "https://w3id.org/security/v1"
    ]
}

Аннотация одинакова для всех действий и объектов.

Акторы

Сообщество

Автоматизированный актор. Пользователи могут отправлять сообщения или комментарии к нему, которые сообщество пересылает своим подписчикам в виде Announce.

Отправляет действия пользователю: Accept/Follow, Announce

:Получает действия от пользователя: Follow, Undo/Follow, Create, Update, Like, Dislike, Remove (только администратор/модератор), Delete (только создатель), Undo (только для собственных действий)

{
    "@context": ...,
    "id": "https://enterprise.lemmy.ml/c/main",
    "type": "Group",
    "preferredUsername": "main",
    "name": "The Main Community",
    "sensitive": false,
    "content": "Welcome to the default community!",
    "mediaType": "text/html",
    "source": {
        "content": "Welcome to the default community!",
        "mediaType": "text/markdown"
    },
    "icon": {
        "type": "Image",
        "url": "https://enterprise.lemmy.ml/pictrs/image/Z8pFFb21cl.png"
    },
    "image": {
        "type": "Image",
        "url": "https://enterprise.lemmy.ml/pictrs/image/Wt8zoMcCmE.jpg"
    },
    "inbox": "https://enterprise.lemmy.ml/c/main/inbox",
    "outbox": "https://enterprise.lemmy.ml/c/main/outbox",
    "followers": "https://enterprise.lemmy.ml/c/main/followers",
    "moderators": "https://enterprise.lemmy.ml/c/main/moderators",
    "endpoints": {
        "sharedInbox": "https://enterprise.lemmy.ml/inbox"
    },
    "published": "2020-10-06T17:27:43.282386+00:00",
    "updated": "2020-10-08T11:57:50.545821+00:00",
    "publicKey": {
        "id": "https://enterprise.lemmy.ml/c/main#main-key",
        "owner": "https://enterprise.lemmy.ml/c/main",
        "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9JJ7Ybp/H7iXeLkWFepg\ny4PHyIXY1TO9rK3lIBmAjNnkNywyGXMgUiiVhGyN9yU7Km8aWayQsNHOkPL7wMZK\nnY2Q+CTQv49kprEdcDVPGABi6EbCSOcRFVaUjjvRHf9Olod2QP/9OtX0oIFKN2KN\nPIUjeKK5tw4EWB8N1i5HOuOjuTcl2BXSemCQLAlXerLjT8xCarGi21xHPaQvAuns\nHt8ye7fUZKPRT10kwDMapjQ9Tsd+9HeBvNa4SDjJX1ONskNh2j4bqHHs2WUymLpX\n1cgf2jmaXAsz6jD9u0wfrLPelPJog8RSuvOzDPrtwX6uyQOl5NK00RlBZwj7bMDx\nzwIDAQAB\n-----END PUBLIC KEY-----\n"
    }
}
Имя в полеОбязательноОписание
preferredUsernameдаИмя актора
nameдаНазвание сообщества
sensitiveдаПравда указывает на то, что все сообщения в сообществе NSFW
attributedToдаСначала создатель сообщества, затем все остальные модераторы
contentнетТекст для боковой панели сообщества, обычно содержащий описание и правила
iconнетЗначок, отображаемый рядом с названием сообщества
imageнетИзображение баннера, отображаемое вверху страницы сообщества
inboxнетURL-адрес папки входящих сообщений ActivityPub
outboxнетURL-адрес исходящего сообщения ActivityPub, содержит только до 20 последних сообщений, без комментариев, голосов или других действий
followersнетURL-адрес коллекции подписчиков, содержит только количество подписчиков, без ссылок на отдельных подписчиков
endpointsнетСодержит URL общего почтового ящика
publishedнетДата и время, когда сообщество было впервые создано
updatedнетДата и время последнего изменения сообщества
publicKeyдаОткрытый ключ, используемый для проверки подписей этого актора

Исходящие Сообщения Сообщества

{
    "@context": ...,
    "items": [
      ...
    ],
    "totalItems": 3,
    "id": "https://enterprise.lemmy.ml/c/main/outbox",
    "type": "OrderedCollection"
}

Исходящие содержат только Create/Post мероприятия на данный момент.

Подписчики Сообщества

{
  "totalItems": 2,
  "@context": ...,
  "id": "https://enterprise.lemmy.ml/c/main/followers",
  "type": "Collection"
}

Коллекция подписчиков используется только для отображения количества подписчиков. Идентификаторы участников не включены, чтобы защитить конфиденциальность пользователей.

Модераторы Сообщества

{
    "items": [
        "https://enterprise.lemmy.ml/u/picard",
        "https://enterprise.lemmy.ml/u/riker"
    ],
    "totalItems": 2,
    "@context": ...,
    "id": "https://enterprise.lemmy.ml/c/main/moderators",
    "type": "OrderedCollection"
}

Пользователь

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

Отправляет действия в Сообщество: Follow, Undo/Follow, Create, Update, Like, Dislike, Remove (только администратор/модератор), Delete (только создатель), Undo (только для собственных действий)

Получает действия от сообщества: Accept/Follow, Announce

Отправляет и получает действия от/для других пользователей: Create/Note, Update/Note, Delete/Note, Undo/Delete/Note (все, что связано с личными сообщениями)

{
    "@context": ...,
    "id": "https://enterprise.lemmy.ml/u/picard",
    "type": "Person",
    "preferredUsername": "picard",
    "name": "Jean-Luc Picard",
    "content": "The user bio",
    "mediaType": "text/html",
    "source": {
        "content": "The user bio",
        "mediaType": "text/markdown"
    },
    "icon": {
        "type": "Image",
        "url": "https://enterprise.lemmy.ml/pictrs/image/DS3q0colRA.jpg"
    },
    "image": {
        "type": "Image",
        "url": "https://enterprise.lemmy.ml/pictrs/image/XenaYI5hTn.png"
    },
    "inbox": "https://enterprise.lemmy.ml/u/picard/inbox",
    "endpoints": {
        "sharedInbox": "https://enterprise.lemmy.ml/inbox"
    },
    "published": "2020-10-06T17:27:43.234391+00:00",
    "updated": "2020-10-08T11:27:17.905625+00:00",
    "publicKey": {
        "id": "https://enterprise.lemmy.ml/u/picard#main-key",
        "owner": "https://enterprise.lemmy.ml/u/picard",
        "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyH9iH83+idw/T4QpuRSY\n5YgQ/T5pJCNxvQWb6qcCu3gEVigfbreqZKJpOih4YT36wu4GjPfoIkbWJXcfcEzq\nMEQoYbPStuwnklpN2zj3lRIPfGLht9CAlENLWikTUoW5kZLyU6UQtOGdT2b1hDuK\nsUEn67In6qYx6pal8fUbO6X3O2BKzGeofnXgHCu7QNIuH4RPzkWsLhvwqEJYP0zG\nodao2j+qmhKFsI4oNOUCGkdJejO7q+9gdoNxAtNNKilIOwUFBYXeZJb+XGlzo0X+\n70jdJ/xQCPlPlItU4pD/0FwPLtuReoOpMzLi20oDsPXJBvn+/NJaxqDINuywcN5p\n4wIDAQAB\n-----END PUBLIC KEY-----\n"
    }
}
Имя в полеОбязательноОписание
preferredUsernameдаИмя Актора
nameнетОтображаемое имя пользователя
contentнетБИО пользователя
iconнетАватар пользователя, отображаемый рядом с именем пользователя
imageнетБаннер пользователя, отображаемый в верхней части профиля
inboxнетURL-адрес папки входящих сообщений ActivityPub
endpointsнетСодержит URL общего почтового ящика
publishedнетДата и время, когда пользователь зарегистрировался
updatedнетДата и время последнего изменения профиля пользователя
publicKeyдаОткрытый ключ используется для проверки подписей из этого актора

Входящие Пользователя

{
    "items": [],
    "totalItems": 0,
    "@context": ...,
    "id": "http://lemmy-alpha:8541/u/lemmy_alpha/outbox",
    "type": "OrderedCollection"
}

Папка для входящих сообщений пользователя еще не реализована и является лишь заполнителем для реализаций ActivityPub, которые в ней нуждаются.

Объект

Пост

Страница с заголовком и необязательным URL-адресом и текстовым содержимым. URL-адрес часто ведет к изображению и в этом случае включается эскиз. Каждый пост принадлежит ровно одному сообществу.

{
    "@context": ...,
    "id": "https://voyager.lemmy.ml/post/29",
    "type": "Page",
    "attributedTo": "https://voyager.lemmy.ml/u/picard",
    "to": [
      "https://voyager.lemmy.ml/c/main",
      "https://www.w3.org/ns/activitystreams#Public"
    ],
    "name": "Test thumbnail 2",
    "content": "blub blub",
    "mediaType": "text/html",
    "source": {
        "content": "blub blub",
        "mediaType": "text/markdown"
    },
    "url": "https://voyager.lemmy.ml:/pictrs/image/fzGwCsq7BJ.jpg",
    "image": {
        "type": "Image",
        "url": "https://voyager.lemmy.ml/pictrs/image/UejwBqrJM2.jpg"
    },
    "commentsEnabled": true,
    "sensitive": false,
    "stickied": false,
    "published": "2020-09-24T17:42:50.396237+00:00",
    "updated": "2020-09-24T18:31:14.158618+00:00"
}
Имя в полеОбязательноОписание
attributedToдаИдентификатор пользователя, который создал этот пост
toдаИдентификатор сообщества, в котором оно было опубликовано
nameдаЗаголовок сообщения
contentнетТело сообщения
urlнетПроизвольная ссылка, которой нужно поделиться
imageнетМиниатюра для url, присутствует только в том случае, если это ссылка на изображение
commentsEnabledдаЗначение false означает, что публикация заблокирована и комментарии к ней добавить нельзя
sensitiveдаTrue отмечает сообщение как NSFW, размывает миниатюру и скрывает ее от пользователей с отключенной настройкой NSFW
stickiedдаTrue означает, что оно отображается в верхней части сообщества
publishedнетДата и время создания сообщения
updatedнетДата и время, когда сообщение было отредактировано (отсутствует, если оно никогда не редактировалось)

Комментарий

Ответ на сообщение или ответ на другой комментарий. Содержит только текст (включая ссылки на других пользователей или сообщества). Lemmy отображает комментарии в виде древовидной структуры.

{
    "@context": ...,
    "id": "https://enterprise.lemmy.ml/comment/95",
    "type": "Note",
    "attributedTo": "https://enterprise.lemmy.ml/u/picard",
    "to": "https://www.w3.org/ns/activitystreams#Public",
    "content": "mmmk",
    "mediaType": "text/html",
    "source": {
        "content": "mmmk",
        "mediaType": "text/markdown"
    },
    "inReplyTo": [
        "https://enterprise.lemmy.ml/post/38",
        "https://voyager.lemmy.ml/comment/73"
    ],
    "published": "2020-10-06T17:53:22.174836+00:00",
    "updated": "2020-10-06T17:53:22.174836+00:00"
}
Имя в полеОбязательноОписание
attributedToдаИдентификатор пользователя, создавшего комментарий
toдаСообщество, в котором был сделан комментарий
contentдаТекст комментария
inReplyToдаИдентификатор поста, в которой был сделан этот комментарий, и родительского комментария. Если это комментарий верхнего уровня, inReplyTo содержит только сообщение
publishedнетДата и время создания комментария
updatedнетДата и время, когда комментарий был отредактирован (отсутствует, если он никогда не редактировался)

Личное сообщение

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

{
    "@context": ...,
    "id": "https://enterprise.lemmy.ml/private_message/34",
    "type": "Note",
    "attributedTo": "https://enterprise.lemmy.ml/u/picard",
    "to": "https://voyager.lemmy.ml/u/janeway",
    "content": "test",
    "source": {
        "content": "test",
        "mediaType": "text/markdown"
    },
    "mediaType": "text/markdown",
    "published": "2020-10-08T19:10:46.542820+00:00",
    "updated": "2020-10-08T20:13:52.547156+00:00"
}
Имя в полеОбязательноОписание
attributedToИдентификатор пользователя, создавшего это личное сообщение
toИдентификатор получателя
contentдаТекст личного сообщения
publishedнетДата и время создания сообщения
updatedнетДата и время, когда сообщение было отредактировано (отсутствует, если оно никогда не редактировалось)

Виды активности

Пользователь в Сообществе

Следовать

Когда пользователь нажимает "Подписаться" в сообществе, Follow отправляется. Сообщество автоматически отвечает Accept/Follow.

{
    "@context": ...,
    "id": "https://enterprise.lemmy.ml/activities/follow/2e4784b7-4edf-4fa1-a352-674d5d5f8891",
    "type": "Follow",
    "actor": "https://enterprise.lemmy.ml/u/picard",
    "to": "https://ds9.lemmy.ml/c/main",
    "object": "https://ds9.lemmy.ml/c/main"
}
Имя в полеОбязательноОписание
actorдаПользователь, отправляющий запрос на отслеживание
objectдаСообщество, за которым нужно следить

Отписаться

Нажатие на кнопку отказа от подписки в сообществе вызывает отправку сообщения Undo/Follow. Сообщество удаляет пользователя из списка подписчиков после его получения.

{
    "@context": ...,
    "id": "http://lemmy-alpha:8541/activities/undo/2c624a77-a003-4ed7-91cb-d502eb01b8e8",
    "type": "Undo",
    "actor": "http://lemmy-alpha:8541/u/lemmy_alpha",
    "to": "http://lemmy-beta:8551/c/main",
    "object": {
        "@context": ...,
        "id": "http://lemmy-alpha:8541/activities/follow/f0d732e7-b1e7-4857-a5e0-9dc83c3f7ee8",
        "type": "Follow",
        "actor": "http://lemmy-alpha:8541/u/lemmy_alpha",
        "object": "http://lemmy-beta:8551/c/main"
    }
}

Создать или Обновить Сообщение

Когда пользователь создает новый пост, он отправляется в соответствующее сообщество. Редактирование ранее созданного сообщения вызывает почти идентичную активность, за исключением type являющейся Update. Мы пока не поддерживаем упоминания в сообщениях.

{
    "@context": ...,
    "id": "https://enterprise.lemmy.ml/activities/create/6e11174f-501a-4531-ac03-818739bfd07d",
    "type": "Create",
    "actor": "https://enterprise.lemmy.ml/u/riker",
    "to": "https://www.w3.org/ns/activitystreams#Public",
    "cc": [
      "https://ds9.lemmy.ml/c/main/"
    ],
    "object": ...
}
Имя в полеОбязательноОписание
typeдалибо Create или Update
ccдаСообщество, в котором пишется пост
objectдаПост создается

Создать или Обновить Комментарий

Ответ на сообщение или другой комментарий. Может содержать упоминания других пользователей. Редактирование ранее созданного сообщения вызывает почти идентичную активность, за исключением type являющейся Update.

{
    "@context": ...,
    "id": "https://enterprise.lemmy.ml/activities/create/6f52d685-489d-4989-a988-4faedaed1a70",
    "type": "Create",
    "actor": "https://enterprise.lemmy.ml/u/riker",
    "to": "https://www.w3.org/ns/activitystreams#Public",
    "tag": [{
        "type": "Mention",
        "name": "@sisko@ds9.lemmy.ml",
        "href": "https://ds9.lemmy.ml/u/sisko"
    }],
    "cc": [
        "https://ds9.lemmy.ml/c/main/",
        "https://ds9.lemmy.ml/u/sisko"
    ],
    "object": ...
}
Имя в полеОбязательноОписание
tagнетСписок пользователей, упомянутых в комментарии (например @user@example.com)
ccдаСообщество, в котором создается публикация, пользователь, которому отвечает (создатель родительской публикации / комментария), а также любые упомянутые пользователи
objectдаСоздаваемый комментарий

Понравилось Сообщение или Комментарий

Голосоывание за публикацию или комментарий.

{
    "@context": ...,
    "id": "https://enterprise.lemmy.ml/activities/like/8f3f48dd-587d-4624-af3d-59605b7abad3",
    "type": "Like",
    "actor": "https://enterprise.lemmy.ml/u/riker",
    "to": "https://www.w3.org/ns/activitystreams#Public",
    "cc": [
        "https://ds9.lemmy.ml/c/main/"
    ],
    "object": "https://enterprise.lemmy.ml/p/123"
}
Имя в полеОбязательноОписание
ccдаИдентификатор сообщества, в котором размещён пост/комментарий
objectдаЗа публикацию или комментарий проголосовали

Сообщение или Комментарий не нравится

Голос против публикации или комментария.

{
    "@context": ...,
    "id": "https://enterprise.lemmy.ml/activities/dislike/fd2b8e1d-719d-4269-bf6b-2cadeebba849",
    "type": "Dislike",
    "actor": "https://enterprise.lemmy.ml/u/riker",
    "to": "https://www.w3.org/ns/activitystreams#Public",
    "cc": [
      "https://ds9.lemmy.ml/c/main/"
    ],
    "object": "https://enterprise.lemmy.ml/p/123"
}
Имя в полеОбязательноОписание
ccдаИдентификатор сообщества, в котором размещён пост/комментарий
objectдаЗа публикацию или комментарий проголосовали

Удалить Пост или Комментарий

Удаляет ранее созданный пост или комментарий. Это может сделать только первоначальный создатель этого сообщения/комментария.

{
    "@context": ...,
    "id": "https://enterprise.lemmy.ml/activities/delete/f1b5d57c-80f8-4e03-a615-688d552e946c",
    "type": "Delete",
    "actor": "https://enterprise.lemmy.ml/u/riker",
    "to": "https://www.w3.org/ns/activitystreams#Public",
    "cc": [
        "https://enterprise.lemmy.ml/c/main/"
    ],
    "object": "https://enterprise.lemmy.ml/post/32"
}
Имя в полеОбязательноОписание
ccдаИдентификатор сообщества, в котором размещён пост/комментарий
objectдаИдентификатор удаляемой записи или комментария

Убрать Пост или Комментарий

Убирает пост или комментарий. Это может быть сделано только модератором сообщества или администратором инстанса, где размещено сообщество.

{
    "@context": ...,
    "id": "https://ds9.lemmy.ml/activities/remove/aab93b8e-3688-4ea3-8212-d00d29519218",
    "type": "Remove",
    "actor": "https://ds9.lemmy.ml/u/sisko",
    "to": "https://www.w3.org/ns/activitystreams#Public",
    "cc": [
        "https://ds9.lemmy.ml/c/main/"
    ],
    "object": "https://enterprise.lemmy.ml/comment/32"
}
Имя в полеОбязательноОписание
ccдаИдентификатор сообщества, в котором размещён пост/комментарий
objectдаИдентификатор удаляемой записи или комментария

Отмена

Отменяет предыдущее действие, может быть выполнено только actor object. В случае Like или Dislike подсчет голосов возвращается обратно. В случае Delete или Remove пост/комментарий восстанавливается. object создается заново, так как идентификатор действия и другие поля отличаются.

{
    "@context": ...,
    "id": "https://ds9.lemmy.ml/activities/undo/70ca5fb2-e280-4fd0-a593-334b7f8a5916",
    "type": "Undo",
    "actor": "https://ds9.lemmy.ml/u/sisko",
    "to": "https://www.w3.org/ns/activitystreams#Public",
    "cc": [
        "https://ds9.lemmy.ml/c/main/"
    ],
    "object": ...
}
Имя в полеОбязательноОписание
objectдаЛюбая Like, Dislike, Delete или Remove активности как описано выше

Добавить Модератора

Добавление нового модератора (зарегистрированного на ds9.lemmy.ml) в сообществе !main@enterprise.lemmy.ml. Должно быть отправлено существующим модератором сообщества.

{
    "@context": ...,
    "id": "https://enterprise.lemmy.ml/activities/add/531471b1-3601-4053-b834-d26718da2a06",
    "type": "Add",
    "cc": [
        "https://enterprise.lemmy.ml/c/main"
    ],
    "to": "https://www.w3.org/ns/activitystreams#Public",
    "object": "https://ds9.lemmy.ml/u/sisko",
    "actor": "https://enterprise.lemmy.ml/u/picard",
    "target": "https://enterprise.lemmy.ml/c/main/moderators"
}

Убрать Модератора

Удаление существующего модератора из сообщества. Должено быть отправлено существующим модератором сообщества.

{
    "@context": ...,
    "id": "https://enterprise.lemmy.ml/activities/remove/63b9a5b2-d3f8-4371-a7eb-711c7928b3c0",
    "type": "Remove",
    "object": "https://ds9.lemmy.ml/u/sisko",
    "to": "https://www.w3.org/ns/activitystreams#Public",
    "actor": "https://enterprise.lemmy.ml/u/picard",
    "cc": [
        "https://enterprise.lemmy.ml/c/main"
    ],
    "target": "https://enterprise.lemmy.ml/c/main/moderators"
}

Сообщество для Пользователя

Принятие Подписки

Автоматически отправляется сообществом в ответ на Follow. В то же время сообщество добавляет этого пользователя в свой список подписчиков.

{
    "@context": ...,
    "id": "https://ds9.lemmy.ml/activities/accept/5314bf7c-dab8-4b01-baf2-9be11a6a812e",
    "type": "Accept",
    "actor": "https://ds9.lemmy.ml/c/main",
    "to": "https://enterprise.lemmy.ml/u/picard",
    "object": {
        "@context": ...,
        "id": "https://enterprise.lemmy.ml/activities/follow/2e4784b7-4edf-4fa1-a352-674d5d5f8891",
        "type": "Follow",
        "object": "https://ds9.lemmy.ml/c/main",
        "actor": "https://enterprise.lemmy.ml/u/picard"
    }
}
Имя в полеОбязательноОписание
actorдаТо же сообщество, что и в Follow активность
toнетИдентификатор пользователя, отправившего Follow
objectдаРанее отправленные Follow активность

Публикация

Когда сообщество получает сообщение или комментарий, оно помещает его в Announce и отправляет его всем подписчикам.

{
  "@context": ...,
  "id": "https://ds9.lemmy.ml/activities/announce/b98382e8-6cb1-469e-aa1f-65c5d2c31cc4",
  "type": "Announce",
  "actor": "https://ds9.lemmy.ml/c/main",
  "to": "https://www.w3.org/ns/activitystreams#Public",
  "cc": [
    "https://ds9.lemmy.ml/c/main/followers"
  ],
  "object": ...
}
Имя в полеОбязательноОписание
objectдаЛюбая из Create, Update, Like, Dislike, Delete Remove или Undo активности описанная в Пользователь в Сообществе секции

Убрать или Удалить Сообщество

Администратор инстанса или модератор могут удалять сообщества.

{
  "@context": ...,
  "id": "http://ds9.lemmy.ml/activities/remove/e4ca7688-af9d-48b7-864f-765e7f9f3591",
  "type": "Remove",
  "actor": "http://ds9.lemmy.ml/c/some_community",
  "cc": [
    "http://ds9.lemmy.ml/c/some_community/followers"
  ],
  "to": "https://www.w3.org/ns/activitystreams#Public",
  "object": "http://ds9.lemmy.ml/c/some_community"
}
Имя в полеОбязательноОписание
typeдаЛибо Remove или Delete

Восстановить Убранное или Удалённое Сообщество

Отменяет убранное сообщество или удалённое.

{
  "@context": ...,
  "id": "http://ds9.lemmy.ml/activities/like/0703668c-8b09-4a85-aa7a-f93621936901",
  "type": "Undo",
  "actor": "http://ds9.lemmy.ml/c/some_community",
  "to": "https://www.w3.org/ns/activitystreams#Public",
  "cc": [
    "http://ds9.lemmy.ml/c/testcom/followers"
  ],
  "object": {
    "@context": ...,
    "id": "http://ds9.lemmy.ml/activities/remove/1062b5e0-07e8-44fc-868c-854209935bdd",
    "type": "Remove",
    "actor": "http://ds9.lemmy.ml/c/some_community",
    "object": "http://ds9.lemmy.ml/c/testcom",
    "to": "https://www.w3.org/ns/activitystreams#Public",
    "cc": [
      "http://ds9.lemmy.ml/c/testcom/followers"
    ]
  }
}

Имя в полеОбязательноОписание
object.typeдаЛибо Remove или Delete

От Пользователя к Пользователю

Создать или Обновить личное сообщение

Создание нового личного сообщения между двумя пользователями.

{
    "@context": ...,
    "id": "https://ds9.lemmy.ml/activities/create/202daf0a-1489-45df-8d2e-c8a3173fed36",
    "type": "Create",
    "actor": "https://ds9.lemmy.ml/u/sisko",
    "to": "https://enterprise.lemmy.ml/u/riker/inbox",
    "object": ...
}
Имя в полеОбязательноОписание
typeдаЛибо Create или Update
objectдаЛичное сообщение

Удалить Личное Сообщение

Удаляет предыдущее личное сообщение.

{
    "@context": ...,
    "id": "https://ds9.lemmy.ml/activities/delete/2de5a5f3-bf26-4949-a7f5-bf52edfca909",
    "type": "Delete",
    "actor": "https://ds9.lemmy.ml/u/sisko",
    "to": "https://enterprise.lemmy.ml/u/riker/inbox",
    "object": "https://ds9.lemmy.ml/private_message/341"
}

Отмена Удаления Личного Сообщения

Восстанавливает ранее удалённое личное сообщение. Объект создается заново, так как идентификатор действия и другие поля отличаются.

{
    "@context": ...,
    "id": "https://ds9.lemmy.ml/activities/undo/b24bc56d-5db1-41dd-be06-3f1db8757842",
    "type": "Undo",
    "actor": "https://ds9.lemmy.ml/u/sisko",
    "to": "https://enterprise.lemmy.ml/u/riker/inbox",
    "object": ...
}

Клиентская разработка

Тематическое руководство

Пользователи Lemmy Bootstrap v4, и не много настраиваемых классов css, поэтому любая тема, совместимая с bootstrap v4, должна работать нормально.

Создание

  • Используйте такой инструмент, как bootstrap.build для создания темы начальной загрузки v4. Экспортируйте bootstrap.min.css как только вы закончите, сохраните _variables.scss тоже.

Тестирование

  • Чтобы протестировать тему, вы можете использовать веб-инструменты своего браузера или плагин, например stylus, для копирования и вставки темы при просмотре Lemmy.

Добавление

  1. Ответвление lemmy-ui.
  2. Скопируйте {my-theme-name}.min.css в src/assets/css/themes. (Вы также можете скопировать в _variables.scss если хотите).
  3. Перейдите в src/shared/utils.ts и добавьте {my-theme-name} в список тем.
  4. Протестируйте локально
  5. Сделайте запрос pull request с этими изменениями в Github

Справочник по API

Lemmy имеет два взаимосвязанных API:

На этой странице описаны общие для них концепции.

Основное использование

Запрос и ответ строк В формате JSON (анг.язык).

Типы данных

Типы Lemmy

Низкоуровневые типы

  • ? обозначает параметр, который может быть опущен в запросах и отсутствовать в ответах. Это будет типа SomeType.
  • [SomeType] список, содержащий объекты типа SomeType.
  • Времена и даты временной метки в строках ISO 8601 (анг.язык) формата. Временные метки будут в формате UTC, ваш клиент должен выполнить преобразование UTC в локальный формат.

Скоростные лимиты по умолчанию

Их можно редактировать в вашем lemmy.hjson файле, скопировав соответствующий раздел из defaults.hjson (анг.язык).

  • 3 в час за регистрацию и создание сообщества.
  • 6 в час за размещение изображений.
  • 6 за 10 минут на создание поста.
  • 180 действий в минуту для постголосования и создания комментариев.

Все остальное не ограничено по скорости.

Смотри также: ограничение скорости для пользовательских интерфейсов (анг.язык).

WebSocket API

Lemmy WebSocket API 2.0 documentation

HTTP API

Создание пользовательского интерфейса

Вклад

Docker разработка

Локальное развитие

Тесты

Rust

После установки local development dependencies, запустите следующую команду:

psql -U lemmy -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
./test.sh

Федерация

Установите Local development dependencies, и добавьте следующую строку /etc/hosts:

127.0.0.1       lemmy-alpha
127.0.0.1       lemmy-beta
127.0.0.1       lemmy-gamma
127.0.0.1       lemmy-delta
127.0.0.1       lemmy-epsilon

Затем используйте следующий скрипт для запуска тестов:

cd api_tests
./run-federation-test.bash

Federation Development

Правила поведения