diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..94da0eb --- /dev/null +++ b/404.html @@ -0,0 +1,1406 @@ + + + + + + + + + + + + + + + + + + Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +

404 - Not found

+ +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..3cbf940 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +www.grampsweb.org \ No newline at end of file diff --git a/Configuration/index.html b/Configuration/index.html new file mode 100644 index 0000000..060e9c8 --- /dev/null +++ b/Configuration/index.html @@ -0,0 +1,1789 @@ + + + + + + + + + + + + + + + + + + + + + + + + Server Configuration - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + +

Server Configuration

+

Using the default Docker image, all necessary configuration can be made from the browser. However, depending on the deployment, it can be necessary to customize the server configuration.

+

This page lists all methods to change the configuration and all existing configuration options.

+

Configuration file vs. environment variables

+

For the settings, you can either use a configuration file or environment variables.

+

When you use the Docker Compose based setup, you can include a configuration file by adding the following list item under the volumes: key in the grampsweb: block:

+

      - /path/to/config.cfg:/app/config/config.cfg
+
+where /path/to/config.cfg is the path to the config file in your server's file system (the right-hand side refers to the path in the container and must not be changed).

+

When using environment variables,

+
    +
  • prefix every setting name with GRAMPSWEB_ to obtain the name of the environment variable
  • +
  • Use double underscores for nested dictionary settings, e.g GRAMPSWEB_THUMBNAIL_CACHE_CONFIG__CACHE_DEFAULT_TIMEOUT will set the value of the THUMBNAIL_CACHE_CONFIG['CACHE_DEFAULT_TIMEOUT'] config option
  • +
+

Existing configuration settings

+

The following configuration options exist.

+

Required settings

+ + + + + + + + + + + + + + + + + +
KeyDescription
TREEThe name of the family tree database to use. Show available trees with gramps -l. If a tree with this name does not exist, a new empty one will be created.
SECRET_KEYThe secret key for flask. The secret must not be shared publicly. Changing it will invalidate all access tokens
+
+

Info

+

You can generate a secure secret key e.g. with the command

+
python3 -c "import secrets;print(secrets.token_urlsafe(32))"
+
+
+

