Skip to content

Development.es

Doug Blank edited this page Oct 5, 2026 · 3 revisions

🌐 English · Deutsch · Français · 简体中文

Desarrollo

Esta página explica cómo preparar un entorno de desarrollo local para el propio app/, a diferencia de Instalación (ejecutar la versión de escritorio empaquetada) o Despliegue (ejecutar la forma de producción en contenedores). Consulte primero Arquitectura para ver cómo encajan las piezas.

Primeros pasos

npm install                 # instala el espacio de trabajo (app/ + packages/gramps-date)
cp app/.env.example app/.env.local   # apunta a una instancia de gramps-web-api en ejecución
npm run dev -w app          # inicia el servidor de desarrollo de Vite

app/ necesita un backend gramps-web-api real con el que hablar: es un cliente puro, no hay modo de datos simulados. La opción más ligera es dev-fixtures/layer2-local-cache/api-fixture-example/setup.sh (véase Entornos de prueba de desarrollo más abajo).

Todos los entornos de prueba ejecutan gramps-web-api desde una copia del código fuente en el mismo entorno de Python que el script del entorno de prueba, así que ese entorno necesita:

pip install -e ~/gramps/gramps --no-deps          # el propio gramps
pip install -e ~/gramps/gramps-web-api --no-deps  # + sus dependencias, véase abajo
python3 deploy/webapi-requirements.py ~/gramps/gramps-web-api/pyproject.toml \
  | pip install -r /dev/stdin

El const.py de gramps-web-api hace gi.require_version("Gtk", "3.0") al importarse, así que tienen que estar presentes PyGObject real y las typelibs de GTK3 (apt install python3-gi gir1.2-gtk-3.0, o conda install -c conda-forge pygobject gtk3); PyICU es opcional, pero silencia una advertencia de localización y corrige la ordenación de nombres.

Tenga en cuenta que los endpoints /api/<type>/query/ sobre los que se construye app/ se incorporaron a la rama master de gramps-project/gramps-web-api: un fork o rama más antiguo devuelve 404 en todos ellos.

Entornos de prueba de desarrollo

dev-fixtures/ contiene backends gramps-web-api reales contra los que ejecutar app/ localmente. No forman parte del producto distribuido, simplemente hacen posible el desarrollo local sin configurar a mano un servidor propio. Lea un script antes de ejecutarlo: ninguno es idempotente frente a un árbol ya poblado. Todos los entornos de prueba inician sesión como gramps/gramps.

  • layer2-local-cache/api-fixture-example/: la opción más ligera: una instancia de SQLite simple en :5002 cargada con la base de datos de ejemplo oficial de Gramps, example.gramps, útil por su variedad real de fechas (modificadores, calidad, rangos/intervalos). Ponga VITE_API_BASE=http://localhost:5002 en app/.env.local para apuntar a ella. La sincronización en vivo también funciona con ella, ya que es solo un sondeo de /api/transactions/history/, no ligado a Postgres.
  • layer2-local-cache/api-fixture/: otra instancia de SQLite simple, cargada en cambio con datos sintéticos generados por gramps-bench, para pruebas de escala con un árbol grande.
  • layer3-sync/api-fixture/: una instancia respaldada por un Postgres real (SharedPostgreSQL), útil para ejercitar ediciones realmente simultáneas de varios escritores sobre el mismo árbol. Es a la que apunta el VITE_API_BASE por defecto de app/.env.example, y necesita un Postgres en ejecución y el complemento SharedPostgreSQL, además de todo lo que necesitan los entornos de prueba con SQLite.

Compilar las wheels de los Gramplets

Los Gramplets ejecutan Python en el navegador con Pyodide, sobre wheels compiladas localmente que el paso postinstall de npm install omite (con una línea en el registro) cuando todavía no existen, lo que deja los Gramplets fallando en tiempo de ejecución con No known package with name 'gramps-gen-lib'. Compílelas una vez:

python3 scripts/build-stub-wheels.py    # sustitutos de gi + orjson para Pyodide
python3 scripts/build-gramps-wheel.py   # gramps.gen.lib como wheel de Pyodide
node app/scripts/copy-wasm.mjs          # las registra en public/pyodide/

