paperless-ngx: 2.14.7 -> 2.15.1 (#397828)

This commit is contained in:
Leona Maroni 2025-04-14 13:50:55 +02:00 committed by GitHub
commit 8e5a0fe6b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 161 additions and 109 deletions

View file

@ -262,6 +262,8 @@
- `linuxPackages.nvidiaPackages.stable` now defaults to the `production` variant instead of `latest`. - `linuxPackages.nvidiaPackages.stable` now defaults to the `production` variant instead of `latest`.
- `paperless-ngx` has been updated to minor version 2.15 which switched the web server from Gunicorn to Granian. If you set Gunicorn specific envs (usually contain GUNICORN) they must be updated. Also `services.paperless.address` no longer accepts a domain name and Granian also does not support listening on unix domain sockets.
- `timescaledb` requires manual upgrade steps. - `timescaledb` requires manual upgrade steps.
After you run ALTER EXTENSION, you must run [this SQL script](https://github.com/timescale/timescaledb-extras/blob/master/utils/2.15.X-fix_hypertable_foreign_keys.sql). For more details, see the following pull requests [#6797](https://github.com/timescale/timescaledb/pull/6797). After you run ALTER EXTENSION, you must run [this SQL script](https://github.com/timescale/timescaledb-extras/blob/master/utils/2.15.X-fix_hypertable_foreign_keys.sql). For more details, see the following pull requests [#6797](https://github.com/timescale/timescaledb/pull/6797).
PostgreSQL 13 is no longer supported in TimescaleDB v2.16. PostgreSQL 13 is no longer supported in TimescaleDB v2.16.

View file

@ -21,7 +21,8 @@ let
PAPERLESS_MEDIA_ROOT = cfg.mediaDir; PAPERLESS_MEDIA_ROOT = cfg.mediaDir;
PAPERLESS_CONSUMPTION_DIR = cfg.consumptionDir; PAPERLESS_CONSUMPTION_DIR = cfg.consumptionDir;
PAPERLESS_THUMBNAIL_FONT_NAME = defaultFont; PAPERLESS_THUMBNAIL_FONT_NAME = defaultFont;
GUNICORN_CMD_ARGS = "--bind=${cfg.address}:${toString cfg.port}"; GRANIAN_HOST = cfg.address;
GRANIAN_PORT = toString cfg.port;
} }
// lib.optionalAttrs (config.time.timeZone != null) { // lib.optionalAttrs (config.time.timeZone != null) {
PAPERLESS_TIME_ZONE = config.time.timeZone; PAPERLESS_TIME_ZONE = config.time.timeZone;
@ -196,7 +197,7 @@ in
address = lib.mkOption { address = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = "localhost"; default = "127.0.0.1";
description = "Web interface address."; description = "Web interface address.";
}; };
@ -539,16 +540,15 @@ in
echo "PAPERLESS_SECRET_KEY is empty, refusing to start." echo "PAPERLESS_SECRET_KEY is empty, refusing to start."
exit 1 exit 1
fi fi
exec ${cfg.package.python.pkgs.gunicorn}/bin/gunicorn \ exec ${lib.getExe cfg.package.python.pkgs.granian} --interface asginl --ws "paperless.asgi:application"
-c ${cfg.package}/lib/paperless-ngx/gunicorn.conf.py paperless.asgi:application
''; '';
serviceConfig = defaultServiceConfig // { serviceConfig = defaultServiceConfig // {
User = cfg.user; User = cfg.user;
Restart = "on-failure"; Restart = "on-failure";
LimitNOFILE = 65536; LimitNOFILE = 65536;
# gunicorn needs setuid, liblapack needs mbind # liblapack needs mbind
SystemCallFilter = defaultServiceConfig.SystemCallFilter ++ [ "@setuid mbind" ]; SystemCallFilter = defaultServiceConfig.SystemCallFilter ++ [ "mbind" ];
# Needs to serve web page # Needs to serve web page
PrivateNetwork = false; PrivateNetwork = false;
}; };

