Skip to content

📅 Simple alternative to Doodle polls and scheduling (Python, Django, TypeScript, React, MUI)

Notifications You must be signed in to change notification settings

hartwork/jawanndenn

Repository files navigation

pre-commit image

What is jawanndenn?

jawanndenn setup

jawanndenn is a simple web application to schedule meetings and run polls, a libre alternative to Doodle. It is using the following technology:

jawanndenn is libre software developed by Sebastian Pipping. The code is licensed under the GNU Affero GPL license version 3 or later.

Please report bugs and let me know if you like it.

Poll Setup Format

The textarea titled "Setup (JSON)" uses a simple JSON-based format that knows the following keys:

  • lifetime — duration after which this poll will be deleted; can be "week" or "month"; an enum-like string
  • options — a list of strings, one for each option; supports Markdown-like syntax for: bold, italic, inline code
  • title — the title or headline of the poll to run; supports Markdown-like syntax for: bold, italic, inline code

Installation

To install the latest release without cloning the Git repository:

# pip3 install jawanndenn --user

To install from a Git clone:

# ./setup.py install --user

Deployment with docker-compose

Create a simple file .env like this one:

JAWANNDENN_POSTGRES_NAME=jawanndenn
JAWANNDENN_POSTGRES_USER=jawanndenn
JAWANNDENN_POSTGRES_PASSWORD=dEb2PIcinemA8poH
JAWANNDENN_SECRET_KEY=606ea88f183a27919d5c27ec7f948906d23fdd7821684eb59e8bcf7377e3853b

Make sure to adjust these values after copy and paste!

You can then build and run a docker image using docker-compose up --build.

The app is served on localhost:54080. PostgreSQL data is saved to ~/.jawanndenn-docker-pgdata/ on the host system. There is also an instance of Redis used for cross-process rate limiting, and a "cron" housekeeping container that will go delete polls that have exceeded their configured lifetime, every 60 minutes.

(If you need a low-maintenance SSL reverse proxy in front of jawanndenn, docker-ssl-reverse-proxy could be of interest.)

There is a few more environment variables that you could want to adjust in your environment. Altogether, there are these variables:

Environment variables

Variable Function
DJANGO_SETTINGS_MODULE Django settings module to use, leave as is, defaults to jawanndenn.settings (see docker-compose.yml)
JAWANNDENN_ALLOWED_HOSTS Hostnames to serve jawanndenn at, list separated by comma, is set to jawanndenn.de,www.jawanndenn.de on the main production server, defaults to 127.0.0.1,0.0.0.0,localhost (see jawanndenn/settings.py)
JAWANNDENN_DEBUG Debug mode, disabled for all values but True, disabled by default, should never be enabled in production for security (see jawanndenn/settings.py)
JAWANNDENN_MAX_POLLS Maximum total number of polls to store, denial of service protection, defaults to 1000 (see jawanndenn/settings.py and docker-compose.yml)
JAWANNDENN_MAX_VOTES_PER_POLL Maximum total number of polls to store, denial of service protection, defaults to 40 (see jawanndenn/settings.py)
JAWANNDENN_POSTGRES_HOST Hostname of the PostgreSQL database to connect to; defaults to postgres (see docker-compose.yml)
JAWANNDENN_POSTGRES_NAME Database name of the PostgreSQL database to connect to; no default, always required
JAWANNDENN_POSTGRES_PASSWORD Password for log-in with the PostgreSQL database; no default, always required
JAWANNDENN_POSTGRES_PORT Port of the PostgreSQL database to connect to; defaults to 5432 (see docker-compose.yml)
JAWANNDENN_POSTGRES_USER Username for log-in with the PostgreSQL database; no default, always required
JAWANNDENN_REDIS_HOST Hostname of the Redis database to connect to; defaults to redis (see docker-compose.yml)
JAWANNDENN_REDIS_PORT Port of the Redis database to connect to; defaults to 6379 (see docker-compose.yml)
JAWANNDENN_SECRET_KEY Django secret key; should be long, generated, not used elsewhere; no default, always required
JAWANNDENN_SENTRY_DSN Data source name (DSN) for use with Sentry, disabled/empty by default (see jawanndenn/settings.py)
JAWANNDENN_URL_PREFIX Prefix string to insert into URLs rather after the domain name to help with hosting multiple apps under the same domain side by side; e.g. prefix prefix123 will result in URLs like https://<domain>/prefix123/poll/<id>; empty by default (see jawanndenn/settings.py)

