nix/pkgs/indico/default.nix
2025-04-05 21:19:36 +02:00

243 lines
6.5 KiB
Nix

{
lib,
fetchFromGitHub,
fetchPypi,
python3,
nodejs,
callPackage,
fetchNpmDeps,
npmHooks,
stdenv,
substituteAll,
prefetch-npm-deps,
pkg-config,
pixman,
cairo,
pango,
}:
let
python = python3.override {
self = python;
packageOverrides = self: super: {
celery = super.celery.overridePythonAttrs rec {
optional-dependencies.redis = [ self.redis ];
};
# Version 3.0.5 is the last one to support SQLAlchemy 1.4
flask-multipass = self.callPackage ../flask-multipass { };
flask-pluginengine = self.callPackage ../flask-pluginengine { };
flask-sqlalchemy = super.flask-sqlalchemy.overridePythonAttrs rec {
version = "3.0.5";
src = fetchPypi {
pname = "flask_sqlalchemy";
inherit version;
hash = "sha256-xXZeWMoUVAG1IQbA9GF4VpJDxdolVWviwjHsxghnxbE=";
};
};
flask-webpackext = self.callPackage ../flask-webpackext { };
indico-fonts = self.callPackage ../indico-fonts { };
lxml = super.lxml.overridePythonAttrs rec {
optional-dependencies.html5 = [ self.html5lib ];
};
pynpm = self.callPackage ../pynpm { };
pywebpack = self.callPackage ../pywebpack { };
sentry-sdk = super.sentry-sdk_1;
sqlalchemy = super.sqlalchemy_1_4;
wtforms-dateutil = self.callPackage ../wtforms-dateutil { };
wtforms-sqlalchemy = self.callPackage ../wtforms-sqlalchemy { };
flask-url-map-serializer = self.callPackage ../flask-url-map-serializer { };
};
};
# TODO PR
qTipUpstreamUrl = "git+https://indico@github.com/indico/qTip2.git#8951e5538a5c0833021b2d2b5d8a587a2c24faae";
qTipWithLockUrl = "git+https://indico@github.com/indico/qTip2.git#95a42a3be49767a631310a5a8bd924f386220799";
in
python.pkgs.buildPythonApplication rec {
pname = "indico";
version = "3.3.5";
pyproject = true;
disabled = python.pkgs.pythonOlder "3.12";
src = fetchFromGitHub {
owner = "indico";
repo = "indico";
rev = "refs/tags/v${version}";
hash = "sha256-OX5tqeIjd7Lb5XfvFFKcYb9Dbf5Z9QLXlVTepTpeOMU=";
};
INDICO_NO_GIT = "true";
INDICO_MAP_VERSION = src.outputHash;
build-system = [
python.pkgs.hatchling
python.pkgs.hatch-requirements-txt
python.pkgs.babel
python.pkgs.flask-url-map-serializer
nodejs
npmHooks.npmConfigHook
# Used by the npm dependency "canvas"
pkg-config
];
buildInputs = [
# Used by the npm dependency "canvas"
pixman
cairo
pango
];
npmDeps = fetchNpmDeps {
inherit src patches postPatch;
pname = "${pname}-${version}-npm-deps";
hash = "sha256-sM+ey/Lu5pJdAFA+k6FvP+apEy/yIRohuZC7kj/tnd8=";
};
# FIXME *why* is it required?
makeCacheWritable = true;
# npmFlags = [ "--verbose" ];
patches = [
./remove_marshmallow_enum.patch
./force_map_version.patch
];
postPatch = ''
# Seems fixed (the dependency is gone in master)
substituteInPlace requirements.in \
--replace-fail "hiredis<3" ""
# See JoshData/python-email-validator#90
substituteInPlace requirements.in \
--replace-fail "email-validator<1.3.0" "email-validator!=1.3.0"
# Botocore doesn't seem to be used anymore
substituteInPlace requirements.in \
--replace-fail "urllib3<2" "urllib3"
# Seems fixed
substituteInPlace requirements.in \
--replace-fail "pydyf<0.10" "pydyf"
# Remove transitive dependencies and unnecessary version pins
cp requirements.in requirements.txt
cp requirements.dev.in requirements.dev.txt
# Nix's pyproject format builds a wheel, but the custom hook
# is configured only for sdists (TODO figure out why)
substituteInPlace pyproject.toml \
--replace-fail "tool.hatch.build.targets.sdist.hooks.custom" \
"tool.hatch.build.hooks.custom" \
--replace-fail "babel==2.16.0" "babel" \
--replace-fail "hatchling==1.25.0" "hatchling"
substituteInPlace package.json \
--replace-fail ${qTipUpstreamUrl} ${qTipWithLockUrl}
substituteInPlace package-lock.json \
--replace-fail ${qTipUpstreamUrl} ${qTipWithLockUrl}
# Make the WSGI module importable by Gunicorn
# (TODO is there a way to use Gunicorn with a path?)
mv indico/web/indico.wsgi indico/web/wsgi.py
# TODO TODO ./bin/maintenance/build-assets.py
'';
# build_urls_map.py tries to import indico.web.flask.app
# which has not been installed yet at this stage
preBuild = ''
PYTHONPATH="$(pwd):$PYTHONPATH" ${lib.getExe python} bin/maintenance/build-assets.py indico --clean
'';
dependencies =
with python.pkgs;
[
alembic
authlib
babel
bcrypt
bleach
blinker
captcha
celery
certifi
click
colorclass
distro
email-validator
feedgen
flask-babel
flask-caching
flask-cors
flask-limiter
flask-marshmallow
flask-migrate
flask-multipass
flask-pluginengine
flask-sqlalchemy
flask-webpackext
flask-wtf
flask
google-auth
html2text
icalendar
indico-fonts
ipython
itsdangerous
jinja2
jsonschema
lxml
markdown
markupsafe
marshmallow-dataclass
marshmallow-oneofschema
marshmallow-sqlalchemy
marshmallow
packaging
pillow
prompt-toolkit
psycopg2
pycountry
pydyf
pygments
pypdf
python-dateutil
pytz
pywebpack
pyyaml
qrcode
redis
reportlab
requests
sentry-sdk
simplejson
speaklater
sqlalchemy
terminaltables
translitcodec
ua-parser
urllib3
wallet-py3k
weasyprint
webargs
werkzeug
wtforms
wtforms-dateutil
wtforms-sqlalchemy
xlsxwriter
]
++ bleach.optional-dependencies.css
++ celery.optional-dependencies.redis
++ qrcode.optional-dependencies.pil
++ lxml.optional-dependencies.html5
++ redis.optional-dependencies.hiredis
++ sentry-sdk_1.optional-dependencies.flask
++ sentry-sdk_1.optional-dependencies.celery
++ sentry-sdk_1.optional-dependencies.sqlalchemy
++ sentry-sdk_1.optional-dependencies.pure_eval
++ wtforms.optional-dependencies.email;
optional-dependencies = {
ldap = [ python.pkgs.python-ldap ];
};
meta = {
description = "Full-featured conferency lifecycle management and meeting/lecture scheduling tool";
homepage = "https://getindico.io/";
changelog = "https://docs.getindico.io/en/stable/changelog/";
license = lib.licenses.mit;
};
}