Pruebas

npm run test -w app         # Vitest: lógica pura de almacén/sincronización, no renderizado completo de la aplicación
npm run typecheck -w app    # tsc --noEmit
npm run test -w packages/gramps-date
pytest tests/               # filtros predefinidos de GOQL frente a las reglas reales de gramps-core

El conjunto de pruebas de pytest (tests/gql_presets/, véase su propio README) comprueba cada filtro predefinido de Filtros (app/src/data/gqlFilterPresets.ts) frente a la clase Rule real de gramps-core que pretende adaptar, ejecutándose sobre el árbol de ejemplo incluido en gramps-core: detecta no solo «¿compila esto?», sino «¿selecciona las mismas filas que seleccionaría la regla de escritorio?». Necesita que gramps/gramps-object-query-language se puedan importar (ya es así dondequiera que se ejecute gramps-web-api); no hace falta ningún paso aparte para mantener sincronizada su propia instantánea JSON de los filtros predefinidos, eso ocurre automáticamente.

Traducciones

Las cadenas de la interfaz de app/ pasan por t() (app/src/i18n/i18n.ts), que imita el enfoque del propio gramps-web (una simple búsqueda {english: translated}, sin biblioteca de i18n), combinando dos fuentes por idioma, elegidas en el momento de setLanguage() y guardadas en memoria hasta el siguiente cambio de idioma:

  • El vocabulario de Gramps de escritorio: se traduce en vivo, por petición, enviando por POST las cadenas realmente en uso al endpoint existente GET/POST /api/translations/<lang> de gramps-web-api, que las pasa por el catálogo gettext del paquete gramps instalado. No hay ninguna copia estática que mantener sincronizada; siempre está tan al día como la versión de gramps que tenga instalada el servidor. La lista fija de qué cadenas del vocabulario de escritorio pedir está en el array desktopStrings de i18n.ts, ampliado a mano, una entrada por cadena, cada vez que una llamada t() recién añadida resulta ser vocabulario real de Gramps y no algo específico de gramps-connect.
  • Las cadenas de la interfaz del propio gramps-web y las de los complementos de Gramps: se generan inicialmente como archivos estáticos app/public/lang/{locale}.json (versionados en git, para que la aplicación funcione sin que nadie necesite una conexión a Weblate) mediante scripts/bootstrap-translations.py, que lee ../gramps-web/lang/ y ../addons-source/*/po/*-local.po, copias hermanas de este repositorio, sin ninguna llamada de red. Ejecútelo (python3 scripts/bootstrap-translations.py, necesita pip install polib) cada vez que se actualicen esas copias hermanas y quiera refrescar el corpus estático; no está conectado a ningún paso de compilación, así que nada lo ejecuta automáticamente. Es seguro volver a ejecutarlo: sin --force omite cualquier .json de configuración regional que ya exista, e incluso con --force solo sobrescribe archivos dentro de app/public/lang/: sin llamadas de red, sin operaciones de git, y cualquier mal resultado se deshace con un git checkout.

Envolver más cadenas propias de la aplicación en t() es un trabajo continuo e incremental: app/scripts/wrap-translations.mjs es un codemod de un solo uso (conservado como herramienta reutilizable) que envuelve mecánicamente el texto JSX simple y una lista segura de atributos permitidos (label/title/placeholder); todo lo que procede de una variable o de una propiedad de un literal de objeto (configuraciones de vistas/columnas en app/src/store/views.ts, datos dinámicos de la API, llamadas a notifications.show()) necesita en cambio un t(...) manual en el componente que lo muestre.

Contribuir

Las conversaciones tienen lugar en el foro Discourse de Gramps; las incidencias y pull requests en el repositorio de gramps-connect son bienvenidas.

Licencia

AGPL-3.0-or-later, igual que gramps-web-api y gramps-web. packages/gramps-date traduce código del núcleo de Gramps con licencia GPL-2.0-or-later a la base de código AGPL-3.0-or-later de este proyecto; consulte su propio README (y Arquitectura) para ver cómo se combinan esas dos licencias.

Clone this wiki locally