Doing backups with Docker Compose

A simple way to create and apply backups of Django's view on the PostgreSQL poll data is the following.

Let's assume you add a docker-compose.override.yml like this:

services:
  jawanndenn:
    volumes:
     - ~/.jawanndenn-docker-backups/:/home/jawanndenn/backups/:rw

Now Django management command dumpdata can be used to backup the poll data to a JSON file like this:

# docker compose run jawanndenn python3 -m django dumpdata -v3 --format json -o "/home/jawanndenn/backups/data-$(date -I).json"

To reset the database to the state of a backup, Django management loaddata would do the job:

# docker compose run jawanndenn python3 -m django loaddata -v3 /home/jawanndenn/backups/data-2025-05-23.json

Command line usage

When installed, invocation is as simple as

# jawanndenn

During development, you may want to run jawanndenn from the Git clone using

# PYTHONPATH=. python3 -m jawanndenn --debug

Currently supported arguments are:

# COLUMNS=80 jawanndenn --help
usage: jawanndenn [-h] [--version] [--debug] [--host HOST] [--port PORT]
                  [--url-prefix PATH] [--database-sqlite3 FILE]
                  [--django-secret-key-file FILE] [--max-polls COUNT]
                  [--max-votes-per-poll COUNT] [--dumpdata]
                  [--loaddata FILE.json]

options:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  --debug               Enable debug mode (default: disabled)
  --host HOST           Hostname or IP address to listen at (default:
                        127.0.0.1)
  --port PORT           Port to listen at (default: 8080)
  --url-prefix PATH     Path to prepend to URLs (default: "")
  --database-sqlite3 FILE
                        File to write the database to (default:
                        ~/jawanndenn.sqlite3)
  --django-secret-key-file FILE
                        File to use for Django secret key data (default:
                        ~/jawanndenn.secret_key)

limit configuration:
  --max-polls COUNT     Maximum number of polls total (default: 1000)
  --max-votes-per-poll COUNT
                        Maximum number of votes per poll (default: 40)

data import/export arguments:
  --dumpdata            Dump a JSON export of the database to standard output,
                        then quit.
  --loaddata FILE.json  Load a JSON export of the database from FILE.json,
                        then quit.

Migrating data from jawanndenn 1.x to 2.x

Migration takes four steps:

  1. Update to the latest version of jawanndenn 1.x, e.g. by running: pip2 install --upgrade 'jawanndenn<2'; the JSON data export was first introduced with release 1.6.3.

  2. Export existing polls:

    1. If you're using the commend line app: python2 -m jawanndenn --dumpdata > dump.json
    2. If you're using docker-compose: docker-compose run -T jawanndenn --database-pickle /data/polls.pickle --dumpdata > dump.json
  3. Deploy latest jawanndenn 2.x somewhere (as described above) or just pip3 install 'jawanndenn>=2' it somewhere

  4. Import the JSON dump created in step (2):

    1. If you're using the commend line app: python3 -m jawanndenn --loaddata dump.json

    2. If you're using docker-compose: docker-compose run -T jawanndenn sh -c 'cat > /tmp/dump.json && DJANGO_SETTINGS_MODULE=jawanndenn.settings python3 -m django loaddata /tmp/dump.json' < dump.json

Goals

Please check out the list of upcoming features.

Non-goals

  • Adding any new non-tiny features
  • Read availability from calendars

Thanks

Special thanks to Arne Maier (@KordonDev) for reporting an XSS vulnerability, responsibly.