View file

@ -2,8 +2,7 @@
lib, lib,
stdenv, stdenv,
fetchFromGitHub, fetchFromGitHub,
fetchpatch, node-gyp,
buildNpmPackage,
nodejs_20, nodejs_20,
nixosTests, nixosTests,
gettext, gettext,
@ -18,6 +17,7 @@
qpdf, qpdf,
tesseract5, tesseract5,
unpaper, unpaper,
pnpm,
poppler-utils, poppler-utils,
liberation_ttf, liberation_ttf,
xcbuild, xcbuild,
@ -27,23 +27,15 @@
xorg, xorg,
}: }:
let let
version = "2.14.7"; version = "2.15.1";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "paperless-ngx"; owner = "paperless-ngx";
repo = "paperless-ngx"; repo = "paperless-ngx";
tag = "v${version}"; tag = "v${version}";
hash = "sha256-p3eUEb/ZPK11NbqE4LU+3TE1Xny9sjfYvVVmABkoAEQ="; hash = "sha256-vICkRfVxzQlqhSBCieVNSGeXb6FCOx0qOnInKMy6Lhg=";
}; };
patches = [
# Fix frontend tests in March (yes, it's date dependent)
(fetchpatch {
url = "https://github.com/paperless-ngx/paperless-ngx/commit/bc90ccc5551f184a683128def772652ad74c65e3.patch";
hash = "sha256-KArPyKZLi5LfaTDTY3DxA3cdQYYadpQo052Xk9eH14c=";
})
];
# subpath installation is broken with uvicorn >= 0.26 # subpath installation is broken with uvicorn >= 0.26
# https://github.com/NixOS/nixpkgs/issues/298719 # https://github.com/NixOS/nixpkgs/issues/298719
# https://github.com/paperless-ngx/paperless-ngx/issues/5494 # https://github.com/paperless-ngx/paperless-ngx/issues/5494
@ -60,16 +52,6 @@ let
# tesseract5 may be overwritten in the paperless module and we need to propagate that to make the closure reduction effective # tesseract5 may be overwritten in the paperless module and we need to propagate that to make the closure reduction effective
ocrmypdf = prev.ocrmypdf.override { tesseract = tesseract5; }; ocrmypdf = prev.ocrmypdf.override { tesseract = tesseract5; };
uvicorn = prev.uvicorn.overridePythonAttrs (_: {
version = "0.25.0";
src = fetchFromGitHub {
owner = "encode";
repo = "uvicorn";
rev = "0.25.0";
hash = "sha256-ng98DTw49zyFjrPnEwfnPfONyjKKZYuLl0qduxSppYk=";
};
});
}; };
}; };
@ -85,73 +67,91 @@ let
poppler-utils poppler-utils
]; ];
frontend = buildNpmPackage { frontend =
pname = "paperless-ngx-frontend"; let
inherit version src patches; frontendSrc = src + "/src-ui";
in
stdenv.mkDerivation rec {
pname = "paperless-ngx-frontend";
inherit version;
nodejs = nodejs_20; # does not build with 22 src = frontendSrc;
postPatch = '' pnpmDeps = pnpm.fetchDeps {
cd src-ui inherit pname version src;
''; hash = "sha256-yoTXlxXLcWD2DMxqjb02ZORJ+E0xE1DbZm1VL7vXM4g=";
};
npmDepsHash = "sha256-hK7Soop9gBZP4m2UzbEIAsLkPKpbQkLmVruY2So4CSs="; nativeBuildInputs =
[
node-gyp
nodejs_20
pkg-config
pnpm.configHook
python3
]
++ lib.optionals stdenv.hostPlatform.isDarwin [
xcbuild
];
nativeBuildInputs = buildInputs =
[ [
pkg-config pango
python3 ]
] ++ lib.optionals stdenv.hostPlatform.isDarwin [
++ lib.optionals stdenv.hostPlatform.isDarwin [ giflib
xcbuild darwin.apple_sdk.frameworks.CoreText
]; ];
buildInputs = CYPRESS_INSTALL_BINARY = "0";
[ NG_CLI_ANALYTICS = "false";
pango
]
++ lib.optionals stdenv.hostPlatform.isDarwin [
giflib
darwin.apple_sdk.frameworks.CoreText
];
CYPRESS_INSTALL_BINARY = "0"; buildPhase = ''
NG_CLI_ANALYTICS = "false"; runHook preBuild
npmBuildFlags = [ pushd node_modules/canvas
"--" node-gyp rebuild
"--configuration" popd
"production"
];
doCheck = true; pnpm run build --configuration production
checkPhase = ''
runHook preCheck
npm run test
runHook postCheck
'';
installPhase = '' runHook postBuild
runHook preInstall '';
mkdir -p $out/lib/paperless-ui
mv ../src/documents/static/frontend $out/lib/paperless-ui/ doCheck = true;
runHook postInstall checkPhase = ''
''; runHook preCheck
};
pnpm run test
runHook postCheck
'';
installPhase = ''
runHook preInstall
mkdir -p $out/lib/paperless-ui
mv ../src/documents/static/frontend $out/lib/paperless-ui/
runHook postInstall
'';
};
in in
python.pkgs.buildPythonApplication rec { python.pkgs.buildPythonApplication rec {
pname = "paperless-ngx"; pname = "paperless-ngx";
pyproject = false; pyproject = true;
inherit version src patches; inherit version src;
postPatch = '' postPatch = ''
# pytest-xdist with to many threads makes the tests flaky # pytest-xdist with to many threads makes the tests flaky
if (( $NIX_BUILD_CORES > 4)); then if (( $NIX_BUILD_CORES > 4)); then
NIX_BUILD_CORES=4 NIX_BUILD_CORES=4
fi fi
substituteInPlace src/setup.cfg \ substituteInPlace pyproject.toml \
--replace-fail "--numprocesses auto --maxprocesses=16" "--numprocesses $NIX_BUILD_CORES" --replace-fail '"--numprocesses=auto",' "" \
--replace-fail '--maxprocesses=16' "--numprocesses=$NIX_BUILD_CORES" \
--replace-fail "djangorestframework-guardian~=0.3.0" "djangorestframework-guardian2"
''; '';
nativeBuildInputs = [ nativeBuildInputs = [
@ -159,6 +159,13 @@ python.pkgs.buildPythonApplication rec {
xorg.lndir xorg.lndir
]; ];
pythonRelaxDeps = [
"django-allauth"
"drf-spectacular-sidecar"
# TODO: https://github.com/NixOS/nixpkgs/pull/373099
"zxing-cpp"
];
dependencies = dependencies =
with python.pkgs; with python.pkgs;
[ [
@ -180,11 +187,13 @@ python.pkgs.buildPythonApplication rec {
django-soft-delete django-soft-delete
djangorestframework djangorestframework
djangorestframework-guardian2 djangorestframework-guardian2
drf-spectacular
drf-spectacular-sidecar
drf-writable-nested drf-writable-nested
filelock filelock
flower flower
gotenberg-client gotenberg-client
gunicorn granian
httpx-oauth httpx-oauth
imap-tools imap-tools
inotifyrecursive inotifyrecursive
@ -208,16 +217,14 @@ python.pkgs.buildPythonApplication rec {
setproctitle setproctitle
tika-client tika-client
tqdm tqdm
uvicorn
watchdog watchdog
whitenoise whitenoise
whoosh whoosh-reloaded
zxing-cpp zxing-cpp
] ]
++ django-allauth.optional-dependencies.mfa ++ django-allauth.optional-dependencies.mfa
++ django-allauth.optional-dependencies.socialaccount ++ django-allauth.optional-dependencies.socialaccount
++ redis.optional-dependencies.hiredis ++ redis.optional-dependencies.hiredis;
++ uvicorn.optional-dependencies.standard;
postBuild = '' postBuild = ''
# Compile manually because `pythonRecompileBytecodeHook` only works # Compile manually because `pythonRecompileBytecodeHook` only works
@ -239,7 +246,7 @@ python.pkgs.buildPythonApplication rec {
runHook preInstall runHook preInstall
mkdir -p $out/lib/paperless-ngx/static/frontend mkdir -p $out/lib/paperless-ngx/static/frontend
cp -r {src,static,LICENSE,gunicorn.conf.py} $out/lib/paperless-ngx cp -r {src,static,LICENSE} $out/lib/paperless-ngx
lndir -silent ${frontend}/lib/paperless-ui/frontend $out/lib/paperless-ngx/static/frontend lndir -silent ${frontend}/lib/paperless-ui/frontend $out/lib/paperless-ngx/static/frontend
chmod +x $out/lib/paperless-ngx/src/manage.py chmod +x $out/lib/paperless-ngx/src/manage.py
makeWrapper $out/lib/paperless-ngx/src/manage.py $out/bin/paperless-ngx \ makeWrapper $out/lib/paperless-ngx/src/manage.py $out/bin/paperless-ngx \

View file

@ -22,6 +22,11 @@ python.pkgs.buildPythonPackage {
]; ];
postPatch = '' postPatch = ''
# high parallelism let the tests easily fail with concurrent errors
if (( $NIX_BUILD_CORES > 4)); then
NIX_BUILD_CORES=4
fi
substituteInPlace pytest.ini --subst-var NIX_BUILD_CORES substituteInPlace pytest.ini --subst-var NIX_BUILD_CORES
''; '';
@ -121,7 +126,7 @@ python.pkgs.buildPythonPackage {
mock mock
pytestCheckHook pytestCheckHook
pytest-asyncio pytest-asyncio
pytest-cov pytest-cov-stub
pytest-django pytest-django
pytest-factoryboy pytest-factoryboy
pytest-html pytest-html

View file

@ -1,21 +1,20 @@
{ {
lib, lib,
aioredis,
asgiref, asgiref,
buildPythonPackage, buildPythonPackage,
channels, channels,
cryptography, cryptography,
fetchFromGitHub, fetchFromGitHub,
hiredis,
msgpack, msgpack,
pythonOlder, pythonOlder,
redis, redis,
setuptools,
}: }:
buildPythonPackage rec { buildPythonPackage rec {
pname = "channels-redis"; pname = "channels-redis";
version = "4.1.0"; version = "4.2.1";
format = "setuptools"; pyproject = true;
disabled = pythonOlder "3.7"; disabled = pythonOlder "3.7";
@ -23,16 +22,13 @@ buildPythonPackage rec {
owner = "django"; owner = "django";
repo = "channels_redis"; repo = "channels_redis";
tag = version; tag = version;
hash = "sha256-Eid9aWlLNnqr3WAnsLe+Pz9gsugCsdDKi0+nFNF02CI="; hash = "sha256-jQkpuOQNU2KCWavXSE/n8gdpQhhAafQbZYfbX71Rcds=";
}; };
buildInputs = [ build-system = [ setuptools ];
hiredis
redis
];
propagatedBuildInputs = [ dependencies = [
aioredis redis
asgiref asgiref
channels channels
msgpack msgpack

View file

@ -3,21 +3,24 @@
buildPythonPackage, buildPythonPackage,
fetchFromGitHub, fetchFromGitHub,
django, django,
setuptools,
}: }:
buildPythonPackage rec { buildPythonPackage rec {
pname = "drf-spectacular-sidecar"; pname = "drf-spectacular-sidecar";
version = "2023.9.1"; version = "2025.4.1";
format = "setuptools"; pyproject = true;
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "tfranzel"; owner = "tfranzel";
repo = "drf-spectacular-sidecar"; repo = "drf-spectacular-sidecar";
rev = version; rev = version;
hash = "sha256-EoQKbxzXEuKC50/W1/tBB2wASJZmNNwg9r1qhIB4Ws8="; hash = "sha256-YzSUwShj7QGCVKlTRM2Gro38Y+jGYQsMGBMAH0radmA=";
}; };
propagatedBuildInputs = [ django ]; build-system = [ setuptools ];
dependencies = [ django ];
# no tests # no tests
doCheck = false; doCheck = false;

View file

@ -5,30 +5,25 @@
django, django,
fetchFromGitHub, fetchFromGitHub,
pytestCheckHook, pytestCheckHook,
pythonOlder,
requests, requests,
setuptools, setuptools,
}: }:
buildPythonPackage rec { buildPythonPackage rec {
pname = "whitenoise"; pname = "whitenoise";
version = "6.7.0"; version = "6.9.0";
pyproject = true; pyproject = true;
disabled = pythonOlder "3.8";
__darwinAllowLocalNetworking = true;
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "evansd"; owner = "evansd";
repo = pname; repo = "whitenoise";
tag = version; tag = version;
hash = "sha256-4SrTiTqBrfFuQ/8mqQL+YiehFWW+ZzKiAF0h2XyYuSs="; hash = "sha256-UmM8Az22ql3uUpyY6jj7ky3LelmttFBqGMYlzlNRAHg=";
}; };
nativeBuildInputs = [ setuptools ]; build-system = [ setuptools ];
propagatedBuildInputs = [ brotli ]; dependencies = [ brotli ];
nativeCheckInputs = [ nativeCheckInputs = [
django django
@ -36,6 +31,8 @@ buildPythonPackage rec {
requests requests
]; ];
__darwinAllowLocalNetworking = true;
disabledTestPaths = [ disabledTestPaths = [
# Don't run Django tests # Don't run Django tests
"tests/test_django_whitenoise.py" "tests/test_django_whitenoise.py"

View file

@ -0,0 +1,40 @@
{
lib,
buildPythonPackage,
cached-property,
fetchFromGitHub,
loguru,
pytestCheckHook,
setuptools,
}:
buildPythonPackage rec {
pname = "whoosh-reloaded";
version = "2.7.5";
pyproject = true;
src = fetchFromGitHub {
owner = "Sygil-Dev";
repo = "whoosh-reloaded";
tag = "v${version}";
hash = "sha256-frM8tw298Yz3u3rLK4CxWUXL6ymCSwYyYhXP/EdyjtQ=";
};
build-system = [ setuptools ];
dependencies = [
cached-property
loguru
];
nativeCheckInputs = [ pytestCheckHook ];
pythonImportsCheck = [ "whoosh" ];
meta = {
description = "Fast, featureful full-text indexing and searching library implemented in pure Python";
homepage = "https://github.com/Sygil-Dev/whoosh-reloaded";
license = lib.licenses.bsd2;
maintainers = with lib.maintainers; [ SuperSandro2000 ];
};
}

View file

@ -20,7 +20,7 @@ buildPythonPackage rec {
hash = "sha256-fKVjPb+p4OD6QA0xUaigxL7FO9Ls7cCmdwWxdWXDGoM="; hash = "sha256-fKVjPb+p4OD6QA0xUaigxL7FO9Ls7cCmdwWxdWXDGoM=";
}; };
nativeBuildInputs = [ setuptools ]; build-system = [ setuptools ];
nativeCheckInputs = [ pytestCheckHook ]; nativeCheckInputs = [ pytestCheckHook ];

View file

@ -18863,6 +18863,8 @@ self: super: with self; {
whoosh = callPackage ../development/python-modules/whoosh { }; whoosh = callPackage ../development/python-modules/whoosh { };
whoosh-reloaded = callPackage ../development/python-modules/whoosh-reloaded { };
widgetsnbextension = callPackage ../development/python-modules/widgetsnbextension { }; widgetsnbextension = callPackage ../development/python-modules/widgetsnbextension { };
widlparser = callPackage ../development/python-modules/widlparser { }; widlparser = callPackage ../development/python-modules/widlparser { };