Translate section 1, 2 and 3 to Spanish (#47)

* Enable Spanish language

* Translated code_of_conduct.md and about.md

* Fix minor issues.

* Translated about folder

* fix source issues

* translated install methods

* Translated (section 1 2 3)
This commit is contained in:
mickie 2021-03-31 06:30:53 -06:00 committed by GitHub
parent b92b50adce
commit cb466f85c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 2059 additions and 5 deletions

2
.gitignore vendored
View file

@ -1 +1 @@
book
book

View file

@ -6,6 +6,6 @@ src = "src"
name = "English"
title = "Lemmy Documentation"
#[language.es]
#name = "Español"
#title = "Documentación Lemmy"
[language.es]
name = "Español"
title = "Documentación Lemmy"

View file

@ -4,7 +4,7 @@
- Must have communities.
- Must have threaded comments.
- Must be federated: liking and following communities across instances.
- Be live-updating: have a right pane for new comments, and a main pain for the full threaded view.
- Be live-updating: have a right pane for new comments, and a main pane for the full threaded view.
- Use websockets for post / gets to your own instance.
# Questions

31
src/es/SUMMARY.md Normal file
View file

@ -0,0 +1,31 @@
# Summary
- [Acerca de](about/about.md)
- [Características](about/features.md)
- [Metas](about/goals.md)
- [Clasificación de las publicaciones y los comentarios](about/ranking.md)
- [Guía](about/guide.md)
- [Administración](administration/administration.md)
- [Instalación con Docker](administration/install_docker.md)
- [Instalación con Ansible](administration/install_ansible.md)
- [Otros Métodos de Instalación](administration/other_installation_methods.md)
- [Configuración](administration/configuration.md)
- [Introducción a la Federación](administration/federation_getting_started.md)
- [Solución de Problemas](administration/troubleshooting.md)
- [Copia de Seguridad y Restauración](administration/backup_and_restore.md)
- [Federación](federation/federation.md)
- [Visión General de la Federación](federation/overview.md)
- [Recursos](federation/resources.md)
- [Protocolo de Lemmy](federation/lemmy_protocol.md)
- [Client Development](client_development/client_development.md)
- [Theming Guide](client_development/theming.md)
- [API reference](client_development/api_reference.md)
- [WebSocket API](https://join.lemmy.ml/api/index.html)
- [HTTP API](client_development/http_api.md)
- [Creating a Custom Frontend](client_development/custom_frontend.md)
- [Contributing](contributing/contributing.md)
- [Docker Development](contributing/docker_development.md)
- [Local Development](contributing/local_development.md)
- [Tests](contributing/tests.md)
- [Federation Development](contributing/federation_development.md)
- [Código de Conducta](code_of_conduct.md)

30
src/es/about/about.md Normal file
View file

@ -0,0 +1,30 @@
## Acerca del proyecto
Página de inicio|Página de publicación
---|---
![captura principal](main_screen.png)|![captura del chat](chat_screen.png)
[Lemmy](https://github.com/LemmyNet/lemmy) es similar a sitios como [Menéame](https://meneame.net), [Reddit](https://reddit.com), [Lobste.rs](https://lobste.rs), [Raddle](https://raddle.me), o [Hacker News](https://news.ycombinator.com/): te subscribes a los foros que te interesan, publicas enlaces y debates, luego votas y comentas en ellos. Entre bastidores, es muy diferente; cualquiera puede gestionar fácilmente un servidor, y todos estos servidores son federados (piensa en el correo electrónico), y conectados al mismo universo, llamado [Fediverso](https://es.wikipedia.org/wiki/Fediverso).
Para un agregador de enlaces, esto significa que un usuario registrado en un servidor puede suscribirse a los foros de otro servidor, lo que le permite mantener discusiones con usuarios registrados en otros lugares.
El objetivo general es crear una alternativa a reddit/menéame y otros agregadores de enlaces, fácilmente auto-hospedada, descentralizada, y fuera del control e intromisión corporativa de éstos.
Cada servidor lemmy puede establecer su propia política de moderación; nombrando a los administradores del sitio y a los moderadores de la comunidad para mantener alejados a los trolls, fomentar un entorno saludable y no tóxico en el que todos puedan sentirse cómodos contribuyendo.
**La Federación está en constante desarrollo**
### ¿Por qué se llama Lemmy?
- Cantante principal de [Motörhead](https://invidio.us/watch?v=pWB5JZRGl0U).
- El [videojuego de la vieja escuela](<https://es.wikipedia.org/wiki/Lemmings>).
- El [Koopa de Super Mario](https://www.mariowiki.com/Lemmy_Koopa).
- Los [roedores peludos](http://sunchild.fpwc.org/lemming-the-little-giant-of-the-north/).
### Desarrollado Con
- [Rust](https://www.rust-lang.org)
- [Actix](https://actix.rs/)
- [Diesel](http://diesel.rs/)
- [Inferno](https://infernojs.org)
- [Typescript](https://www.typescriptlang.org/)

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

37
src/es/about/features.md Normal file
View file

@ -0,0 +1,37 @@
# Características
- Código abierto, [Licencia AGPL](/LICENSE).
- Auto-hospedado, fácil de desplegar (deploy).
- Viene con [Docker](#docker) y [Ansible](#ansible).
- Interfaz limpia y fácil de usar. Apta para dispositivos móviles.
- Sólo se requiere como mínimo un nombre de usuario y una contraseñar para inscribirse!
- Soporte de avatar de usuario.
- Hilos de comentarios actualizados en directo.
- Puntuaciones completas de los votos `(+/-)` como en el antiguo reddit.
- Temas, incluidos los claros, los oscuros, y los solarizados.
- Emojis con soporte de autocompletado. Empieza tecleando `:`
- *Ejemplo* `miau :cat:` => `miau 🐈`
- Etiquetado de Usuarios con `@`, etiquetado de Comunidades con `!`.
- *Ejemplo* `@miguel@lemmy.ml me invitó a la comunidad !gaming@lemmy.ml`
- Carga de imágenes integrada tanto en las publicaciones como en los comentarios.
- Una publicación puede consistir en un título y cualquier combinación de texto propio, una URL o nada más.
- Notificaciones, sobre las respuestas a los comentarios y cuando te etiquetan.
- Las notificaciones se pueden enviar por correo electrónico.
- Soporte de i18n / internacionalización.
- Fuentes RSS / Atom para Todo `All`, Suscrito `Subscribed`, Bandeja de entrada `inbox`, Usuario `User`, y Comunidad `Community`.
- Soporte para la publicación cruzada (cross-posting).
- **búsqueda de publicaciones similares** al crear una nueva. Ideal para comunidades de preguntas y respuestas.
- Capacidades de moderación.
- Registros públicos de moderación.
- Puedes pegar las publicaciones a la parte superior de las comunidades.
- Tanto los administradores del sitio, como los moderadores de la comunidad, pueden nombrar a otros moderadores.
- Puedes bloquear, eliminar y restaurar publicaciones y comentarios.
- Puedes banear y desbanear usuarios de las comunidades y del sitio.
- Puedes transferir el sitio y las comunidades a otros.
- Puedes borrar completamente tus datos, reemplazando todas las publicaciones y comentarios.
- Soporte para publicaciones y comunidades NSFW.
- Alto rendimiento.
- El servidor está escrito en rust.
- El front end está comprimido (gzipped) en `~80kB`.
- El front end funciona sin javascript (sólo lectura).
- Soporta arm64 / Raspberry Pi.

41
src/es/about/goals.md Normal file
View file

@ -0,0 +1,41 @@
# Metas
*Esta sección contiene ideas y recursos del equipo que desarrolla Lemmy*. **Parecido a un bloc de notas**
- Piensa en un nombre / nombre clave.
- Debe tener comunidades.
- Debe tener comentarios hilados.
- Debe ser federado: enlazar y seguir comunidades en todas las instancias.
- Debe estar actualizado en vivo: tener un panel derecho para nuevos comentarios y un panel principal para la vista completa de los hilos.
- Usar websockets para publicar (post) / obtener (gets) hacia tu propia instancia.
# Preguntas
- ¿Cómo funciona la votación? ¿Debemos volver a la antigua forma de mostrar y contar los votos negativos? ¿O sólo una puntuación?
- Decidir la tecnología que se utilizará
- Backend: Actix, Diesel.
- Frontend: inferno, typescript y bootstrap por ahora.
- ¿Deberia permitir bots?
- ¿Deberían los comentarios/votos ser estáticos, o sentirse como un chat, como [flowchat?](https://flow-chat.com).
- Modelo de dos paneles - El panel derecho para comentarios en vivo, el panel izquierdo para la vista en árbol en vivo
- En el móvil, permite cambiar entre ellos. ¿Por defecto?
# Recursos / Librerías potenciales
- [Diesel to Postgres data types](https://kotiri.com/2018/01/31/postgresql-diesel-rust-types.html)
- [helpful diesel examples](http://siciarz.net/24-days-rust-diesel/)
- [Recursive query for adjacency list for nested comments](https://stackoverflow.com/questions/192220/what-is-the-most-efficient-elegant-way-to-parse-a-flat-table-into-a-tree/192462#192462)
- https://github.com/sparksuite/simplemde-markdown-editor
- [Markdown-it](https://github.com/markdown-it/markdown-it)
- [Sticky Sidebar](https://stackoverflow.com/questions/38382043/how-to-use-css-position-sticky-to-keep-a-sidebar-visible-with-bootstrap-4/49111934)
- [RXJS websocket](https://stackoverflow.com/questions/44060315/reconnecting-a-websocket-in-angular-and-rxjs/44067972#44067972)
- [Rust JWT](https://github.com/Keats/jsonwebtoken)
- [Hierarchical tree building javascript](https://stackoverflow.com/a/40732240/1655478)
- [Hot sorting discussion](https://meta.stackexchange.com/questions/11602/what-formula-should-be-used-to-determine-hot-questions) [2](https://medium.com/hacking-and-gonzo/how-reddit-ranking-algorithms-work-ef111e33d0d9)
- [Classification types.](https://www.reddit.com/r/ModeratorDuck/wiki/subreddit_classification)
- [RES expando - Possibly make this into a switching react component.](https://github.com/honestbleeps/Reddit-Enhancement-Suite/tree/d21f55c21e734f47d8ed03fe0ebce5b16653b0bd/lib/modules/hosts)
- [Temp Icon](https://www.flaticon.com/free-icon/mouse_194242)
- [Rust docker build](https://shaneutt.com/blog/rust-fast-small-docker-image-builds/)
- [Zurb mentions](https://github.com/zurb/tribute)
- [TippyJS](https://github.com/atomiks/tippyjs)
- [SQL function indexes](https://sorentwo.com/2013/12/30/let-postgres-do-the-work.html)

66
src/es/about/guide.md Normal file
View file

@ -0,0 +1,66 @@
# Guía de Lemmy
**¿Eres nuevo aquí?** Esta sección es la indicada para que los nuevos (y no tan nuevos 😙) usuarios puedan sacar provecho de todo lo que Lemmy ofrece.
## Vídeo Explicativo (en inglés)
<iframe id='ivplayer' width='640' height='360' src='https://invidious.xyz/embed/5axSUJj0bBY' style='border:none;'></iframe>
## Comandos Útiles
Empieza tecleando...
- `@nombre_usuario` para obtener una lista de nombres de usuario.
- `!nombre_comunidad` para obtener una lista de comunidades.
- `:emoji` para obtener una lista de emojis.
## Clasificación
*Se aplica tanto a las publicaciones como a los comentarios.*
Tipo | Descripción
--- | ---
Activo | Tendencias ordenadas en base a la puntuación, y la hora del comentario mas reciente.
Popular | Tendencias ordenadas en base a la puntuación, y la hora de creación de la publicación.
Nuevo | Las publicaciones más nuevas.
Más comentados | Las publicaciones con más comentarios.
Nuevos comentarios | Las publicaciones con los comentarios más recientes, es decir un ordenamiento tipo foro.
Top | Las publicaciones con mayor puntuación en el periodo de dado.
Para más detalles, revisa el [Apartado de la Clasificación de las publicaciones y los comentarios](ranking.md).
## Moderación / Administración
Todas las acciones de los moderadores y administradores sobre los usuarios se realizan en los comentarios o entradas, haciendo clic en el icono de 3 puntos "Más".
Esto incluye:
- Agregar / Eliminar mods y admins.
- Eliminar / Restaurar comentarios.
- Banear / Desbanear usuarios.
Todas las acciones de los administradores en las comunidades se realizan en la barra lateral de la comunidad. Esto actualmente sólo incluye la eliminación/restauración de comunidades.
## Guía de Markdown
Enriquece todas tus publicaciones / comentarios aplicando el formato Markdown para que el texto no se vea tan aburrido.
Tipo | O | … para obtener
--- | --- | ---
\*Italica\* | \_Italica\_ | _Italica_
\*\*Negrita\*\* | \_\_Negrita\_\_ | **Negrita**
\# Titulo 1 | Titulo 1 <br> ========= | <h4>Titulo 1</h4>
\## Titulo 2 | Titulo 2 <br>--------- | <h5>Titulo 2</h5>
\[enlace\](http://a.com) | \[enlace\]\[1\]<br><br>\[1\]: http://b.org | [enlace](https://commonmark.org/)
!\[Imagen\](http://url/a.png) | !\[Imagen\]\[1\]<br><br>\[1\]: http://url/b.jpg | ![Markdown](https://commonmark.org/help/images/favicon.png)
\> Cita en bloque | | <blockquote>Cita en bloque</blockquote>
\* Lista <br>\* Lista <br>\* Lista | \- Lista <br>\- Lista <br>\- Lista <br> | * Lista <br>* Lista <br>* Lista <br>
1\. Uno <br>2\. Dos <br>3\. Tres | 1) Uno<br>2) Dos<br>3) Tres | 1. Uno<br>2. Dos<br>3. Tres
Línea Horizontal <br>\--- | Línea Horizontal<br>\*\*\* | Línea Horizontal <br><hr>
\`Código en línea\` con acento grave | |`Código en línea` con acento grave
\`\`\`<br>\# Bloque de código <br>print '3 acentos graves o'<br>print 'indentar 4 espacios' <br>\`\`\` | ····\# Bloque de código<br>····print '3 acentos graves o'<br>····print 'indentar 4 espacios' | \# Bloque de código <br>print '3 acentos graves o'<br>print 'indentar 4 espacios'
::: spoiler o nsfw oculto <br>*mucho spoiler aquí*<br>::: | | <details><summary> spoiler o nsfw oculto </summary><p><em>mucho spoiler aquí</em></p></details>
Texto de ~subíndice~ | | Texto de <sub>subíndice</sub>
Texto de ^superíndice^ | | Texto de <sup>superíndice</sup>
[Tutorial de CommonMark](https://commonmark.org/help/tutorial/)

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

46
src/es/about/ranking.md Normal file
View file

@ -0,0 +1,46 @@
# Tendencia / Popular / Mejor algoritmo de clasificación
## Metas
- Durante el día, las nuevas publicaciones y comentarios deben estar cerca de la parte superior, para que puedan ser votados.
- Después de un día más o menos, el factor tiempo debería desaparecer.
- Utilizar una escala logarítmica, ya que los votos tienden a convertirse en una bola de nieve, por lo que los primeros 10 votos son tan importantes como los siguientes cien.
## Implementaciones
### Reddit
No tiene en cuenta la duración del hilo, [lo que da a los primeros comentarios una ventaja abrumadora sobre los posteriores,](https://minimaxir.com/2016/11/first-comment/) siendo el efecto aún peor en las comunidades pequeñas. Los nuevos comentarios se acumulan en la parte inferior del hilo, acabando con la discusión y convirtiendo cada hilo en una carrera por comentar antes. Esto reduce la calidad de la conversación y premia los comentarios repetitivos y el spam.
### Hacker News
Aunque es muy superior a la implementación de Reddit por su decaimiento de las puntuaciones en el tiempo, [el algoritmo de clasificación de Hacker News](https://medium.com/hacking-and-gonzo/how-hacker-news-ranking-algorithm-works-1d9b0cf2c08d) no utiliza una escala logarítmica para las puntuaciones.
### Lemmy
Contrarresta el efecto de bola de nieve de los votos a lo largo del tiempo con una escala logarítmica. Anula la ventaja inherente de los primeros comentarios y garantiza que los votos sigan siendo importantes a largo plazo, sin perjudicar los comentarios populares más antiguos.
```
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 utiliza el mismo algoritmo `Rank` anterior, en dos tipos: `Active` y `Hot`.
- El algoritmo "activo" utiliza los votos de las publicaciones y el tiempo de los últimos comentarios (limitado a dos días).
- `Hot` utiliza los votos de las publicaciones, y la hora de publicación de los mismos.
- Utiliza Max(1, score) para asegurarse de que todos los comentarios se ven afectados por el decaimiento del tiempo.
- Añade 3 a la puntuación, para que todo lo que tenga menos de 3 downvotes parezca nuevo. De lo contrario, todos los comentarios nuevos se quedarían en cero, cerca del fondo.
- El signo y los abs de la puntuación son necesarios para tratar el registro de las puntuaciones negativas.
- Un factor de escala de 10k obtiene el rango en forma de número entero.
Un gráfico del rango a lo largo de 24 horas, de puntuaciones de 1, 5, 10, 100, 1000, con un factor de escala de 10k.
![](rank_algorithm.png)
#### Conteo de usuarios activos
Lemmy también muestra el conteo de *usuarios activos* de tu sitio y sus comunidades. Estos se cuentan en el último día `day`, semana `week`, mes `month` y medio año `half year`, almacenándose en caché al iniciar Lemmy, y cada hora.
Un usuario activo es alguien que ha publicado o comentado en nuestra instancia o comunidad en el último periodo de tiempo. Para el conteo de sitios, sólo se cuentan los usuarios locales. Para los conteos de la comunidad, se incluyen los usuarios federados.

View file

@ -0,0 +1,11 @@
# Información Administrativa
Información para administradores de las instancias de Lemmy, y para aquellos que quieran gestionar un servidor.
## Instalación
Lemmy tiene dos métodos principales de instalación, [manual con Docker](install_docker.md), y [automatizado con Ansible](install_ansible.md). Recomendamos usar Ansible, porque simplifica la instalación y también facilita la actualización.
## Otros métodos de instalación
En algunos casos, puede ser necesario utilizar [otros métodos de instalación](other_installation_methods.md). Pero no lo recomendamos y no podemos dar soporte para ellos.

View file

@ -0,0 +1,78 @@
# Guía de Copia de Seguridad Y Restauración
## Docker y Ansible
Cuando se utiliza docker o ansible, debe haber una carpeta llamada `volumes`, la cual contiene tanto la Base de Datos como todas las Imágenes. Copia esta carpeta a la nueva instancia para restaurar tus datos.
### Copia de seguridad incremental de la BD
Para hacer una copia de seguridad incremental de una base de datos en archivo `.sql` puedes ejecutar:
```bash
docker-compose exec postgres pg_dumpall -c -U lemmy > lemmy_dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql
```
### Un ejemplo de script de copia de seguridad
```bash
#!/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
```
### Restauración de la BD
Si necesitas restaurar la base de datos a partir de un archivo `pg_dumpall`, primero necesitas borrar la base de datos existente
```bash
# Drop the existing DB
docker exec -i FOLDERNAME_postgres_1 psql -U lemmy -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
# Restore from the .sql backup
cat db_dump.sql | docker exec -i FOLDERNAME_postgres_1 psql -U lemmy # restores the db
# This also might be necessary when doing a db import with a different password.
docker exec -i FOLDERNAME_postgres_1 psql -U lemmy -c "alter user lemmy with password 'bleh'"
```
### Cambiar el nombre de dominio
Si aún no te has federado, puedes cambiar tu nombre de dominio en la base de datos.
**Advertencia: no haga esto después de haber federado o romperás la federación.**
Entra al `psql` de tu 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');
```
## Más recursos
- https://stackoverflow.com/questions/24718706/backup-restore-a-dockerized-postgresql-database

View file

@ -0,0 +1,19 @@
# Configuración
La configuración está basada en el archivo [defaults.hjson](https://yerbamate.ml/LemmyNet/lemmy/src/branch/main/config/defaults.hjson). Este archivo también contiene la documentación de todas las opciones disponibles. Para anular los valores predeterminados, puedes copiar las opciones que deseas cambiar dentro de tu archivo local `config.hjson`.
Los archivos `defaults.hjson` y `config.hjson` se encuentran en `config/defaults.hjson` y `config/config.hjson`, respectivamente. Para cambiar estas localizaciones predeterminadas, puedes establecer las siguientes variables de entorno:
- LEMMY_CONFIG_LOCATION # config.hjson
- LEMMY_CONFIG_DEFAULTS_LOCATION # defaults.hjson
Adicionalmente, puedes sobrescribir cualquier archivo de configuración con las variables de entorno. Éstas tienen el mismo nombre que las opciones de configuración, llevando el prefijo `LEMMY_`. Por ejemplo, puedes sobrescribir el `database.password` con `LEMMY_DATABASE__POOL_SIZE=10`.
Una opción adicional `LEMMY_DATABASE_URL` está disponible, la cual puede ser usada con una cadena de conexión PostgreSQL como `postgres://lemmy:password@lemmy_db:5432/lemmy`, pasando todos los detalles de la conexión a la vez.
Si no se utiliza el contenedor Docker, cree manualmente la base de datos especificada anteriormente ejecutando los siguientes comandos:
```bash
cd server
./db-init.sh
```

View file

@ -0,0 +1,37 @@
# Federación
Lemmy utiliza el protocolo ActivityPub (un estándar del W3C) para permitir la federación entre diferentes servidores (a menudo llamados instancias). Esto es muy parecido al funcionamiento del correo electrónico. Por ejemplo, si utilizas gmail.com, no sólo puedes enviar correos a otros usuarios de gmail.com, sino también a yahoo.com, yandex.ru, etc. El correo electrónico utiliza el protocolo SMTP para lograr esto, así que puedes pensar en ActivityPub como "SMTP para las redes sociales". La cantidad de acciones posibles en las redes sociales (publicar, comentar, gustar, compartir, etc.) hace que ActivityPub sea mucho más complicado que SMTP.
Al igual que con el correo electrónico, la federación de ActivityPub sólo se produce entre servidores. Así, si estás registrado en `enterprise.lemmy.ml`, sólo te conectas a la API de `enterprise.lemmy.ml`, mientras que el servidor se encarga de enviar y recibir datos de otras instancias (por ejemplo, `voyager.lemmy.ml`). La gran ventaja de este enfoque es que el usuario medio no tiene que hacer nada para utilizar la federación. De hecho, si está utilizando Lemmy, es probable que ya lo estés haciendo. Una forma de confirmarlo es ir a una comunidad o perfil de usuario. Si estás en `enterprise.lemmy.ml` y ves un usuario como `@nutomic@voyager.lemmy.ml`, o una comunidad como `!main@ds9.lemmy.ml`, entonces están federados, lo que significa que utilizan una instancia diferente a la tuya.
Una forma de aprovechar la federación es abrir una instancia diferente, como `ds9.lemmy.ml`, y navegar por ella. Si ves una comunidad, una publicación o un usuario interesante con el que quieres interactuar, sólo tienes que copiar su URL y pegarla en el campo de búsqueda de tu propia instancia (parte superior de página). Tu instancia se conectará a la otra (suponiendo que la lista de permitidos/bloqueados lo permita), y te mostrará directamente el contenido remoto, para que puedas seguir una comunidad o comentar un publicación. Estos son algunos ejemplos de búsquedas que funcionan:
- `!main@lemmy.ml` (Comunidad)
- `@nutomic@lemmy.ml` (Usuario)
- `https://lemmy.ml/c/programming` (Comunidad)
- `https://lemmy.ml/u/nutomic` (Usuario)
- `https://lemmy.ml/post/123` (Publicación)
- `https://lemmy.ml/comment/321` (Comentario)
Puedes ver la lista de instancias vinculadas siguiendo el enlace "Instancias" en la parte inferior de cualquier página de Lemmy.
## Búsqueda de comunidades
Si buscas una comunidad por primera vez, inicialmente se obtienen 20 publicaciones. Sólo si al menos un usuario de tu instancia se suscribe a la comunidad remota, ésta enviará actualizaciones a tu instancia. Las actualizaciones incluyen:
- Nuevas publicaciones / comentarios
- Votos
- Publicación, ediciones y supresiones de comentarios
- Acciones de los modeladores
Puedes copiar la URL de la comunidad desde la barra de direcciones de tu navegador e insertarla en el campo de búsqueda. Espera unos segundos y la publicación aparecerá a continuación. Por el momento no hay un indicador de carga para la búsqueda, así que espera unos segundos si muestra "sin resultados".
## Búsqueda de publicaciones
Pega la URL de una publicación en el campo de búsqueda de tu instancia de Lemmy. Espera unos segundos hasta que aparezca la publicación. Esto también recuperará el perfil de la comunidad y el perfil del creador de la publicación.
## Búsqueda de comentarios
Si encuentras un comentario interesante bajo una publicación en otra instancia, puedes encontrar debajo del comentario en el menú de 3 puntos el símbolo del enlace. Copia este enlace. Se parece a `https://lemmy.ml/post/56382/comment/40796`. Elimina la parte `post/XXX` y ponlo en tu barra de búsqueda. Para este ejemplo, busqua `https://lemmy.ml/comment/40796`. Este comentario, todos los comentarios padre, usuarios, la comunidad y la publicación correspondiente se obtienen de la instancia remota, si no se conocen localmente.
Los comentarios hermanos no se obtienen. Si quieres más comentarios de publicaciones anteriores, tienes que buscar cada uno de ellos como se ha descrito anteriormente.

View file

@ -0,0 +1,25 @@
# Instalación con Ansible
Esto es lo mismo que la [instalación con Docker](install_docker.md), excepto que Ansible lo maneja todo automáticamente. También hace algunas cosas adicionales como la configuración de TLS y el correo electrónico para tu instancia Lemmy.
En primer lugar, necesitas [instalar Ansible en tu computador local](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html). Tambien necesitas instalar el [SDK de Docker para Python](https://pypi.org/project/docker/) usando `pip install docker` ([más información en la documentación de Ansible](https://docs.ansible.com/ansible/latest/collections/community/docker/docker_compose_module.html#id4)).
A continuación, ejecuta los siguientes comandos en tu computador local:
```bash
git clone https://github.com/LemmyNet/lemmy.git
cd lemmy/ansible/
cp inventory.example inventory
nano inventory # ingresa tu servidor, dominio, correo electrónico de contacto
# Si el comando siguiente falla, es posible que tengas que comentar esta linea
# En el archivo ansible.cfg:
# interpreter_python=/usr/bin/python3
ansible-playbook lemmy.yml --become
```
Para actualizar a una nueva versión, simplemente ejecuta lo siguiente en tu repo local de Lemmy:
```bash
git pull origin main
cd ansible
ansible-playbook lemmy.yml --become
```

View file

@ -0,0 +1,55 @@
# Instalación con Docker
Asegúrate de tener instalados tanto docker como docker-compose(>=`1.24.0`). En Ubuntu, simplemente ejecuta `apt install docker-compose docker.io`. Siguiente,
```bash
# crea una carpeta para los archivos de lemmy. La ubicación no importa, puede ser en cualquier sitio
mkdir /lemmy
cd /lemmy
# descarga los archivos de la configuración por defecto
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
# Establece los permisos correctos para la carpeta pictrs
mkdir -p volumes/pictrs
sudo chown -R 991:991 volumes/pictrs
```
Abre tu `docker-compose.yml`, y asegúrate de que `LEMMY_EXTERNAL_HOST` para `lemmy-ui` esta configurado en el host correcto.
```
- LEMMY_INTERNAL_HOST=lemmy:8536
- LEMMY_EXTERNAL_HOST=your-domain.com
- LEMMY_HTTPS=false
```
Si quieres una contraseña de base de datos diferente, también debes cambiarla en el `docker-compose.yml` **antes** de tu primera ejecución.
Después de esto, echa un vistazo al [archivo de configuración](configuration.md) llamado `lemmy.hjson`, y ajústalo, en particular el nombre de host, y posiblemente la contraseña de la base de datos. Luego ejecuta:
`docker-compose up -d`
puedes acceder a la interfaz de usuario de lemmy (lemmy-ui) en `http://localhost:1235`
Para hacer que Lemmy esté disponible fuera del servidor, necesitas configurar un proxy inverso, como Nginx. [Un ejemplo de configuración de ngix](https://raw.githubusercontent.com/LemmyNet/lemmy/main/ansible/templates/nginx.conf), podría ser establecido con:
```bash
wget https://raw.githubusercontent.com/LemmyNet/lemmy/main/ansible/templates/nginx.conf
# Remplaza los {{ valores }}
# El valor por defecto para lemmy_port es 8536
# El valor por defecto para lemmy_ui_port es 1235
sudo mv nginx.conf /etc/nginx/sites-enabled/lemmy.conf
```
También necesitarás configurar el TLS, por ejemplo con [Let's Encrypt](https://letsencrypt.org/). Después de esto necesitas reiniciar Nginx para recargar la configuración.
## Actualizar
Para actualizar a la versión más reciente, puedes cambiar manualmente la versión en `docker-compose.yml`. De manera alternativa puedes obtener la última versión de nuestro repositorio git:
```bash
wget https://raw.githubusercontent.com/LemmyNet/lemmy/main/docker/prod/docker-compose.yml
docker-compose up -d
```

View file

@ -0,0 +1,15 @@
# Otros Métodos de Instalación
**Descargo de responsabilidad:** los desarrolladores de Lemmy no recomiendan estos métodos de instalación. Si tienes algún problema, debes resolverlo tú mismo o preguntar a los respectivos autores. Si observas algún fallo de Lemmy en una instancia instalada de esta manera, menciónalo en el informe de fallos.
## Instalación de Lemmy sin Docker
Instrucciones para instalar Lemmy de forma nativa, sin depender de Docker.
[https://lemmy.ca/post/1066](https://lemmy.ca/post/1066)
## Instalación en Amazon Web Services (AWS)
Contiene las definiciones de infraestructura necesarias para desplegar Lemmy en [AWS](https://aws.amazon.com/) utilizando su [Kit de Desarrollo en la Nube](https://docs.aws.amazon.com/cdk/latest/guide/home.html).
[https://github.com/jetbridge/lemmy-cdk](https://github.com/jetbridge/lemmy-cdk)

View file

@ -0,0 +1,64 @@
# Solución de Problemas
Se muestran diferentes problemas que pueden ocurrir en una nueva instancia, y cómo resolverlos.
Muchas características de Lemmy dependen de una correcta configuración del proxy inverso. Asegúrate de que tu configuración es equivalente a nuestra [configuración de nginx](https://github.com/LemmyNet/lemmy/blob/main/ansible/templates/nginx.conf).
## Generalidades
### Registros
Para los problemas del frontend, revisa la [consola del navegador](https://webmasters.stackexchange.com/a/77337) para ver si hay mensajes de error.
Para los registros del servidor, ejecuta `docker-compose logs -f lemmy` en tu carpeta de instalación. También puedes hacer `docker-compose logs -f lemmy lemmy-ui pictrs` para obtener los registros de los diferentes servicios.
Si eso no da suficiente información, intenta cambiar la línea `RUST_LOG=error` en `docker-compose.yml` a `RUST_LOG=info` o `RUST_LOG=verbose`, y luego hacer `docker-compose restart lemmy`.
### La creación del usuario administrador no funciona
Asegúrate de que el websocket está funcionando correctamente, revisa la consola del navegador en busca de errores. En nginx, las siguientes cabeceras son importantes para esto:
```
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
```
### Error de limite de velocidad cuando muchos usuarios acceden al sitio
Revisa que las cabeceras `X-Real-IP` y `X-Forwarded-For` son enviadas a Lemmy por el proxy inverso. De lo contrario, se contarán todas las acciones hacia el limite de velocidad de la IP del proxy inverso. En nginx debería verse así:
```
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
```
## Federación
### Otras instancias no pueden obtener objetos locales (comunidad, publicaciones, etc)
Tu proxy reverso (ejemplo nginx) necesita reenviar las solicitudes con la cabecera `Accept: application/activity+json` al backend. Esto es manejado por las siguientes líneas:
```
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;
```
Puedes probar que funciona correctamente ejecutando los siguientes comandos, todos ellos deberían devolver JSON válido:
```
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
```
### La obtención de objetos remotos funciona, pero publicar/comentar en comunidades remotas falla
Comprueba que la [federación está permitida en ambas instancias](../federation/administration.md#instance-allowlist-and-blocklist).
Asegúrate también de que la hora está ajustada con precisión en tu servidor. Las actividades están firmadas con una marca de tiempo, y serán descartadas si se desvía más de 10 segundos.

View file

@ -0,0 +1,49 @@
# API reference
Lemmy has two, intertwined APIs:
- [WebSocket](https://join.lemmy.ml/api/index.html)
- [HTTP](http_api.md)
This page describes concepts that are common to both.
<!-- toc -->
- [Basic usage](#basic-usage)
- [Data types](#data-types)
* [Lemmy types](#lemmy-types)
* [Lower-level types](#lower-level-types)
- [Default rate limits](#default-rate-limits)
<!-- tocstop -->
## Basic usage
Request and response strings are in [JSON format](https://www.json.org).
## Data types
### Lemmy types
- [Source tables, that have the columns / fields](https://github.com/LemmyNet/lemmy-js-client/blob/main/src/interfaces/source.ts)
- [Aggregates (for things like scores)](https://github.com/LemmyNet/lemmy-js-client/blob/main/src/interfaces/aggregates.ts)
- [Views - The main lemmy return types](https://github.com/LemmyNet/lemmy-js-client/blob/main/src/interfaces/views.ts)
- [Request Forms / Responses are in this folder](https://github.com/LemmyNet/lemmy-js-client/tree/main/src/interfaces/api)
### Lower-level types
- `?` designates an option which may be omitted in requests and not be present in responses. It will be of type ***SomeType***.
- `[SomeType]` is a list which contains objects of type ***SomeType***.
- Times and dates are timestamp strings in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. Timestamps will be UTC, your client must do the UTC to local conversion.
## Default rate limits
These can be edited in your `lemmy.hjson` file, by copying the relevant section from [defaults.hjson](https://github.com/LemmyNet/lemmy/blob/main/config/defaults.hjson).
- 3 per hour for signups and community creation.
- 6 per hour for image posting.
- 6 per 10 minutes for post creation.
- 180 actions per minute for post voting and comment creation.
Everything else is not rate-limited.
**See also:** [rate limiting for custom front-ends](custom_frontend.md#rate-limiting).

View file

@ -0,0 +1,6 @@
# Client Development
- [Theming Guide](client_development/theming.md)
- [API reference](client_development/api_reference.md)
- [WebSocket API](https://join.lemmy.ml/api/index.html)
- [HTTP API](client_development/http_api.md)

View file

@ -0,0 +1,66 @@
# Creating a Custom Frontend
The backend and frontend are completely decoupled, and run in independent Docker containers. They only communicate over the [Lemmy API](api_reference.md), which makes it quite easy to write alternative frontends.
This creates a lot of potential for custom frontends, which could change much of the design and user experience of Lemmy. For example, it would be possible to create a frontend in the style of a traditional forum like [phpBB](https://www.phpbb.com/), or a question-and-answer site like [stackoverflow](https://stackoverflow.com/). All without having to think about database queries, authentification or ActivityPub, which you essentially get for free.
## Development
You can use any language to create a custom frontend. The easiest option would be forking our [official frontend](https://github.com/LemmyNet/lemmy-ui), [lemmy-lite](https://github.com/IronOxidizer/lemmy-lite), or the [lemmy-frontend-example](https://github.com/LemmyNet/lemmy-front-end-example). In any case, the principle is the same: bind to `LEMMY_EXTERNAL_HOST` (default: `localhost:8536`) and handle requests using the Lemmy API at `LEMMY_INTERNAL_HOST` (default: `lemmy:8536`). Also use `LEMMY_HTTPS` to generate links with the correct protocol.
The next step is building a Docker image from your frontend. If you forked an existing project, it should already include a `Dockerfile` and instructions to build it. Otherwise, try searching for your language on [dockerhub](https://hub.docker.com/), official images usually have build instructions in their readme. Build a Docker image with a tag, then look for the following section in `docker/dev/docker-compose.yml`:
```
lemmy-ui:
image: dessalines/lemmy-ui:v0.8.10
ports:
- "1235:1234"
restart: always
environment:
- LEMMY_INTERNAL_HOST=lemmy:8536
- LEMMY_EXTERNAL_HOST=localhost:8536
- LEMMY_HTTPS=false
depends_on:
- lemmy
```
All you need to do is replace the value for `image` with the tag of your own Docker image (and possibly the environment variables if you need different ones). Then run `./docker_update.sh`, and after compilation, your frontend will be available on `http://localhost:1235`. You can also make the same change to `docker/federation/docker-compose.yml` and run `./start-local-instances.bash` to test federation with your frontend.
## Deploy with Docker
After building the Docker image, you need to push it to a Docker registry (such as [dockerhub](https://hub.docker.com/)). Then update the `docker-compose.yml` on your server, replacing the `image` for `lemmy-ui`, just as described above. Run `docker-compose.yml`, and after a short wait, your instance will use the new frontend.
Note, if your instance is deployed with Ansible, it will override `docker-compose.yml` with every run, reverting back to the default frontend. In that case you should copy the `ansible/` folder from this project to your own repository, and adjust `docker-compose.yml` directly in the repo.
It is also possible to use multiple frontends for the same Lemmy instance, either using subdomains or subfolders. To do that, don't edit the `lemmy-ui` section in `docker-compose.yml`, but duplicate it, adjusting the name, image and port so they are distinct for each. Then edit your nginx config to pass requests to the appropriate frontend, depending on the subdomain or path.
## Translations
You can add the [lemmy-translations](https://github.com/LemmyNet/lemmy-translations) repository to your project as a [git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules). That way you can take advantage of same translations used in the official frontend, and you will also receive new translations contributed via weblate.
## Rate limiting
Lemmy does rate limiting for many actions based on the client IP. But if you make any API calls on the server side (eg in the case of server-side rendering, or javascript pre-rendering), Lemmy will take the IP of the Docker container. Meaning that all requests come from the same IP, and get rate limited much earlier. To avoid this problem, you need to pass the headers `X-REAL-IP` and `X-FORWARDED-FOR` on to Lemmy (the headers are set by our nginx config).
Here is an example snipped for NodeJS:
```javascript
function setForwardedHeaders(
headers: IncomingHttpHeaders
): { [key: string]: string } {
let out = {
host: headers.host,
};
if (headers['x-real-ip']) {
out['x-real-ip'] = headers['x-real-ip'];
}
if (headers['x-forwarded-for']) {
out['x-forwarded-for'] = headers['x-forwarded-for'];
}
return out;
}
let headers = setForwardedHeaders(req.headers);
let client = new LemmyHttp(httpUri, headers);
```

View file

@ -0,0 +1,116 @@
# Lemmy HTTP API
<!-- toc -->
- [Websocket vs HTTP API](#websocket-vs-http-api)
- [Examples](#examples)
* [TypeScript](#typescript)
* [Curl](#curl)
+ [GET](#get-example)
+ [POST](#post-example)
- [HTTP API exclusive features](#http-api-exclusive-features)
* [RSS/Atom feeds](#rss-atom-feeds)
* [Images](#images)
+ [Create (request)](#create-request)
+ [Create (response)](#create-response)
* [Delete](#delete)
<!-- tocstop -->
## WebSocket vs HTTP API
Lemmy's HTTP API is almost identical to its WebSocket API:
- **WebSocket API** needs `let send = { op: userOperation[op], data: form}` as shown in [the WebSocketAPI specification](https://join.lemmy.ml/api/index.html)
- **HTTP API** needs the form (data) at the top level, an HTTP operation (GET, PUT or POST) and endpoint (at `http(s)://host/api/v2/endpoint`). For example:
> `POST {username_or_email: X, password: X}`
For more information, see the [http.ts](https://github.com/LemmyNet/lemmy-js-client/blob/main/src/http.ts) file.
[The WebSocket API](https://join.lemmy.ml/api/index.html) should be regarded as the primary source for the HTTP API since it also provides information about how to form HTTP API calls.
## Examples
### TypeScript
```ts
async editComment(form: EditComment): Promise<CommentResponse> {
return this.wrapper(HttpType.Put, '/comment', form);
}
```
| Type | URL | Body type | Return type |
| --- | --- | --- | --- |
| `PUT` | `/comment` | `EditComment` | `CommentResponse` |
### Curl
**GET example**
```
curl "http://localhost:8536/api/v2/community/list?sort=Hot"`
```
**POST example**
```
curl -i -H \
"Content-Type: application/json" \
-X POST \
-d '{
"comment_id": 374,
"score": 1,
"auth": eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MiwiaXNzIjoidGVzdC5sZW1teS5tbCJ9.P77RX_kpz1a_geY5eCp29sl_5mAm-k27Cwnk8JcIZJk
}' \
http://localhost:8536/api/v2/comment/like
```
## HTTP API exclusive features
These features cannot be accessed from the WebSocket API:
- [RSS/Atom feeds](#rss-atom-feeds)
- [Images](#images)
### RSS/Atom feeds
- All - `/feeds/all.xml?sort=Hot`
- Community - `/feeds/c/community-name.xml?sort=Hot`
- User - `/feeds/u/user-name.xml?sort=Hot`
### Images
Lemmy forwards image requests to a locally running Pictrs.
`GET /pictrs/image/{filename}?format={webp, jpg, ...}&thumbnail={96}`
*Format and thumbnail are optional.*
#### Create (request)
Uploaded content must be valid multipart/form-data with an image array located within the images[] key.
`POST /pictrs/image`
#### Create (response)
```
{
"files": [
{
"delete_token": "{token}",
"file": "{file}.jpg"
}
],
"msg": "ok"
}
```
#### Delete
`GET /pictrs/image/delete/{delete_token}/{file}`
# Note
This documentation may lag behind the actual [API endpoints](https://github.com/LemmyNet/lemmy-js-client/blob/main/src/http.ts) and the API itself should be considered unstable (since it may change at any time).

View file

@ -0,0 +1,19 @@
# Theming Guide
Lemmy uses [Bootstrap v4](https://getbootstrap.com/), and very few custom css classes, so any bootstrap v4 compatible theme should work fine.
## Creating
- Use a tool like [bootstrap.build](https://bootstrap.build/) to create a bootstrap v4 theme. Export the `bootstrap.min.css` once you're done, and save the `_variables.scss` too.
## Testing
- To test out a theme, you can either use your browser's web tools, or a plugin like stylus to copy-paste a theme, when viewing Lemmy.
## Adding
1. Fork the [lemmy-ui](https://github.com/LemmyNet/lemmy-ui).
1. Copy `{my-theme-name}.min.css` to `src/assets/css/themes`. (You can also copy the `_variables.scss` here if you want).
1. Go to `src/shared/utils.ts` and add `{my-theme-name}` to the themes list.
1. Test locally
1. Do a pull request with those changes.

35
src/es/code_of_conduct.md Normal file
View file

@ -0,0 +1,35 @@
# Código de Conducta
- Nos comprometemos a proporcionar un entorno seguro, positivo y acogedor para todos, independientemente de su nivel de experiencia, identidad y expresión de género, orientación sexual, discapacidad, apariencia personal, tamaño corporal, raza, etnia, edad, religión, nacionalidad, u otra característica similar.
- Evita el uso de apodos abiertamente sexuales u otros alias que puedan dificultar un entorno seguro, positivo y acogedor para todos.
- Sé respetuoso y educado. No es necesario ser grosero o antipático.
- Respeta el hecho de que la gente tiene diferencias de parecer, y de que cada opción de diseño o implementación tiene pros y contras, y costes diversos. Rara vez hay una respuesta correcta.
- Evita las críticas imprecisas en lo posible. Si tienes ideas firmes con las que quieres expermientar, crea un fork y comprueba si funcionan.
- Se te apartará de interaccionar con el resto si insultas, menosprecias o acosas a alguien. Este comportamiento no se admite. Nuestra interpretación del término "acoso" (harassment) está en línea con la definición del [Citizen Code of Conduct](https://github.com/stumpsyn/policies/blob/master/citizen_code_of_conduct.md); si tienes dudas respecto a qué se incluye en este concepto, lee dicha definición. En particular, no toleramos comportamientos que excluyan a grupos marginados socialmente.
- El acoso en privado tampoco es aceptable. Seas quien seas, si crees que has sido o estás siendo acosado o te están haciendo sentir incómodo, contacta con uno de los administradores del canal o cualquiera en el equipo de moderación de Lemmy inmediatamente. Ya seas un contribuidor regular o un recién llegado, queremos hacer de esta comunidad un lugar seguro para ti y te ayudaremos.
- De igual modo, el spam, el troleo, la provocación (flaming y baiting) u otros comportamientos para atraer atención no se permiten.
[**Contacta con el Equipo de Moderación en Mastodon**](https://mastodon.social/@LemmyDev)
[**Envía un correo electrónico al Equipo de Moderación**](mailto:contact@lemmy.ml)
## Moderación
Estas son las políticas para hacer valer los estándares de conducta de nuestra comunidad. Si crees que un hilo necesita ser moderado, contacta con el equipo de moderación de Lemmy.
1. Los comentarios que violen los estándares de conducta de Rust, incluyendo comentarios hirientes, opresivos, exclusivos o de odio, no están permitidos. (Las imprecaciones están permitidas, pero nunca contra otro usuario y nunca con contenido de odio).
2. Los comentarios que los moderadores crean inapropiados, estén recogidos en el código de conducta o no, tampoco están permitidos.
3. Los moderadores responderán a dichos comentarios con un aviso en primera instancia.
4. Si el aviso es ignorado, el usuario será expulsado temporalmente del canal de comunicación para que se calme.
5. Si el usuario retorna y continúa causando problemas, se le expulsará permanentemente.
6. Los moderadores pueden elegir según su criterio levantar la expulsión al usuario si se trata de una primera ofensa y este se disculpa de forma genuina ante el afectado.
7. Si crees que un moderador ha expulsado a alguien de forma injustificada, tráta el tema con dicho moderador u otro, en privado. Las discusiones sobre expulsiones dentro del propio canal no están permitidas.
8. Los moderadores están sujetos a un estándar de conducta más exigente que el del resto de miembros de la comunidad. Si un moderador crea una situación inapropiada, debería esperar más severidad que para con el resto.
En la comunidad Lemmy aspiramos a superarnos en cuanto cómo nos tratamos entre nosotros. No intentes mantenerte intachable solo en lo técnico, trata de dar lo mejor de tí. En particular, evita los temas sensibles u ofensivos, especialmente si no guardan relación: muy a menudo llevan a disputas innecesarias, agravios y pérdida de confianza; aún peor, pueden apartar a gente de la comunidad por completo.
Si alguien se muestra en desacuerdo con algo que digas o hagas, resiste el reflejo de ponerte a la defensiva. Simplemente para de hacer lo que fuera que provocó la queja y discúlpate. Incluso si crees que ha habido un malentendido o acusado injustamente, es probable que hubiera algo que podrías haber comunicado mejor; recuerda que es tu responsabilidad hacer que los demás se sientan cómodos. Todos queremos llevarnos bien y todos estamos aquí principalmente porque queremos hablar de una tecnología maravillosa. Te darás cuenta de que la gente tiende a asumir buena fé y a perdonar siempre que te ganes su confianza.
Las políticas de moderación listadas más arriba se aplican en todos los canales oficiales de Lemmy; incluyendo los repositorios git bajo [github.com/LemmyNet](https://github.com/LemmyNet) y [yerbamate.ml/LemmyNet](https://yerbamate.ml/LemmyNet), el [canal en Matrix](https://matrix.to/#/!BZVTUuEiNmRcbFeLeI:matrix.org); [lemmy.ml](https://lemmy.ml) y otras instancias bajo ese dominio. En otros proyectos que adopten el código de conducta de Lemmy, contacta con sus encargados para su aplicación. Si quieres usar este código de conducta en tu propio proyecto, valora si mencionar tu política de moderación explícitamente o hacer una copia con tu propia política de moderación para evitar confusiones.
Adaptado a partir del [Código de Conducta de Rust](https://www.rust-lang.org/es/policies/code-of-conduct), que se basa en la [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) así como del [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).

View file

@ -0,0 +1,40 @@
# Contributing
Information about contributing to Lemmy, whether it is translating, testing, designing or programming.
## Issue tracking / Repositories
- [GitHub (for issues and pull requests)](https://github.com/LemmyNet/lemmy)
- [Gitea (only for pull requests)](https://yerbamate.ml/LemmyNet/lemmy)
- [Codeberg](https://codeberg.org/LemmyNet/lemmy)
## Translating
Check out [Lemmy's Weblate](https://weblate.yerbamate.ml/projects/lemmy/) for translations. You can also help by [translating this documentation](https://github.com/LemmyNet/lemmy-docs#adding-a-new-language).
## Architecture
### Front end
- The front end is written in `typescript`, using a react-like framework called [inferno](https://infernojs.org/). All UI elements are reusable `.tsx` components.
- The front end repository is [lemmy-ui](https://github.com/LemmyNet/lemmy-ui).
- The routes are at `src/shared/routes.ts`.
- The components are located in `src/shared/components`.
### Back end
- The back end is written in `rust`, using `diesel`, and `actix`.
- The server source code is split into main sections in `src`. These include:
- `db` - The low level database actions.
- Database additions are done using diesel migrations. Run `diesel migration generate xxxxx` to add new things.
- `api` - The high level user interactions (things like `CreateComment`)
- `routes` - The server endpoints .
- `apub` - The activitypub conversions.
- `websocket` - Creates the websocket server.
## Linting / Formatting
- Every front and back end commit is automatically formatted then linted using `husky`, and `lint-staged`.
- Rust with `cargo fmt` and `cargo clippy`.
- Typescript with `prettier` and `eslint`.

View file

@ -0,0 +1,32 @@
# Docker Development
## Dependencies (on Ubuntu)
```bash
sudo apt install git docker-compose
sudo systemctl start docker
git clone https://github.com/LemmyNet/lemmy
```
## Running
```bash
cd docker/dev
./docker_update.sh
```
and go to http://localhost:1235.
*Note: many features (like docs and pictures) will not work without using an nginx profile like that in `ansible/templates/nginx.conf`.
To speed up the Docker compile, add the following to `/etc/docker/daemon.json` and restart Docker.
```
{
"features": {
"buildkit": true
}
}
```
If the build is still too slow, you will have to use a
[local build](local_development.md) instead.

View file

@ -0,0 +1,69 @@
# Federation Development
## Running locally
Install the dependencies as described in [Docker development](docker_development.md). Then run the following
```bash
cd docker/federation
./start-local-instances.bash
```
The federation test sets up 5 instances:
Instance | Username | Location | Notes
--- | --- | --- | ---
lemmy-alpha | lemmy_alpha | [127.0.0.1:8540](http://127.0.0.1:8540) | federated with all other instances
lemmy-beta | lemmy_beta | [127.0.0.1:8550](http://127.0.0.1:8550) | federated with all other instances
lemmy-gamma | lemmy_gamma | [127.0.0.1:8560](http://127.0.0.1:8560) | federated with all other instances
lemmy-delta | lemmy_delta | [127.0.0.1:8570](http://127.0.0.1:8570) | only allows federation with lemmy-beta
lemmy-epsilon | lemmy_epsilon | [127.0.0.1:8580](http://127.0.0.1:8580) | uses blocklist, has lemmy-alpha blocked
You can log into each using the instance name, and `lemmy` as the password, IE (`lemmy_alpha`, `lemmy`).
To start federation between instances, visit one of them and search for a user, community or post, like this. Note that
the Lemmy backend runs on a different port than the frontend, so you have to increment the port number from
the URL bar by one.
- `!main@lemmy-alpha:8541`
- `http://lemmy-beta:8551/post/3`
- `@lemmy-gamma@lemmy-gamma:8561`
Firefox containers are a good way to test them interacting.
## Running on a server
Note that federation is currently in alpha. **Only use it for testing**, not on any production server, and be aware that turning on federation may break your instance.
Follow the normal installation instructions, either with [Ansible](../administration/install_ansible.md) or
[manually](../administration/install_docker.md). Then replace the line `image: dessalines/lemmy:v0.x.x` in
`/lemmy/docker-compose.yml` with `image: dessalines/lemmy:federation`. Also add the following in
`/lemmy/lemmy.hjson`:
```
federation: {
enabled: true
tls_enabled: true,
allowed_instances: example.com,
}
```
Afterwards, and whenever you want to update to the latest version, run these commands on the server:
```
cd /lemmy/
sudo docker-compose pull
sudo docker-compose up -d
```
## Security Model
- HTTP signature verify: This ensures that activity really comes from the activity that it claims
- check_is_apub_valid : Makes sure its in our allowed instances list
- Lower level checks: To make sure that the user that creates/updates/removes a post is actually on the same instance as that post
For the last point, note that we are *not* checking whether the actor that sends the create activity for a post is
actually identical to the post's creator, or that the user that removes a post is a mod/admin. These things are checked
by the API code, and its the responsibility of each instance to check user permissions. This does not leave any attack
vector, as a normal instance user cant do actions that violate the API rules. The only one who could do that is the
admin (and the software deployed by the admin). But the admin can do anything on the instance, including send activities
from other user accounts. So we wouldnt actually gain any security by checking mod permissions or similar.

View file

@ -0,0 +1,85 @@
### Install build requirements
#### Ubuntu
```
sudo apt install git cargo libssl-dev pkg-config libpq-dev yarn curl gnupg2 espeak
# install yarn
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update && sudo apt install yarn
```
#### macOS
Install Rust using [the recommended option on rust-lang.org](https://www.rust-lang.org/tools/install) (rustup).
Then, install [Homebrew](https://brew.sh/) if you don't already have it installed.
Finally, install Node and Yarn.
```
brew install node yarn
```
### Get the back end source code
```
git clone https://github.com/LemmyNet/lemmy.git
# or alternatively from gitea
# git clone https://yerbamate.ml/LemmyNet/lemmy.git
```
### Build the backend (Rust)
```
cargo build
# for development, use `cargo check` instead)
```
### Get the front end source code
```
git clone https://github.com/LemmyNet/lemmy-ui.git --recurse-submodules
```
### Setup postgresql
#### Ubuntu
```
sudo apt install postgresql
sudo systemctl start postgresql
# Either execute db-init.sh, or manually initialize the postgres database:
sudo -u postgres psql -c "create user lemmy with password 'password' superuser;" -U postgres
sudo -u postgres psql -c 'create database lemmy with owner lemmy;' -U postgres
export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy
```
#### macOS
```
brew install postgresql
brew services start postgresql
/usr/local/opt/postgres/bin/createuser -s postgres
# Either execute db-init.sh, or manually initialize the postgres database:
psql -c "create user lemmy with password 'password' superuser;" -U postgres
psql -c 'create database lemmy with owner lemmy;' -U postgres
export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy
```
### Run a local development instance
```
cd lemmy
cargo run
```
Then open [localhost:1235](http://localhost:1235) in your browser. To reload back-end changes, you will have to rerun `cargo run`. You can use `cargo check` as a faster way to find compilation errors.
To do front end development:
```
cd lemmy-ui
yarn
yarn dev
```
and go to [localhost:1234](http://localhost:1234). Front end saves should rebuild the project.
Note that this setup doesn't include image uploads or link previews (provided by pict-rs and
iframely respectively). If you want to test those, you should use the
[Docker development](docker_development.md).

View file

@ -0,0 +1,29 @@
### Tests
#### Rust
After installing [local development dependencies](local_development.md), run the
following commands:
```bash
psql -U lemmy -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
./test.sh
```
### Federation
Install the [Local development dependencies](local_development.md), and add the following lines to `/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
```
Then use the following script to run the tests:
```
cd api_tests
./run-federation-test.bash
```

View file

@ -0,0 +1,28 @@
# Federation Administration
Note: ActivityPub federation is still under development. We recommend that you only enable it on test instances for now.
To enable federation, change the setting `federation.enabled` to `true` in `lemmy.hjson`, and restart Lemmy.
Federation does not start automatically, but needs to be triggered manually through the search. To do this you have to enter a reference to a remote object, such as:
- `!main@lemmy.ml` (Community)
- `@nutomic@lemmy.ml` (User)
- `https://lemmy.ml/c/programming` (Community)
- `https://lemmy.ml/u/nutomic` (User)
- `https://lemmy.ml/post/123` (Post)
- `https://lemmy.ml/comment/321` (Comment)
For an overview of how federation in Lemmy works on a technical level, check out our [Federation Overview](contributing_federation_overview.md).
## Instance allowlist and blocklist
The federation section of Lemmy's config has two variables `allowed_instances` and `blocked_instances`. These control which other instances Lemmy will federate with. Both settings take a comma separated list of domains, eg `lemmy.ml,example.com`. You can either change those settings via `/admin`, or directly on the server filesystem.
It is important to note that these settings only affect sending and receiving of data between instances. If allow federation with a certain instance, and then remove it from the allowlist, this will not affect previously federated data. These communities, users, posts and comments will still be shown. They will just not be updated anymore. And even if an instance is blocked, it can still fetch and display public data from your instance.
By default, both `allowed_instances` and `blocked_instances` values are empty, which means that Lemmy will federate with every compatible instance. We do not recommend this, because the moderation tools are not yet ready to deal with malicious instances.
What we do recommend is putting a list of trusted instances into `allowed_instances`, and only federating with those. Note that both sides need to add each other to their `allowed_instances` to allow two-way federation.
Alternatively you can also use blocklist based federation. In this case, add the domains of instances you do *not* want to federate with. You can only set one of `allowed_instances` and `blocked_instances`, as setting both doesn't make sense.

View file

@ -0,0 +1,780 @@
# Protocolo de la Federación Lemmy
El protocolo de Lemmy (o Protocolo de la Federación Lemmy) es un subconjunto estricto del [Protocolo ActivityPub](https://www.w3.org/TR/activitypub/). Cualquier desviación del protocolo ActivityPub es un error (bug) en Lemmy o en esta documentación (o ambos).
Este documento está dirigido a desarrolladores que están familiarizados con los protocolos ActivityPub y ActivityStreams. Ofrece un esquema detallado de los actores, objetos y actividades utilizados por Lemmy.
Antes de leerlo, echa un vistazo a nuestra [Visión General de la Federación](overview.md) para hacerte una idea de cómo funciona la federación de Lemmy a alto nivel.
Lemmy todavía no sigue la especificación ActivityPub en todos los aspectos. Por ejemplo, no establecemos un contexto válido indicando nuestros campos de contexto. También ignoramos campos como la bandeja de entrada `inbox`, la bandeja de salida `outbox` o los puntos finales `endpoints` de los actores remotos, y asumimos que todo es Lemmy. Para una visión general de las desviaciones, lea el tema [#698](https://github.com/LemmyNet/lemmy/issues/698). Serán corregidas en un futuro próximo.
Lemmy también es realmente inflexible cuando se trata de actividades y objetos entrantes. Tienen que ser exactamente idénticos a los ejemplos de abajo. Cosas como tener un array en lugar de un solo valor, o un ID de objeto en lugar del objeto completo resultará en un error.
En las siguientes tablas, "obligatorio" se refiere a si Lemmy aceptará o no una actividad entrante sin este campo. El propio Lemmy siempre incluirá todos los campos no vacíos.
<!-- toc -->
- [Contexto](#context)
- [Actores](#actors)
* [Comunidad](#community)
+ [Bandeja de salida de la Comunidad](#community-outbox)
+ [Seguidores de la Comunidad](#community-followers)
+ [Moderadores de la Comunidad](#community-moderators)
* [Usuario](#user)
+ [Bandeja de salida del Usuario](#user-outbox)
- [Objectos](#objects)
* [Publicación](#post)
* [Comentario](#comment)
* [Mensaje privado](#private-message)
- [Actividades](#activities)
* [Usuario a Comunidad](#user-to-community)
+ [Seguir](#follow)
+ [Dejar de seguir](#unfollow)
+ [Crear o Actualizar Publicación](#create-or-update-post)
+ [Crear o Actualizar Comentario](#create-or-update-comment)
+ [Me gusta Publicación o Comentario](#like-post-or-comment)
+ [No me gusta Publicación o Comentario](#dislike-post-or-comment)
+ [Eliminar Publicación o Comentario](#delete-post-or-comment)
+ [Remover Publicación o Comentario](#remove-post-or-comment)
+ [Deshacer](#undo)
* [Comunidad a Usuario](#community-to-user)
+ [Aceptar Seguir](#accept-follow)
+ [Anunciar](#announce)
+ [Remover o Eliminar Comunidad](#remove-or-delete-community)
+ [Restaurar Comunidad Removida o Eliminada](#restore-removed-or-deleted-community)
* [Usuario a Usuario](#user-to-user)
+ [Crear o Actualizar Mensaje Privado](#create-or-update-private-message)
+ [Eliminar Mensaje Privado](#delete-private-message)
+ [Deshacer la Eliminación del Mensaje Privado](#undo-delete-private-message)⏎
<!-- tocstop -->
## Contexto
```json
{
"@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"
]
}
```
El contexto es identico para todas las actividades y objetos.
## Actores
### Comunidad
Un actor automatizado. Los usuarios pueden enviarle mensajes o comentarios, que la comunidad reenvía a sus seguidores en forma de Anuncio `Announce`.
Envía actividades al usuario: Aceptar/Seguir `Accept/Follow`, Anunciar `Announce`.
Recibe actividades del usuario: Seguir `Follow`, Deshacer/Seguir `Undo/Follow`, Crear `Create`, Actualizar `Update`, Me gusta `Like`, No me gusta `Dislike`, Remover `Remove` (sólo admin/mod), Eliminar `Delete` (sólo creador), Deshacer `Undo` (sólo para acciones propias).
```json
{
"@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"
}
}
```
| Nombre del Campo | Obligatorio | Descripción |
|---|---|---|
| `preferredUsername` | si | Nombre del actor |
| `name` | si | Titulo de la comunidad |
| `sensitive` | si | True indica que todas las publicaciones en la comunidad son nsfw |
| `attributedTo` | si | Primero el creador de la comunidad, luego el resto de los moderadores |
| `content` | no | Texto para la barra lateral de lac comunidad, que suele contener una descripción y normas |
| `icon` | no | Icono que aparece junto al nombre de la comunidad |
| `image` | no | Imagen de banner, mostrada en la parte superior de la página de la comunidad |
| `inbox` | no | URL de la bandeja de entrada de ActivityPub |
| `outbox` | no | URL de la bandeja de salida de ActivityPub, sólo contiene las últimas 20 publicaciones sin comentarios, votos u otras actividades |
| `followers` | no | URL de la colección de seguidores, sólo contiene el número de seguidores, sin referencias a seguidores individuales |
| `endpoints` | no | Contiene la URL de la bandeja de entrada compartida |
| `published` | no | Fecha de creación de la comunidad |
| `updated` | no | Fecha de la última modificación de la comunidad |
| `publicKey` | si | La clave pública utilizada para verificar las firmas de este actor |
#### Bandeja de Salida de la Comunidad
```json
{
"@context": ...,
"items": [
...
],
"totalItems": 3,
"id": "https://enterprise.lemmy.ml/c/main/outbox",
"type": "OrderedCollection"
}
```
La bandeja de salida sólo contiene las actividades Crear/Publicación `Create/Post` por ahora.
#### Seguidores de la Comunidad
```json
{
"totalItems": 2,
"@context": ...,
"id": "https://enterprise.lemmy.ml/c/main/followers",
"type": "Collection"
}
```
La colección de seguidores sólo se utiliza para exponer el número de seguidores. Los ID de los actores no se incluyen, para proteger la privacidad de los usuarios.
#### Moderadores de la Comunidad
```json
{
"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"
}
```
### Usuario
Una persona, interactúa principalmente con la comunidad en la que envía y recibe publicaciones/comentarios. También puede crear y moderar comunidades, y enviar mensajes privados a otros usuarios.
Envía actividades a la Comunidad: Seguir `Follow`, Deshacer/Seguir `Undo/Follow`, Crear `Create`, Actualizar `Update`, Me gusta `Like`, No me gusta `Dislike`, Remover `Remove` (sólo admin/mod), Eliminar `Delete` (sólo creador), Deshacer `Undo` (sólo para acciones propias)
Recibe actividades de la Comunidad: Aceptar/Seguir `Accept/Follow`, Anunciar `Announce`.
Envía y recibe actividades de/para otros usuarios: Crear/Nota `Create/Note`, Actualizar/Nota `Update/Note`, Eliminar/Nota `Delete/Note`, Deshacer/Eliminar/Nota `Undo/Delete/Note` (todas las relacionadas con mensajes privados).
```json
{
"@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"
}
}
```
| Nombre del Campo | Obligatorio | Descripción |
|---|---|---|
| `preferredUsername` | si | Nombre del actor |
| `name` | no | El nombre para mostrar del usuario |
| `content` | no | La biografía del usuario |
| `icon` | no | El avatar del usuario, que aparece junto al nombre del usuario |
| `image` | no | Banner del usuario, mostrada en la parte superior del perfil |
| `inbox` | no | URL de la bandeja de entrada de ActivityPub |
| `endpoints` | no | Contiene la URL de la bandeja de entrada compartida |
| `published` | no | Fecha de registro del usuario |
| `updated` | no | Fecha de la última actualización del perfil del usuario |
| `publicKey` | si | La clave pública utilizada para verificar las firmas de este actor |
#### Bandeja de salida del Usuario
```json
{
"items": [],
"totalItems": 0,
"@context": ...,
"id": "http://lemmy-alpha:8541/u/lemmy_alpha/outbox",
"type": "OrderedCollection"
}
```
La bandeja de salida del usuario no está implementada todavía, y es sólo un marcador de posición para las implementaciones de ActivityPub que lo requieren.
## Objetos
### Publicación
Una página con título, y contenido opcional de URL y texto. La URL suele llevar a una imagen, en cuyo caso se incluye una miniatura. Cada entrada pertenece exactamente a una comunidad.
```json
{
"@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"
}
```
| Nombre del Campo | Obligatorio | Description |
|---|---|---|
| `attributedTo` | si | ID del usuario que creó esta publicación |
| `to` | si | ID de la comunidad en la que se publicó |
| `name` | si | Título de la publicación |
| `content` | no | Cuerpo de la publicación |
| `url` | no | Un enlace arbitrario para compartir |
| `image` | no | Miniatura para la `url`, sólo aparece si es un enlace de imagen |
| `commentsEnabled` | si | False indica que la publicación está bloqueada, y no se pueden añadir comentarios |
| `sensitive` | si | True marca la publicación como NSFW,difumina la miniatura y la oculta a los usuarios con la configuración NSFW desactivada |
| `stickied` | si | True significa que se muestra en la parte superior de la comunidad |
| `published` | no | Fecha de creación de la publicación |
| `updated` | no | Fecha en la que se editó la publicación (no está presente si nunca se editó) |
### Comentario
Una respuesta a una publicación, o una respuesta a otro comentario. Contiene sólo texto (incluyendo referencias a otros usuarios o comunidades). Lemmy muestra los comentarios en una estructura de árbol.
```json
{
"@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"
}
```
| Nombre del Campo | Obligatorio | Descripción |
|---|---|---|
| `attributedTo` | si | ID del usuario que creó el comentario |
| `to` | si | Comunidad donde se hizo el comentario |
| `content` | si | El texto del comentario |
| `inReplyTo` | si | ID de la publicación donde se hizo el comentario, y el comentario padre. Si este es un comentario de nivel superior, `inReplyTo` sólo contiene la publicación |
| `published` | no | Fecha de creación del comentario |
| `updated` | no | Fecha en la que se editó la publicación (no está presente si nunca se editó) |
### Mensaje Privado
Un mensaje directo de un usuario a otro. No puede incluir usuarios adicionales. Todavía no se ha implementado el hilo, por lo que falta el campo `inReplyTo`.
```json
{
"@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"
}
```
<!-- Fix table in english version --->
| Nombre del Campo | Obligatorio | Descripción |
|---|---|---|
| `attributedTo` | | ID del usuario que creo este mensaje |
| `to` | | ID del destinatario |
| `content` | si | El texto del mensaje privado |
| `published` | no | Fecha de creación del mensaje |
| `updated` | no | Fecha en la que se editó la publicación (no está presente si nunca se editó) |
## Actividades
### Usuario a Comunidad
#### Seguir
Cuando el usuario hace clic en "Suscribirse" en una comunidad, se envía un `Follow`. La comunidad responde automáticamente con un `Accept/Follow`.
```json
{
"@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"
}
```
| Nombre del Campo | Obligatorio | Descripción |
|---|---|---|
| `actor` | si | El usuario que envía la solicitud de seguimiento `Follow` |
| `object` | si | La comunidad a seguir |
#### Dejar de Seguir
Al pulsar el botón de "dar de baja" en una comunidad se envía un `Undo/Follow`. La comunidad retira al usuario de su lista de seguidores tras recibirlo.
```json
{
"@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"
}
}
```
#### Crear o Actualizar Publicación
Cuando un usuario crea una nueva publicación, ésta se envía a la comunidad correspondiente. La edición de una publicación previamente creada envía una actividad casi idéntica, excepto que el tipo `type` es Actualizar `Update`. Todavía no admitimos las menciones en las publicaciones.
```json
{
"@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": ...
}
```
| Nombre del Campo | Obligatorio | Descripción |
|---|---|---|
| `type` | si | Crear `Create` o Actualizar `Update` |
| `cc` | si | Comunidad donde se hizo la publicación |
| `object` | si | La publicación que se crea |
#### Crear o Actulizar Comentario
Una respuesta a una publicación, o a otro comentario. Puede contener menciones a otros usuarios. La edición de una publicación previamente creada envía una actividad casi idéntica, excepto que el tipo `type` es Actualizar `Update`.
```json
{
"@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": ...
}
```
| Nombre del Campo | Obligatorio | Descripción |
|---|---|---|
| `tag` | no | Lista de los usuarios que se mencionan en el comentario (como `@usuario@ejemplo.com`) |
| `cc` | si | Comunidad en la que se hace la publicación, el usuario al que se responde (creador de la publicación/comentario principal), así como los usuarios mencionados |
| `object` | si | El comentario que se crea |
#### Me gusta Publicación o Comentario
Un voto positivo para una publicación o un comentario
```json
{
"@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"
}
```
| Nombre del Campo | Obligatorio | Descripción|
|---|---|---|
| `cc` | si | ID de la comunidad en la que se encuentra la publicación/comentario |
| `object` | si | La publicación o comentario que se ha votado |
#### No me gusta Publicación o Comentario
Un voto negativo para una publicación o un comentario
```json
{
"@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"
}
```
| Nombre del Campo | Obligatorio | Descripción|
|---|---|---|
| `cc` | si | ID de la comunidad en la que se encuentra la publicación/comentario |
| `object` | si | La publicación o comentario que se ha votado |
#### Eliminar Publicación o Comentario
Elimina una publicación o comentario creado anteriormente. Esto sólo lo puede hacer el creador original de esa publicación/comentario.
```json
{
"@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"
}
```
| Nombre del Campo | Obligatorio | Descripción|
|---|---|---|
| `cc` | si | ID de la comunidad en la que se encuentra la publicación/comentario |
| `object` | si | La publicación o comentario que se está eliminando |
#### Remover Publicación o Comentario
Remover una publicación o un comentario. Esto sólo puede hacerlo un mod de la comunidad, o un administrador en la instancia donde se aloja la comunidad.
```json
{
"@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"
}
```
| Nombre del Campo | Obligatorio | Descripción|
|---|---|---|
| `cc` | si | ID de la comunidad en la que se encuentra la publicación/comentario |
| `object` | si | La publicación o comentario que se está removiendo |
#### Deshacer
Revierte una actividad anterior, sólo puede hacerlo el actor `actor` del objeto `object`. En caso de un `Like` o `Dislike`, se vuelve a cambiar el conteo de votos. En el caso de un `Delete`o `Remove`, se restablece la publicación/comentario. El objeto se regenera desde cero, por lo que el ID de la actividad y otros campos son diferentes.
```json
{
"@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": ...
}
```
| Nombre del Campo | Obligatorio | Descripción |
|---|---|---|
| `object` | si | Cualquier actividad `Like`, `Dislike`, `Delete` o `Remove` tal como se ha descrito anteriormente |
#### Agregar Moderador
Añade un nuevo mod (registrado en `ds9.lemmy.ml`) a la comunidad `!main@enterprise.lemmy.ml`. Tiene que ser enviado por un mod de la comunidad existente.
```json
{
"@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"
}
```
#### Remover Moderador
Remueve un mod existente de la comunidad. Tiene que ser enviado por un mod de la comunidad existente.
```json
{
"@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"
}
```
### Comunidad a Usuario
#### Aceptar Seguir
Enviado automáticamente por la comunidad en respuesta a un `Follow`. Al mismo tiempo, la comunidad añade a este usuario a su lista de seguidores.
```json
{
"@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"
}
}
```
| Nombre del Campo | Obligatorio | Descripción |
|---|---|---|
| `actor` | si | La misma comunidad que en la actividad `Follow` |
| `to` | no | ID del usuario que envió el `Follow` |
| `object` | si | La actividad de `Follow` enviada anteriormente |
#### Anuncio
Cuando la comunidad recibe una actividad publicación o comentario, lo envuelve en un anuncio `Announce` y lo envía a todos los seguidores.
```json
{
"@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": ...
}
```
| Nombre del Campo | Obligatorio | Descripción |
|---|---|---|
| `object` | si | Cualquier actividad `Create`, `Update`, `Like`, `Dislike`, `Delete`, `Remove` o `Undo` tal como se ha descrito en la sección [Usuario a Comunidad](#user-to-community) |
#### Remover o Eliminar Comunidad
Un administrador de instancia puede remover la comunidad, o un mod puede eliminarla.
```json
{
"@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"
}
```
| Nombre del Campo| Obligatorio | Descripción |
|---|---|---|
| `type` | si | Remover `Remove` o Eliminar `Delete` |
#### Restaurar Comunidad Removida o Eliminada
Revierte la remoción o eliminación
```json
{
"@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"
]
}
}
```
| Nombre del Campo | Obligatorio | Descripción|
|---|---|---|
| `object.type` | si | Remover `Remove` o Eliminar `Delete` |
### Usuario a Usuario
#### Crear o Actualizar Mensaje Privado
Crea un nuevo mensaje privado entre dos usuarios.
```json
{
"@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": ...
}
```
| Nombre del Campo | Obligatorio| Descripción |
|---|---|---|
| `type` | si | Crear `Create` o Actualizar `Update` |
| `object` | si | Un [Mensaje Privado](#private-message) |
#### Eliminar Mensaje Privado
Elimina un mensaje privado previo
```json
{
"@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"
}
```
#### Deshacer la Eliminación del Mensaje Privado
Restaura un mensaje privado previamente eliminado. El objeto `object` se regenera desde cero, por lo que el ID de actividad y otros campos son diferentes.
```json
{
"@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": ...
}
```

View file

@ -0,0 +1,123 @@
# Visión General de la Federación
Este documento es para cualquiera que quiera saber como funciona la federación en Lemmy, sin ser demasiado técnico. Se pretende proporcionar una visión general de alto nivel de la federación ActivityPub en Lemmy. Si estás implementando ActivityPub por ti mismo y quieres ser compatible con Lemmy, lee nuestro
[esquema de la API de ActivityPub](contributing_apub_api_outline.md).
## Convenciones de la documentación
Para mantener las cosas simples, a veces verás cosas formateadas como Crear/Nota `Create/Note` o Eliminar/Evento `Delete/Event` o Deshacer/Seguir `Undo/Follow`. La cosa antes de la barra es la Actividad, y la cosa después de la barra es el Objeto dentro de la Actividad, una propiedad del objeto `objet`. Así que estos deben ser leídos como sigue:
* `Create/Note`: una actividad `Create` que contiene una `Note` en el campo del `object`
* `Delete/Event`: una actividad `Delete` que contiene un `Event` en el campo del `object`
* `Undo/Follow`: una actividad `Undo` que contiene un `Follow` en el campo del `object`
En Lemmy utilizamos algunos términos específicos para referirnos a los elementos de ActivityPub. Son esencialmente nuestras implementaciones específicas de conceptos conocidos de ActivityPub:
- Comunidad (community): Grupo `Group`
- Usuario (user): Persona `Person`
- Publicación (post): Página `Page`
- Comentario (comment): Nota `Note`
Este documento tiene tres secciones principales:
* __Filosofía de la federación:__ expone el modelo general de cómo se debe federar.
* __Actividades del usuario:__ describen las acciones que un usuario puede realizar para interactuar.
* __Actividades de la comunidad:__ describen lo que hace la comunidad en respuesta a determinadas acciones de los usuarios.
## Filosofía de la federación
El actor principal de Lemmy es la Comunidad. Cada comunidad reside en una única instancia, y consiste en una lista de Publicaciones y una lista de seguidores. La interacción principal es la de un usuario que envía una actividad relacionada con una Publicación o un Comentario a la bandeja de entrada de la Comunidad, que la anuncia a todos sus seguidores.
Cada Comunidad tiene un Usuario creador específico, que es responsable de establecer las reglas, nombrar moderadores y eliminar el contenido que viola las reglas.
Además de la moderación a nivel de comunidad, cada instancia tiene un conjunto de Usuarios administradores, que tienen el poder de realizar eliminaciones y baneos en todo el sitio.
Los Usuarios siguen a las comunidades que les interesan para recibir Publicaciones y Comentarios. También votan las Publicaciones y los Comentarios, además de crear otros nuevos. Los Comentarios se organizan en una estructura de árbol y suelen ordenarse por número de votos. Los mensajes directos entre Usuarios también son compatibles.
Los Usuarios no pueden seguirse unos a otros, y las Comunidades tampoco pueden seguir nada.
Nuestra implementación de la federación ya está completa, pero hasta ahora no nos hemos centrado en absoluto en el cumplimiento de la especificación ActivityPub. Como tal, Lemmy probablemente no es compatible con las implementaciones que esperan enviar y recibir actividades válidas. Esto es algo que planeamos arreglar en un futuro próximo. Consulta el tema [#698](https://github.com/LemmyNet/lemmy/issues/698) para ver un resumen de nuestras desviaciones.
## Actividades del usuario
### Seguir a una Comunidad
Cada página de la Comunidad tiene un botón "Seguir". Al hacer clic en él, el usuario envía una actividad de Seguir `Follow` a la bandeja de entrada de la Comunidad. La Comunidad responderá automáticamente con una actividad de Aceptar/Seguir `Accept/Follow` a la bandeja de entrada del usuario. También añadirá al usuario a su lista de seguidores y le enviará cualquier actividad sobre las publicaciones/comentarios de la comunidad.
### Dejar de seguir una Comunidad
Después de seguir una Comunidad, el botón "Seguir" se sustituye por "Dejar de seguir". Al hacer clic en él, se envía una actividad de Deshacer/Seguir `Undo/Follow` a la bandeja de entrada de la Comunidad. La Comunidad elimina al usuario de su lista de seguidores y ya no le envía ninguna actividad.
### Crear una Publicación
Cuando un usuario crea una nueva publicación en una Comunidad determinada, se envía como Crear/Página `Create/Page` a la bandeja de entrada de la Comunidad.
### Crear un Comentario
Cuando se crea un nuevo Comentario para una Publicación, tanto el ID de la Publicación como el ID del Comentario principal (si existe) se escriben en el campo `in_reply_to`. Esto permite asignarlo a la Publicación correcta y construir el árbol de Comentarios. A continuación, se envía a la bandeja de entrada de la Comunidad como Crear/Note `Create/Note`.
La instancia de origen también escanea el Comentario en busca de cualquier mención de Usuario, y envía el Crear/Nota`Create/Note` a esos Usuarios también.
### Editar una Publicación
Cambia el contenido de una Publicación existente. Sólo puede hacerlo el usuario que lo crea.
### Editar un Comentario
Cambia el contenido de un Comentario existente. Sólo puede hacerlo el usuario que lo crea.
### Me Gusta y No Me Gusta
Los usuarios pueden poner Me gustar o No me gusta de cualquier Publicación o Comentario. Estos se envían como Me gusta / Página `like/Page`, No me gusta / Nota `Dislike/Note`, etc. a la bandeja de entrada de la Comunidad.
### Eliminaciones
El creador de una Publicación, Comentario o Comunidad puede eliminarla. Entonces se envía a los seguidores de la Comunidad. El elemento queda entonces oculto para todos los usuarios.
### Remociones
Los mods pueden remover Publicaciones y Comentarios de sus Comunidades. Los administradores pueden remover cualquier Publicación o Comentario en todo el sitio. Las Comunidades también pueden ser removidas por los administradores. El elemento se oculta para todos los usuarios.
Las remociones se envían a todos los seguidores de la Comunidad, por lo que también tienen efecto allí. La excepción es si un administrador elimina un elemento de una Comunidad que está alojada en una instancia diferente. En este caso, la eliminación sólo tiene efecto a nivel local.
### Revertir una acción anterior
**No eliminamos nada de nuestra base de datos, sólo lo ocultamos a los usuarios**. Las Comunidades/Publicaciones/Comentarios removidos o eliminados tienen un botón de "restauración". Este botón genera una actividad de Deshacer `Undo` que establece la actividad original de eliminar/remover como objeto, como Deshacer/Remover/Publicación `Undo/Remove/Post` o Deshacer/Eliminar/Comunidad `Undo/Delete/Community`.
Al hacer clic en el botón de "Voto positivo" (upvote) de una publicación/comentario ya votado (o en el botón de "Voto negativo" (downvote) de una publicación/comentario ya votado) también se genera un Deshacer `Undo`. En este caso Deshacer/Me gusta/Publicación `Undo/Like/Post` o Deshacer/No me gusta/Comentario `Undo/Dislike/Comment`.
### Crear un mensaje privado
Los perfiles de los usuarios tienen un botón "Enviar mensaje", que abre un diálogo que permite enviar un mensaje privado a este usuario. Se envía como un Crear/Nota `Create/Note` a la bandeja de entrada del usuario. Los mensajes privados sólo pueden dirigirse a un único usuario.
### Editar mensaje privado
Actualizar/Nota `Update/Note` cambia el texto de un mensaje enviado previamente.
### Eliminar mensaje privado
Eliminar/Nota `Delete/Note` borra un mensaje privado.
### Restaurar mensaje privado
Deshacer/Eliminar/Nota `Undo/Delete/Note` Revierte la eliminación de un mensaje privado.
## Actividades de la Comunidad
La Comunidad es esencialmente un bot, que sólo hará algo en reacción a las acciones de los Usuarios. El usuario que creó la Comunidad por primera vez se convierte en el primer moderador, y puede añadir moderadores adicionales. En general, cada vez que la Comunidad recibe una actividad válida en su bandeja de entrada, esa actividad se reenvía a todos sus seguidores.
### Aceptar seguir
Si la Comunidad recibe una actividad de Seguir `Follow`, responde automáticamente con Aceptar/Seguir `Accept/Follow`. También añade al Usuario a su lista de seguidores.
### Dejar de seguir
Al recibir un Deshacer/Seguir `Undo/Follow`, la Comunidad elimina al Usuario de su lista de seguidores.
### Anunciar
Si la Comunidad recibe cualquier actividad relacionada con una publicación o comentario (Crear, Actualizar, Me gusta, No me gusta, Eliminar, Borrar, Deshacer), lo anunciará a sus seguidores. Para ello, se crea un Anuncio con la Comunidad como actor, y la actividad recibida como objeto. De este modo, las instancias seguidoras se mantienen actualizadas sobre cualquier acción en las Comunidades que siguen.
### Eliminar Comunidad
Si el creador o un administrador elimina la Comunidad, envía un Anuncio de Eliminar/Grupo `Delete/Group` a todos sus seguidores.

View file

@ -0,0 +1,22 @@
# Recursos de ActivityPub
## Documentos Oficiales
- [ActivityPub standard](https://www.w3.org/TR/activitypub/)
- [Activitypub vocabulary](https://www.w3.org/TR/activitystreams-vocabulary/)
## Explicaciones
- [ActivityPub - one protocol to rule them all?](https://schub.io/blog/2018/02/01/activitypub-one-protocol-to-rule-them-all.html)
- [A highly opinionated guide to learning about ActivityPub](https://tinysubversions.com/notes/reading-activitypub/)
- [Activitypub implementers guide](https://socialhub.activitypub.rocks/t/draft-guide-for-new-activitypub-implementers/479)
- [Mastodon Blog: How to implement a basic ActivityPub server](https://blog.joinmastodon.org/2018/06/how-to-implement-a-basic-activitypub-server/)
- [Mastodon Blog: Implementing an ActivityPub inbox](https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/)
- [Data storage questions](https://socialhub.activitypub.rocks/t/data-storage-questions/579)
- [Activitypub as it has been understood](https://flak.tedunangst.com/post/ActivityPub-as-it-has-been-understood)
## Ejemplos y Bibliotecas
- [ActivityPub example server](https://github.com/tOkeshu/activitypub-example)
- [ActivityStreams crate](https://docs.rs/activitystreams/)
- [HTTP Signatures crate](https://git.asonix.dog/Aardwolf/http-signature-normalization)