Optional settings

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyDescription
MEDIA_BASE_DIRPath to use as base directory for media files, overriding the media base directory set in Gramps. When using S3, must have the form s3://<bucket_name>
SEARCH_INDEX_DIRPath for the full-text search index. Defaults to indexdir relative to the path where the script is run
STATIC_PATHPath to serve static files from (e.g. a static web frontend)
BASE_URLBase URL where the API can be reached (e.g. https://mygramps.mydomain.com/). This is necessary e.g. to build correct passwort reset links
CORS_ORIGINSOrigins where CORS requests are allowed from. By default, all are disallowed. Use "*" to allow requests from any domain.
EMAIL_HOSTSMTP server host (e.g. for sending password reset e-mails)
EMAIL_PORTSMTP server port. defaults to 465
EMAIL_HOST_USERSMTP server username
EMAIL_HOST_PASSWORDSMTP server password
EMAIL_USE_TLSBoolean, whether to use TLS for sending e-mails. Defaults to True. When using STARTTLS, set this to False and use a port different from 25.
DEFAULT_FROM_EMAIL"From" address for automated e-mails
THUMBNAIL_CACHE_CONFIGDictionary with settings for the thumbnail cache. See Flask-Caching for possible settings.
CELERY_CONFIGSettings for the Celery background task queue. See Celery for possible settings.
REPORT_DIRTemporary directory where the output of running Gramps reports will be stored
EXPORT_DIRTemporary directory where the output of exporting the Gramps database will be stored
+
+

Info

+

When using environment variables for configuration, boolean options like EMAIL_USE_TLS must be either the string true or false (case senitive!).

+
+

Settings only for PostgreSQL backend database

+

This is required if you've configured your Gramps database to work with the PostgreSQL addon.

+ + + + + + + + + + + + + + + + + +
KeyDescription
POSTGRES_USERThe user name for the database connection
POSTGRES_PASSWORDThe password for the database user
+

Settings relevant for hosting multiple trees

+

The following settings are relevant when hosting multiple trees.

+ + + + + + + + + + + + + + + + + +
KeyDescription
MEDIA_PREFIX_TREEBoolean, whether or not to use a separate subfolder for the media files of each tree. Defaults to False, but strongly recommend to use True in a multi-tree setup
NEW_DB_BACKENDThe database backend to use for newly created family trees. Must be one of sqlite, postgresql, or sharedpostgresql. Defaults to sqlite.
+

Example configuration file

+

A minimal configuration file for production could look like this: +

TREE="My Family Tree"
+BASE_URL="https://mytree.example.com"
+SECRET_KEY="..."  # your secret key
+USER_DB_URI="sqlite:////path/to/users.sqlite"
+EMAIL_HOST="mail.example.com"
+EMAIL_PORT=465
+EMAIL_USE_TLS=True
+EMAIL_HOST_USER="gramps@example.com"
+EMAIL_HOST_PASSWORD="..." # your SMTP password
+DEFAULT_FROM_EMAIL="gramps@example.com"
+

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/Deployment/index.html b/Deployment/index.html new file mode 100644 index 0000000..956eb46 --- /dev/null +++ b/Deployment/index.html @@ -0,0 +1,1605 @@ + + + + + + + + + + + + + + + + + + + + + + + + Deploy with Docker - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Deploying Gramps Web with Docker

+

The most convenient option to host Gramps Web on your own server (or virtual server) is with Docker Compose.

+

We will assume that Docker and Docker Compose are already installed in your system. You can use Windows, Mac OS, or Linux as a host system. The supported architectures include not only x86-64 (desktop systems), but also ARM systems such as a Raspberry Pi, which can serve as a low-cost, but powerful (enough) web server.

+
+

Note

+

You do not need to install Gramps on the server as it is contained in the docker image.

+
+

Step 1: Docker configuration

+

Create a new file on the server named docker-compose.yml and insert the following contents: docker-compose.yml.

+

This will generate six named volumes to make sure that all relevant data will persist when restarting the container.

+
+

Warning

+

The above will make the API available on port 80 of the host machine without SSL/TLS protection. You can use this for local testing, but do not expose this directly to the internet, it is completely insecure!

+
+

Step 2: Secure access with SSL/TLS

+

The web API must be served to the public internet over HTTPS. There are several options, e.g.

+
    +
  • Using docker hosting that includes SSL/TLS automatically
  • +
  • Using an Nginx Reverse Proxy with a Let's Encrypt certificate
  • +
+

See Docker with Let's Encrypt for how to set up the former.

+

If you plan to use Gramps Web only on your local network, you can skip this step.

+

Step 3: Start the server

+

Run

+
docker-compose up -d
+
+

On first run, the app will display a first-run wizard that will allow you to

+
    +
  • Create and account for the owner (admin) user
  • +
  • Set some necessary configuration options
  • +
  • Import a family tree in Gramps XML (.gramps) format
  • +
+

Step 4: Upload media files

+

There are several options for uploading media files.

+
    +
  • When using files stored on the same server as Gramps Web, you can mount a directory into the Docker container instead of using a named volume, i.e. /home/server_user/gramps_media/:/app/mediainstead of gramps_media:/app/media, and upload your media files there.
  • +
  • When using media files hosted on S3, you can use he S3 Media Uploader Addon
  • +
  • The arguably most convenient option is to use Gramps Web Sync.
  • +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/DigitalOcean/index.html b/DigitalOcean/index.html new file mode 100644 index 0000000..9d78f62 --- /dev/null +++ b/DigitalOcean/index.html @@ -0,0 +1,1605 @@ + + + + + + + + + + + + + + + + + + + + + + + + DigitalOcean - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + +

Gramps Web DigitalOcean 1-Click App

+

Instead of setting up Gramps Web yourself, you can also use the Gramps Web DigitalOcean 1-Click App.

+

As part of the setup procedure, you will have to sign up for an account with DigitalOcean and select a paid plan for the "droplet" (virtual machine) to use.

+

Arguably, this is currently the simplest way to deploy your own, self-hosted Gramps Web instance, secured with SSL, without using your own hardware.

+
+

Info

+

Note that you will be paying DigitalOcean for the hosting services. The Gramps open source project does not provide paid support.

+
+

Step 1: Create a DigitalOcean account

+

Create an account at DigitalOcean if you don't have one yet.

+

Step 2: Create the droplet

+
    +
  • Go to Gramps Web 1-Click App and click "Create Gramps Web Droplet".
  • +
  • Choose a plan with at least 2 GB of RAM.
  • +
  • Set up authentication to your droplet
  • +
  • Click "Create Droplet"
  • +
+

Step 3: Set up a domain name

+

You will need a domain name (or subdomain). If you own a domain, point it to the IP address of your droplet. Otherwise, you could use a free service such as DuckDNS.

+

Step 4: Log in to your droplet

+

SSH into your droplet. You should be presented with the message "Welcome to the Gramps Web DigitalOcean 1-click app setup!". If this is not the case, wait a few minutes and try again (the installation is not yet finished).

+

The setup script will ask you for the domain name (e.g. mygrampswebinstance.duckdns.org) and an e-mail address (needed for the Let's Encrypt certificate).

+

When this is done, wait for the setup to be completed in the background

+

Step 5: Launch Gramps Web

+

Your Gramps Web instance should now be accessible at the root of your domain, with a valid SSL certificate, and it should be showing the first-run assistant.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/LetsEncrypt/index.html b/LetsEncrypt/index.html new file mode 100644 index 0000000..d921b80 --- /dev/null +++ b/LetsEncrypt/index.html @@ -0,0 +1,1483 @@ + + + + + + + + + + + + + + + + + + + + + + + + Docker with Let's Encrypt - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Setting up HTTPS with Let's Encrypt and Docker Compose

+

When served to the public internet, Gramps Web must use HTTPS encryption.

+

A particularly convenient option is to use a dockerized Nginx reverse proxy with automated Let's Encrypt certificate generation. This is achieved with this docker-compose.yml. +(The nginx_proxy.conf needs to be stored in the same directory to allow uploading large media files to Gramps Web.)

+

Please see the acme-companion docs for how to set up your domain.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/Postgres/index.html b/Postgres/index.html new file mode 100644 index 0000000..f65a991 --- /dev/null +++ b/Postgres/index.html @@ -0,0 +1,1617 @@ + + + + + + + + + + + + + + + + + + + + + + + + Using PostgreSQL - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Using a PostgreSQL database

+

By default, Gramps uses a file-based SQLite database to store the family tree. This works perfectly fine for Gramps Web and is recommended for most users. However, starting with Gramps Web API version 0.3.0, also a PostgreSQL server with a single family tree per database is supported, powered by the Gramps PostgreSQL Addon.

+

Setting up the PostgreSQL server

+

You can follow the instructions in the Gramps Wiki to set up the PostgreSQL server.

+

Alternatively, you can also use Docker Compose to run the PostgreSQL server in a container on the same docker host as Gramps Web.

+

Using a dockerized PostgreSQL with Gramps is only complicated by the fact the the default PostgreSQL images do not have any locales installed, which are however needed by Gramps for localized collation of objects. Thus, it is necessary to use a custom Dockerfile.

+

Create a Dockerfile with the following contens in a directory postgres next to your docker-compose.yml:

+
FROM postgres:14
+
+RUN apt-get update && apt-get install -y locales-all \
+    && rm -rf /var/lib/apt/lists/*
+
+

Next, add the following section to your docker-compose.yml:

+

  postgres_gramps:
+    build: ./postgres
+    restart: unless-stopped
+    environment:
+      POSTGRES_PASSWORD: your_postgres_password
+      POSTGRES_USER: postgres
+    volumes:
+      - postgres_data:/var/lib/postgresql/data
+
+and also add postgres_data: as key under the volumes: section of this YAML file.

+

Importing a Gramps family tree

+

Again, if you have set up the PostgreSQL server yourself, you can follow the instructions in the Gramps Wiki to import a family tree into the database.

+

Alternatively, if you have followed the Docker Compose instructions above, you can use the following command to import a Gramps XML file located on your docker host:

+
docker-compose run --entrypoint "" grampsweb \
+    gramps -C postgres \
+    -i /root/.gramps/grampsdb/my_tree.gramps \
+    --config=database.backend:postgresql \
+    --config=database.host:postgres_gramps \
+    --config=database.port:5432 \
+    --username=postgres --password=your_postgres_password
+
+

Configuring Web API for use with the database

+

To configure Web API for use with the PostgreSQL database, add the following under the environment: key of the grampsweb service in docker-compose.yml:

+
      # the PostgreSQL addon assumes the tree name to be
+      # equal to the database name and here the default 
+      # database name of the PostgreSQL image is used
+      TREE: postgres
+      # The credentials must agree with the ones used for
+      # the PostgreSQL container
+      POSTGRES_USER: postgres
+      POSTGRES_PASSWORD: your_postgres_password
+
+

Issues

+

In case of issues, please monitor the log output of Gramps Web and the PostgreSQL server. In the case of docker, this is achieved with

+
docker-compose logs grampsweb
+docker-compose logs postgres_grampsweb
+
+

If you suspect there is an issue with Gramps Web (or the documentation), please file an issue on Github.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/Update/index.html b/Update/index.html new file mode 100644 index 0000000..4e678e0 --- /dev/null +++ b/Update/index.html @@ -0,0 +1,1485 @@ + + + + + + + + + + + + + + + + + + + + + + + + Update - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Update Gramps Web

+

If you are using one of the installation methods based on Docker Compose, updating Gramps Web to the latest version is simple. In the folder where your docker-compose.yml is located, run the following commands

+
docker-compose pull
+docker-compose up -d
+
+

For minor version jumps of Gramps Web API, this is all that is needed. Do follow the release notes of Gramps Web API though, as there could be breaking changes that require additional attention or configuration changes.

+

Note that the default grampsweb:latest docker image always combines the latest version of the API with the latest version of the frontend. If you want to upgrade the two components separately - which is possible - a more involved setup than described here is necessary.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/Users/index.html b/Users/index.html new file mode 100644 index 0000000..8be5056 --- /dev/null +++ b/Users/index.html @@ -0,0 +1,1622 @@ + + + + + + + + + + + + + + + + + + + + + + + + User system - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

User system

+

Gramps Web is not meant to be exposed to the internet for public access, but only by authenticated users. User accounts can be created by the site owner via the command line or web interface, or by self-registration and subsequent approval by the site owner.

+

User roles

+

The following user roles are currently defined.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
RoleRole IDPermissions
Guest0View non-private objects
Member1Guest + view private objects
Contributor*2Member + add objects
Editor3Contributor + edit and delete objects
Owner4Editor + manage users
Admin5Owner + edit other trees in multi-tree setup
+

* Note that the "Contributor" role is currently only partially supported; e.g., family objects cannot be added since they imply a modification of the underlying Gramps person objects of family members. It is recommended to use the other roles whenever possible.

+

Managing users

+

There are two ways to manage users:

+
    +
  • With owner permissions using the web interface
  • +
  • On the command line on the server
  • +
+

The owner account required to first access the web app can be added in the onboarding wizard that is automatically launched when accessing Gramps Web with an empty user database.

+

Managing users on the command line

+

When using Docker Compose, the basic command is

+
docker-compose run grampsweb python3 -m gramps_webapi user COMMAND [ARGS]
+
+

The COMMAND can be add or delete. Use --help for [ARGS] to show the syntax and possible configuration options.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/admin/index.html b/admin/index.html new file mode 100644 index 0000000..f1d33e5 --- /dev/null +++ b/admin/index.html @@ -0,0 +1,1482 @@ + + + + + + + + + + + + + + + + + + + + + + + + Introduction - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Gramps Web Family Tree Administration

+

Whether you have set up your own instance of Gramps Web or signed up for a pre-installed one, the next step is to populate and manage your family tree database.

+

The focus of this section is on administrative tasks performed by tree owners. Usually, there is one tree owner for each family tree database (although as tree owner, you can also create other tree owner accounts).

+

This section only deals with actions that can be performed from the web interface. For command line tools or server configuration, see the previous section Setup.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 0000000..1cf13b9 Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.51d95adb.min.js b/assets/javascripts/bundle.51d95adb.min.js new file mode 100644 index 0000000..b20ec68 --- /dev/null +++ b/assets/javascripts/bundle.51d95adb.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var Hi=Object.create;var xr=Object.defineProperty;var Pi=Object.getOwnPropertyDescriptor;var $i=Object.getOwnPropertyNames,kt=Object.getOwnPropertySymbols,Ii=Object.getPrototypeOf,Er=Object.prototype.hasOwnProperty,an=Object.prototype.propertyIsEnumerable;var on=(e,t,r)=>t in e?xr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,P=(e,t)=>{for(var r in t||(t={}))Er.call(t,r)&&on(e,r,t[r]);if(kt)for(var r of kt(t))an.call(t,r)&&on(e,r,t[r]);return e};var sn=(e,t)=>{var r={};for(var n in e)Er.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&kt)for(var n of kt(e))t.indexOf(n)<0&&an.call(e,n)&&(r[n]=e[n]);return r};var Ht=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Fi=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of $i(t))!Er.call(e,o)&&o!==r&&xr(e,o,{get:()=>t[o],enumerable:!(n=Pi(t,o))||n.enumerable});return e};var yt=(e,t,r)=>(r=e!=null?Hi(Ii(e)):{},Fi(t||!e||!e.__esModule?xr(r,"default",{value:e,enumerable:!0}):r,e));var fn=Ht((wr,cn)=>{(function(e,t){typeof wr=="object"&&typeof cn!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(wr,function(){"use strict";function e(r){var n=!0,o=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(T){return!!(T&&T!==document&&T.nodeName!=="HTML"&&T.nodeName!=="BODY"&&"classList"in T&&"contains"in T.classList)}function f(T){var Ke=T.type,We=T.tagName;return!!(We==="INPUT"&&a[Ke]&&!T.readOnly||We==="TEXTAREA"&&!T.readOnly||T.isContentEditable)}function c(T){T.classList.contains("focus-visible")||(T.classList.add("focus-visible"),T.setAttribute("data-focus-visible-added",""))}function u(T){T.hasAttribute("data-focus-visible-added")&&(T.classList.remove("focus-visible"),T.removeAttribute("data-focus-visible-added"))}function p(T){T.metaKey||T.altKey||T.ctrlKey||(s(r.activeElement)&&c(r.activeElement),n=!0)}function m(T){n=!1}function d(T){s(T.target)&&(n||f(T.target))&&c(T.target)}function h(T){s(T.target)&&(T.target.classList.contains("focus-visible")||T.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),u(T.target))}function v(T){document.visibilityState==="hidden"&&(o&&(n=!0),B())}function B(){document.addEventListener("mousemove",z),document.addEventListener("mousedown",z),document.addEventListener("mouseup",z),document.addEventListener("pointermove",z),document.addEventListener("pointerdown",z),document.addEventListener("pointerup",z),document.addEventListener("touchmove",z),document.addEventListener("touchstart",z),document.addEventListener("touchend",z)}function re(){document.removeEventListener("mousemove",z),document.removeEventListener("mousedown",z),document.removeEventListener("mouseup",z),document.removeEventListener("pointermove",z),document.removeEventListener("pointerdown",z),document.removeEventListener("pointerup",z),document.removeEventListener("touchmove",z),document.removeEventListener("touchstart",z),document.removeEventListener("touchend",z)}function z(T){T.target.nodeName&&T.target.nodeName.toLowerCase()==="html"||(n=!1,re())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",m,!0),document.addEventListener("pointerdown",m,!0),document.addEventListener("touchstart",m,!0),document.addEventListener("visibilitychange",v,!0),B(),r.addEventListener("focus",d,!0),r.addEventListener("blur",h,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var un=Ht(Sr=>{(function(e){var t=function(){try{return!!Symbol.iterator}catch(c){return!1}},r=t(),n=function(c){var u={next:function(){var p=c.shift();return{done:p===void 0,value:p}}};return r&&(u[Symbol.iterator]=function(){return u}),u},o=function(c){return encodeURIComponent(c).replace(/%20/g,"+")},i=function(c){return decodeURIComponent(String(c).replace(/\+/g," "))},a=function(){var c=function(p){Object.defineProperty(this,"_entries",{writable:!0,value:{}});var m=typeof p;if(m!=="undefined")if(m==="string")p!==""&&this._fromString(p);else if(p instanceof c){var d=this;p.forEach(function(re,z){d.append(z,re)})}else if(p!==null&&m==="object")if(Object.prototype.toString.call(p)==="[object Array]")for(var h=0;hd[0]?1:0}),c._entries&&(c._entries={});for(var p=0;p1?i(d[1]):"")}})})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Sr);(function(e){var t=function(){try{var o=new e.URL("b","http://a");return o.pathname="c d",o.href==="http://a/c%20d"&&o.searchParams}catch(i){return!1}},r=function(){var o=e.URL,i=function(f,c){typeof f!="string"&&(f=String(f)),c&&typeof c!="string"&&(c=String(c));var u=document,p;if(c&&(e.location===void 0||c!==e.location.href)){c=c.toLowerCase(),u=document.implementation.createHTMLDocument(""),p=u.createElement("base"),p.href=c,u.head.appendChild(p);try{if(p.href.indexOf(c)!==0)throw new Error(p.href)}catch(T){throw new Error("URL unable to set base "+c+" due to "+T)}}var m=u.createElement("a");m.href=f,p&&(u.body.appendChild(m),m.href=m.href);var d=u.createElement("input");if(d.type="url",d.value=f,m.protocol===":"||!/:/.test(m.href)||!d.checkValidity()&&!c)throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:m});var h=new e.URLSearchParams(this.search),v=!0,B=!0,re=this;["append","delete","set"].forEach(function(T){var Ke=h[T];h[T]=function(){Ke.apply(h,arguments),v&&(B=!1,re.search=h.toString(),B=!0)}}),Object.defineProperty(this,"searchParams",{value:h,enumerable:!0});var z=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==z&&(z=this.search,B&&(v=!1,this.searchParams._fromString(this.search),v=!0))}})},a=i.prototype,s=function(f){Object.defineProperty(a,f,{get:function(){return this._anchorElement[f]},set:function(c){this._anchorElement[f]=c},enumerable:!0})};["hash","host","hostname","port","protocol"].forEach(function(f){s(f)}),Object.defineProperty(a,"search",{get:function(){return this._anchorElement.search},set:function(f){this._anchorElement.search=f,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(a,{toString:{get:function(){var f=this;return function(){return f.href}}},href:{get:function(){return this._anchorElement.href.replace(/\?$/,"")},set:function(f){this._anchorElement.href=f,this._updateSearchParams()},enumerable:!0},pathname:{get:function(){return this._anchorElement.pathname.replace(/(^\/?)/,"/")},set:function(f){this._anchorElement.pathname=f},enumerable:!0},origin:{get:function(){var f={"http:":80,"https:":443,"ftp:":21}[this._anchorElement.protocol],c=this._anchorElement.port!=f&&this._anchorElement.port!=="";return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(c?":"+this._anchorElement.port:"")},enumerable:!0},password:{get:function(){return""},set:function(f){},enumerable:!0},username:{get:function(){return""},set:function(f){},enumerable:!0}}),i.createObjectURL=function(f){return o.createObjectURL.apply(o,arguments)},i.revokeObjectURL=function(f){return o.revokeObjectURL.apply(o,arguments)},e.URL=i};if(t()||r(),e.location!==void 0&&!("origin"in e.location)){var n=function(){return e.location.protocol+"//"+e.location.hostname+(e.location.port?":"+e.location.port:"")};try{Object.defineProperty(e.location,"origin",{get:n,enumerable:!0})}catch(o){setInterval(function(){e.location.origin=n()},100)}}})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Sr)});var Qr=Ht((Lt,Kr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof Lt=="object"&&typeof Kr=="object"?Kr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Lt=="object"?Lt.ClipboardJS=r():t.ClipboardJS=r()})(Lt,function(){return function(){var e={686:function(n,o,i){"use strict";i.d(o,{default:function(){return ki}});var a=i(279),s=i.n(a),f=i(370),c=i.n(f),u=i(817),p=i.n(u);function m(j){try{return document.execCommand(j)}catch(O){return!1}}var d=function(O){var w=p()(O);return m("cut"),w},h=d;function v(j){var O=document.documentElement.getAttribute("dir")==="rtl",w=document.createElement("textarea");w.style.fontSize="12pt",w.style.border="0",w.style.padding="0",w.style.margin="0",w.style.position="absolute",w.style[O?"right":"left"]="-9999px";var k=window.pageYOffset||document.documentElement.scrollTop;return w.style.top="".concat(k,"px"),w.setAttribute("readonly",""),w.value=j,w}var B=function(O,w){var k=v(O);w.container.appendChild(k);var F=p()(k);return m("copy"),k.remove(),F},re=function(O){var w=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},k="";return typeof O=="string"?k=B(O,w):O instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(O==null?void 0:O.type)?k=B(O.value,w):(k=p()(O),m("copy")),k},z=re;function T(j){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?T=function(w){return typeof w}:T=function(w){return w&&typeof Symbol=="function"&&w.constructor===Symbol&&w!==Symbol.prototype?"symbol":typeof w},T(j)}var Ke=function(){var O=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},w=O.action,k=w===void 0?"copy":w,F=O.container,q=O.target,Le=O.text;if(k!=="copy"&&k!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(q!==void 0)if(q&&T(q)==="object"&&q.nodeType===1){if(k==="copy"&&q.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(k==="cut"&&(q.hasAttribute("readonly")||q.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Le)return z(Le,{container:F});if(q)return k==="cut"?h(q):z(q,{container:F})},We=Ke;function Ie(j){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Ie=function(w){return typeof w}:Ie=function(w){return w&&typeof Symbol=="function"&&w.constructor===Symbol&&w!==Symbol.prototype?"symbol":typeof w},Ie(j)}function Ti(j,O){if(!(j instanceof O))throw new TypeError("Cannot call a class as a function")}function nn(j,O){for(var w=0;w0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof F.action=="function"?F.action:this.defaultAction,this.target=typeof F.target=="function"?F.target:this.defaultTarget,this.text=typeof F.text=="function"?F.text:this.defaultText,this.container=Ie(F.container)==="object"?F.container:document.body}},{key:"listenClick",value:function(F){var q=this;this.listener=c()(F,"click",function(Le){return q.onClick(Le)})}},{key:"onClick",value:function(F){var q=F.delegateTarget||F.currentTarget,Le=this.action(q)||"copy",Rt=We({action:Le,container:this.container,target:this.target(q),text:this.text(q)});this.emit(Rt?"success":"error",{action:Le,text:Rt,trigger:q,clearSelection:function(){q&&q.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(F){return yr("action",F)}},{key:"defaultTarget",value:function(F){var q=yr("target",F);if(q)return document.querySelector(q)}},{key:"defaultText",value:function(F){return yr("text",F)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(F){var q=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return z(F,q)}},{key:"cut",value:function(F){return h(F)}},{key:"isSupported",value:function(){var F=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],q=typeof F=="string"?[F]:F,Le=!!document.queryCommandSupported;return q.forEach(function(Rt){Le=Le&&!!document.queryCommandSupported(Rt)}),Le}}]),w}(s()),ki=Ri},828:function(n){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,f){for(;s&&s.nodeType!==o;){if(typeof s.matches=="function"&&s.matches(f))return s;s=s.parentNode}}n.exports=a},438:function(n,o,i){var a=i(828);function s(u,p,m,d,h){var v=c.apply(this,arguments);return u.addEventListener(m,v,h),{destroy:function(){u.removeEventListener(m,v,h)}}}function f(u,p,m,d,h){return typeof u.addEventListener=="function"?s.apply(null,arguments):typeof m=="function"?s.bind(null,document).apply(null,arguments):(typeof u=="string"&&(u=document.querySelectorAll(u)),Array.prototype.map.call(u,function(v){return s(v,p,m,d,h)}))}function c(u,p,m,d){return function(h){h.delegateTarget=a(h.target,p),h.delegateTarget&&d.call(u,h)}}n.exports=f},879:function(n,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(n,o,i){var a=i(879),s=i(438);function f(m,d,h){if(!m&&!d&&!h)throw new Error("Missing required arguments");if(!a.string(d))throw new TypeError("Second argument must be a String");if(!a.fn(h))throw new TypeError("Third argument must be a Function");if(a.node(m))return c(m,d,h);if(a.nodeList(m))return u(m,d,h);if(a.string(m))return p(m,d,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(m,d,h){return m.addEventListener(d,h),{destroy:function(){m.removeEventListener(d,h)}}}function u(m,d,h){return Array.prototype.forEach.call(m,function(v){v.addEventListener(d,h)}),{destroy:function(){Array.prototype.forEach.call(m,function(v){v.removeEventListener(d,h)})}}}function p(m,d,h){return s(document.body,m,d,h)}n.exports=f},817:function(n){function o(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var f=window.getSelection(),c=document.createRange();c.selectNodeContents(i),f.removeAllRanges(),f.addRange(c),a=f.toString()}return a}n.exports=o},279:function(n){function o(){}o.prototype={on:function(i,a,s){var f=this.e||(this.e={});return(f[i]||(f[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var f=this;function c(){f.off(i,c),a.apply(s,arguments)}return c._=a,this.on(i,c,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),f=0,c=s.length;for(f;f{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var is=/["'&<>]/;Jo.exports=as;function as(e){var t=""+e,r=is.exec(t);if(!r)return t;var n,o="",i=0,a=0;for(i=r.index;i0&&i[i.length-1])&&(c[0]===6||c[0]===2)){r=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function W(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var n=r.call(e),o,i=[],a;try{for(;(t===void 0||t-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(r=n.return)&&r.call(n)}finally{if(a)throw a.error}}return i}function D(e,t,r){if(r||arguments.length===2)for(var n=0,o=t.length,i;n1||s(m,d)})})}function s(m,d){try{f(n[m](d))}catch(h){p(i[0][3],h)}}function f(m){m.value instanceof Xe?Promise.resolve(m.value.v).then(c,u):p(i[0][2],m)}function c(m){s("next",m)}function u(m){s("throw",m)}function p(m,d){m(d),i.shift(),i.length&&s(i[0][0],i[0][1])}}function mn(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof xe=="function"?xe(e):e[Symbol.iterator](),r={},n("next"),n("throw"),n("return"),r[Symbol.asyncIterator]=function(){return this},r);function n(i){r[i]=e[i]&&function(a){return new Promise(function(s,f){a=e[i](a),o(s,f,a.done,a.value)})}}function o(i,a,s,f){Promise.resolve(f).then(function(c){i({value:c,done:s})},a)}}function A(e){return typeof e=="function"}function at(e){var t=function(n){Error.call(n),n.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var $t=at(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(n,o){return o+1+") "+n.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function De(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Fe=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,n,o,i;if(!this.closed){this.closed=!0;var a=this._parentage;if(a)if(this._parentage=null,Array.isArray(a))try{for(var s=xe(a),f=s.next();!f.done;f=s.next()){var c=f.value;c.remove(this)}}catch(v){t={error:v}}finally{try{f&&!f.done&&(r=s.return)&&r.call(s)}finally{if(t)throw t.error}}else a.remove(this);var u=this.initialTeardown;if(A(u))try{u()}catch(v){i=v instanceof $t?v.errors:[v]}var p=this._finalizers;if(p){this._finalizers=null;try{for(var m=xe(p),d=m.next();!d.done;d=m.next()){var h=d.value;try{dn(h)}catch(v){i=i!=null?i:[],v instanceof $t?i=D(D([],W(i)),W(v.errors)):i.push(v)}}}catch(v){n={error:v}}finally{try{d&&!d.done&&(o=m.return)&&o.call(m)}finally{if(n)throw n.error}}}if(i)throw new $t(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)dn(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&De(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&De(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Or=Fe.EMPTY;function It(e){return e instanceof Fe||e&&"closed"in e&&A(e.remove)&&A(e.add)&&A(e.unsubscribe)}function dn(e){A(e)?e():e.unsubscribe()}var Ae={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var st={setTimeout:function(e,t){for(var r=[],n=2;n0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var n=this,o=this,i=o.hasError,a=o.isStopped,s=o.observers;return i||a?Or:(this.currentObservers=null,s.push(r),new Fe(function(){n.currentObservers=null,De(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,a=n.isStopped;o?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new U;return r.source=this,r},t.create=function(r,n){return new wn(r,n)},t}(U);var wn=function(e){ne(t,e);function t(r,n){var o=e.call(this)||this;return o.destination=r,o.source=n,o}return t.prototype.next=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.next)===null||o===void 0||o.call(n,r)},t.prototype.error=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.error)===null||o===void 0||o.call(n,r)},t.prototype.complete=function(){var r,n;(n=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||n===void 0||n.call(r)},t.prototype._subscribe=function(r){var n,o;return(o=(n=this.source)===null||n===void 0?void 0:n.subscribe(r))!==null&&o!==void 0?o:Or},t}(E);var Et={now:function(){return(Et.delegate||Date).now()},delegate:void 0};var wt=function(e){ne(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=Et);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=n,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=n===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,n),i}return t.prototype.next=function(r){var n=this,o=n.isStopped,i=n._buffer,a=n._infiniteTimeWindow,s=n._timestampProvider,f=n._windowTime;o||(i.push(r),!a&&i.push(s.now()+f)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var n=this._innerSubscribe(r),o=this,i=o._infiniteTimeWindow,a=o._buffer,s=a.slice(),f=0;f0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=ut.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){var i;if(o===void 0&&(o=0),o!=null?o>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);var a=r.actions;n!=null&&((i=a[a.length-1])===null||i===void 0?void 0:i.id)!==n&&(ut.cancelAnimationFrame(n),r._scheduled=void 0)},t}(Ut);var On=function(e){ne(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var n=this._scheduled;this._scheduled=void 0;var o=this.actions,i;r=r||o.shift();do if(i=r.execute(r.state,r.delay))break;while((r=o[0])&&r.id===n&&o.shift());if(this._active=!1,i){for(;(r=o[0])&&r.id===n&&o.shift();)r.unsubscribe();throw i}},t}(Wt);var we=new On(Tn);var R=new U(function(e){return e.complete()});function Dt(e){return e&&A(e.schedule)}function kr(e){return e[e.length-1]}function Qe(e){return A(kr(e))?e.pop():void 0}function Se(e){return Dt(kr(e))?e.pop():void 0}function Vt(e,t){return typeof kr(e)=="number"?e.pop():t}var pt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function zt(e){return A(e==null?void 0:e.then)}function Nt(e){return A(e[ft])}function qt(e){return Symbol.asyncIterator&&A(e==null?void 0:e[Symbol.asyncIterator])}function Kt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Ki(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Qt=Ki();function Yt(e){return A(e==null?void 0:e[Qt])}function Gt(e){return ln(this,arguments,function(){var r,n,o,i;return Pt(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,Xe(r.read())];case 3:return n=a.sent(),o=n.value,i=n.done,i?[4,Xe(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,Xe(o)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function Bt(e){return A(e==null?void 0:e.getReader)}function $(e){if(e instanceof U)return e;if(e!=null){if(Nt(e))return Qi(e);if(pt(e))return Yi(e);if(zt(e))return Gi(e);if(qt(e))return _n(e);if(Yt(e))return Bi(e);if(Bt(e))return Ji(e)}throw Kt(e)}function Qi(e){return new U(function(t){var r=e[ft]();if(A(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Yi(e){return new U(function(t){for(var r=0;r=2;return function(n){return n.pipe(e?_(function(o,i){return e(o,i,n)}):me,Oe(1),r?He(t):zn(function(){return new Xt}))}}function Nn(){for(var e=[],t=0;t=2,!0))}function fe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new E}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,f=s===void 0?!0:s;return function(c){var u,p,m,d=0,h=!1,v=!1,B=function(){p==null||p.unsubscribe(),p=void 0},re=function(){B(),u=m=void 0,h=v=!1},z=function(){var T=u;re(),T==null||T.unsubscribe()};return g(function(T,Ke){d++,!v&&!h&&B();var We=m=m!=null?m:r();Ke.add(function(){d--,d===0&&!v&&!h&&(p=jr(z,f))}),We.subscribe(Ke),!u&&d>0&&(u=new et({next:function(Ie){return We.next(Ie)},error:function(Ie){v=!0,B(),p=jr(re,o,Ie),We.error(Ie)},complete:function(){h=!0,B(),p=jr(re,a),We.complete()}}),$(T).subscribe(u))})(c)}}function jr(e,t){for(var r=[],n=2;ne.next(document)),e}function K(e,t=document){return Array.from(t.querySelectorAll(e))}function V(e,t=document){let r=se(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function se(e,t=document){return t.querySelector(e)||void 0}function _e(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}function tr(e){return L(b(document.body,"focusin"),b(document.body,"focusout")).pipe(ke(1),l(()=>{let t=_e();return typeof t!="undefined"?e.contains(t):!1}),N(e===_e()),Y())}function Be(e){return{x:e.offsetLeft,y:e.offsetTop}}function Yn(e){return L(b(window,"load"),b(window,"resize")).pipe(Ce(0,we),l(()=>Be(e)),N(Be(e)))}function rr(e){return{x:e.scrollLeft,y:e.scrollTop}}function dt(e){return L(b(e,"scroll"),b(window,"resize")).pipe(Ce(0,we),l(()=>rr(e)),N(rr(e)))}var Bn=function(){if(typeof Map!="undefined")return Map;function e(t,r){var n=-1;return t.some(function(o,i){return o[0]===r?(n=i,!0):!1}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(r){var n=e(this.__entries__,r),o=this.__entries__[n];return o&&o[1]},t.prototype.set=function(r,n){var o=e(this.__entries__,r);~o?this.__entries__[o][1]=n:this.__entries__.push([r,n])},t.prototype.delete=function(r){var n=this.__entries__,o=e(n,r);~o&&n.splice(o,1)},t.prototype.has=function(r){return!!~e(this.__entries__,r)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(r,n){n===void 0&&(n=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!zr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),xa?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!zr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var r=t.propertyName,n=r===void 0?"":r,o=ya.some(function(i){return!!~n.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),Jn=function(e,t){for(var r=0,n=Object.keys(t);r0},e}(),Zn=typeof WeakMap!="undefined"?new WeakMap:new Bn,eo=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var r=Ea.getInstance(),n=new Ra(t,r,this);Zn.set(this,n)}return e}();["observe","unobserve","disconnect"].forEach(function(e){eo.prototype[e]=function(){var t;return(t=Zn.get(this))[e].apply(t,arguments)}});var ka=function(){return typeof nr.ResizeObserver!="undefined"?nr.ResizeObserver:eo}(),to=ka;var ro=new E,Ha=I(()=>H(new to(e=>{for(let t of e)ro.next(t)}))).pipe(x(e=>L(Te,H(e)).pipe(C(()=>e.disconnect()))),J(1));function de(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ge(e){return Ha.pipe(S(t=>t.observe(e)),x(t=>ro.pipe(_(({target:r})=>r===e),C(()=>t.unobserve(e)),l(()=>de(e)))),N(de(e)))}function bt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function ar(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var no=new E,Pa=I(()=>H(new IntersectionObserver(e=>{for(let t of e)no.next(t)},{threshold:0}))).pipe(x(e=>L(Te,H(e)).pipe(C(()=>e.disconnect()))),J(1));function sr(e){return Pa.pipe(S(t=>t.observe(e)),x(t=>no.pipe(_(({target:r})=>r===e),C(()=>t.unobserve(e)),l(({isIntersecting:r})=>r))))}function oo(e,t=16){return dt(e).pipe(l(({y:r})=>{let n=de(e),o=bt(e);return r>=o.height-n.height-t}),Y())}var cr={drawer:V("[data-md-toggle=drawer]"),search:V("[data-md-toggle=search]")};function io(e){return cr[e].checked}function qe(e,t){cr[e].checked!==t&&cr[e].click()}function je(e){let t=cr[e];return b(t,"change").pipe(l(()=>t.checked),N(t.checked))}function $a(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ia(){return L(b(window,"compositionstart").pipe(l(()=>!0)),b(window,"compositionend").pipe(l(()=>!1))).pipe(N(!1))}function ao(){let e=b(window,"keydown").pipe(_(t=>!(t.metaKey||t.ctrlKey)),l(t=>({mode:io("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),_(({mode:t,type:r})=>{if(t==="global"){let n=_e();if(typeof n!="undefined")return!$a(n,r)}return!0}),fe());return Ia().pipe(x(t=>t?R:e))}function Me(){return new URL(location.href)}function ot(e){location.href=e.href}function so(){return new E}function co(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)co(e,r)}function M(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="undefined"&&(typeof t[o]!="boolean"?n.setAttribute(o,t[o]):n.setAttribute(o,""));for(let o of r)co(n,o);return n}function fr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function fo(){return location.hash.substring(1)}function uo(e){let t=M("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Fa(){return b(window,"hashchange").pipe(l(fo),N(fo()),_(e=>e.length>0),J(1))}function po(){return Fa().pipe(l(e=>se(`[id="${e}"]`)),_(e=>typeof e!="undefined"))}function Nr(e){let t=matchMedia(e);return Zt(r=>t.addListener(()=>r(t.matches))).pipe(N(t.matches))}function lo(){let e=matchMedia("print");return L(b(window,"beforeprint").pipe(l(()=>!0)),b(window,"afterprint").pipe(l(()=>!1))).pipe(N(e.matches))}function qr(e,t){return e.pipe(x(r=>r?t():R))}function ur(e,t={credentials:"same-origin"}){return ve(fetch(`${e}`,t)).pipe(ce(()=>R),x(r=>r.status!==200?Tt(()=>new Error(r.statusText)):H(r)))}function Ue(e,t){return ur(e,t).pipe(x(r=>r.json()),J(1))}function mo(e,t){let r=new DOMParser;return ur(e,t).pipe(x(n=>n.text()),l(n=>r.parseFromString(n,"text/xml")),J(1))}function pr(e){let t=M("script",{src:e});return I(()=>(document.head.appendChild(t),L(b(t,"load"),b(t,"error").pipe(x(()=>Tt(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(l(()=>{}),C(()=>document.head.removeChild(t)),Oe(1))))}function ho(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function bo(){return L(b(window,"scroll",{passive:!0}),b(window,"resize",{passive:!0})).pipe(l(ho),N(ho()))}function vo(){return{width:innerWidth,height:innerHeight}}function go(){return b(window,"resize",{passive:!0}).pipe(l(vo),N(vo()))}function yo(){return Q([bo(),go()]).pipe(l(([e,t])=>({offset:e,size:t})),J(1))}function lr(e,{viewport$:t,header$:r}){let n=t.pipe(X("size")),o=Q([n,r]).pipe(l(()=>Be(e)));return Q([r,t,o]).pipe(l(([{height:i},{offset:a,size:s},{x:f,y:c}])=>({offset:{x:a.x-f,y:a.y-c+i},size:s})))}(()=>{function e(n,o){parent.postMessage(n,o||"*")}function t(...n){return n.reduce((o,i)=>o.then(()=>new Promise(a=>{let s=document.createElement("script");s.src=i,s.onload=a,document.body.appendChild(s)})),Promise.resolve())}var r=class{constructor(n){this.url=n,this.onerror=null,this.onmessage=null,this.onmessageerror=null,this.m=a=>{a.source===this.w&&(a.stopImmediatePropagation(),this.dispatchEvent(new MessageEvent("message",{data:a.data})),this.onmessage&&this.onmessage(a))},this.e=(a,s,f,c,u)=>{if(s===this.url.toString()){let p=new ErrorEvent("error",{message:a,filename:s,lineno:f,colno:c,error:u});this.dispatchEvent(p),this.onerror&&this.onerror(p)}};let o=new EventTarget;this.addEventListener=o.addEventListener.bind(o),this.removeEventListener=o.removeEventListener.bind(o),this.dispatchEvent=o.dispatchEvent.bind(o);let i=document.createElement("iframe");i.width=i.height=i.frameBorder="0",document.body.appendChild(this.iframe=i),this.w.document.open(),this.w.document.write(` + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + +

How to contribute to Gramps Web

+

Thanks for considering to contribute to Gramps Web! Depending on your skills and interests, there are many ways how you can help.

+

Help translating Gramps Web to your language

+

Gramps & Gramps Web support several dozen different languages. Helping to translate the app does not require any programming skills. We use the powerful Weblate online tool for translations. Please see here for instructions on how to get started.

+

Help answering other users' questions

+

If you are already using Gramps Web, help new users finding the answers to their questions by contributing to discussions in the Gramps Web category of the official Gramps Discourse forum.

+

Help improve the documentation

+

The documentation site you're looking at is hosted on Github. Contributions to improve it are highly welcome. Just submit a pull request to that repository.

+

Contribute to backend development (Python)

+

If you are a Python programmer, contribute to the development of the Gramps Web API, which is the backend powering Gramps Web. See Backend development for instructions on how to get started.

+

Contribute to frontend development (Javascript)

+

If you are a web programmer, contribute to the development of Gramps Web's responsive frontend. See Frontend development for instructions on how to get started.

+

Contribute to the Sync addon (Python)

+

If you have experience with developing with Python and GTK, contribute to the improvement of The Gramps Web Sync Addon. You can use the development repository for suggesting and submitting improvements.

+ + + + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/cpu-limited/index.html b/cpu-limited/index.html new file mode 100644 index 0000000..cdb71ad --- /dev/null +++ b/cpu-limited/index.html @@ -0,0 +1,1500 @@ + + + + + + + + + + + + + + + + + + + + + + + + Limit CPU usage - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Limit CPU usage

+

In order to avoid high CPU/RAM usage, it is possible to set the number of workers +using the environment variable GUNICORN_NUM_WORKERS.

+

Here, we will take a number of workers = 2. Adjust it according to your needs. +It may be a good idea to check the CPU/Threads available before choosing the value:

+
+

lscpu | grep CPU

+
+

The easiest way is to declare the variable in the docker-compose.yml file, +under the "environment".

+
version: "3.7"
+services:
+  grampsweb:
+    environment:
+      GUNICORN_NUM_WORKERS: 2
+
+

Other ways are possible, for example by storing the variable in a file, +and calling it in the startup command:

+
+

docker compose --env-file ./env up

+
+

In this case, the env file would contain a single line: GUNICORN_NUM_WORKERS=2

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/dev-backend/api/index.html b/dev-backend/api/index.html new file mode 100644 index 0000000..0fc6159 --- /dev/null +++ b/dev-backend/api/index.html @@ -0,0 +1,1488 @@ + + + + + + + + + + + + + + + + + + + + + + + + API specification - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + + + +
+
+
+ + + + + + +
+
+
+ + + + + + + + + +
+ +
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/dev-backend/index.html b/dev-backend/index.html new file mode 100644 index 0000000..39b1da8 --- /dev/null +++ b/dev-backend/index.html @@ -0,0 +1,1490 @@ + + + + + + + + + + + + + + + + + + + + + + + + Introduction - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + + + +
+
+
+ + + + + + +
+
+
+ + + + + + + + + +
+
+ + + + + + + + +

Gramps Web backend development

+

The backend of Gramps Web is called Gramps Web API. In fact it is more than just an app backend: it provides a RESTful API to read and modify a Gramps database.

+

Gramps Web API is a Python application and is powered by the gramps library itself (which also powers the Gramps Desktop application).

+

In this section of the docs, you can learn how to contribute to Gramps Web API development.

+ + + + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/dev-backend/queries/index.html b/dev-backend/queries/index.html new file mode 100644 index 0000000..6884d4f --- /dev/null +++ b/dev-backend/queries/index.html @@ -0,0 +1,1556 @@ + + + + + + + + + + + + + + + + + + + + + + + + Manual queries - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Manual queries

+ +

For backend and frontend development, it can be useful to send manual queries to the Gramps Web API. Using HTTPie and jq, this can be done conveniently including JWT authentication.

+

Installation

+

HTTPie is installed with pip:

+
python3 -m pip install httpie
+
+

You will need HTTPie version 3.0.0 or newer.

+

jq can be installed in Ubuntu via

+
sudo apt install jq
+
+

Fetching an access token

+

To fetch an access token, query the token endpoint. Assuming your development instance is running on localhost:5555, you can use the command

+
http POST http://localhost:5555/api/token/ username=owner password=owner
+
+

You will see the JSON tokens as output.

+

Using jq, you can also store the access token in an environment variable:

+
export ACCESS_TOKEN=$(http POST http://localhost:5555/api/token/ \
+  username=owner password=owner | jq -r '.access_token')
+
+

You can now use this token in all API calls that require authentication, e.g.

+
http -A bearer -a $ACCESS_TOKEN GET http://localhost:5555/api/metadata/
+
+

Note that, by default, access tokens will expire after 15 minutes.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/dev-backend/setup/index.html b/dev-backend/setup/index.html new file mode 100644 index 0000000..585ff14 --- /dev/null +++ b/dev-backend/setup/index.html @@ -0,0 +1,1706 @@ + + + + + + + + + + + + + + + + + + + + + + + + Development setup - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + +

Development setup

+ +

This page lists the steps required to start developing Gramps Web API. It will be assumed that you are using Ubuntu Linux.

+

Python version

+

The Web API requires Python 3.7 or newer.

+

Install Gramps

+

The Web API requires the Gramps Python library to be importable. Starting from Gramps 5.2.0, it will be installable via pip. Right now, development is still based on Gramps 5.1.x, so the most convenient option is to install the Gramps apt package on Ubuntu

+
sudo apt install gramps
+
+
+

Info

+

Note that using the gramps Python package from Gramps installed with apt requires using the system Python interpreter, so you cannot work in a virtual environment.

+
+

Clone the Web API repository

+

Clone the Web API to your PC (assuming you have set up an SSH key with Github) using

+
git clone git@github.com:gramps-project/gramps-web-api.git
+cd gramps-web-api
+
+

Install prerequisites

+

To start development, please install the dependencies by running +

pip3 install -r requirements-dev.txt
+

+

Install the library in editable mode

+

Run +

pip3 install -e . --user
+

+

Set up pre-commit hooks

+

To set up the pre-commit hooks for the repository, run +

pre-commit install
+
+in the repository root. This will e.g. make sure that all source files are nicely formatted with black.

+

Run tests

+

To run the unit tests, run +

pytest
+
+in the repository root.

+

Generate a configuration file

+

Example content:

+
TREE="My Family Tree"
+SECRET_KEY="not_secure_enough"
+USER_DB_URI="sqlite:///users.sqlite"
+
+
+

Warning

+

Do not use this configuration in production.

+
+

See Configuration for a full list of config options.

+
+

Warning

+

Do not use your production database for development, but use a copy of it or the Gramps example database.

+
+

Add users

+

You can add a user with owner permissions by running +

python3 -m gramps_webapi --config path/to/config user add owner owner --role 4
+
+This uses username and password owner.

+

Run the app in development mode

+

Run +

python3 -m gramps_webapi --config path/to/config run
+
+The API will be accesible at http://127.0.0.1:5000 by default, which displays an empty page. Access your Gramps data using the API described by gramps-project.github.io/gramps-web-api. For example, to show people go to http://127.0.0.1:5000/api/people

+

To choose a different port, add the --port option.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/dev-frontend/architecture/index.html b/dev-frontend/architecture/index.html new file mode 100644 index 0000000..fc1e09d --- /dev/null +++ b/dev-frontend/architecture/index.html @@ -0,0 +1,1571 @@ + + + + + + + + + + + + + + + + + + + + + + + + Architecture - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Architecture

+

Components

+

The frontend is built out of web components. They are defined in the Javascript files in the src directory.

+

Typically, each file defines one component, starting with +

class GrampsjsSomeElement extends LitElement
+
+and ending with +
customElements.define('grampsjs-some-element', GrampsjsSomeElement)`
+
+that defines the new HTML element grampsjs-some-element that can be used elsewhere.

+

The main entrypoint, included in index.html , is the gramps-js element defined in GrampsJs.js. This contains the definition of all individual pages (that correspond simply to elements that are shown or hidden based on the route/URL), the menu, and routing.

+

The components in the src/views directory usually corresponds to full-page components that fetch data from the backend (e.g., the people list view), while components in src/components are usually smaller building blocks used inside the views that get their data from attributes provided by their parent element. However, this separation is not strict.

+

Data flow

+

Data is exchanged with the Backend/API via the apiGet, apiPut, and apiPost methods in src/api.js, which automatically take care of authentication.

+

Data is passed from parent components to child components via properties (see e.g. the Lit documentation).

+

When data needs to be fed back from a child to a parent component, custom events are used that can be fired with the fireEvent function in src/api.js and listened to using Lit's @ syntax (docs).

+

Authentication

+

The refresh token and authentication token are stored in the browser's local storage. Whenever an API call is made and the token is expired, the stored refresh token is used to fetch a new access token and the API call is repeated.

+

The user's authorization scope, which is stored in the access token's claims, is obtained with the getPermissions function and used in the top-level GrampsJs element to set the boolean properties canAdd, canEdit, canManageUsers, which are flowed down to child elements to implement authorization-specific functionality.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/dev-frontend/build/index.html b/dev-frontend/build/index.html new file mode 100644 index 0000000..afae74f --- /dev/null +++ b/dev-frontend/build/index.html @@ -0,0 +1,1422 @@ + + + + + + + + + + + + + + + + + + + + Build - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

To build the frontend for deployment, run +

npm run build
+

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/dev-frontend/index.html b/dev-frontend/index.html new file mode 100644 index 0000000..9983d77 --- /dev/null +++ b/dev-frontend/index.html @@ -0,0 +1,1489 @@ + + + + + + + + + + + + + + + + + + + + + + + + Introduction - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + + + +
+
+
+ + + + + + +
+
+
+ + + + + + + + + +
+
+ + + + + + + + +

Gramps Web frontend development

+

The Gramps Web frontend is written in Javascript and built using web components with Lit. This allows encapsulating functionality into reusable components.

+

The frontend is designed as a progressive single-page web app with a mobile-first experience. It makes heavy use of Material Web Components for a Material Design look and feel.

+ + + + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/dev-frontend/setup/index.html b/dev-frontend/setup/index.html new file mode 100644 index 0000000..ef8e991 --- /dev/null +++ b/dev-frontend/setup/index.html @@ -0,0 +1,1578 @@ + + + + + + + + + + + + + + + + + + + + + + + + Development setup - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Development setup

+ +

This page describes the steps needed to start with frontend development. It is assumed that you are using Ubuntu Linux and you will need Docker, docker-compose, and git.

+

Step 1: Clone the repository

+

Clone the frontend repository +

git clone git@github.com:gramps-project/gramps-web.git
+cd gramps-web
+

+

Step 2: Build and start the development containers

+

To build and start the containers running the Gramps Web backend with the Gramps example database, as well as the frontend in development mode, simply run

+
docker-compose up -d
+
+

Options for logging in are: owner, editor, contributor, guest or member (use same word for both username and password).

+
+

Warning

+

Do not use the development server in production.

+
+

As part of the build process, git hooks for formatting and linting will be installed as well.

+

Usage instructions

+

Once the containers are up and running, Gramps Web will be accessible at http://localhost:5555.

+
+

Info

+

Note since the *.json translation files are imported with the new syntax suggested in T39, you must use the Chrome or Chromium browser for the development server to work without errors. This issue is about to change in the future.

+
+

Once you make changes to the frontend code, you browser will be reloaded automatically.

+

The installed git hooks will format and lint the code on every commit. You can run the scripts manually using

+

docker-compose run gramps-frontend format
+
+and +
docker-compose run gramps-frontend lint
+
+respectively.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/dev-frontend/translation/index.html b/dev-frontend/translation/index.html new file mode 100644 index 0000000..576e57f --- /dev/null +++ b/dev-frontend/translation/index.html @@ -0,0 +1,1479 @@ + + + + + + + + + + + + + + + + + + + + + + + + Translation - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + + + +
+
+
+ + + + + + +
+
+
+ + + + + + + + + +
+
+ + + + + + + + +

Gramps Web leverages the translations of Gramps Desktop provided by the community for over 40 languages. The additional strings that only needed for the Web app are translated via Weblate.

+

To contribute, follow the instructions in the Gramps Wiki to get started with Weblate for Gramps. Once authenticated, you can start translating strings both for Gramps Desktop and Gramps Web.

+ + + + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/dev/index.html b/dev/index.html new file mode 100644 index 0000000..633b211 --- /dev/null +++ b/dev/index.html @@ -0,0 +1,1494 @@ + + + + + + + + + + + + + + + + + + + + + + + + Overview - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + + + +
+
+
+ + + + + + +
+
+
+ + + + + + + + + +
+
+ + + + + + + + +

Gramps Web development: overview

+

Gramps Web is a web application that consists of two components that are developed separately:

+
    +
  • Gramps Web API is a RESTful API written in Python and based on Flask. The source code is hosted at github.com/gramps-project/gramps-web-api. It manages database access and genealogical functions directly leveraging the Gramps Python library. It serves as the backend of Gramps Web. For development documentation, see Backend.
  • +
  • Gramps Web Frontend is a Javascript web application that serves as the frontend to Gramps Web. The source code is hosted at github.com/gramps-project/gramps-web. For development documentation, see Frontend.
  • +
+

A note on versioning: Gramps Web API and and the Gramps Web frontend are versioned independently. At present, "Gramps Web" – the combined application – does not have a separate version number. Both projects adhere to SemVer.

+

If you are not a Python or Javascript developer but would still like to contribute to Gramps Web, check out Contribute.

+ + + + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..c4a0fc6 Binary files /dev/null and b/favicon.ico differ diff --git a/frontend-config/index.html b/frontend-config/index.html new file mode 100644 index 0000000..1dedfa1 --- /dev/null +++ b/frontend-config/index.html @@ -0,0 +1,1527 @@ + + + + + + + + + + + + + + + + + + + + + + + + Frontend customization - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Customizing the frontend

+

The Gramps Web frontend is a Javascript application that is deployed as a set of static HTML, CSS, and Javascript files. Normally, no special configuration is necessary for the frontend. However, some behaviour can be changed by setting appropriate options in the config.js file at the root of the distriubtion.

+

The file should have the following structure:

+
window.grampsjsConfig = {
+    option: value
+}
+
+

The following option keys exist.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyTypeDescription
hideRegisterLinkbooleanIf true, hide the registration link on the login page. This should be used for multi-tree deployments.
loginRedirectstringURL to redirect to when not logged in and navigating to any page other than "login" or "register"
leafletTileUrlstringCustom tile URL for Leaflet maps
leafletTileSizenumberCustom tile size for Leaflet maps
leafletZoomOffsetnumberCustom zoom offset for Leaflet maps
leafletTileAttributionstringCustom attribution for Leaflet maps
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/help/index.html b/help/index.html new file mode 100644 index 0000000..7ea2520 --- /dev/null +++ b/help/index.html @@ -0,0 +1,1576 @@ + + + + + + + + + + + + + + + + + + + + + + Get Help - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + + + + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Get Help

+ +

If you run into issues or need help with Gramps Web, please pick one of the following options.

+

Forum +Backend issues +Frontend issues

+

See below for some guidance on where to head first.

+

Asking questions

+

The official Gramps Discourse forum has a separate category for Gramps Web. Please use it to ask any questions you may have about Gramps Web, for instance

+
    +
  • Questions on the usage of Gramps Web
  • +
  • Questions on the configuration of Gramps Web
  • +
  • Troubleshooting a deployment of Gramps Web
  • +
  • Ideas about improvements to Gramps Web
  • +
  • ...
  • +
+

Reporting issues

+

If you encounter a problem that you believe is a bug in Gramps Web, please support it via Github.

+

There are two separate Github repositories for the code used in Gramps Web, one for the user interface (“frontend”) and one for the server code (“backend”):

+ +

If you are unsure where to file an issue, don't worry and just choose either of the two – the maintainers will be able to transfer the issue if necessary.

+

In either case, please always include the following information in your report:

+
    +
  • Details about your setup (e.g. a docker-compose file with sensitive values redacted, or whether your are using a hosted version, such as Grampshub, or a pre-configured image, such as DigitalOcean)
  • +
  • Version information. To obtain it, go to the "System information" tab on the Settings page in Gramps Web and copy/paste the values in the box, which should look something like this:
  • +
+
Gramps 5.1.6
+Gramps Web API 1.5.1
+Gramps.js 24.1.0
+locale: en
+multi-tree: false
+task queue: true
+
+

Suggesting enhancements

+

For general ideas and discussion about future improvements, feel free to open a discussion in the forum. You may also want to check the issue pages (see links above) whether a particular feature is already planned or being worked on.

+

For specific enhancements with a limited scope, feel free to directly open an issue with a feature request in the appropriate frontend or backend Github repository.

+ + + + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..a705bbf --- /dev/null +++ b/index.html @@ -0,0 +1,1793 @@ + + + + + + + + + + + + + + + + + + + + + + Features - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + +

+

Research & organize your family tree together

+ +

Gramps Web is a web app for collaborative genealogy. It is based on and interoperable with Gramps, the leading open source genealogy desktop application. Gramps Web is free & open source software and puts your privacy and your control of your research data first.

+ +

 

+ +
+ +

Image title

+

Access to all your data, respecting privacy

+

Browse all objects in your family tree: people, families, events, places, repositories, sources, citations, media objects, and notes.

+

Choose for each user whether they are allowed to view records marked as private. Private records are filtered out at the database layer for maximum security.

+
+
+ +

Image title

+

Collaborative editing & adding data on the go

+

Grant users the right to add new or editing existing objects.

+

Upload new sources, photos, or create new objects from any device.

+
+
+ +

Image title

+

Interactive family tree graphs

+

Navigate your family tree as an ancestor chart, descendant chart, hourglass chart, or as fan chart, with high-quality interactive graphics and configurable number of generations.

+
+
+ +

Image title

+

Powerful map

+

Display all places on an interactive, searchable map.

+

Turn a historical map stored as media object in Gramps into a custom map overlay.

+
+
+ +

Image title

+

Genealogy Blog included

+

Summarize your research in the form of blog stories with pictures. All data is stored in the Gramps database.

+
+
+ +

Image title

+

Fully internationalized

+

Switch the language of the interface between any of 40 languages translated by the Gramps community.

+
+
+ +

Image title

+

No lock-in – data import and export

+

Apart from being able to import data in various formats including Gramps XML and GEDCOM, Gramps Web makes it easy for users to download all of their data (family tree data, media files, user accounts) anytime, for backup purposes or to move to a different server. Your data is yours alone!

+
+
+ +

Image title

+

Generate printable reports

+

Since it's built directly on the core powering Gramps Desktop, you can generate almost all of the reports the desktop app supports right from the browser, including relationship graphs or book reports as PDF.

+
+
+ +

Image title

+

Full integration with Gramps Desktop

+

Gramps Web uses the core of Gramps, the most powerful and popular open-source cross-platform desktop application. It does not only use the same data model and database for storing genalogical data, but can also be synchronized both ways using a Gramps addon.

+

Edit your tree on the Web and in the fully-featured desktop app you've grown to love – they work together seamlessly.

+
+
+ +

Image title

+

Tag people in photos with automated face detection

+

Collaborate with your relatives to identify ancestors in old family photos. Thanks to automated face detection, tagging people is just two clicks away.

+
+
+ +

Image title

+ +

The search engine supports searching all Gramps object types, including the content of text notes, and supports wildcard syntax and logical operators.

+
+
+ +

Image title

+

DNA matches & chromosome browser

+

If you have DNA match data from one of the DNA genealogy providers, upload it and store it in a future-proof way and view your matches in an interactive chromosome browser.

+
+
+ +

Image title

+

Integrated task management app

+

Gramps Web comes with an integrated task management app to organize and plan your genealogical research. The tasks are stored as sources in the Gramps database, so they form part of your genealogical data an can be accessed and edited in Gramps Desktop as well.

+
+
+ +

 

+ +

Demo

+

Open Demo

+

Use owner, editor, contributor, or member as username and the same as password.

+ + + + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/logo.svg b/logo.svg new file mode 100644 index 0000000..8474717 --- /dev/null +++ b/logo.svg @@ -0,0 +1,154 @@ + +image/svg+xml diff --git a/multi-tree/index.html b/multi-tree/index.html new file mode 100644 index 0000000..9ab8dfd --- /dev/null +++ b/multi-tree/index.html @@ -0,0 +1,1638 @@ + + + + + + + + + + + + + + + + + + + + + + + + Multi-tree setup - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + +

Setup for hosting multiple trees

+

By default, Gramps Web only allows accessing a single family tree database (“tree”), specified in the configuration file.

+

However, starting with version 0.7.0 of the Gramps Web API backend, it is also possible to serve multiple trees from a single installation. However, each user is (currently) tied to a single tree, so this setup is not suited for sharing trees among users, but for hosting multiple isolated Gramps Web instances.

+

Enable multi-tree support

+

To enable multi-tree support, the TREE config option must be set to a single asterisk *, e.g. in a configuration file:

+
TREE = "*"
+
+

This will make all trees in the server's Gramps database directory accessible (given sufficient user permissions). The tree's ID is the name of the subdirectory. You can list existing trees (names and IDs) with the command

+
python -m gramps_webapi --config /app/config/config.cfg tree list
+
+

In addition, you should set the MEDIA_PREFIX_TREE configuration option to True to ensure media files are stored in separate subfolders. Otherwise, users are able to access media files that belong to a tree they have no permission for!

+

Add a user account to a specific tree

+

To add a user to a specific tree, simply add the --tree TREEID command line option to the add user command. You can also POST to the /users/ endpoint with the tree property set in the JSON payload.

+

User names and e-mail addresses are required to be unique across all trees.

+

Create a new tree

+

To create a new tree, it is recommended to POST to the /trees/ endpoint rather than using the Gramps CLI. This will use a UUIDv4 as tree ID, which leads to additional security as the name cannot be guessed. Currently, only SQLite is supported for newly created trees.

+

Authorize

+

To authorize (fetch a token), only user name and password are necessary, like in single-tree mode, since the tree ID is known for each user, so there is no need to provide it.

+

Migrate existing media files

+

If you want to migrate an existing Gramps Web instance to multi-tree support and are using local media files, you can simply move them to a subfolder of the original location with the tree ID as name.

+

If you are using media files hosted on S3, you can use the script provided in the scripts directory of the gramps-web-api repository:

+
python scripts/s3_rename.py BUCKET_NAME TREE_ID
+
+

This assumes the relevant access keys are set as environment variables already.

+

Migrate existing user database

+

If you want to enable multi-tree support and reuse existing users, you need to assign them to a specific tree. You can use the following command provided for this purpose,

+
python -m gramps_webapi --config /app/config/config.cfg user fill-tree TREE_ID
+
+

Customize the frontend

+

The registration page accessible from the login page does not work in a multi-tree setup, since a tree needs to be specified for registration. It is thus advisable to set hideRegisterLink to true in the frontend configuration.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/quickstart/index.html b/quickstart/index.html new file mode 100644 index 0000000..13ed293 --- /dev/null +++ b/quickstart/index.html @@ -0,0 +1,1483 @@ + + + + + + + + + + + + + + + + + + + + + + + + Try out locally - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

To try out Gramps Web on your local computer (Linux, Mac, or Windows) without interfering with your Gramps Desktop installation, you can use Docker with the following command:

+
docker run -p "5055:5000" -e TREE=new ghcr.io/gramps-project/grampsweb:latest
+
+

This will make a new, empty Gramps Web instance accessible at http://localhost:5055, where you can create an admin user and import a Gramps XML file.

+
+

Info

+

Since this simple setup does not allow running long tasks in a separate process, importing a large Gramps XML file might fail due to a timeout in the first-run assistant.

+
+

To use media files from your computer you can mount the Gramps media folder into the container with

+
docker run -p "5055:5000" -e TREE=new \
+  -v /path/to/my/gramps_media_folder:/app/media \
+  ghcr.io/gramps-project/grampsweb:latest
+
+

Note that this will not persist the changes you make to the database when you restart the container. To properly set up Gramps Web, continue reading about Deployment.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/requirements/index.html b/requirements/index.html new file mode 100644 index 0000000..af1333b --- /dev/null +++ b/requirements/index.html @@ -0,0 +1,1447 @@ + + + + + + + + + + + + + + + + + + + + Setup Requirements - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Setup Requirements

+

Gramps Web is a web app that runs on a server and is accessed via the web browser. It is meant to be made accessible to authenticated users via the internet.

+

Server Requirements

+

The most convenient way to host Gramps Web is via Docker Compose. While this is not possible with ordinary "shared hosting" providers, this makes it possible to host the app on Linux, Mac, or Windows; it can be hosted on a virtual server or on a Raspberry Pi (we provide Docker images for the ARM architecture) in your basement.

+

Apart from Docker, you will also need some storage space to store your media files (images, documents).

+

Finally, Gramps Web is only secure when served via HTTPS, so you will require an SSL/TLS certificate. The docs below show how to get one automatically for free from Let's Encrypt.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/s3/index.html b/s3/index.html new file mode 100644 index 0000000..fbb8538 --- /dev/null +++ b/s3/index.html @@ -0,0 +1,1596 @@ + + + + + + + + + + + + + + + + + + + + + + + + Hosting media on S3 - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Hosting media files on S3

+

Instead of hosting the media files of the family tree on the same server as the Gramps database, they can also be hosted on Amazon S3 or a different API-compatible object storage service. This strongly reduces storage and traffic requirements for the Gramps Web server.

+

Preparing credentials

+

In your AWS (or other object storage service) account, get an access key ID and secret access key (you may first want to create a separate user with a security policy allowing only access to S3).

+

Upload media files

+

To upload your existing media files to S3, on Linux you can use a local Gramps installation with the S3 Media Uploader Addon, that you can install directly from Gramps desktop. However, some additional configuration is necessary.

+

The addon uses the boto3 Python library under the hood. You need to install it first with

+
python3 -m pip install boto3
+
+

On the command line, export the access key ID and secret key to the appropriate environment variables: +

export AWS_ACCESS_KEY_ID=my_access_key_id
+export AWS_SECRET_ACCESS_KEY=my_secret_access_key
+

+

Now, you can start the uploader by runing the following command,

+
gramps -O "My Family Tree" -a tool \
+    -p "name=s3uploader,bucket_name=my_bucket_name"
+
+

replacing "My Family Tree" with the name of your family tree and my_bucket_name with the complete name of your S3 bucket. You will need a dedicated S3 bucket for your Gramps Web instance. If the bucket does not exist yet, the S3 Uploader Addon will attempt to create it.

+

Configure Gramps Web

+

To use the new S3 bucket as media source for Gramps Web, simply set the MEDIA_BASE_DIR configuration option to s3://my_bucket_name.

+

When using Docker Compose, the easiest option is to add all environment variables to the env block:

+
env:
+  AWS_ACCESS_KEY_ID: my_access_key_id
+  AWS_SECRET_ACCESS_KEY: my_secret_access_key
+  MEDIA_BASE_DIR: s3://my_bucket_name
+  AWS_DEFAULT_REGION: eu-central-1
+
+

If you want to use an S3-compatible object storage other than AWS (e.g. GCP or for local testing), set the AWS_ENDPOINT_URL environment variable.

+

Synchronizing media files

+

To keep media files in sync between a local Gramps installation and S3-hosted Gramps Web media files, the Gramps Web Sync Addon supports file synchronization via the Web API.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..c9297d8 Binary files /dev/null and b/screenshot.png differ diff --git a/screenshots/blog.png b/screenshots/blog.png new file mode 100644 index 0000000..cb6c19d Binary files /dev/null and b/screenshots/blog.png differ diff --git a/screenshots/dna.png b/screenshots/dna.png new file mode 100644 index 0000000..600bc06 Binary files /dev/null and b/screenshots/dna.png differ diff --git a/screenshots/export.png b/screenshots/export.png new file mode 100644 index 0000000..fe9a32c Binary files /dev/null and b/screenshots/export.png differ diff --git a/screenshots/fan.png b/screenshots/fan.png new file mode 100644 index 0000000..ce21f54 Binary files /dev/null and b/screenshots/fan.png differ diff --git a/screenshots/lang.png b/screenshots/lang.png new file mode 100644 index 0000000..ed5d305 Binary files /dev/null and b/screenshots/lang.png differ diff --git a/screenshots/list.png b/screenshots/list.png new file mode 100644 index 0000000..c48907a Binary files /dev/null and b/screenshots/list.png differ diff --git a/screenshots/map.png b/screenshots/map.png new file mode 100644 index 0000000..597e625 Binary files /dev/null and b/screenshots/map.png differ diff --git a/screenshots/new_event.png b/screenshots/new_event.png new file mode 100644 index 0000000..c420bcd Binary files /dev/null and b/screenshots/new_event.png differ diff --git a/screenshots/new_media.png b/screenshots/new_media.png new file mode 100644 index 0000000..0857e08 Binary files /dev/null and b/screenshots/new_media.png differ diff --git a/screenshots/report.png b/screenshots/report.png new file mode 100644 index 0000000..b91b5ef Binary files /dev/null and b/screenshots/report.png differ diff --git a/screenshots/search.png b/screenshots/search.png new file mode 100644 index 0000000..f17c64c Binary files /dev/null and b/screenshots/search.png differ diff --git a/screenshots/sync.png b/screenshots/sync.png new file mode 100644 index 0000000..f852907 Binary files /dev/null and b/screenshots/sync.png differ diff --git a/screenshots/tag.png b/screenshots/tag.png new file mode 100644 index 0000000..922c4b5 Binary files /dev/null and b/screenshots/tag.png differ diff --git a/screenshots/tasks.png b/screenshots/tasks.png new file mode 100644 index 0000000..ebf52f0 Binary files /dev/null and b/screenshots/tasks.png differ diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 0000000..18ce7a4 --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Research & organize your family tree together","text":"

Gramps Web is a web app for collaborative genealogy. It is based on and interoperable with Gramps, the leading open source genealogy desktop application. Gramps Web is free & open source software and puts your privacy and your control of your research data first.

"},{"location":"#access-to-all-your-data-respecting-privacy","title":"Access to all your data, respecting privacy","text":"

Browse all objects in your family tree: people, families, events, places, repositories, sources, citations, media objects, and notes.

Choose for each user whether they are allowed to view records marked as private. Private records are filtered out at the database layer for maximum security.

"},{"location":"#collaborative-editing-adding-data-on-the-go","title":"Collaborative editing & adding data on the go","text":"

Grant users the right to add new or editing existing objects.

Upload new sources, photos, or create new objects from any device.

"},{"location":"#interactive-family-tree-graphs","title":"Interactive family tree graphs","text":"

Navigate your family tree as an ancestor chart, descendant chart, hourglass chart, or as fan chart, with high-quality interactive graphics and configurable number of generations.

"},{"location":"#powerful-map","title":"Powerful map","text":"

Display all places on an interactive, searchable map.

Turn a historical map stored as media object in Gramps into a custom map overlay.

"},{"location":"#genealogy-blog-included","title":"Genealogy Blog included","text":"

Summarize your research in the form of blog stories with pictures. All data is stored in the Gramps database.

"},{"location":"#fully-internationalized","title":"Fully internationalized","text":"

Switch the language of the interface between any of 40 languages translated by the Gramps community.

"},{"location":"#no-lock-in-data-import-and-export","title":"No lock-in \u2013 data import and export","text":"

Apart from being able to import data in various formats including Gramps XML and GEDCOM, Gramps Web makes it easy for users to download all of their data (family tree data, media files, user accounts) anytime, for backup purposes or to move to a different server. Your data is yours alone!

"},{"location":"#generate-printable-reports","title":"Generate printable reports","text":"

Since it's built directly on the core powering Gramps Desktop, you can generate almost all of the reports the desktop app supports right from the browser, including relationship graphs or book reports as PDF.

"},{"location":"#full-integration-with-gramps-desktop","title":"Full integration with Gramps Desktop","text":"

Gramps Web uses the core of Gramps, the most powerful and popular open-source cross-platform desktop application. It does not only use the same data model and database for storing genalogical data, but can also be synchronized both ways using a Gramps addon.

Edit your tree on the Web and in the fully-featured desktop app you've grown to love \u2013 they work together seamlessly.

"},{"location":"#tag-people-in-photos-with-automated-face-detection","title":"Tag people in photos with automated face detection","text":"

Collaborate with your relatives to identify ancestors in old family photos. Thanks to automated face detection, tagging people is just two clicks away.

"},{"location":"#powerful-full-text-search","title":"Powerful full-text search","text":"

The search engine supports searching all Gramps object types, including the content of text notes, and supports wildcard syntax and logical operators.

"},{"location":"#dna-matches-chromosome-browser","title":"DNA matches & chromosome browser","text":"

If you have DNA match data from one of the DNA genealogy providers, upload it and store it in a future-proof way and view your matches in an interactive chromosome browser.

"},{"location":"#integrated-task-management-app","title":"Integrated task management app","text":"

Gramps Web comes with an integrated task management app to organize and plan your genealogical research. The tasks are stored as sources in the Gramps database, so they form part of your genealogical data an can be accessed and edited in Gramps Desktop as well.

"},{"location":"#demo","title":"Demo","text":"

Open Demo

Use owner, editor, contributor, or member as username and the same as password.

"},{"location":"Configuration/","title":"Server Configuration","text":"

Using the default Docker image, all necessary configuration can be made from the browser. However, depending on the deployment, it can be necessary to customize the server configuration.

This page lists all methods to change the configuration and all existing configuration options.

"},{"location":"Configuration/#configuration-file-vs-environment-variables","title":"Configuration file vs. environment variables","text":"

For the settings, you can either use a configuration file or environment variables.

When you use the Docker Compose based setup, you can include a configuration file by adding the following list item under the volumes: key in the grampsweb: block:

      - /path/to/config.cfg:/app/config/config.cfg\n
where /path/to/config.cfg is the path to the config file in your server's file system (the right-hand side refers to the path in the container and must not be changed).

When using environment variables,

  • prefix every setting name with GRAMPSWEB_ to obtain the name of the environment variable
  • Use double underscores for nested dictionary settings, e.g GRAMPSWEB_THUMBNAIL_CACHE_CONFIG__CACHE_DEFAULT_TIMEOUT will set the value of the THUMBNAIL_CACHE_CONFIG['CACHE_DEFAULT_TIMEOUT'] config option
"},{"location":"Configuration/#existing-configuration-settings","title":"Existing configuration settings","text":"

The following configuration options exist.

"},{"location":"Configuration/#required-settings","title":"Required settings","text":"Key Description TREE The name of the family tree database to use. Show available trees with gramps -l. If a tree with this name does not exist, a new empty one will be created. SECRET_KEY The secret key for flask. The secret must not be shared publicly. Changing it will invalidate all access tokens

Info

You can generate a secure secret key e.g. with the command

python3 -c \"import secrets;print(secrets.token_urlsafe(32))\"\n
"},{"location":"Configuration/#optional-settings","title":"Optional settings","text":"Key Description MEDIA_BASE_DIR Path to use as base directory for media files, overriding the media base directory set in Gramps. When using S3, must have the form s3://<bucket_name> SEARCH_INDEX_DIR Path for the full-text search index. Defaults to indexdir relative to the path where the script is run STATIC_PATH Path to serve static files from (e.g. a static web frontend) BASE_URL Base URL where the API can be reached (e.g. https://mygramps.mydomain.com/). This is necessary e.g. to build correct passwort reset links CORS_ORIGINS Origins where CORS requests are allowed from. By default, all are disallowed. Use \"*\" to allow requests from any domain. EMAIL_HOST SMTP server host (e.g. for sending password reset e-mails) EMAIL_PORT SMTP server port. defaults to 465 EMAIL_HOST_USER SMTP server username EMAIL_HOST_PASSWORD SMTP server password EMAIL_USE_TLS Boolean, whether to use TLS for sending e-mails. Defaults to True. When using STARTTLS, set this to False and use a port different from 25. DEFAULT_FROM_EMAIL \"From\" address for automated e-mails THUMBNAIL_CACHE_CONFIG Dictionary with settings for the thumbnail cache. See Flask-Caching for possible settings. CELERY_CONFIG Settings for the Celery background task queue. See Celery for possible settings. REPORT_DIR Temporary directory where the output of running Gramps reports will be stored EXPORT_DIR Temporary directory where the output of exporting the Gramps database will be stored

Info

When using environment variables for configuration, boolean options like EMAIL_USE_TLS must be either the string true or false (case senitive!).

"},{"location":"Configuration/#settings-only-for-postgresql-backend-database","title":"Settings only for PostgreSQL backend database","text":"

This is required if you've configured your Gramps database to work with the PostgreSQL addon.

Key Description POSTGRES_USER The user name for the database connection POSTGRES_PASSWORD The password for the database user"},{"location":"Configuration/#settings-relevant-for-hosting-multiple-trees","title":"Settings relevant for hosting multiple trees","text":"

The following settings are relevant when hosting multiple trees.

Key Description MEDIA_PREFIX_TREE Boolean, whether or not to use a separate subfolder for the media files of each tree. Defaults to False, but strongly recommend to use True in a multi-tree setup NEW_DB_BACKEND The database backend to use for newly created family trees. Must be one of sqlite, postgresql, or sharedpostgresql. Defaults to sqlite."},{"location":"Configuration/#example-configuration-file","title":"Example configuration file","text":"

A minimal configuration file for production could look like this:

TREE=\"My Family Tree\"\nBASE_URL=\"https://mytree.example.com\"\nSECRET_KEY=\"...\"  # your secret key\nUSER_DB_URI=\"sqlite:////path/to/users.sqlite\"\nEMAIL_HOST=\"mail.example.com\"\nEMAIL_PORT=465\nEMAIL_USE_TLS=True\nEMAIL_HOST_USER=\"gramps@example.com\"\nEMAIL_HOST_PASSWORD=\"...\" # your SMTP password\nDEFAULT_FROM_EMAIL=\"gramps@example.com\"\n

"},{"location":"Deployment/","title":"Deploying Gramps Web with Docker","text":"

The most convenient option to host Gramps Web on your own server (or virtual server) is with Docker Compose.

We will assume that Docker and Docker Compose are already installed in your system. You can use Windows, Mac OS, or Linux as a host system. The supported architectures include not only x86-64 (desktop systems), but also ARM systems such as a Raspberry Pi, which can serve as a low-cost, but powerful (enough) web server.

Note

You do not need to install Gramps on the server as it is contained in the docker image.

"},{"location":"Deployment/#step-1-docker-configuration","title":"Step 1: Docker configuration","text":"

Create a new file on the server named docker-compose.yml and insert the following contents: docker-compose.yml.

This will generate six named volumes to make sure that all relevant data will persist when restarting the container.

Warning

The above will make the API available on port 80 of the host machine without SSL/TLS protection. You can use this for local testing, but do not expose this directly to the internet, it is completely insecure!

"},{"location":"Deployment/#step-2-secure-access-with-ssltls","title":"Step 2: Secure access with SSL/TLS","text":"

The web API must be served to the public internet over HTTPS. There are several options, e.g.

  • Using docker hosting that includes SSL/TLS automatically
  • Using an Nginx Reverse Proxy with a Let's Encrypt certificate

See Docker with Let's Encrypt for how to set up the former.

If you plan to use Gramps Web only on your local network, you can skip this step.

"},{"location":"Deployment/#step-3-start-the-server","title":"Step 3: Start the server","text":"

Run

docker-compose up -d\n

On first run, the app will display a first-run wizard that will allow you to

  • Create and account for the owner (admin) user
  • Set some necessary configuration options
  • Import a family tree in Gramps XML (.gramps) format
"},{"location":"Deployment/#step-4-upload-media-files","title":"Step 4: Upload media files","text":"

There are several options for uploading media files.

  • When using files stored on the same server as Gramps Web, you can mount a directory into the Docker container instead of using a named volume, i.e. /home/server_user/gramps_media/:/app/mediainstead of gramps_media:/app/media, and upload your media files there.
  • When using media files hosted on S3, you can use he S3 Media Uploader Addon
  • The arguably most convenient option is to use Gramps Web Sync.
"},{"location":"DigitalOcean/","title":"Gramps Web DigitalOcean 1-Click App","text":"

Instead of setting up Gramps Web yourself, you can also use the Gramps Web DigitalOcean 1-Click App.

As part of the setup procedure, you will have to sign up for an account with DigitalOcean and select a paid plan for the \"droplet\" (virtual machine) to use.

Arguably, this is currently the simplest way to deploy your own, self-hosted Gramps Web instance, secured with SSL, without using your own hardware.

Info

Note that you will be paying DigitalOcean for the hosting services. The Gramps open source project does not provide paid support.

"},{"location":"DigitalOcean/#step-1-create-a-digitalocean-account","title":"Step 1: Create a DigitalOcean account","text":"

Create an account at DigitalOcean if you don't have one yet.

"},{"location":"DigitalOcean/#step-2-create-the-droplet","title":"Step 2: Create the droplet","text":"
  • Go to Gramps Web 1-Click App and click \"Create Gramps Web Droplet\".
  • Choose a plan with at least 2 GB of RAM.
  • Set up authentication to your droplet
  • Click \"Create Droplet\"
"},{"location":"DigitalOcean/#step-3-set-up-a-domain-name","title":"Step 3: Set up a domain name","text":"

You will need a domain name (or subdomain). If you own a domain, point it to the IP address of your droplet. Otherwise, you could use a free service such as DuckDNS.

"},{"location":"DigitalOcean/#step-4-log-in-to-your-droplet","title":"Step 4: Log in to your droplet","text":"

SSH into your droplet. You should be presented with the message \"Welcome to the Gramps Web DigitalOcean 1-click app setup!\". If this is not the case, wait a few minutes and try again (the installation is not yet finished).

The setup script will ask you for the domain name (e.g. mygrampswebinstance.duckdns.org) and an e-mail address (needed for the Let's Encrypt certificate).

When this is done, wait for the setup to be completed in the background

"},{"location":"DigitalOcean/#step-5-launch-gramps-web","title":"Step 5: Launch Gramps Web","text":"

Your Gramps Web instance should now be accessible at the root of your domain, with a valid SSL certificate, and it should be showing the first-run assistant.

"},{"location":"LetsEncrypt/","title":"Setting up HTTPS with Let's Encrypt and Docker Compose","text":"

When served to the public internet, Gramps Web must use HTTPS encryption.

A particularly convenient option is to use a dockerized Nginx reverse proxy with automated Let's Encrypt certificate generation. This is achieved with this docker-compose.yml. (The nginx_proxy.conf needs to be stored in the same directory to allow uploading large media files to Gramps Web.)

Please see the acme-companion docs for how to set up your domain.

"},{"location":"Postgres/","title":"Using a PostgreSQL database","text":"

By default, Gramps uses a file-based SQLite database to store the family tree. This works perfectly fine for Gramps Web and is recommended for most users. However, starting with Gramps Web API version 0.3.0, also a PostgreSQL server with a single family tree per database is supported, powered by the Gramps PostgreSQL Addon.

"},{"location":"Postgres/#setting-up-the-postgresql-server","title":"Setting up the PostgreSQL server","text":"

You can follow the instructions in the Gramps Wiki to set up the PostgreSQL server.

Alternatively, you can also use Docker Compose to run the PostgreSQL server in a container on the same docker host as Gramps Web.

Using a dockerized PostgreSQL with Gramps is only complicated by the fact the the default PostgreSQL images do not have any locales installed, which are however needed by Gramps for localized collation of objects. Thus, it is necessary to use a custom Dockerfile.

Create a Dockerfile with the following contens in a directory postgres next to your docker-compose.yml:

FROM postgres:14\n\nRUN apt-get update && apt-get install -y locales-all \\\n    && rm -rf /var/lib/apt/lists/*\n

Next, add the following section to your docker-compose.yml:

  postgres_gramps:\nbuild: ./postgres\nrestart: unless-stopped\nenvironment:\nPOSTGRES_PASSWORD: your_postgres_password\nPOSTGRES_USER: postgres\nvolumes:\n- postgres_data:/var/lib/postgresql/data\n
and also add postgres_data: as key under the volumes: section of this YAML file.

"},{"location":"Postgres/#importing-a-gramps-family-tree","title":"Importing a Gramps family tree","text":"

Again, if you have set up the PostgreSQL server yourself, you can follow the instructions in the Gramps Wiki to import a family tree into the database.

Alternatively, if you have followed the Docker Compose instructions above, you can use the following command to import a Gramps XML file located on your docker host:

docker-compose run --entrypoint \"\" grampsweb \\\ngramps -C postgres \\\n-i /root/.gramps/grampsdb/my_tree.gramps \\\n--config=database.backend:postgresql \\\n--config=database.host:postgres_gramps \\\n--config=database.port:5432 \\\n--username=postgres --password=your_postgres_password\n
"},{"location":"Postgres/#configuring-web-api-for-use-with-the-database","title":"Configuring Web API for use with the database","text":"

To configure Web API for use with the PostgreSQL database, add the following under the environment: key of the grampsweb service in docker-compose.yml:

      # the PostgreSQL addon assumes the tree name to be\n# equal to the database name and here the default \n# database name of the PostgreSQL image is used\nTREE: postgres\n# The credentials must agree with the ones used for\n# the PostgreSQL container\nPOSTGRES_USER: postgres\nPOSTGRES_PASSWORD: your_postgres_password\n
"},{"location":"Postgres/#issues","title":"Issues","text":"

In case of issues, please monitor the log output of Gramps Web and the PostgreSQL server. In the case of docker, this is achieved with

docker-compose logs grampsweb\ndocker-compose logs postgres_grampsweb\n

If you suspect there is an issue with Gramps Web (or the documentation), please file an issue on Github.

"},{"location":"Update/","title":"Update Gramps Web","text":"

If you are using one of the installation methods based on Docker Compose, updating Gramps Web to the latest version is simple. In the folder where your docker-compose.yml is located, run the following commands

docker-compose pull\ndocker-compose up -d\n

For minor version jumps of Gramps Web API, this is all that is needed. Do follow the release notes of Gramps Web API though, as there could be breaking changes that require additional attention or configuration changes.

Note that the default grampsweb:latest docker image always combines the latest version of the API with the latest version of the frontend. If you want to upgrade the two components separately - which is possible - a more involved setup than described here is necessary.

"},{"location":"Users/","title":"User system","text":"

Gramps Web is not meant to be exposed to the internet for public access, but only by authenticated users. User accounts can be created by the site owner via the command line or web interface, or by self-registration and subsequent approval by the site owner.

"},{"location":"Users/#user-roles","title":"User roles","text":"

The following user roles are currently defined.

Role Role ID Permissions Guest 0 View non-private objects Member 1 Guest + view private objects Contributor* 2 Member + add objects Editor 3 Contributor + edit and delete objects Owner 4 Editor + manage users Admin 5 Owner + edit other trees in multi-tree setup

* Note that the \"Contributor\" role is currently only partially supported; e.g., family objects cannot be added since they imply a modification of the underlying Gramps person objects of family members. It is recommended to use the other roles whenever possible.

"},{"location":"Users/#managing-users","title":"Managing users","text":"

There are two ways to manage users:

  • With owner permissions using the web interface
  • On the command line on the server

The owner account required to first access the web app can be added in the onboarding wizard that is automatically launched when accessing Gramps Web with an empty user database.

"},{"location":"Users/#managing-users-on-the-command-line","title":"Managing users on the command line","text":"

When using Docker Compose, the basic command is

docker-compose run grampsweb python3 -m gramps_webapi user COMMAND [ARGS]\n

The COMMAND can be add or delete. Use --help for [ARGS] to show the syntax and possible configuration options.

"},{"location":"admin/","title":"Gramps Web Family Tree Administration","text":"

Whether you have set up your own instance of Gramps Web or signed up for a pre-installed one, the next step is to populate and manage your family tree database.

The focus of this section is on administrative tasks performed by tree owners. Usually, there is one tree owner for each family tree database (although as tree owner, you can also create other tree owner accounts).

This section only deals with actions that can be performed from the web interface. For command line tools or server configuration, see the previous section Setup.

"},{"location":"contribute/","title":"How to contribute to Gramps Web","text":"

Thanks for considering to contribute to Gramps Web! Depending on your skills and interests, there are many ways how you can help.

"},{"location":"contribute/#help-translating-gramps-web-to-your-language","title":"Help translating Gramps Web to your language","text":"

Gramps & Gramps Web support several dozen different languages. Helping to translate the app does not require any programming skills. We use the powerful Weblate online tool for translations. Please see here for instructions on how to get started.

"},{"location":"contribute/#help-answering-other-users-questions","title":"Help answering other users' questions","text":"

If you are already using Gramps Web, help new users finding the answers to their questions by contributing to discussions in the Gramps Web category of the official Gramps Discourse forum.

"},{"location":"contribute/#help-improve-the-documentation","title":"Help improve the documentation","text":"

The documentation site you're looking at is hosted on Github. Contributions to improve it are highly welcome. Just submit a pull request to that repository.

"},{"location":"contribute/#contribute-to-backend-development-python","title":"Contribute to backend development (Python)","text":"

If you are a Python programmer, contribute to the development of the Gramps Web API, which is the backend powering Gramps Web. See Backend development for instructions on how to get started.

"},{"location":"contribute/#contribute-to-frontend-development-javascript","title":"Contribute to frontend development (Javascript)","text":"

If you are a web programmer, contribute to the development of Gramps Web's responsive frontend. See Frontend development for instructions on how to get started.

"},{"location":"contribute/#contribute-to-the-sync-addon-python","title":"Contribute to the Sync addon (Python)","text":"

If you have experience with developing with Python and GTK, contribute to the improvement of The Gramps Web Sync Addon. You can use the development repository for suggesting and submitting improvements.

"},{"location":"cpu-limited/","title":"Limit CPU usage","text":"

In order to avoid high CPU/RAM usage, it is possible to set the number of workers using the environment variable GUNICORN_NUM_WORKERS.

Here, we will take a number of workers = 2. Adjust it according to your needs. It may be a good idea to check the CPU/Threads available before choosing the value:

lscpu | grep CPU

The easiest way is to declare the variable in the docker-compose.yml file, under the \"environment\".

version: \"3.7\"\nservices:\n  grampsweb:\n    environment:\n      GUNICORN_NUM_WORKERS: 2\n

Other ways are possible, for example by storing the variable in a file, and calling it in the startup command:

docker compose --env-file ./env up

In this case, the env file would contain a single line: GUNICORN_NUM_WORKERS=2

"},{"location":"dev/","title":"Gramps Web development: overview","text":"

Gramps Web is a web application that consists of two components that are developed separately:

  • Gramps Web API is a RESTful API written in Python and based on Flask. The source code is hosted at github.com/gramps-project/gramps-web-api. It manages database access and genealogical functions directly leveraging the Gramps Python library. It serves as the backend of Gramps Web. For development documentation, see Backend.
  • Gramps Web Frontend is a Javascript web application that serves as the frontend to Gramps Web. The source code is hosted at github.com/gramps-project/gramps-web. For development documentation, see Frontend.

A note on versioning: Gramps Web API and and the Gramps Web frontend are versioned independently. At present, \"Gramps Web\" \u2013 the combined application \u2013 does not have a separate version number. Both projects adhere to SemVer.

If you are not a Python or Javascript developer but would still like to contribute to Gramps Web, check out Contribute.

"},{"location":"frontend-config/","title":"Customizing the frontend","text":"

The Gramps Web frontend is a Javascript application that is deployed as a set of static HTML, CSS, and Javascript files. Normally, no special configuration is necessary for the frontend. However, some behaviour can be changed by setting appropriate options in the config.js file at the root of the distriubtion.

The file should have the following structure:

window.grampsjsConfig = {\noption: value\n}\n

The following option keys exist.

Key Type Description hideRegisterLink boolean If true, hide the registration link on the login page. This should be used for multi-tree deployments. loginRedirect string URL to redirect to when not logged in and navigating to any page other than \"login\" or \"register\" leafletTileUrl string Custom tile URL for Leaflet maps leafletTileSize number Custom tile size for Leaflet maps leafletZoomOffset number Custom zoom offset for Leaflet maps leafletTileAttribution string Custom attribution for Leaflet maps"},{"location":"help/","title":"Get Help","text":"

If you run into issues or need help with Gramps Web, please pick one of the following options.

Forum Backend issues Frontend issues

See below for some guidance on where to head first.

"},{"location":"help/#asking-questions","title":"Asking questions","text":"

The official Gramps Discourse forum has a separate category for Gramps Web. Please use it to ask any questions you may have about Gramps Web, for instance

  • Questions on the usage of Gramps Web
  • Questions on the configuration of Gramps Web
  • Troubleshooting a deployment of Gramps Web
  • Ideas about improvements to Gramps Web
  • ...
"},{"location":"help/#reporting-issues","title":"Reporting issues","text":"

If you encounter a problem that you believe is a bug in Gramps Web, please support it via Github.

There are two separate Github repositories for the code used in Gramps Web, one for the user interface (\u201cfrontend\u201d) and one for the server code (\u201cbackend\u201d):

  • Frontend issues
  • Backend issues

If you are unsure where to file an issue, don't worry and just choose either of the two \u2013 the maintainers will be able to transfer the issue if necessary.

In either case, please always include the following information in your report:

  • Details about your setup (e.g. a docker-compose file with sensitive values redacted, or whether your are using a hosted version, such as Grampshub, or a pre-configured image, such as DigitalOcean)
  • Version information. To obtain it, go to the \"System information\" tab on the Settings page in Gramps Web and copy/paste the values in the box, which should look something like this:
Gramps 5.1.6\nGramps Web API 1.5.1\nGramps.js 24.1.0\nlocale: en\nmulti-tree: false\ntask queue: true\n
"},{"location":"help/#suggesting-enhancements","title":"Suggesting enhancements","text":"

For general ideas and discussion about future improvements, feel free to open a discussion in the forum. You may also want to check the issue pages (see links above) whether a particular feature is already planned or being worked on.

For specific enhancements with a limited scope, feel free to directly open an issue with a feature request in the appropriate frontend or backend Github repository.

"},{"location":"multi-tree/","title":"Setup for hosting multiple trees","text":"

By default, Gramps Web only allows accessing a single family tree database (\u201ctree\u201d), specified in the configuration file.

However, starting with version 0.7.0 of the Gramps Web API backend, it is also possible to serve multiple trees from a single installation. However, each user is (currently) tied to a single tree, so this setup is not suited for sharing trees among users, but for hosting multiple isolated Gramps Web instances.

"},{"location":"multi-tree/#enable-multi-tree-support","title":"Enable multi-tree support","text":"

To enable multi-tree support, the TREE config option must be set to a single asterisk *, e.g. in a configuration file:

TREE = \"*\"\n

This will make all trees in the server's Gramps database directory accessible (given sufficient user permissions). The tree's ID is the name of the subdirectory. You can list existing trees (names and IDs) with the command

python -m gramps_webapi --config /app/config/config.cfg tree list\n

In addition, you should set the MEDIA_PREFIX_TREE configuration option to True to ensure media files are stored in separate subfolders. Otherwise, users are able to access media files that belong to a tree they have no permission for!

"},{"location":"multi-tree/#add-a-user-account-to-a-specific-tree","title":"Add a user account to a specific tree","text":"

To add a user to a specific tree, simply add the --tree TREEID command line option to the add user command. You can also POST to the /users/ endpoint with the tree property set in the JSON payload.

User names and e-mail addresses are required to be unique across all trees.

"},{"location":"multi-tree/#create-a-new-tree","title":"Create a new tree","text":"

To create a new tree, it is recommended to POST to the /trees/ endpoint rather than using the Gramps CLI. This will use a UUIDv4 as tree ID, which leads to additional security as the name cannot be guessed. Currently, only SQLite is supported for newly created trees.

"},{"location":"multi-tree/#authorize","title":"Authorize","text":"

To authorize (fetch a token), only user name and password are necessary, like in single-tree mode, since the tree ID is known for each user, so there is no need to provide it.

"},{"location":"multi-tree/#migrate-existing-media-files","title":"Migrate existing media files","text":"

If you want to migrate an existing Gramps Web instance to multi-tree support and are using local media files, you can simply move them to a subfolder of the original location with the tree ID as name.

If you are using media files hosted on S3, you can use the script provided in the scripts directory of the gramps-web-api repository:

python scripts/s3_rename.py BUCKET_NAME TREE_ID\n

This assumes the relevant access keys are set as environment variables already.

"},{"location":"multi-tree/#migrate-existing-user-database","title":"Migrate existing user database","text":"

If you want to enable multi-tree support and reuse existing users, you need to assign them to a specific tree. You can use the following command provided for this purpose,

python -m gramps_webapi --config /app/config/config.cfg user fill-tree TREE_ID\n
"},{"location":"multi-tree/#customize-the-frontend","title":"Customize the frontend","text":"

The registration page accessible from the login page does not work in a multi-tree setup, since a tree needs to be specified for registration. It is thus advisable to set hideRegisterLink to true in the frontend configuration.

"},{"location":"quickstart/","title":"Try out locally","text":"

To try out Gramps Web on your local computer (Linux, Mac, or Windows) without interfering with your Gramps Desktop installation, you can use Docker with the following command:

docker run -p \"5055:5000\" -e TREE=new ghcr.io/gramps-project/grampsweb:latest\n

This will make a new, empty Gramps Web instance accessible at http://localhost:5055, where you can create an admin user and import a Gramps XML file.

Info

Since this simple setup does not allow running long tasks in a separate process, importing a large Gramps XML file might fail due to a timeout in the first-run assistant.

To use media files from your computer you can mount the Gramps media folder into the container with

docker run -p \"5055:5000\" -e TREE=new \\\n-v /path/to/my/gramps_media_folder:/app/media \\\nghcr.io/gramps-project/grampsweb:latest\n

Note that this will not persist the changes you make to the database when you restart the container. To properly set up Gramps Web, continue reading about Deployment.

"},{"location":"requirements/","title":"Setup Requirements","text":"

Gramps Web is a web app that runs on a server and is accessed via the web browser. It is meant to be made accessible to authenticated users via the internet.

"},{"location":"requirements/#server-requirements","title":"Server Requirements","text":"

The most convenient way to host Gramps Web is via Docker Compose. While this is not possible with ordinary \"shared hosting\" providers, this makes it possible to host the app on Linux, Mac, or Windows; it can be hosted on a virtual server or on a Raspberry Pi (we provide Docker images for the ARM architecture) in your basement.

Apart from Docker, you will also need some storage space to store your media files (images, documents).

Finally, Gramps Web is only secure when served via HTTPS, so you will require an SSL/TLS certificate. The docs below show how to get one automatically for free from Let's Encrypt.

"},{"location":"s3/","title":"Hosting media files on S3","text":"

Instead of hosting the media files of the family tree on the same server as the Gramps database, they can also be hosted on Amazon S3 or a different API-compatible object storage service. This strongly reduces storage and traffic requirements for the Gramps Web server.

"},{"location":"s3/#preparing-credentials","title":"Preparing credentials","text":"

In your AWS (or other object storage service) account, get an access key ID and secret access key (you may first want to create a separate user with a security policy allowing only access to S3).

"},{"location":"s3/#upload-media-files","title":"Upload media files","text":"

To upload your existing media files to S3, on Linux you can use a local Gramps installation with the S3 Media Uploader Addon, that you can install directly from Gramps desktop. However, some additional configuration is necessary.

The addon uses the boto3 Python library under the hood. You need to install it first with

python3 -m pip install boto3\n

On the command line, export the access key ID and secret key to the appropriate environment variables:

export AWS_ACCESS_KEY_ID=my_access_key_id\nexport AWS_SECRET_ACCESS_KEY=my_secret_access_key\n

Now, you can start the uploader by runing the following command,

gramps -O \"My Family Tree\" -a tool \\\n-p \"name=s3uploader,bucket_name=my_bucket_name\"\n

replacing \"My Family Tree\" with the name of your family tree and my_bucket_name with the complete name of your S3 bucket. You will need a dedicated S3 bucket for your Gramps Web instance. If the bucket does not exist yet, the S3 Uploader Addon will attempt to create it.

"},{"location":"s3/#configure-gramps-web","title":"Configure Gramps Web","text":"

To use the new S3 bucket as media source for Gramps Web, simply set the MEDIA_BASE_DIR configuration option to s3://my_bucket_name.

When using Docker Compose, the easiest option is to add all environment variables to the env block:

env:\nAWS_ACCESS_KEY_ID: my_access_key_id\nAWS_SECRET_ACCESS_KEY: my_secret_access_key\nMEDIA_BASE_DIR: s3://my_bucket_name\nAWS_DEFAULT_REGION: eu-central-1\n

If you want to use an S3-compatible object storage other than AWS (e.g. GCP or for local testing), set the AWS_ENDPOINT_URL environment variable.

"},{"location":"s3/#synchronizing-media-files","title":"Synchronizing media files","text":"

To keep media files in sync between a local Gramps installation and S3-hosted Gramps Web media files, the Gramps Web Sync Addon supports file synchronization via the Web API.

"},{"location":"setup/","title":"Gramps Web Setup","text":"

This section deals with the installation and setup of Gramps Web, as well as other options to get started.

"},{"location":"setup/#getting-started-with-gramps-web","title":"Getting started with Gramps Web","text":"

Gramps Web is a web app that runs on a server and is accessed via the web browser. It is meant to be made accessible to authenticated users via the internet.

If you want to use Gramps Web for your genealogical research data, you have to choose one of the following options:

  1. Self-host on your own hardware
  2. Self-host in the cloud
  3. Sign up for a hosted instance

While the first option gives you maximal flexibility and control, it can also be technically challenging.

Tip

One of the main principles of Gramps Web is to put users in control of their own data at any time, so migrating data from one instance to another is simple. Don't worry about being locked in after having chosen one of the options!

"},{"location":"setup/#self-host-on-your-own-hardware","title":"Self-host on your own hardware","text":"

The most convenient way to self-host Gramps Web is via Docker Compose. We also provide Docker images for the ARM architecture, so you can run Gramps Web on a Raspberry Pi in your basement.

See Deploy with Docker for setup instructions.

"},{"location":"setup/#self-host-in-the-cloud","title":"Self-host in the cloud","text":"

Installing Gramps Web can be more challenging than other, simple web applications and is not compatible with ordinary \"shared hosting\" providers. You can sign up for a virtual server and install Gramps Web manually.

A simpler option is to use a pre-installed cloud image. One example is our DigitalOcean 1-click app.

"},{"location":"setup/#sign-up-for-a-hosted-instance","title":"Sign up for a hosted instance","text":"

A hosted Gramps Web is the easiest way to get started with Gramps Web, since no installation or configuration is required.

Here is a list of dedicated hosting providers for Gramps Web (the Gramps open source community does not take responsibility for their services):

  • Grampshub (www.grampshub.com), offered by one of the Gramps Web main contributors

If you use a hosted option for Gramps Web, you can skip the rest of this section and jump right to the Administration section.

"},{"location":"dev-backend/","title":"Gramps Web backend development","text":"

The backend of Gramps Web is called Gramps Web API. In fact it is more than just an app backend: it provides a RESTful API to read and modify a Gramps database.

Gramps Web API is a Python application and is powered by the gramps library itself (which also powers the Gramps Desktop application).

In this section of the docs, you can learn how to contribute to Gramps Web API development.

"},{"location":"dev-backend/api/","title":"API specification","text":"

The full API specification for the Gramps Web API can be found at https://gramps-project.github.io/gramps-web-api/.

"},{"location":"dev-backend/queries/","title":"Manual queries","text":"

For backend and frontend development, it can be useful to send manual queries to the Gramps Web API. Using HTTPie and jq, this can be done conveniently including JWT authentication.

"},{"location":"dev-backend/queries/#installation","title":"Installation","text":"

HTTPie is installed with pip:

python3 -m pip install httpie\n

You will need HTTPie version 3.0.0 or newer.

jq can be installed in Ubuntu via

sudo apt install jq\n
"},{"location":"dev-backend/queries/#fetching-an-access-token","title":"Fetching an access token","text":"

To fetch an access token, query the token endpoint. Assuming your development instance is running on localhost:5555, you can use the command

http POST http://localhost:5555/api/token/ username=owner password=owner\n

You will see the JSON tokens as output.

Using jq, you can also store the access token in an environment variable:

export ACCESS_TOKEN=$(http POST http://localhost:5555/api/token/ \\\nusername=owner password=owner | jq -r '.access_token')\n

You can now use this token in all API calls that require authentication, e.g.

http -A bearer -a $ACCESS_TOKEN GET http://localhost:5555/api/metadata/\n

Note that, by default, access tokens will expire after 15 minutes.

"},{"location":"dev-backend/setup/","title":"Development setup","text":"

This page lists the steps required to start developing Gramps Web API. It will be assumed that you are using Ubuntu Linux.

"},{"location":"dev-backend/setup/#python-version","title":"Python version","text":"

The Web API requires Python 3.7 or newer.

"},{"location":"dev-backend/setup/#install-gramps","title":"Install Gramps","text":"

The Web API requires the Gramps Python library to be importable. Starting from Gramps 5.2.0, it will be installable via pip. Right now, development is still based on Gramps 5.1.x, so the most convenient option is to install the Gramps apt package on Ubuntu

sudo apt install gramps\n

Info

Note that using the gramps Python package from Gramps installed with apt requires using the system Python interpreter, so you cannot work in a virtual environment.

"},{"location":"dev-backend/setup/#clone-the-web-api-repository","title":"Clone the Web API repository","text":"

Clone the Web API to your PC (assuming you have set up an SSH key with Github) using

git clone git@github.com:gramps-project/gramps-web-api.git\ncd gramps-web-api\n
"},{"location":"dev-backend/setup/#install-prerequisites","title":"Install prerequisites","text":"

To start development, please install the dependencies by running

pip3 install -r requirements-dev.txt\n

"},{"location":"dev-backend/setup/#install-the-library-in-editable-mode","title":"Install the library in editable mode","text":"

Run

pip3 install -e . --user\n

"},{"location":"dev-backend/setup/#set-up-pre-commit-hooks","title":"Set up pre-commit hooks","text":"

To set up the pre-commit hooks for the repository, run

pre-commit install\n
in the repository root. This will e.g. make sure that all source files are nicely formatted with black.

"},{"location":"dev-backend/setup/#run-tests","title":"Run tests","text":"

To run the unit tests, run

pytest\n
in the repository root.

"},{"location":"dev-backend/setup/#generate-a-configuration-file","title":"Generate a configuration file","text":"

Example content:

TREE=\"My Family Tree\"\nSECRET_KEY=\"not_secure_enough\"\nUSER_DB_URI=\"sqlite:///users.sqlite\"\n

Warning

Do not use this configuration in production.

See Configuration for a full list of config options.

Warning

Do not use your production database for development, but use a copy of it or the Gramps example database.

"},{"location":"dev-backend/setup/#add-users","title":"Add users","text":"

You can add a user with owner permissions by running

python3 -m gramps_webapi --config path/to/config user add owner owner --role 4\n
This uses username and password owner.

"},{"location":"dev-backend/setup/#run-the-app-in-development-mode","title":"Run the app in development mode","text":"

Run

python3 -m gramps_webapi --config path/to/config run\n
The API will be accesible at http://127.0.0.1:5000 by default, which displays an empty page. Access your Gramps data using the API described by gramps-project.github.io/gramps-web-api. For example, to show people go to http://127.0.0.1:5000/api/people

To choose a different port, add the --port option.

"},{"location":"dev-frontend/","title":"Gramps Web frontend development","text":"

The Gramps Web frontend is written in Javascript and built using web components with Lit. This allows encapsulating functionality into reusable components.

The frontend is designed as a progressive single-page web app with a mobile-first experience. It makes heavy use of Material Web Components for a Material Design look and feel.

"},{"location":"dev-frontend/architecture/","title":"Architecture","text":""},{"location":"dev-frontend/architecture/#components","title":"Components","text":"

The frontend is built out of web components. They are defined in the Javascript files in the src directory.

Typically, each file defines one component, starting with

class GrampsjsSomeElement extends LitElement\n
and ending with
customElements.define('grampsjs-some-element', GrampsjsSomeElement)`\n
that defines the new HTML element grampsjs-some-element that can be used elsewhere.

The main entrypoint, included in index.html , is the gramps-js element defined in GrampsJs.js. This contains the definition of all individual pages (that correspond simply to elements that are shown or hidden based on the route/URL), the menu, and routing.

The components in the src/views directory usually corresponds to full-page components that fetch data from the backend (e.g., the people list view), while components in src/components are usually smaller building blocks used inside the views that get their data from attributes provided by their parent element. However, this separation is not strict.

"},{"location":"dev-frontend/architecture/#data-flow","title":"Data flow","text":"

Data is exchanged with the Backend/API via the apiGet, apiPut, and apiPost methods in src/api.js, which automatically take care of authentication.

Data is passed from parent components to child components via properties (see e.g. the Lit documentation).

When data needs to be fed back from a child to a parent component, custom events are used that can be fired with the fireEvent function in src/api.js and listened to using Lit's @ syntax (docs).

"},{"location":"dev-frontend/architecture/#authentication","title":"Authentication","text":"

The refresh token and authentication token are stored in the browser's local storage. Whenever an API call is made and the token is expired, the stored refresh token is used to fetch a new access token and the API call is repeated.

The user's authorization scope, which is stored in the access token's claims, is obtained with the getPermissions function and used in the top-level GrampsJs element to set the boolean properties canAdd, canEdit, canManageUsers, which are flowed down to child elements to implement authorization-specific functionality.

"},{"location":"dev-frontend/build/","title":"Build","text":"

To build the frontend for deployment, run

npm run build\n

"},{"location":"dev-frontend/setup/","title":"Development setup","text":"

This page describes the steps needed to start with frontend development. It is assumed that you are using Ubuntu Linux and you will need Docker, docker-compose, and git.

"},{"location":"dev-frontend/setup/#step-1-clone-the-repository","title":"Step 1: Clone the repository","text":"

Clone the frontend repository

git clone git@github.com:gramps-project/gramps-web.git\ncd gramps-web\n

"},{"location":"dev-frontend/setup/#step-2-build-and-start-the-development-containers","title":"Step 2: Build and start the development containers","text":"

To build and start the containers running the Gramps Web backend with the Gramps example database, as well as the frontend in development mode, simply run

docker-compose up -d\n

Options for logging in are: owner, editor, contributor, guest or member (use same word for both username and password).

Warning

Do not use the development server in production.

As part of the build process, git hooks for formatting and linting will be installed as well.

"},{"location":"dev-frontend/setup/#usage-instructions","title":"Usage instructions","text":"

Once the containers are up and running, Gramps Web will be accessible at http://localhost:5555.

Info

Note since the *.json translation files are imported with the new syntax suggested in T39, you must use the Chrome or Chromium browser for the development server to work without errors. This issue is about to change in the future.

Once you make changes to the frontend code, you browser will be reloaded automatically.

The installed git hooks will format and lint the code on every commit. You can run the scripts manually using

docker-compose run gramps-frontend format\n
and
docker-compose run gramps-frontend lint\n
respectively.

"},{"location":"dev-frontend/translation/","title":"Translation","text":"

Gramps Web leverages the translations of Gramps Desktop provided by the community for over 40 languages. The additional strings that only needed for the Web app are translated via Weblate.

To contribute, follow the instructions in the Gramps Wiki to get started with Weblate for Gramps. Once authenticated, you can start translating strings both for Gramps Desktop and Gramps Web.

"},{"location":"setup/v2/","title":"Gramps 5.2 upgrade guide","text":"

Gramps 5.2 was released on February 23, 2024. Since it uses a new family tree database schema compared to Gramps 5.1, additional steps are necessary when upgrading Gramps Web to be used with Gramps 5.2. This page describes the necessary steps.

"},{"location":"setup/v2/#overview-of-the-steps","title":"Overview of the steps","text":"

This is an overview of the steps required to upgrade. It also shows which steps are executed by the administrator of the Gramps Web server, the owner of the family tree, and whether it's needed only for users of the sync addon

Server administrator Tree owner Action \u2713 Back up your family tree \u2713 1 Synchronize Gramps Web with Gramps Desktop \u2713 Update Gramps Web \u2713 Update the tree's database schema \u2713 1 Update Gramps Desktop \u2713 1 Install the updated Sync Addon \u2713 Back up your family tree \u2713 1 Synchronize Gramps Web with Gramps Desktop

1 Only needed if you synchronize Gramps Web with Gramps Desktop.

"},{"location":"setup/v2/#overview-of-the-release-status","title":"Overview of the release status","text":"

The following table gives an overview of when the components needed for Gramps Web with Gramps 5.2 have been released.

Component Released Gramps 5.2.0 2024-02-23 \u2713 Gramps Web Sync Addon 1.0.4 for Gramps 5.2 2024-02-23 \u2713 Gramps Web API 2.0.0 2024-02-28 \u2713 Gramps Web 23.3.0 2024-02-28 \u2713"},{"location":"setup/v2/#detailed-steps","title":"Detailed steps","text":"

This section provides more details about some of the individual steps above.

"},{"location":"setup/v2/#back-up-your-family-tree","title":"Back up your family tree","text":"

In Gramps Web, go to the \"Export\" page and select \"Gramps XML (family tree)\" (the default option). Click \"Generate\" and wait until the download of the .gramps file starts.

You can also create a backup in Gramps Desktop in the usual way.

"},{"location":"setup/v2/#update-the-trees-database-schema","title":"Update the tree's database schema","text":"

When you access Gramps Web for the first time after having upgraded it, you will be presented with a screen showing the message:

The Family Tree you are trying to load is in a schema version not supported by this version of Gramps Web. Therefore you cannot load this Family Tree without upgrading its schema. This action cannot be undone.

You can now click on the button \"Upgrade Family Tree\". It will show a progress bar and should not take more than a minute to complete. Don't worry, if you accidentally close your browser window, the conversion will continue in the background.

Warning

If you use a non-standard setup without background task queue, the database upgrade might fail and your family tree might get corrupted. You can check (before updating Gramps Web) if you are using a background task queue by going to the \"System Information\" section in the settings and making sure it has \"task queue: true\".

"},{"location":"setup/v2/#update-gramps-desktop","title":"Update Gramps Desktop","text":"

Follow the Gramps Desktop installation instructions for your operating system.

"},{"location":"setup/v2/#install-the-updated-sync-addon","title":"Install the updated Sync Addon","text":"

You can use the new Plugin Manager included in Gramps 5.2 - just search for Gramps Web Sync, click on install, and restart Gramps.

"},{"location":"user-guide/","title":"Introduction","text":"

This section contains the documentation for users of Gramps Web.

"},{"location":"user-guide/blog/","title":"Use the built-in blog","text":"

The blog is meant for presenting stories about your family history research.

In the Gramps database, blog posts are represented as sources with a note attached, containg the blog's text, and optionally, media files for the images of the blog post. Gramps Web treats every source with a tag Blog as blog article.

"},{"location":"user-guide/blog/#add-a-blog-post","title":"Add a blog post","text":"

To add a blog post, you can use Gramps Web or Gramps Dekstop (synchronized with Gramps Web), the steps are the same in both cases:

  • Add a new source. The title of the source will be the title of your blog post, the author of the source will be the author of the post.
  • Optionally, associate the source with a repository corresponding to your Gramps Web blog
  • Add a new note to the source. Write your blog post and copy the text into the note.
  • Optionally, add one or more media files to your source. The first media file will be taken as the post preview picture shown above the text. All media files will be shown below the text as a gallery.
  • Add the label Blog to the source (create it if it doesn't exist)
"},{"location":"user-guide/blog/#relation-between-blog-and-sources","title":"Relation between blog and sources","text":"

Since blog posts are just sources, all blog articles also appear on the list of sources and show up as sources in searches. In the source view, there is a button \"show in blog\" that will take you to the blog view for that blog post. The URL of the blog post also contains the Gramps ID of the corresponding source, so an article at yourdomain.com/blog/S0123 corresponds to the source at yourdomain.com/source/S0123.

At the bottom of every blog post, there is a button \"details\" that will take you to the source view.

"},{"location":"user-guide/dna/","title":"DNA segment map","text":"

The DNA segment map view, accessible under the \"DNA\" tab in the person view, shows DNA matches with other people in the tree as segments highlighted on the person's chromosomes.

This feature does not rely on raw DNA data being uploaded to Gramps Web, but on the segment match data directly, which can be obtained from websites like Gedmatch or MyHeritage.

The DNA segment map is based on the Gramplet Addon that provides the same functionality in Gramps Desktop. Its wiki page contains more details about how to obtain the data, how to interpret it, and how to enter the data in Gramps.

The data is added as notes attached to associations (or attached to association citations), which is possible directly in Gramps Web.

"},{"location":"user-guide/export/","title":"Export data","text":""},{"location":"user-guide/export/#back-up-your-family-tree","title":"Back up your family tree","text":"

To create a backup of your family tree, open the Export page in Gramps Web and select the Gramps XML format.

Clicking on \"export\" will generate the file and start the download once it is ready.

Note that if your Gramps Web user does not have permission to view private records, the export will not be a full backup, since it will not contain any private records.

"},{"location":"user-guide/export/#share-your-family-tree-with-users-of-other-genealogy-programs","title":"Share your family tree with users of other genealogy programs","text":"

When sharing genealogical data as Gramps XML is not an option, you can also export a GEDCOM file. Note that this is not suited as a backup of your Gramps Web tree.

"},{"location":"user-guide/export/#back-up-your-media-files","title":"Back up your media files","text":"

To back up your media files, you can create and download a ZIP archive of all media files on the Export page.

Note that, especially for large trees, this can be an expensive operation for the server and should only be done if absolutely necessary.

A better option to back up your media files on a regular basis is to use the Gramps Web Sync addon (which itself is not a backup solution) and create incremental backups on your local computer.

In both bases, if your Gramps Web user does not have permission to view private records, the export will not contain files of private media objects.

"},{"location":"user-guide/export/#move-to-a-different-gramps-web-instance","title":"Move to a different Gramps Web instance","text":"

Gramps Web does not lock you in with a specific provider and you can always move to a different Gramps Web instance without loosing any data, and without having direct access to either of the servers.

To achieve a full migration, follow these steps (assuming you have tree owner permissions):

  1. Go to the Export page and export your tree as a Gramps XML (.gramps) file. If you use the Sync addon, you can also generate the export in Gramps desktop.
  2. On the Export page, generate & download a media archive. If you use the Sync addon, you can also simply ZIP your local Gramps media folder.
  3. Go to Settings > Administration > Manage users and click the \"Export user details\" button. It will download a JSON file.
  4. In the new Gramps Web instance, open the Import page. Import the .gramps file exported in step 1.
  5. On the Import page of the new Gramps Web instance, upload the media archive (ZIP).
  6. Go to Settings > Administration > Manage users of the new Gramps Web instance. Click the \"Import user accounts\" button and upload the JSON file downloaded in step 3.

Note that, while your user accounts will be migrated, all your users will need to set new passwords by using the \"forgot password\" link, since passwords are stored in encrypted form and cannot be exported.

"},{"location":"user-guide/first-login/","title":"First login","text":"

When logging in to Gramps Web for the first time, a form will be displayed requiring the user to select a language for the frontend and a home person.

This home person does not have to coincide with the home person in Gramps desktop \u2013 it is a personal setting for every user of Gramps Web. The home person is used e.g. for the initial view of the family tree. A typical choice would be for a user to select themselves as home person.

To select a person as home person, start typing in the text field and a drop-down list with matches will appear.

The language and home person settings are stored in the browser's local storage, so they will persist on a given device.

"},{"location":"user-guide/gql/","title":"Filter using the Gramps Query Language","text":"

The object list views (people, families, events, ...) have an optional advanced filter mode based on the Gramps Query Language (GQL).

To use it, type a query in GQL syntax and press enter (or hit the \"apply\" button). The view will be filtered by the query. If the query is invalid, the input field's frame turns red.

The GQL syntax is described below, copied from the GQL documentation.

"},{"location":"user-guide/gql/#syntax","title":"Syntax","text":"

A GQL query is a string composed of statements of the form property operator value, optionally combined with the keywords and and or as well as parentheses.

"},{"location":"user-guide/gql/#properties","title":"Properties","text":""},{"location":"user-guide/gql/#class","title":"class","text":"

Filters for the Gramps object class and can be one of person, family, event, place, citation, source, repository, media, or note.

"},{"location":"user-guide/gql/#object-properties","title":"Object properties","text":"

GQL supports querying nested properties of Gramps objects, e.g. primary_name.date.calendar. See below for a full list of properties \u2013 see also Gramps Data Model.

"},{"location":"user-guide/gql/#list-elements-by-index","title":"List elements by index","text":"

Individual elements in list-like properties can be accessed by positional index in square brackets. This can be combined with nested properties, e.g. primary_name.surname_list[0].surname.

"},{"location":"user-guide/gql/#length","title":"length","text":"

This is a special property that returns the length of an array-like Gramps property, e.g. media_list.length > 0 to get objects with media references.

"},{"location":"user-guide/gql/#all-any","title":"all, any","text":"

Two more special properties for array-like Gramps properties. all requires a condition to apply to all items of the list, any requires it to apply to at least one item. Both properties can be combined with other properties before and after. Examples: media_list.any.citation_list.length > 0 to return objects with media references that have citations; media_list.all.citation_list.length = 0 to return objects where all media objects do not have citations.

"},{"location":"user-guide/gql/#array-index","title":"Array index","text":"

A numerical array index can be used to access specific elements of a list, e.g. child_ref_list[0] for the first child.

"},{"location":"user-guide/gql/#get_person-etc","title":"get_person, etc.","text":"

While all the preceding properties refer to a single Gramps object, it is also possible to filter on different objects referred to by the initial object. For instance, an event has a place handle in its place property. Using the get_place pseudo-property, GQL switches to the properties of that object. For instance, it is possible to search for class = event and place.get_place.name.value ~ York. This can also be combined with any or all, e.g. class = person and event_ref_list.any.ref.get_event.description ~ farmer.

"},{"location":"user-guide/gql/#operators","title":"Operators","text":""},{"location":"user-guide/gql/#_1","title":"=, !=","text":"

Equality or inequality. Examples: class = person, class != family

"},{"location":"user-guide/gql/#_2","title":">, >=, <, <=","text":"

Comparison. Works for strings as well as numbers. Examples: confidence <= 1, change > 1712477760, gramps_id > \"I2015\"

"},{"location":"user-guide/gql/#_3","title":"~, !~","text":"

Contains or does not contain. Works for lists as well as strings. Examples: gramps_id !~ F00, author ~ David, family_list ~ \"3a16680f7d226e3ac3eefc8b57a\"

"},{"location":"user-guide/gql/#no-operatorvalue","title":"No operator/value","text":"

If no operator and value is given, the value is interpreted as a boolean (true or false). This works for all types of properties and Python rules for casting to true/false are applied. For instance, the query private returns private objects; confidence returns objects where confidence is greater than 0; media_list returns objects with at least one media reference.

"},{"location":"user-guide/gql/#values","title":"Values","text":"

Values can be numbers or strings. If numbers should be interpreted as strings or special characters like = are involved, enclose the value in strings. Examples: gramps_id = F0001, but gramps_id = \"0001\".

"},{"location":"user-guide/gql/#commented-examples","title":"Commented examples","text":"
class = note and private and text.string ~ David\n

All private notes that contain the string \"David\" in their text

media_list.length >= 10\n

All objects (of any class) with 10 or more media references

class != person and media_list.any.rect\n

All objects that are not a person but have a media reference that is part of an image. Here, media_list.any.rect means that for each of the items in the media list, it is checked whether the rect (rectangle) property has a truthy value, meaning it is a non-empty list. (media_list.any.rect.length > 0 would have the same effect.)

class = family and child_ref_list.length > 10\n

Families with more than 10 children.

class = event and date.modifier = 0 and date.dateval[2] > 2020\n

Events where the date is a normal date (not a range etc.) and the year is after 2020.

note_list.any.get_note.text.string ~ \"David\"\n

All objects with at least one note that contains the string \"David\" in their text.

class = family and child_ref_list.all.ref.get_person.gender = 0 and child_ref_list.length = 3\n

All families with three daughters.

"},{"location":"user-guide/gql/#full-list-of-gramps-properties","title":"Full list of Gramps Properties","text":"

For a full list of Gramps properties, see the GQL documentation.

"},{"location":"user-guide/import/","title":"Import data","text":""},{"location":"user-guide/import/#prepare-your-gramps-database","title":"Prepare your Gramps database","text":"

If you are using Gramps Desktop, there are two steps to prepare your database to make sure everything will run smoothly in the following. If you are migrating from a different genealogy program, you can skip this step.

  1. Check and repair the database
    • Optional: create a database backup by exporting to Gramps XML
    • Run the Check and repair database tool. This fixes some internal inconsistencies that could lead to problems in Gramps Web.
  2. Convert media paths to relative
    • Use the Gramps Media Manager to convert all media paths from absolute to relative. Note that even with relative paths, any media files outside of your Gramps media directory will not work properly when synchronized with Gramps Web.
"},{"location":"user-guide/import/#import-genealogical-data","title":"Import genealogical data","text":"

To import an existing family tree, use the \"Import\" page and upload a file in any of the file formats supported by Gramps \u2013 see Import from another genealogy program in the Gramps Wiki.

If you already use Gramps Desktop, it is strongly recommended to use the Gramps XML (.gramps) format to ensure your online and offline trees use the same identifiers and can be synchronized.

"},{"location":"user-guide/import/#why-no-support-for-gramps-xml-package","title":"Why no support for Gramps XML package?","text":"

While Gramps XML (.gramps) is the preferred format for importing data, Gramps XML package (.gpkg) is not supported by Gramps Web. This is because the import and export routines for media files are not suited for use on a web server.

To import the media files belonging to an imported .gramps file, see the next section.

"},{"location":"user-guide/import/#import-media-files","title":"Import media files","text":"

If you have uploaded a family tree and need to upload the corresponding media files, you can use the \"import media archive\" button on the \"Import\" page.

It expects a ZIP file with the missing media files inside. The folder structure in the ZIP file does not have to be the same as the folder structure inside the Gramps media folder as the files are matched to media objects by their checksum.

Note that this feature only works for files that have the correct checksum in the Gramps database (which should be ensured by running the check and repair tool in the first step).

When moving to Gramps Web from a different genalogy program including media files, it is recommended to first import everything into Gramps Desktop, which has more options to associate existing media files with an imported tree.

"},{"location":"user-guide/media/","title":"Add media files","text":"

There are two ways to add a new media file (an image, audio file, video file, or any other file):

"},{"location":"user-guide/media/#add-a-new-standalone-media-file","title":"Add a new standalone media file","text":"

To add a standalone media file, click the + icon in the top app bar and select \"Media Object\".

Click on \"select a file\" to select a file from your computer. On a mobile device, clicking this button will give you the option of directly taking a photo with your device's camera.

Optionally,

  • enter a description of the media file under \"title\"
  • enter a date
  • set the media file as private (which will make it visible only to users with sufficient authorization)

Click \"add\" to upload the file and create the media object.

"},{"location":"user-guide/media/#add-a-new-media-file-and-link-it-to-another-object","title":"Add a new media file and link it to another object","text":"

The following object types in Gramps can have media objects attached: people, families, events, places, sources, and citations.

In the detail view of any object, click the blue edit button in the bottom right (if you do not see it, your user does not have edit permissions). Click on the \"gallery\" tab and click the blue + button.

A dialog will open that offers the same fields as described in the previous section. Click \"save\" to upload the file, add a new media object, and link it to the viewed object.

"},{"location":"user-guide/owner/","title":"Create an account for the tree owner","text":"

Before you can start using Gramps Web, you need to create an account for the tree owner. If no user account exists for a given tree, a form will be shown to create an account. The form depends on the server setup being for a single tree or for multiple trees.

"},{"location":"user-guide/owner/#single-tree-setup-create-admin-account","title":"Single-tree setup: create admin account","text":"

On a server with single-tree setup, when no user account exists yet, opening Gramps Web shows a form to create an admin account. The admin user will be both the owner of the (single) tree and the administrator of the installation. The form also allows setting the e-mail configuration needed for e-mail notifications (e.g. resetting a user password). If the e-mail configuration has already been added via a configuration file or environment variables on the server, this part of the form can be left empty.

The form also allows to import genealogical data by uploading a file. This can also be done later from the \"Import\" page in Gramps Web (see Import data).

"},{"location":"user-guide/owner/#multi-tree-setup-create-admin-account","title":"Multi-tree setup: create admin account","text":"

In a multi-tree setup, the same form to create an admin account will be shown if no users exists in any tree, i.e. when the server has just been created.

"},{"location":"user-guide/owner/#multi-tree-setup-create-tree-owner-account","title":"Multi-tree setup: create tree owner account","text":"

In a multi-tree setup, every user is tied to a single tree. Even if users already exist in other trees, a tree owner can be created in the web interface if no owner exists for this tree yet.

However, the owner creation form will not be displayed automatically on the Gramps Web home page, which is the same for all trees. Instead, it can be reached at https://my-gramps-instance/firstrun/my-tree-id, where https://my-gramps-instance is the base address of your Gramps Web installation, and my-tree-id is the ID of your tree.

A possible workflow for a site administrator to create a new tree is to

  • Create a tree via the REST API, obtaing the tree ID of the new tree
  • Share the link to the owner creation form with the appropriate tree ID with the prospective tree owner

The tree owner creation form is analogous to the admin creation form described above, except that it does not allow to change the e-mail configuration (which is only allowed for admins).

"},{"location":"user-guide/registration/","title":"Registration","text":"

In a single-tree installation, anybody can register a new account at a Gramps Web instance, but it will need to be enabled manually by a site owner before it can be used to log in.

In a multi-tree installation, users additionally require the tree ID to sign up; in practice, this means they can sign up using a registration link shared by the tree owner.

"},{"location":"user-guide/registration/#1-find-registration-form","title":"1. Find registration form","text":"

On the login form on the home page of Gramps Web, usually there is a link \"Register new account\".

If this link is missing, it is probably because it is a multi-tree installation of Gramps Web. In that case, contact the tree owner for a registration link.

The tree owner can find and copy the registration link under Settings/Administration.

"},{"location":"user-guide/registration/#2-submit-registration-form","title":"2. Submit registration form","text":"

The registration form has four mandatory fields: username, password, e-mail address, and full name. When all four fields have been filled, click \"submit\" to start the registration process.

"},{"location":"user-guide/registration/#3-confirm-e-mail-address","title":"3. Confirm e-mail address","text":"

After the form has been submitted, an automated e-mail will be sent to the e-mail address provided containing an e-mail confirmation link. Clicking it will open a confirmation page.

If the confirmation e-mail does not arrive (and you have checked your Spam folder), it could be that e-mail has not been configured correctly by the Gramps Web server administrator.

"},{"location":"user-guide/registration/#4-enable-account","title":"4. Enable account","text":"

After the e-mail address has been confirmed, the tree owner will receive an e-mail notification and can enable the new user account by going to the \"User administration\" section in settings page (accessible via the user icon in the top app bar) and changing the user role from \"disabled\" to any of the other roles.

Note that the new user will not receive an automated notification that their account has been enabled, so it is advisible for the administrator to notify them personally.

"},{"location":"user-guide/revisions/","title":"Revision History","text":"

The revision history view shows all edits that have been made to the family tree.

The list view shows the edits grouped by \"transactions\". A transaction is a group of one or more additions, deletions, or changes to Gramps objects. For instance, adding a new family with two existing persons as father and mother generates a transaction with one added family object and two modified person objects (because they contain the link to the new family object).

Clicking on a transaction opens the transaction detail view. It contains the list of individual additions, deletions, and updates by Gramps object.

Selecting an indivdial change opens a view of the raw JSON representation of the Gramps object with additions and deletions highlighted in green and red, respectively.

"},{"location":"user-guide/sync/","title":"Synchronize Gramps Web and Gramps Desktop","text":"

Gramps Web Sync is an addon for Gramps that allows to synchronize your Gramps database on your desktop computer with Gramps Web, including media files.

Warning

As with any synchronization tool, please do not consider this as a backup tool. An accidental deletion on one side will be propagated to the other side. Make sure to create regular backups (in Gramps XML format) of your family tree.

Using Gramps Web Sync requires tree owner permissions in Gramps Web.

"},{"location":"user-guide/sync/#installation","title":"Installation","text":"

The addon requires Gramps 5.2 running on Python 3.8 or newer. It is available in Gramps Desktop and can be installed in the usual way.

Warn

Please make sure to use the same version of Gramps on your desktop as the one running on your server. See the Get Help section for how to find out which Gramps version your server is running. The Gramps version has the form MAJOR.MINOR.PATCH, and MAJOR and MINOR must be the same on web and desktop.

Optional step:

  • Install keyring (e.g. sudo apt install python3-keyring) to allow storing the API password safely in your system's password manager
"},{"location":"user-guide/sync/#usage","title":"Usage","text":"

Once installed, the addon is availabe in Gramps under Tools > Family Tree Processing > Gramps\u00a0Web\u00a0Sync. Once started, and after confirming the dialog that the undo history will be discarded, the tool will ask you for the base URL (example: https://mygrampsweb.com/) of your Gramps Web instance, your username, and password. You need an account with owner privileges To sync changes back to your remote database. The username and URL will be stored in plain text in your Gramps user directory, the password will only be stored if keyring is installed (see above).

If there are any changes, the tool will display a confirmation dialog before applying the changes. (At present, the confirmation dialog only shows the Gramps IDs of the affected objects.)

"},{"location":"user-guide/sync/#media-file-synchronization","title":"Media file synchronization","text":"

After the databases have been synchronized, the tool checks for any new or updated media files. It displays the files missing locally or on the remote server and, upon user confirmation, tries to download and upload the files.

Limitations:

  • If a local file has a different checksum from the one stored in the Gramps database (this can happen e.g. for Word files when edited after being added to Gramps), the upload will fail with an error message.
  • The tool does not check integrity of all local files, so if a local file exist under the path stored for the media object, but the file is different from the file on the server, the tool will not detect it. Use the Media Verify Addon to detect files with incorrect checksums.
"},{"location":"user-guide/sync/#background-how-the-addon-works","title":"Background: how the addon works","text":"

The addon is meant to keep a local Gramps database in sync with a remote Gramps Web database, to allow both local and remote changes (collaborative editing).

It is not suited

  • To synchronize with a database that is not direct derivative (starting from a database copy or Gramps XML export/import) of the local database
  • To merge two databases with a large number of changes on both sides that need manual attention for merging. Use the excellent Import Merge Tool for this purpose.

The principles of operation of the tool are very simple:

  • It compares the local and remote databases
  • If there are any differences, it checks the timestamp of the latest identical object, let's call it t
  • If an object changed more recently than t exists in one database but not the other, it is synced to both (assume new object)
  • If an object changed the last time before t is absent in one database, it is deleted in both (assume deleted object)
  • If an object is different but changed after t only in one database, sync to the other one (assume modified object)
  • If an object is different but changed after t in both databases, merge them (assume conflicting modification)

This algorithm is simple and robust as it does not require tracking syncrhonization history. However, it works best when you synchronize often.

"},{"location":"user-guide/tagging/","title":"Tag people in photos","text":"

Gramps Web allows tagging people in photographs, similar to Gramps Desktop, linking the person and the media object. This is simplified by automated face detection.

To tag a person in a photo, follow these steps:

  • Open the detail view of the media object, e.g. by clicking on \"show details\" in the full-screen preview.
  • Click the blue edit button in the bottom-right corner. If you do not see this button, your user does not have edit permissions.
  • Overlayed on the image, you will see boxes with dashed border corresponding to detected facial regions. To tag a person, click on the box to highlight it and click tge \"person\" button to select an existing person.
  • To manually draw a rectangle instead, click the button
  • To delete an existing tag, select an existing rectangle (with a solid border) and click the button
"},{"location":"user-guide/tasks/","title":"Use the built-in task management","text":"

Gramps Web contains a built-in genealogical task management tool. It is meant to enable reserarches to plan and prioritize, but also document their tasks. This is why tasks are represented as sources in the Gramps database. After completing a task, the associated content can serve as a source documenting the research process.

"},{"location":"user-guide/tasks/#task-basics","title":"Task basics","text":"

Tasks have the following properties:

  • Status. This can be \"Open\", \"In Progress\", \"Blocked\", or \"Done\"
  • Priority. This can be \"Low\", \"Medium\", or \"High\"
  • Tags. The labels are normal Gramps tags of the underlying source. (Note that all tasks additionally have the ToDo label to identify them as tasks, but this label is hidden in the task list to avoid clutter.)
  • Title. Shown in the task list
  • Description. A rich-text field that can be used to describe the problem statement, but also document any progress made
  • Media. Any media files attached to the task
"},{"location":"user-guide/tasks/#create-a-task","title":"Create a task","text":"

Since tasks are normal Gramps objects, they can be edited or created by the same group of users that can edit or create other objects (like people or events).

To create a task, click on the + button on the task list page. Enter at least a title. The status will always be \"Open\" on creation.

"},{"location":"user-guide/tasks/#edit-a-task","title":"Edit a task","text":"

To any of the task's details, click on it in the task list.

The task detail page does not have a separate \"edit mode\" like other Gramps objects. Changes to the title, status, and priority are applied immediately. Changes to the rich-text description require clicking the \"save\" button beneath it.

"},{"location":"user-guide/tasks/#bulk-change-of-task-properties","title":"Bulk change of task properties","text":"

The priority and status of tasks can be changed in bulk by using the checkboxes in the task list for selection and the appropriate buttons above the task list.

"},{"location":"user-guide/tasks/#tasks-in-gramps-desktop","title":"Tasks in Gramps Desktop","text":"

When adding tasks via Gramps Web, both the sources and the notes will have the ToDo tag attached to them, so the tasks will show up in the desktop To Do Notes Gramplet as well as the To Do Report.

To add or edit a task in Gramps Desktop, use the following guidelines

  • Add a source with tag ToDo and the task title as title
  • Optionally, add a note to the source with tag ToDo, type \"To Do\", and the description as text
  • Add an attribute \"Status\" and set it to \"Open\", \"In Progress\", \"Blocked\", or \"Done\"
  • Add an attribute \"Priority\" and set it to 9 for low, 5 for medium, or 1 for high (these counter-intuitive values are taken from the iCalendar specification)
"}]} \ No newline at end of file diff --git a/setup/index.html b/setup/index.html new file mode 100644 index 0000000..07f2c84 --- /dev/null +++ b/setup/index.html @@ -0,0 +1,1594 @@ + + + + + + + + + + + + + + + + + + + + + + + + Getting Started - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Gramps Web Setup

+

This section deals with the installation and setup of Gramps Web, as well as other options to get started.

+

Getting started with Gramps Web

+

Gramps Web is a web app that runs on a server and is accessed via the web browser. It is meant to be made accessible to authenticated users via the internet.

+

If you want to use Gramps Web for your genealogical research data, you have to choose one of the following options:

+
    +
  1. Self-host on your own hardware
  2. +
  3. Self-host in the cloud
  4. +
  5. Sign up for a hosted instance
  6. +
+

While the first option gives you maximal flexibility and control, it can also be technically challenging.

+
+

Tip

+

One of the main principles of Gramps Web is to put users in control of their own data at any time, so migrating data from one instance to another is simple. Don't worry about being locked in after having chosen one of the options!

+
+

Self-host on your own hardware

+

The most convenient way to self-host Gramps Web is via Docker Compose. We also provide Docker images for the ARM architecture, so you can run Gramps Web on a Raspberry Pi in your basement.

+

See Deploy with Docker for setup instructions.

+

Self-host in the cloud

+

Installing Gramps Web can be more challenging than other, simple web applications and is not compatible with ordinary "shared hosting" providers. You can sign up for a virtual server and install Gramps Web manually.

+

A simpler option is to use a pre-installed cloud image. One example is our DigitalOcean 1-click app.

+

Sign up for a hosted instance

+

A hosted Gramps Web is the easiest way to get started with Gramps Web, since no installation or configuration is required.

+

Here is a list of dedicated hosting providers for Gramps Web (the Gramps open source community does not take responsibility for their services):

+
    +
  • Grampshub (www.grampshub.com), offered by one of the Gramps Web main contributors
  • +
+

If you use a hosted option for Gramps Web, you can skip the rest of this section and jump right to the Administration section.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/setup/v2/index.html b/setup/v2/index.html new file mode 100644 index 0000000..253cc56 --- /dev/null +++ b/setup/v2/index.html @@ -0,0 +1,1724 @@ + + + + + + + + + + + + + + + + + + + + + + + + 2.0 upgrade guide - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + +

Gramps 5.2 upgrade guide

+

Gramps 5.2 was released on February 23, 2024. Since it uses a new family tree database schema compared to Gramps 5.1, additional steps are necessary when upgrading Gramps Web to be used with Gramps 5.2. This page describes the necessary steps.

+

Overview of the steps

+

This is an overview of the steps required to upgrade. +It also shows which steps are executed by the administrator of the Gramps Web server, the owner of the family tree, and whether it's needed only for users of the sync addon

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Server administratorTree ownerAction
 Back up your family tree
 1Synchronize Gramps Web with Gramps Desktop
Update Gramps Web
 Update the tree's database schema
 1Update Gramps Desktop
 1Install the updated Sync Addon
 Back up your family tree
 1Synchronize Gramps Web with Gramps Desktop
+

1 Only needed if you synchronize Gramps Web with Gramps Desktop.

+

Overview of the release status

+

The following table gives an overview of when the components needed for Gramps Web with Gramps 5.2 have been released.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ComponentReleased
Gramps 5.2.02024-02-23 ✓
Gramps Web Sync Addon 1.0.4 for Gramps 5.22024-02-23 ✓
Gramps Web API 2.0.02024-02-28 ✓
Gramps Web 23.3.02024-02-28 ✓
+

Detailed steps

+

This section provides more details about some of the individual steps above.

+

Back up your family tree

+

In Gramps Web, go to the "Export" page and select "Gramps XML (family tree)" (the default option). Click "Generate" and wait until the download of the .gramps file starts.

+

You can also create a backup in Gramps Desktop in the usual way.

+

Update the tree's database schema

+

When you access Gramps Web for the first time after having upgraded it, you will be presented with a screen showing the message:

+
+

The Family Tree you are trying to load is in a schema version not supported by this version of Gramps Web. Therefore you cannot load this Family Tree without upgrading its schema. This action cannot be undone.

+
+

You can now click on the button "Upgrade Family Tree". It will show a progress bar and should not take more than a minute to complete. Don't worry, if you accidentally close your browser window, the conversion will continue in the background.

+
+

Warning

+

If you use a non-standard setup without background task queue, the database upgrade might fail and your family tree might get corrupted. You can check (before updating Gramps Web) if you are using a background task queue by going to the "System Information" section in the settings and making sure it has "task queue: true".

+
+

Update Gramps Desktop

+

Follow the Gramps Desktop installation instructions for your operating system.

+

Install the updated Sync Addon

+

You can use the new Plugin Manager included in Gramps 5.2 - just search for Gramps Web Sync, click on install, and restart Gramps.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 0000000..c37d677 --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,218 @@ + + + + https://www.grampsweb.org/ + 2024-05-04 + daily + + + https://www.grampsweb.org/Configuration/ + 2024-05-04 + daily + + + https://www.grampsweb.org/Deployment/ + 2024-05-04 + daily + + + https://www.grampsweb.org/DigitalOcean/ + 2024-05-04 + daily + + + https://www.grampsweb.org/LetsEncrypt/ + 2024-05-04 + daily + + + https://www.grampsweb.org/Postgres/ + 2024-05-04 + daily + + + https://www.grampsweb.org/Update/ + 2024-05-04 + daily + + + https://www.grampsweb.org/Users/ + 2024-05-04 + daily + + + https://www.grampsweb.org/admin/ + 2024-05-04 + daily + + + https://www.grampsweb.org/contribute/ + 2024-05-04 + daily + + + https://www.grampsweb.org/cpu-limited/ + 2024-05-04 + daily + + + https://www.grampsweb.org/dev/ + 2024-05-04 + daily + + + https://www.grampsweb.org/frontend-config/ + 2024-05-04 + daily + + + https://www.grampsweb.org/help/ + 2024-05-04 + daily + + + https://www.grampsweb.org/multi-tree/ + 2024-05-04 + daily + + + https://www.grampsweb.org/quickstart/ + 2024-05-04 + daily + + + https://www.grampsweb.org/requirements/ + 2024-05-04 + daily + + + https://www.grampsweb.org/s3/ + 2024-05-04 + daily + + + https://www.grampsweb.org/setup/ + 2024-05-04 + daily + + + https://www.grampsweb.org/dev-backend/ + 2024-05-04 + daily + + + https://www.grampsweb.org/dev-backend/api/ + 2024-05-04 + daily + + + https://www.grampsweb.org/dev-backend/queries/ + 2024-05-04 + daily + + + https://www.grampsweb.org/dev-backend/setup/ + 2024-05-04 + daily + + + https://www.grampsweb.org/dev-frontend/ + 2024-05-04 + daily + + + https://www.grampsweb.org/dev-frontend/architecture/ + 2024-05-04 + daily + + + https://www.grampsweb.org/dev-frontend/build/ + 2024-05-04 + daily + + + https://www.grampsweb.org/dev-frontend/setup/ + 2024-05-04 + daily + + + https://www.grampsweb.org/dev-frontend/translation/ + 2024-05-04 + daily + + + https://www.grampsweb.org/setup/v2/ + 2024-05-04 + daily + + + https://www.grampsweb.org/user-guide/ + 2024-05-04 + daily + + + https://www.grampsweb.org/user-guide/blog/ + 2024-05-04 + daily + + + https://www.grampsweb.org/user-guide/dna/ + 2024-05-04 + daily + + + https://www.grampsweb.org/user-guide/export/ + 2024-05-04 + daily + + + https://www.grampsweb.org/user-guide/first-login/ + 2024-05-04 + daily + + + https://www.grampsweb.org/user-guide/gql/ + 2024-05-04 + daily + + + https://www.grampsweb.org/user-guide/import/ + 2024-05-04 + daily + + + https://www.grampsweb.org/user-guide/media/ + 2024-05-04 + daily + + + https://www.grampsweb.org/user-guide/owner/ + 2024-05-04 + daily + + + https://www.grampsweb.org/user-guide/registration/ + 2024-05-04 + daily + + + https://www.grampsweb.org/user-guide/revisions/ + 2024-05-04 + daily + + + https://www.grampsweb.org/user-guide/sync/ + 2024-05-04 + daily + + + https://www.grampsweb.org/user-guide/tagging/ + 2024-05-04 + daily + + + https://www.grampsweb.org/user-guide/tasks/ + 2024-05-04 + daily + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 0000000..8ec1b12 Binary files /dev/null and b/sitemap.xml.gz differ diff --git a/user-guide/blog/index.html b/user-guide/blog/index.html new file mode 100644 index 0000000..d81d481 --- /dev/null +++ b/user-guide/blog/index.html @@ -0,0 +1,1553 @@ + + + + + + + + + + + + + + + + + + + + + + + + Use the blog - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Use the built-in blog

+

The blog is meant for presenting stories about your family history research.

+

In the Gramps database, blog posts are represented as sources with a note attached, containg the blog's text, and optionally, media files for the images of the blog post. Gramps Web treats every source with a tag Blog as blog article.

+

Add a blog post

+

To add a blog post, you can use Gramps Web or Gramps Dekstop (synchronized with Gramps Web), the steps are the same in both cases:

+
    +
  • Add a new source. The title of the source will be the title of your blog post, the author of the source will be the author of the post.
  • +
  • Optionally, associate the source with a repository corresponding to your Gramps Web blog
  • +
  • Add a new note to the source. Write your blog post and copy the text into the note.
  • +
  • Optionally, add one or more media files to your source. The first media file will be taken as the post preview picture shown above the text. All media files will be shown below the text as a gallery.
  • +
  • Add the label Blog to the source (create it if it doesn't exist)
  • +
+

Relation between blog and sources

+

Since blog posts are just sources, all blog articles also appear on the list of sources and show up as sources in searches. In the source view, there is a button "show in blog" that will take you to the blog view for that blog post. The URL of the blog post also contains the Gramps ID of the corresponding source, so an article at yourdomain.com/blog/S0123 corresponds to the source at yourdomain.com/source/S0123.

+

At the bottom of every blog post, there is a button "details" that will take you to the source view.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/user-guide/dna/index.html b/user-guide/dna/index.html new file mode 100644 index 0000000..30c47b1 --- /dev/null +++ b/user-guide/dna/index.html @@ -0,0 +1,1483 @@ + + + + + + + + + + + + + + + + + + + + + + + + DNA - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

DNA segment map

+

The DNA segment map view, accessible under the "DNA" tab in the person view, shows DNA matches with other people in the tree as segments highlighted on the person's chromosomes.

+

This feature does not rely on raw DNA data being uploaded to Gramps Web, but on the segment match data directly, which can be obtained from websites like Gedmatch or MyHeritage.

+

The DNA segment map is based on the Gramplet Addon that provides the same functionality in Gramps Desktop. Its wiki page contains more details about how to obtain the data, how to interpret it, and how to enter the data in Gramps.

+

The data is added as notes attached to associations (or attached to association citations), which is possible directly in Gramps Web.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/user-guide/export/index.html b/user-guide/export/index.html new file mode 100644 index 0000000..7c77bcc --- /dev/null +++ b/user-guide/export/index.html @@ -0,0 +1,1585 @@ + + + + + + + + + + + + + + + + + + + + + + + + Export data - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + +

Export data

+ +

Back up your family tree

+

To create a backup of your family tree, open the Export page in Gramps Web and select the Gramps XML format.

+

Clicking on "export" will generate the file and start the download once it is ready.

+

Note that if your Gramps Web user does not have permission to view private records, the export will not be a full backup, since it will not contain any private records.

+

Share your family tree with users of other genealogy programs

+

When sharing genealogical data as Gramps XML is not an option, you can also export a GEDCOM file. Note that this is not suited as a backup of your Gramps Web tree.

+

Back up your media files

+

To back up your media files, you can create and download a ZIP archive of all media files on the Export page.

+

Note that, especially for large trees, this can be an expensive operation for the server and should only be done if absolutely necessary.

+

A better option to back up your media files on a regular basis is to use the Gramps Web Sync addon (which itself is not a backup solution) and create incremental backups on your local computer.

+

In both bases, if your Gramps Web user does not have permission to view private records, the export will not contain files of private media objects.

+

Move to a different Gramps Web instance

+

Gramps Web does not lock you in with a specific provider and you can always move to a different Gramps Web instance without loosing any data, and without having direct access to either of the servers.

+

To achieve a full migration, follow these steps (assuming you have tree owner permissions):

+
    +
  1. Go to the Export page and export your tree as a Gramps XML (.gramps) file. If you use the Sync addon, you can also generate the export in Gramps desktop.
  2. +
  3. On the Export page, generate & download a media archive. If you use the Sync addon, you can also simply ZIP your local Gramps media folder.
  4. +
  5. Go to Settings > Administration > Manage users and click the "Export user details" button. It will download a JSON file.
  6. +
  7. In the new Gramps Web instance, open the Import page. Import the .gramps file exported in step 1.
  8. +
  9. On the Import page of the new Gramps Web instance, upload the media archive (ZIP).
  10. +
  11. Go to Settings > Administration > Manage users of the new Gramps Web instance. Click the "Import user accounts" button and upload the JSON file downloaded in step 3.
  12. +
+

Note that, while your user accounts will be migrated, all your users will need to set new passwords by using the "forgot password" link, since passwords are stored in encrypted form and cannot be exported.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/user-guide/first-login/index.html b/user-guide/first-login/index.html new file mode 100644 index 0000000..c202cba --- /dev/null +++ b/user-guide/first-login/index.html @@ -0,0 +1,1473 @@ + + + + + + + + + + + + + + + + + + + + + + + + First login - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

When logging in to Gramps Web for the first time, a form will be displayed requiring the user to select a language for the frontend and a home person.

+

This home person does not have to coincide with the home person in Gramps desktop – it is a personal setting for every user of Gramps Web. The home person is used e.g. for the initial view of the family tree. A typical choice would be for a user to select themselves as home person.

+

To select a person as home person, start typing in the text field and a drop-down list with matches will appear.

+

The language and home person settings are stored in the browser's local storage, so they will persist on a given device.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/user-guide/gql/index.html b/user-guide/gql/index.html new file mode 100644 index 0000000..0f868c2 --- /dev/null +++ b/user-guide/gql/index.html @@ -0,0 +1,1841 @@ + + + + + + + + + + + + + + + + + + + + + + + + GQL filters - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Filter using the Gramps Query Language

+

The object list views (people, families, events, ...) have an optional advanced filter mode based on the Gramps Query Language (GQL).

+

To use it, type a query in GQL syntax and press enter (or hit the "apply" button). The view will be filtered by the query. If the query is invalid, the input field's frame turns red.

+

The GQL syntax is described below, copied from the GQL documentation.

+

Syntax

+

A GQL query is a string composed of statements of the form property operator value, optionally combined with the keywords and and or as well as parentheses.

+

Properties

+

class

+

Filters for the Gramps object class and can be one of person, family, event, place, citation, source, repository, media, or note.

+

Object properties

+

GQL supports querying nested properties of Gramps objects, e.g. primary_name.date.calendar. See below for a full list of properties – see also Gramps Data Model.

+

List elements by index

+

Individual elements in list-like properties can be accessed by positional index in square brackets. This can be combined with nested properties, e.g. primary_name.surname_list[0].surname.

+

length

+

This is a special property that returns the length of an array-like Gramps property, e.g. media_list.length > 0 to get objects with media references.

+

all, any

+

Two more special properties for array-like Gramps properties. all requires a condition to apply to all items of the list, any requires it to apply to at least one item. Both properties can be combined with other properties before and after. Examples: media_list.any.citation_list.length > 0 to return objects with media references that have citations; media_list.all.citation_list.length = 0 to return objects where all media objects do not have citations.

+

Array index

+

A numerical array index can be used to access specific elements of a list, e.g. child_ref_list[0] for the first child.

+

get_person, etc.

+

While all the preceding properties refer to a single Gramps object, it is also possible to filter on different objects referred to by the initial object. For instance, an event has a place handle in its place property. Using the get_place pseudo-property, GQL switches to the properties of that object. For instance, it is possible to search for class = event and place.get_place.name.value ~ York. This can also be combined with any or all, e.g. class = person and event_ref_list.any.ref.get_event.description ~ farmer.

+

Operators

+

=, !=

+

Equality or inequality. Examples: class = person, class != family

+

>, >=, <, <=

+

Comparison. Works for strings as well as numbers. Examples: confidence <= 1, change > 1712477760, gramps_id > "I2015"

+

~, !~

+

Contains or does not contain. Works for lists as well as strings. Examples: gramps_id !~ F00, author ~ David, family_list ~ "3a16680f7d226e3ac3eefc8b57a"

+

No operator/value

+

If no operator and value is given, the value is interpreted as a boolean (true or false). This works for +all types of properties and Python rules for casting to true/false are applied. For instance, the query private returns private objects; confidence returns objects where confidence is greater than 0; media_list returns objects with at least one media reference.

+

Values

+

Values can be numbers or strings. If numbers should be interpreted as strings or special characters like = are involved, enclose the value in strings. Examples: gramps_id = F0001, but gramps_id = "0001".

+

Commented examples

+
class = note and private and text.string ~ David
+
+

All private notes that contain the string "David" in their text

+
media_list.length >= 10
+
+

All objects (of any class) with 10 or more media references

+
class != person and media_list.any.rect
+
+

All objects that are not a person but have a media reference that is part of an image. Here, media_list.any.rect means that for each of the items in the media list, it is checked whether the rect (rectangle) property has a truthy value, meaning it is a non-empty list. (media_list.any.rect.length > 0 would have the same effect.)

+
class = family and child_ref_list.length > 10
+
+

Families with more than 10 children.

+
class = event and date.modifier = 0 and date.dateval[2] > 2020
+
+

Events where the date is a normal date (not a range etc.) and the year is after 2020.

+
note_list.any.get_note.text.string ~ "David"
+
+

All objects with at least one note that contains the string "David" in their text.

+
class = family and child_ref_list.all.ref.get_person.gender = 0 and child_ref_list.length = 3
+
+

All families with three daughters.

+

Full list of Gramps Properties

+

For a full list of Gramps properties, see the GQL documentation.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/user-guide/import/index.html b/user-guide/import/index.html new file mode 100644 index 0000000..c72b318 --- /dev/null +++ b/user-guide/import/index.html @@ -0,0 +1,1586 @@ + + + + + + + + + + + + + + + + + + + + + + + + Import data - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Import data

+ +

Prepare your Gramps database

+

If you are using Gramps Desktop, there are two steps to prepare your database to make sure everything will run smoothly in the following. If you are migrating from a different genealogy program, you can skip this step.

+
    +
  1. Check and repair the database
      +
    • Optional: create a database backup by exporting to Gramps XML
    • +
    • Run the Check and repair database tool. This fixes some internal inconsistencies that could lead to problems in Gramps Web.
    • +
    +
  2. +
  3. Convert media paths to relative +
  4. +
+

Import genealogical data

+

To import an existing family tree, use the "Import" page and upload a file in any of the file formats supported by Gramps – see Import from another genealogy program in the Gramps Wiki.

+

If you already use Gramps Desktop, it is strongly recommended to use the Gramps XML (.gramps) format to ensure your online and offline trees use the same identifiers and can be synchronized.

+

Why no support for Gramps XML package?

+

While Gramps XML (.gramps) is the preferred format for importing data, Gramps XML package (.gpkg) is not supported by Gramps Web. This is because the import and export routines for media files are not suited for use on a web server.

+

To import the media files belonging to an imported .gramps file, see the next section.

+

Import media files

+

If you have uploaded a family tree and need to upload the corresponding media files, you can use the "import media archive" button on the "Import" page.

+

It expects a ZIP file with the missing media files inside. The folder structure in the ZIP file does not have to be the same as the folder structure inside the Gramps media folder as the files are matched to media objects by their checksum.

+

Note that this feature only works for files that have the correct checksum in the Gramps database (which should be ensured by running the check and repair tool in the first step).

+

When moving to Gramps Web from a different genalogy program including media files, it is recommended to first import everything into Gramps Desktop, which has more options to associate existing media files with an imported tree.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/user-guide/index.html b/user-guide/index.html new file mode 100644 index 0000000..8e46aad --- /dev/null +++ b/user-guide/index.html @@ -0,0 +1,1478 @@ + + + + + + + + + + + + + + + + + + + + + + + + Introduction - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + + + +
+
+
+ + + + + + +
+
+
+ + + + + + + + + +
+
+ + + + + + + + +

This section contains the documentation for users of Gramps Web.

+ + + + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/user-guide/media/index.html b/user-guide/media/index.html new file mode 100644 index 0000000..94808bc --- /dev/null +++ b/user-guide/media/index.html @@ -0,0 +1,1549 @@ + + + + + + + + + + + + + + + + + + + + + + + + Add media files - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Add media files

+ +

There are two ways to add a new media file (an image, audio file, video file, or any other file):

+

Add a new standalone media file

+

To add a standalone media file, click the + icon in the top app bar and select "Media Object".

+

Click on "select a file" to select a file from your computer. On a mobile device, clicking this button will give you the option of directly taking a photo with your device's camera.

+

Optionally,

+
    +
  • enter a description of the media file under "title"
  • +
  • enter a date
  • +
  • set the media file as private (which will make it visible only to users with sufficient authorization)
  • +
+

Click "add" to upload the file and create the media object.

+ +

The following object types in Gramps can have media objects attached: people, families, events, places, sources, and citations.

+

In the detail view of any object, click the blue edit button in the bottom right (if you do not see it, your user does not have edit permissions). Click on the "gallery" tab and click the blue + button.

+

A dialog will open that offers the same fields as described in the previous section. Click "save" to upload the file, add a new media object, and link it to the viewed object.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/user-guide/owner/index.html b/user-guide/owner/index.html new file mode 100644 index 0000000..5b3077d --- /dev/null +++ b/user-guide/owner/index.html @@ -0,0 +1,1568 @@ + + + + + + + + + + + + + + + + + + + + + + + + Create owner account - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+ +
+ + + +
+
+ + + + + + + + +

Create an account for the tree owner

+

Before you can start using Gramps Web, you need to create an account for the tree owner. If no user account exists for a given tree, a form will be shown to create an account. The form depends on the server setup being for a single tree or for multiple trees.

+

Single-tree setup: create admin account

+

On a server with single-tree setup, when no user account exists yet, opening Gramps Web shows a form to create an admin account. The admin user will be both the owner of the (single) tree and the administrator of the installation. The form also allows setting the e-mail configuration needed for e-mail notifications (e.g. resetting a user password). If the e-mail configuration has already been added via a configuration file or environment variables on the server, this part of the form can be left empty.

+

The form also allows to import genealogical data by uploading a file. This can also be done later from the "Import" page in Gramps Web (see Import data).

+

Multi-tree setup: create admin account

+

In a multi-tree setup, the same form to create an admin account will be shown if no users exists in any tree, i.e. when the server has just been created.

+

Multi-tree setup: create tree owner account

+

In a multi-tree setup, every user is tied to a single tree. Even if users already exist in other trees, a tree owner can be created in the web interface if no owner exists for this tree yet.

+

However, the owner creation form will not be displayed automatically on the Gramps Web home page, which is the same for all trees. Instead, it can be reached at https://my-gramps-instance/firstrun/my-tree-id, where https://my-gramps-instance is the base address of your Gramps Web installation, and my-tree-id is the ID of your tree.

+

A possible workflow for a site administrator to create a new tree is to

+
    +
  • Create a tree via the REST API, obtaing the tree ID of the new tree
  • +
  • Share the link to the owner creation form with the appropriate tree ID with the prospective tree owner
  • +
+

The tree owner creation form is analogous to the admin creation form described above, except that it does not allow to change the e-mail configuration (which is only allowed for admins).

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/user-guide/registration/index.html b/user-guide/registration/index.html new file mode 100644 index 0000000..0c9d0d6 --- /dev/null +++ b/user-guide/registration/index.html @@ -0,0 +1,1576 @@ + + + + + + + + + + + + + + + + + + + + + + + + Registration - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Registration

+ +

In a single-tree installation, anybody can register a new account at a Gramps Web instance, but it will need to be enabled manually by a site owner before it can be used to log in.

+

In a multi-tree installation, users additionally require the tree ID to sign up; in practice, this means they can sign up using a registration link shared by the tree owner.

+

1. Find registration form

+

On the login form on the home page of Gramps Web, usually there is a link "Register new account".

+

If this link is missing, it is probably because it is a multi-tree installation of Gramps Web. In that case, contact the tree owner for a registration link.

+

The tree owner can find and copy the registration link under Settings/Administration.

+

2. Submit registration form

+

The registration form has four mandatory fields: username, password, e-mail address, and full name. When all four fields have been filled, click "submit" to start the registration process.

+

3. Confirm e-mail address

+

After the form has been submitted, an automated e-mail will be sent to the e-mail address provided containing an e-mail confirmation link. Clicking it will open a confirmation page.

+

If the confirmation e-mail does not arrive (and you have checked your Spam folder), it could be that e-mail has not been configured correctly by the Gramps Web server administrator.

+

4. Enable account

+

After the e-mail address has been confirmed, the tree owner will receive an e-mail notification and can enable the new user account by going to the "User administration" section in settings page (accessible via the user icon in the top app bar) and changing the user role from "disabled" to any of the other roles.

+

Note that the new user will not receive an automated notification that their account has been enabled, so it is advisible for the administrator to notify them personally.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/user-guide/revisions/index.html b/user-guide/revisions/index.html new file mode 100644 index 0000000..762ec52 --- /dev/null +++ b/user-guide/revisions/index.html @@ -0,0 +1,1483 @@ + + + + + + + + + + + + + + + + + + + + + + + + Revision history - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Revision History

+

The revision history view shows all edits that have been made to the family tree.

+

The list view shows the edits grouped by "transactions". A transaction is a group of one or more additions, deletions, or changes to Gramps objects. For instance, adding a new family with two existing persons as father and mother generates a transaction with one added family object and two modified person objects (because they contain the link to the new family object).

+

Clicking on a transaction opens the transaction detail view. It contains the list of individual additions, deletions, and updates by Gramps object.

+

Selecting an indivdial change opens a view of the raw JSON representation of the Gramps object with additions and deletions highlighted in green and red, respectively.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/user-guide/sync/index.html b/user-guide/sync/index.html new file mode 100644 index 0000000..d17eb01 --- /dev/null +++ b/user-guide/sync/index.html @@ -0,0 +1,1611 @@ + + + + + + + + + + + + + + + + + + + + + + + + Synchronize with Gramps - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Synchronize Gramps Web and Gramps Desktop

+

Gramps Web Sync is an addon for Gramps that allows to synchronize your Gramps database on your desktop computer with Gramps Web, including media files.

+
+

Warning

+

As with any synchronization tool, please do not consider this as a backup tool. An accidental deletion on one side will be propagated to the other side. Make sure to create regular backups (in Gramps XML format) of your family tree.

+
+

Using Gramps Web Sync requires tree owner permissions in Gramps Web.

+

Installation

+

The addon requires Gramps 5.2 running on Python 3.8 or newer. +It is available in Gramps Desktop and can be installed in the usual way.

+
+

Warn

+

Please make sure to use the same version of Gramps on your desktop as the one running on your server. See the Get Help section for how to find out which Gramps version your server is running. The Gramps version has the form MAJOR.MINOR.PATCH, and MAJOR and MINOR must be the same on web and desktop.

+
+

Optional step:

+
    +
  • Install keyring (e.g. sudo apt install python3-keyring) to allow storing the API password safely in your system's password manager
  • +
+

Usage

+

Once installed, the addon is availabe in Gramps under Tools > Family Tree Processing > Gramps Web Sync. Once started, and after confirming the dialog that the undo history will be discarded, the tool will ask you for the base URL (example: https://mygrampsweb.com/) of your Gramps Web instance, your username, and password. You need an account with owner privileges To sync changes back to your remote database. The username and URL will be stored in plain text in your Gramps user directory, the password will only be stored if keyring is installed (see above).

+

If there are any changes, the tool will display a confirmation dialog before applying the changes. (At present, the confirmation dialog only shows the Gramps IDs of the affected objects.)

+

Media file synchronization

+

After the databases have been synchronized, the tool checks for any new or updated media files. It displays the files missing locally or on the remote server and, upon user confirmation, tries to download and upload the files.

+

Limitations:

+
    +
  • If a local file has a different checksum from the one stored in the Gramps database (this can happen e.g. for Word files when edited after being added to Gramps), the upload will fail with an error message.
  • +
  • The tool does not check integrity of all local files, so if a local file exist under the path stored for the media object, but the file is different from the file on the server, the tool will not detect it. Use the Media Verify Addon to detect files with incorrect checksums.
  • +
+

Background: how the addon works

+

The addon is meant to keep a local Gramps database in sync with a remote Gramps Web database, to allow both local and remote changes (collaborative editing).

+

It is not suited

+
    +
  • To synchronize with a database that is not direct derivative (starting from a database copy or Gramps XML export/import) of the local database
  • +
  • To merge two databases with a large number of changes on both sides that need manual attention for merging. Use the excellent Import Merge Tool for this purpose.
  • +
+

The principles of operation of the tool are very simple:

+
    +
  • It compares the local and remote databases
  • +
  • If there are any differences, it checks the timestamp of the latest identical object, let's call it t
  • +
  • If an object changed more recently than t exists in one database but not the other, it is synced to both (assume new object)
  • +
  • If an object changed the last time before t is absent in one database, it is deleted in both (assume deleted object)
  • +
  • If an object is different but changed after t only in one database, sync to the other one (assume modified object)
  • +
  • If an object is different but changed after t in both databases, merge them (assume conflicting modification)
  • +
+

This algorithm is simple and robust as it does not require tracking syncrhonization history. However, it works best when you synchronize often.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/user-guide/tagging/index.html b/user-guide/tagging/index.html new file mode 100644 index 0000000..3ec1fd6 --- /dev/null +++ b/user-guide/tagging/index.html @@ -0,0 +1,1486 @@ + + + + + + + + + + + + + + + + + + + + + + + + Tag people in photos - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Gramps Web allows tagging people in photographs, similar to Gramps Desktop, linking the person and the media object. This is simplified by automated face detection.

+

To tag a person in a photo, follow these steps:

+
    +
  • Open the detail view of the media object, e.g. by clicking on "show details" in the full-screen preview.
  • +
  • Click the blue edit button in the bottom-right corner. If you do not see this button, your user does not have edit permissions.
  • +
  • Overlayed on the image, you will see boxes with dashed border corresponding to detected facial regions. To tag a person, click on the box to highlight it and click tge "person" button to select an existing person.
  • +
  • To manually draw a rectangle instead, click the + + + +button
  • +
  • To delete an existing tag, select an existing rectangle (with a solid border) and click the + + + +button
  • +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/user-guide/tasks/index.html b/user-guide/tasks/index.html new file mode 100644 index 0000000..6df6a56 --- /dev/null +++ b/user-guide/tasks/index.html @@ -0,0 +1,1609 @@ + + + + + + + + + + + + + + + + + + + + + + + + Manage tasks - Gramps Web + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Use the built-in task management

+

Gramps Web contains a built-in genealogical task management tool. It is meant to enable reserarches to plan and prioritize, but also document their tasks. This is why tasks are represented as sources in the Gramps database. After completing a task, the associated content can serve as a source documenting the research process.

+

Task basics

+

Tasks have the following properties:

+
    +
  • Status. This can be "Open", "In Progress", "Blocked", or "Done"
  • +
  • Priority. This can be "Low", "Medium", or "High"
  • +
  • Tags. The labels are normal Gramps tags of the underlying source. (Note that all tasks additionally have the ToDo label to identify them as tasks, but this label is hidden in the task list to avoid clutter.)
  • +
  • Title. Shown in the task list
  • +
  • Description. A rich-text field that can be used to describe the problem statement, but also document any progress made
  • +
  • Media. Any media files attached to the task
  • +
+

Create a task

+

Since tasks are normal Gramps objects, they can be edited or created by the same group of users that can edit or create other objects (like people or events).

+

To create a task, click on the + button on the task list page. Enter at least a title. The status will always be "Open" on creation.

+

Edit a task

+

To any of the task's details, click on it in the task list.

+

The task detail page does not have a separate "edit mode" like other Gramps objects. Changes to the title, status, and priority are applied immediately. Changes to the rich-text description require clicking the "save" button beneath it.

+

Bulk change of task properties

+

The priority and status of tasks can be changed in bulk by using the checkboxes in the task list for selection and the appropriate buttons above the task list.

+

Tasks in Gramps Desktop

+

When adding tasks via Gramps Web, both the sources and the notes will have the ToDo tag attached to them, so the tasks will show up in the desktop To Do Notes Gramplet as well as the To Do Report.

+

To add or edit a task in Gramps Desktop, use the following guidelines

+
    +
  • Add a source with tag ToDo and the task title as title
  • +
  • Optionally, add a note to the source with tag ToDo, type "To Do", and the description as text
  • +
  • Add an attribute "Status" and set it to "Open", "In Progress", "Blocked", or "Done"
  • +
  • Add an attribute "Priority" and set it to 9 for low, 5 for medium, or 1 for high (these counter-intuitive values are taken from the iCalendar specification)
  • +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file