{ lib
, fetchFromGitHub
, python
, writeShellScriptBin
, writeText
, settings ? { }
}:

let
  # set some dummy values to make the package build
  settingsWithDefaults = {
    DOMAIN = "localhost";
    DEBUG = false;
    USE_HTTPS = false;
    EMAIL = "your@email.here";
    PGPORT = 5432;
    POSTGRES_USER = "bookwyrm";
    POSTGRES_DB = "bookwyrm";
    POSTGRES_HOST = "localhost";
    REDIS_ACTIVITY_HOST = "localhost";
    REDIS_ACTIVITY_PORT = 6379;
    REDIS_BROKER_HOST = "localhost";
    REDIS_BROKER_PORT = 6379;
    EMAIL_HOST = "smtp.example.com";
    EMAIL_PORT = 587;
    EMAIL_HOST_USER = "mail@example.org";
    EMAIL_HOST_PASSWORD = "blub";
    MEDIA_ROOT = "/var/lib/bookwyrm/images";
  } // settings;

  # toShellVar produces "" for false, which bookwyrm rejects
  toDjangoVar = name: value: lib.toShellVar name
    (if value == false then "false" else
      (if value == true then "true" else value));

  envfile = writeText "bookwyrm.env"
    (lib.strings.concatLines
      (lib.mapAttrsToList toDjangoVar settingsWithDefaults));

  bookwyrm = python.pkgs.buildPythonApplication rec {
    pname = "bookwyrm";
    version = "0.7.4";

    format = "other";

    src = fetchFromGitHub {
      owner = "bookwyrm-social";
      repo = "bookwyrm";
      rev = "refs/tags/v${version}";
      hash = "sha256-fhFgAsq859fbCvCw+QAioI5lW1c2k6rEiCxwFBGe7vE=";
    };

    propagatedBuildInputs = with python.pkgs; [
      aiohttp
      bleach
      celery
      colorthief
      django
      django-celery-beat
      bw-file-resubmit
      django-compressor
      django-imagekit
      django-model-utils
      django-sass-processor
      django-csp
      django-oauth-toolkit
      django-storages
      django-pgtrigger
      s3-tar
      environs
      flower
      gunicorn
      libsass
      markdown
      packaging
      pillow
      psycopg2
      pycryptodome
      dateutil
      redis
      requests
      responses
      pytz
      boto3
      django-storages
      django-redis
      opentelemetry-api
      opentelemetry-exporter-otlp-proto-grpc
      # opentelemetry-instrumentation-celery
      opentelemetry-instrumentation-django
      # opentelemetry-instrumentation-pyscopg2
      opentelemetry-sdk
      protobuf
      pyotp
      qrcode
      grpcio
    ];

    postBuild = ''
      ln -s ${envfile} .env
      # needed for the python settings.py file to not fail, but not
      # used during the commands executed below, so this is safe
      export SECRET_KEY=fnord

      substituteInPlace contrib/systemd/* \
        --replace /opt/bookwyrm/venv/bin/gunicorn ${lib.getExe python.pkgs.gunicorn} \
        --replace /opt/bookwyrm/venv/bin/celery ${lib.getExe' python.pkgs.celery "celery"} \
        --replace /opt/bookwyrm $out

      sed -i /BindPath/d contrib/systemd/*

      python manage.py compile_themes
      python manage.py collectstatic --no-input
    '';

    postInstall = ''
      mkdir -p $out/lib/systemd/system
      cp -r * .env $out
      cp -r contrib/systemd/* $out/lib/systemd/system
    '';

    passthru = {
      pythonPath = python.pkgs.makePythonPath propagatedBuildInputs;
      gunicorn = python.pkgs.gunicorn;
      celery = python.pkgs.celery;
      manage = environmentFile: writeShellScriptBin "bookwyrm-manage.py" ''
        set -a
        ${if environmentFile != null
          then "source ${environmentFile}"
          else ""}
        export PYTHONPATH=${passthru.pythonPath}
        cd ${bookwyrm.outPath}
        exec ${bookwyrm.outPath}/manage.py "$@"
      '';
    };

    # hacky hacky hack
    shellHook = ''
      export PYTHONPATH=${passthru.pythonPath}
    '';
  };
in bookwyrm