mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-08-14 00:26:21 +00:00
Compare commits
1 Commits
feature-lo
...
feature-tr
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1f8c60a108 |
18
Dockerfile
18
Dockerfile
@@ -5,7 +5,7 @@
|
|||||||
# Purpose: Compiles the frontend
|
# Purpose: Compiles the frontend
|
||||||
# Notes:
|
# Notes:
|
||||||
# - Does PNPM stuff with Typescript and such
|
# - Does PNPM stuff with Typescript and such
|
||||||
FROM --platform=$BUILDPLATFORM docker.io/node:20-bookworm-slim AS compile-frontend
|
FROM --platform=$BUILDPLATFORM docker.io/node:20-trixie-slim AS compile-frontend
|
||||||
|
|
||||||
COPY ./src-ui /src/src-ui
|
COPY ./src-ui /src/src-ui
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ RUN set -eux \
|
|||||||
# Purpose: Installs s6-overlay and rootfs
|
# Purpose: Installs s6-overlay and rootfs
|
||||||
# Comments:
|
# Comments:
|
||||||
# - Don't leave anything extra in here either
|
# - Don't leave anything extra in here either
|
||||||
FROM ghcr.io/astral-sh/uv:0.8.8-python3.12-bookworm-slim AS s6-overlay-base
|
FROM ghcr.io/astral-sh/uv:0.8.8-python3.12-trixie-slim AS s6-overlay-base
|
||||||
|
|
||||||
WORKDIR /usr/src/s6
|
WORKDIR /usr/src/s6
|
||||||
|
|
||||||
@@ -170,20 +170,8 @@ RUN set -eux \
|
|||||||
&& apt-get update \
|
&& apt-get update \
|
||||||
&& apt-get install --yes --quiet --no-install-recommends ${RUNTIME_PACKAGES} \
|
&& apt-get install --yes --quiet --no-install-recommends ${RUNTIME_PACKAGES} \
|
||||||
&& echo "Installing pre-built updates" \
|
&& echo "Installing pre-built updates" \
|
||||||
&& curl --fail --silent --no-progress-meter --show-error --location --remote-name-all --parallel --parallel-max 4 \
|
&& curl --fail --silent --no-progress-meter --show-error --location --remote-name-all \
|
||||||
https://github.com/paperless-ngx/builder/releases/download/qpdf-${QPDF_VERSION}/libqpdf29_${QPDF_VERSION}-1_${TARGETARCH}.deb \
|
|
||||||
https://github.com/paperless-ngx/builder/releases/download/qpdf-${QPDF_VERSION}/qpdf_${QPDF_VERSION}-1_${TARGETARCH}.deb \
|
|
||||||
https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/libgs10_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \
|
|
||||||
https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/ghostscript_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \
|
|
||||||
https://github.com/paperless-ngx/builder/releases/download/ghostscript-${GS_VERSION}/libgs10-common_${GS_VERSION}.dfsg-1_all.deb \
|
|
||||||
https://github.com/paperless-ngx/builder/releases/download/jbig2enc-${JBIG2ENC_VERSION}/jbig2enc_${JBIG2ENC_VERSION}-1_${TARGETARCH}.deb \
|
https://github.com/paperless-ngx/builder/releases/download/jbig2enc-${JBIG2ENC_VERSION}/jbig2enc_${JBIG2ENC_VERSION}-1_${TARGETARCH}.deb \
|
||||||
&& echo "Installing qpdf ${QPDF_VERSION}" \
|
|
||||||
&& dpkg --install ./libqpdf29_${QPDF_VERSION}-1_${TARGETARCH}.deb \
|
|
||||||
&& dpkg --install ./qpdf_${QPDF_VERSION}-1_${TARGETARCH}.deb \
|
|
||||||
&& echo "Installing Ghostscript ${GS_VERSION}" \
|
|
||||||
&& dpkg --install ./libgs10-common_${GS_VERSION}.dfsg-1_all.deb \
|
|
||||||
&& dpkg --install ./libgs10_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \
|
|
||||||
&& dpkg --install ./ghostscript_${GS_VERSION}.dfsg-1_${TARGETARCH}.deb \
|
|
||||||
&& echo "Installing jbig2enc" \
|
&& echo "Installing jbig2enc" \
|
||||||
&& dpkg --install ./jbig2enc_${JBIG2ENC_VERSION}-1_${TARGETARCH}.deb \
|
&& dpkg --install ./jbig2enc_${JBIG2ENC_VERSION}-1_${TARGETARCH}.deb \
|
||||||
&& echo "Configuring imagemagick" \
|
&& echo "Configuring imagemagick" \
|
||||||
|
319
dev.txt
Normal file
319
dev.txt
Normal file
@@ -0,0 +1,319 @@
|
|||||||
|
adduser 3.134
|
||||||
|
apt 2.6.1
|
||||||
|
base-files 12.4+deb12u11
|
||||||
|
base-passwd 3.6.1
|
||||||
|
bash 5.2.15-2+b8
|
||||||
|
bsdutils 1:2.38.1-5+deb12u3
|
||||||
|
ca-certificates 20230311+deb12u1
|
||||||
|
coreutils 9.1-1
|
||||||
|
curl 7.88.1-10+deb12u12
|
||||||
|
dash 0.5.12-2
|
||||||
|
debconf 1.5.82
|
||||||
|
debian-archive-keyring 2023.3+deb12u2
|
||||||
|
debianutils 5.7-0.5~deb12u1
|
||||||
|
diffutils 1:3.8-4
|
||||||
|
dirmngr 2.2.40-1.1
|
||||||
|
dpkg 1.21.22
|
||||||
|
e2fsprogs 1.47.0-2
|
||||||
|
file 1:5.44-3
|
||||||
|
findutils 4.9.0-4
|
||||||
|
fontconfig 2.14.1-4
|
||||||
|
fontconfig-config 2.14.1-4
|
||||||
|
fonts-liberation 1:1.07.4-11
|
||||||
|
fonts-urw-base35 20200910-7
|
||||||
|
gcc-12-base 12.2.0-14+deb12u1
|
||||||
|
gettext 0.21-12
|
||||||
|
gettext-base 0.21-12
|
||||||
|
ghostscript 10.03.1~dfsg-1
|
||||||
|
gnupg 2.2.40-1.1
|
||||||
|
gnupg-l10n 2.2.40-1.1
|
||||||
|
gnupg-utils 2.2.40-1.1
|
||||||
|
gosu 1.14-1+b10
|
||||||
|
gpg 2.2.40-1.1
|
||||||
|
gpg-agent 2.2.40-1.1
|
||||||
|
gpg-wks-client 2.2.40-1.1
|
||||||
|
gpg-wks-server 2.2.40-1.1
|
||||||
|
gpgconf 2.2.40-1.1
|
||||||
|
gpgsm 2.2.40-1.1
|
||||||
|
gpgv 2.2.40-1.1
|
||||||
|
grep 3.8-5
|
||||||
|
gzip 1.12-1
|
||||||
|
hicolor-icon-theme 0.17-2
|
||||||
|
hostname 3.23+nmu1
|
||||||
|
icc-profiles-free 2.0.1+dfsg-1.1
|
||||||
|
imagemagick 8:6.9.11.60+dfsg-1.6+deb12u3
|
||||||
|
imagemagick-6-common 8:6.9.11.60+dfsg-1.6+deb12u3
|
||||||
|
imagemagick-6.q16 8:6.9.11.60+dfsg-1.6+deb12u3
|
||||||
|
init-system-helpers 1.65.2
|
||||||
|
jbig2dec 0.19-3
|
||||||
|
jbig2enc 0.30-1
|
||||||
|
libacl1 2.3.1-3
|
||||||
|
libaom3 3.6.0-1+deb12u1
|
||||||
|
libapt-pkg6.0 2.6.1
|
||||||
|
libarchive13 3.6.2-1+deb12u2
|
||||||
|
libassuan0 2.5.5-5
|
||||||
|
libattr1 1:2.5.1-4
|
||||||
|
libaudit-common 1:3.0.9-1
|
||||||
|
libaudit1 1:3.0.9-1
|
||||||
|
libavahi-client3 0.8-10+deb12u1
|
||||||
|
libavahi-common-data 0.8-10+deb12u1
|
||||||
|
libavahi-common3 0.8-10+deb12u1
|
||||||
|
libavcodec59 7:5.1.6-0+deb12u1
|
||||||
|
libavformat59 7:5.1.6-0+deb12u1
|
||||||
|
libavutil57 7:5.1.6-0+deb12u1
|
||||||
|
libblkid1 2.38.1-5+deb12u3
|
||||||
|
libbluray2 1:1.3.4-1
|
||||||
|
libbrotli1 1.0.9-2+b6
|
||||||
|
libbsd0 0.11.7-2
|
||||||
|
libbz2-1.0 1.0.8-5+b1
|
||||||
|
libc-bin 2.36-9+deb12u10
|
||||||
|
libc6 2.36-9+deb12u10
|
||||||
|
libcairo-gobject2 1.16.0-7
|
||||||
|
libcairo2 1.16.0-7
|
||||||
|
libcap-ng0 0.8.3-1+b3
|
||||||
|
libcap2 1:2.66-4+deb12u1
|
||||||
|
libchromaprint1 1.5.1-2+b1
|
||||||
|
libcjson1 1.7.15-1+deb12u2
|
||||||
|
libcodec2-1.0 1.0.5-1
|
||||||
|
libcom-err2 1.47.0-2
|
||||||
|
libconfig-inifiles-perl 3.000003-2
|
||||||
|
libcrypt1 1:4.4.33-2
|
||||||
|
libcups2 2.4.2-3+deb12u8
|
||||||
|
libcurl4 7.88.1-10+deb12u12
|
||||||
|
libdatrie1 0.2.13-2+b1
|
||||||
|
libdav1d6 1.0.0-2+deb12u1
|
||||||
|
libdb5.3 5.3.28+dfsg2-1
|
||||||
|
libdbus-1-3 1.14.10-1~deb12u1
|
||||||
|
libde265-0 1.0.11-1+deb12u2
|
||||||
|
libdebconfclient0 0.270
|
||||||
|
libdeflate0 1.14-1
|
||||||
|
libdrm-common 2.4.114-1
|
||||||
|
libdrm2 2.4.114-1+b1
|
||||||
|
libedit2 3.1-20221030-2
|
||||||
|
libexpat1 2.5.0-1+deb12u1
|
||||||
|
libext2fs2 1.47.0-2
|
||||||
|
libffi8 3.4.4-1
|
||||||
|
libfftw3-double3 3.3.10-1
|
||||||
|
libfontconfig1 2.14.1-4
|
||||||
|
libfontenc1 1:1.1.4-1
|
||||||
|
libfreetype6 2.12.1+dfsg-5+deb12u4
|
||||||
|
libfribidi0 1.0.8-2.1
|
||||||
|
libgcc-s1 12.2.0-14+deb12u1
|
||||||
|
libgcrypt20 1.10.1-3
|
||||||
|
libgdbm-compat4 1.23-3
|
||||||
|
libgdbm6 1.23-3
|
||||||
|
libgdk-pixbuf-2.0-0 2.42.10+dfsg-1+deb12u2
|
||||||
|
libgdk-pixbuf2.0-common 2.42.10+dfsg-1+deb12u2
|
||||||
|
libgif7 5.2.1-2.5
|
||||||
|
libglib2.0-0 2.74.6-2+deb12u6
|
||||||
|
libgme0 0.6.3-6
|
||||||
|
libgmp10 2:6.2.1+dfsg1-1.1
|
||||||
|
libgnutls30 3.7.9-2+deb12u5
|
||||||
|
libgomp1 12.2.0-14+deb12u1
|
||||||
|
libgpg-error0 1.46-1
|
||||||
|
libgraphite2-3 1.3.14-1
|
||||||
|
libgs-common 10.0.0~dfsg-11+deb12u7
|
||||||
|
libgs10 10.03.1~dfsg-1
|
||||||
|
libgs10-common 10.03.1~dfsg-1
|
||||||
|
libgsm1 1.0.22-1
|
||||||
|
libgssapi-krb5-2 1.20.1-2+deb12u3
|
||||||
|
libharfbuzz0b 6.0.0+dfsg-3
|
||||||
|
libheif1 1.15.1-1+deb12u1
|
||||||
|
libhogweed6 3.8.1-2
|
||||||
|
libhwy1 1.0.3-3+deb12u1
|
||||||
|
libice6 2:1.0.10-1
|
||||||
|
libicu72 72.1-3+deb12u1
|
||||||
|
libidn12 1.41-1
|
||||||
|
libidn2-0 2.3.3-1+b1
|
||||||
|
libijs-0.35 0.35-15
|
||||||
|
libimagequant0 2.17.0-1
|
||||||
|
libjbig0 2.1-6.1
|
||||||
|
libjbig2dec0 0.19-3
|
||||||
|
libjpeg62-turbo 1:2.1.5-2
|
||||||
|
libjxl0.7 0.7.0-10+deb12u1
|
||||||
|
libk5crypto3 1.20.1-2+deb12u3
|
||||||
|
libkeyutils1 1.6.3-2
|
||||||
|
libkrb5-3 1.20.1-2+deb12u3
|
||||||
|
libkrb5support0 1.20.1-2+deb12u3
|
||||||
|
libksba8 1.6.3-2
|
||||||
|
liblcms2-2 2.14-2
|
||||||
|
libldap-2.5-0 2.5.13+dfsg-5
|
||||||
|
liblept5 1.82.0-3+b3
|
||||||
|
liblerc4 4.0.0+ds-2
|
||||||
|
liblqr-1-0 0.4.2-2.1
|
||||||
|
libltdl7 2.4.7-7~deb12u1
|
||||||
|
liblz4-1 1.9.4-1
|
||||||
|
liblzma5 5.4.1-1
|
||||||
|
libmagic-mgc 1:5.44-3
|
||||||
|
libmagic1 1:5.44-3
|
||||||
|
libmagickcore-6.q16-6 8:6.9.11.60+dfsg-1.6+deb12u3
|
||||||
|
libmagickwand-6.q16-6 8:6.9.11.60+dfsg-1.6+deb12u3
|
||||||
|
libmariadb3 1:10.11.11-0+deb12u1
|
||||||
|
libmbedcrypto7 2.28.3-1
|
||||||
|
libmd0 1.0.4-2
|
||||||
|
libmfx1 22.5.4-1
|
||||||
|
libmount1 2.38.1-5+deb12u3
|
||||||
|
libmp3lame0 3.100-6
|
||||||
|
libmpg123-0 1.31.2-1+deb12u1
|
||||||
|
libncurses6 6.4-4
|
||||||
|
libncursesw6 6.4-4
|
||||||
|
libnettle8 3.8.1-2
|
||||||
|
libnghttp2-14 1.52.0-1+deb12u2
|
||||||
|
libnorm1 1.5.9+dfsg-2
|
||||||
|
libnpth0 1.6-3
|
||||||
|
libnsl2 1.3.0-2
|
||||||
|
libnspr4 2:4.35-1
|
||||||
|
libnss3 2:3.87.1-1+deb12u1
|
||||||
|
libnuma1 2.0.16-1
|
||||||
|
libogg0 1.3.5-3
|
||||||
|
libopenjp2-7 2.5.0-2+deb12u1
|
||||||
|
libopenmpt0 0.6.9-1
|
||||||
|
libopus0 1.3.1-3
|
||||||
|
libp11-kit0 0.24.1-2
|
||||||
|
libpam-modules 1.5.2-6+deb12u1
|
||||||
|
libpam-modules-bin 1.5.2-6+deb12u1
|
||||||
|
libpam-runtime 1.5.2-6+deb12u1
|
||||||
|
libpam0g 1.5.2-6+deb12u1
|
||||||
|
libpango-1.0-0 1.50.12+ds-1
|
||||||
|
libpangocairo-1.0-0 1.50.12+ds-1
|
||||||
|
libpangoft2-1.0-0 1.50.12+ds-1
|
||||||
|
libpaper1 1.1.29
|
||||||
|
libpcre2-8-0 10.42-1
|
||||||
|
libperl5.36 5.36.0-7+deb12u2
|
||||||
|
libpgm-5.3-0 5.3.128~dfsg-2
|
||||||
|
libpixman-1-0 0.42.2-1
|
||||||
|
libpng16-16 1.6.39-2
|
||||||
|
libpoppler126 22.12.0-2+deb12u1
|
||||||
|
libpq5 15.13-0+deb12u1
|
||||||
|
libpsl5 0.21.2-1
|
||||||
|
libqpdf29 11.9.0-1
|
||||||
|
librabbitmq4 0.11.0-1+deb12u1
|
||||||
|
librav1e0 0.5.1-6
|
||||||
|
libreadline8 8.2-1.3
|
||||||
|
librist4 0.2.7+dfsg-1
|
||||||
|
librsvg2-2 2.54.7+dfsg-1~deb12u1
|
||||||
|
librtmp1 2.4+20151223.gitfa8646d.1-2+b2
|
||||||
|
libsasl2-2 2.1.28+dfsg-10
|
||||||
|
libsasl2-modules-db 2.1.28+dfsg-10
|
||||||
|
libseccomp2 2.5.4-1+deb12u1
|
||||||
|
libselinux1 3.4-1+b6
|
||||||
|
libsemanage-common 3.4-1
|
||||||
|
libsemanage2 3.4-1+b5
|
||||||
|
libsepol2 3.4-2.1
|
||||||
|
libshine3 3.1.1-2
|
||||||
|
libsm6 2:1.2.3-1
|
||||||
|
libsmartcols1 2.38.1-5+deb12u3
|
||||||
|
libsnappy1v5 1.1.9-3
|
||||||
|
libsodium23 1.0.18-1
|
||||||
|
libsoxr0 0.1.3-4
|
||||||
|
libspeex1 1.2.1-2
|
||||||
|
libsqlite3-0 3.40.1-2+deb12u1
|
||||||
|
libsrt1.5-gnutls 1.5.1-1+deb12u1
|
||||||
|
libss2 1.47.0-2
|
||||||
|
libssh-gcrypt-4 0.10.6-0+deb12u1
|
||||||
|
libssh2-1 1.10.0-3+b1
|
||||||
|
libssl3 3.0.17-1~deb12u1
|
||||||
|
libstdc++6 12.2.0-14+deb12u1
|
||||||
|
libsvtav1enc1 1.4.1+dfsg-1
|
||||||
|
libswresample4 7:5.1.6-0+deb12u1
|
||||||
|
libsystemd0 252.38-1~deb12u1
|
||||||
|
libtasn1-6 4.19.0-2+deb12u1
|
||||||
|
libtesseract5 5.3.0-2
|
||||||
|
libthai-data 0.1.29-1
|
||||||
|
libthai0 0.1.29-1
|
||||||
|
libtheora0 1.1.1+dfsg.1-16.1+b1
|
||||||
|
libtiff6 4.5.0-6+deb12u2
|
||||||
|
libtinfo6 6.4-4
|
||||||
|
libtirpc-common 1.3.3+ds-1
|
||||||
|
libtirpc3 1.3.3+ds-1
|
||||||
|
libtwolame0 0.4.0-2
|
||||||
|
libudev1 252.38-1~deb12u1
|
||||||
|
libudfread0 1.1.2-1
|
||||||
|
libunistring2 1.0-2
|
||||||
|
libuuid1 2.38.1-5+deb12u3
|
||||||
|
libv4l-0 1.22.1-5+b2
|
||||||
|
libv4lconvert0 1.22.1-5+b2
|
||||||
|
libva-drm2 2.17.0-1
|
||||||
|
libva-x11-2 2.17.0-1
|
||||||
|
libva2 2.17.0-1
|
||||||
|
libvdpau1 1.5-2
|
||||||
|
libvorbis0a 1.3.7-1
|
||||||
|
libvorbisenc2 1.3.7-1
|
||||||
|
libvorbisfile3 1.3.7-1
|
||||||
|
libvpx7 1.12.0-1+deb12u4
|
||||||
|
libwebp7 1.2.4-0.2+deb12u1
|
||||||
|
libwebpdemux2 1.2.4-0.2+deb12u1
|
||||||
|
libwebpmux3 1.2.4-0.2+deb12u1
|
||||||
|
libx11-6 2:1.8.4-2+deb12u2
|
||||||
|
libx11-data 2:1.8.4-2+deb12u2
|
||||||
|
libx11-xcb1 2:1.8.4-2+deb12u2
|
||||||
|
libx264-164 2:0.164.3095+gitbaee400-3
|
||||||
|
libx265-199 3.5-2+b1
|
||||||
|
libxau6 1:1.0.9-1
|
||||||
|
libxcb-dri3-0 1.15-1
|
||||||
|
libxcb-render0 1.15-1
|
||||||
|
libxcb-shm0 1.15-1
|
||||||
|
libxcb1 1.15-1
|
||||||
|
libxdmcp6 1:1.1.2-3
|
||||||
|
libxext6 2:1.3.4-1+b1
|
||||||
|
libxfixes3 1:6.0.0-2
|
||||||
|
libxml2 2.9.14+dfsg-1.3~deb12u2
|
||||||
|
libxrender1 1:0.9.10-1.1
|
||||||
|
libxslt1.1 1.1.35-1+deb12u1
|
||||||
|
libxt6 1:1.2.1-1.1
|
||||||
|
libxvidcore4 2:1.3.7-1
|
||||||
|
libxxhash0 0.8.1-1
|
||||||
|
libzbar0 0.23.92-7+deb12u1
|
||||||
|
libzmq5 4.3.4-6
|
||||||
|
libzstd1 1.5.4+dfsg2-5
|
||||||
|
libzvbi-common 0.2.41-1
|
||||||
|
libzvbi0 0.2.41-1
|
||||||
|
login 1:4.13+dfsg1-1+deb12u1
|
||||||
|
logsave 1.47.0-2
|
||||||
|
mariadb-client 1:10.11.11-0+deb12u1
|
||||||
|
mariadb-client-core 1:10.11.11-0+deb12u1
|
||||||
|
mariadb-common 1:10.11.11-0+deb12u1
|
||||||
|
mawk 1.3.4.20200120-3.1
|
||||||
|
media-types 10.0.0
|
||||||
|
mount 2.38.1-5+deb12u3
|
||||||
|
mysql-common 5.8+1.1.0
|
||||||
|
ncurses-base 6.4-4
|
||||||
|
ncurses-bin 6.4-4
|
||||||
|
netbase 6.4
|
||||||
|
ocl-icd-libopencl1 2.3.1-1
|
||||||
|
openssl 3.0.17-1~deb12u1
|
||||||
|
passwd 1:4.13+dfsg1-1+deb12u1
|
||||||
|
perl 5.36.0-7+deb12u2
|
||||||
|
perl-base 5.36.0-7+deb12u2
|
||||||
|
perl-modules-5.36 5.36.0-7+deb12u2
|
||||||
|
pinentry-curses 1.2.1-1
|
||||||
|
pngquant 2.17.0-1
|
||||||
|
poppler-data 0.4.12-1
|
||||||
|
poppler-utils 22.12.0-2+deb12u1
|
||||||
|
postgresql-client 15+248
|
||||||
|
postgresql-client-15 15.13-0+deb12u1
|
||||||
|
postgresql-client-common 248
|
||||||
|
qpdf 11.9.0-1
|
||||||
|
readline-common 8.2-1.3
|
||||||
|
sed 4.9-1
|
||||||
|
sensible-utils 0.0.17+nmu1
|
||||||
|
shared-mime-info 2.2-1
|
||||||
|
sysvinit-utils 3.06-4
|
||||||
|
tar 1.34+dfsg-1.2+deb12u1
|
||||||
|
tesseract-ocr 5.3.0-2
|
||||||
|
tesseract-ocr-deu 1:4.1.0-2
|
||||||
|
tesseract-ocr-eng 1:4.1.0-2
|
||||||
|
tesseract-ocr-fra 1:4.1.0-2
|
||||||
|
tesseract-ocr-ita 1:4.1.0-2
|
||||||
|
tesseract-ocr-osd 1:4.1.0-2
|
||||||
|
tesseract-ocr-spa 1:4.1.0-2
|
||||||
|
tzdata 2025b-0+deb12u1
|
||||||
|
ucf 3.0043+nmu1+deb12u1
|
||||||
|
unpaper 7.0.0-0.1
|
||||||
|
usr-is-merged 37~deb12u1
|
||||||
|
util-linux 2.38.1-5+deb12u3
|
||||||
|
util-linux-extra 2.38.1-5+deb12u3
|
||||||
|
x11-common 1:7.7+23
|
||||||
|
xfonts-encodings 1:1.0.4-2.2
|
||||||
|
xfonts-utils 1:7.7+6
|
||||||
|
zlib1g 1:1.2.13.dfsg-1
|
@@ -434,136 +434,6 @@ provided. The template is provided as a string, potentially multiline, and rende
|
|||||||
In addition, the entire Document instance is available to be utilized in a more advanced way, as well as some variables which only make sense to be accessed
|
In addition, the entire Document instance is available to be utilized in a more advanced way, as well as some variables which only make sense to be accessed
|
||||||
with more complex logic.
|
with more complex logic.
|
||||||
|
|
||||||
#### Custom Jinja2 Filters
|
|
||||||
|
|
||||||
##### Custom Field Access
|
|
||||||
|
|
||||||
The `get_cf_value` filter retrieves a value from custom field data with optional default fallback.
|
|
||||||
|
|
||||||
###### Syntax
|
|
||||||
|
|
||||||
```jinja2
|
|
||||||
{{ custom_fields | get_cf_value('field_name') }}
|
|
||||||
{{ custom_fields | get_cf_value('field_name', 'default_value') }}
|
|
||||||
```
|
|
||||||
|
|
||||||
###### Parameters
|
|
||||||
|
|
||||||
- `custom_fields`: This _must_ be the provided custom field data
|
|
||||||
- `name` (str): Name of the custom field to retrieve
|
|
||||||
- `default` (str, optional): Default value to return if field is not found or has no value
|
|
||||||
|
|
||||||
###### Returns
|
|
||||||
|
|
||||||
- `str | None`: The field value, default value, or `None` if neither exists
|
|
||||||
|
|
||||||
###### Examples
|
|
||||||
|
|
||||||
```jinja2
|
|
||||||
<!-- Basic usage -->
|
|
||||||
{{ custom_fields | get_cf_value('department') }}
|
|
||||||
|
|
||||||
<!-- With default value -->
|
|
||||||
{{ custom_fields | get_cf_value('phone', 'Not provided') }}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Datetime Formatting
|
|
||||||
|
|
||||||
The `format_datetime`filter formats a datetime string or datetime object using Python's strftime formatting.
|
|
||||||
|
|
||||||
###### Syntax
|
|
||||||
|
|
||||||
```jinja2
|
|
||||||
{{ datetime_value | format_datetime('%Y-%m-%d %H:%M:%S') }}
|
|
||||||
```
|
|
||||||
|
|
||||||
###### Parameters
|
|
||||||
|
|
||||||
- `value` (str | datetime): Date/time value to format (strings will be parsed automatically)
|
|
||||||
- `format` (str): Python strftime format string
|
|
||||||
|
|
||||||
###### Returns
|
|
||||||
|
|
||||||
- `str`: Formatted datetime string
|
|
||||||
|
|
||||||
###### Examples
|
|
||||||
|
|
||||||
```jinja2
|
|
||||||
<!-- Format datetime object -->
|
|
||||||
{{ created_at | format_datetime('%B %d, %Y at %I:%M %p') }}
|
|
||||||
<!-- Output: "January 15, 2024 at 02:30 PM" -->
|
|
||||||
|
|
||||||
<!-- Format datetime string -->
|
|
||||||
{{ "2024-01-15T14:30:00" | format_datetime('%m/%d/%Y') }}
|
|
||||||
<!-- Output: "01/15/2024" -->
|
|
||||||
|
|
||||||
<!-- Custom formatting -->
|
|
||||||
{{ timestamp | format_datetime('%A, %B %d, %Y') }}
|
|
||||||
<!-- Output: "Monday, January 15, 2024" -->
|
|
||||||
```
|
|
||||||
|
|
||||||
See the [strftime format code documentation](https://docs.python.org/3.13/library/datetime.html#strftime-and-strptime-format-codes)
|
|
||||||
for the possible codes and their meanings.
|
|
||||||
|
|
||||||
##### Date Localization
|
|
||||||
|
|
||||||
The `localize_date` filter formats a date or datetime object into a localized string using Babel internationalization.
|
|
||||||
This takes into account the provided locale for translation.
|
|
||||||
|
|
||||||
###### Syntax
|
|
||||||
|
|
||||||
```jinja2
|
|
||||||
{{ date_value | localize_date('medium', 'en_US') }}
|
|
||||||
{{ datetime_value | localize_date('short', 'fr_FR') }}
|
|
||||||
```
|
|
||||||
|
|
||||||
###### Parameters
|
|
||||||
|
|
||||||
- `value` (date | datetime): Date or datetime object to format (datetime should be timezone-aware)
|
|
||||||
- `format` (str): Format type - either a Babel preset ('short', 'medium', 'long', 'full') or custom pattern
|
|
||||||
- `locale` (str): Locale code for localization (e.g., 'en_US', 'fr_FR', 'de_DE')
|
|
||||||
|
|
||||||
###### Returns
|
|
||||||
|
|
||||||
- `str`: Localized, formatted date string
|
|
||||||
|
|
||||||
###### Examples
|
|
||||||
|
|
||||||
```jinja2
|
|
||||||
<!-- Preset formats -->
|
|
||||||
{{ created_date | localize_date('short', 'en_US') }}
|
|
||||||
<!-- Output: "1/15/24" -->
|
|
||||||
|
|
||||||
{{ created_date | localize_date('medium', 'en_US') }}
|
|
||||||
<!-- Output: "Jan 15, 2024" -->
|
|
||||||
|
|
||||||
{{ created_date | localize_date('long', 'en_US') }}
|
|
||||||
<!-- Output: "January 15, 2024" -->
|
|
||||||
|
|
||||||
{{ created_date | localize_date('full', 'en_US') }}
|
|
||||||
<!-- Output: "Monday, January 15, 2024" -->
|
|
||||||
|
|
||||||
<!-- Different locales -->
|
|
||||||
{{ created_date | localize_date('medium', 'fr_FR') }}
|
|
||||||
<!-- Output: "15 janv. 2024" -->
|
|
||||||
|
|
||||||
{{ created_date | localize_date('medium', 'de_DE') }}
|
|
||||||
<!-- Output: "15.01.2024" -->
|
|
||||||
|
|
||||||
<!-- Custom patterns -->
|
|
||||||
{{ created_date | localize_date('dd/MM/yyyy', 'en_GB') }}
|
|
||||||
<!-- Output: "15/01/2024" -->
|
|
||||||
```
|
|
||||||
|
|
||||||
See the [supported format codes](https://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns) for more options.
|
|
||||||
|
|
||||||
### Format Presets
|
|
||||||
|
|
||||||
- **short**: Abbreviated format (e.g., "1/15/24")
|
|
||||||
- **medium**: Medium-length format (e.g., "Jan 15, 2024")
|
|
||||||
- **long**: Long format with full month name (e.g., "January 15, 2024")
|
|
||||||
- **full**: Full format including day of week (e.g., "Monday, January 15, 2024")
|
|
||||||
|
|
||||||
#### Additional Variables
|
#### Additional Variables
|
||||||
|
|
||||||
- `{{ tag_name_list }}`: A list of tag names applied to the document, ordered by the tag name. Note this is a list, not a single string
|
- `{{ tag_name_list }}`: A list of tag names applied to the document, ordered by the tag name. Note this is a list, not a single string
|
||||||
|
@@ -15,7 +15,6 @@ classifiers = [
|
|||||||
# This will allow testing to not install a webserver, mysql, etc
|
# This will allow testing to not install a webserver, mysql, etc
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"babel>=2.17",
|
|
||||||
"bleach~=6.2.0",
|
"bleach~=6.2.0",
|
||||||
"celery[redis]~=5.5.1",
|
"celery[redis]~=5.5.1",
|
||||||
"channels~=4.2",
|
"channels~=4.2",
|
||||||
@@ -224,7 +223,7 @@ lint.isort.force-single-line = true
|
|||||||
|
|
||||||
[tool.codespell]
|
[tool.codespell]
|
||||||
write-changes = true
|
write-changes = true
|
||||||
ignore-words-list = "criterias,afterall,valeu,ureue,equest,ure,assertIn,Oktober"
|
ignore-words-list = "criterias,afterall,valeu,ureue,equest,ure,assertIn"
|
||||||
skip = "src-ui/src/locale/*,src-ui/pnpm-lock.yaml,src-ui/e2e/*,src/paperless_mail/tests/samples/*,src/documents/tests/samples/*,*.po,*.json"
|
skip = "src-ui/src/locale/*,src-ui/pnpm-lock.yaml,src-ui/e2e/*,src/paperless_mail/tests/samples/*,src/documents/tests/samples/*,*.po,*.json"
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
|
@@ -2,13 +2,10 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
from datetime import date
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import PurePath
|
from pathlib import PurePath
|
||||||
|
|
||||||
import pathvalidate
|
import pathvalidate
|
||||||
from babel import Locale
|
|
||||||
from babel import dates
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.dateparse import parse_date
|
from django.utils.dateparse import parse_date
|
||||||
from django.utils.text import slugify as django_slugify
|
from django.utils.text import slugify as django_slugify
|
||||||
@@ -93,51 +90,19 @@ def get_cf_value(
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
_template_environment.filters["get_cf_value"] = get_cf_value
|
||||||
|
|
||||||
|
|
||||||
def format_datetime(value: str | datetime, format: str) -> str:
|
def format_datetime(value: str | datetime, format: str) -> str:
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
value = parse_date(value)
|
value = parse_date(value)
|
||||||
return value.strftime(format=format)
|
return value.strftime(format=format)
|
||||||
|
|
||||||
|
|
||||||
def localize_date(value: date | datetime, format: str, locale: str) -> str:
|
|
||||||
"""
|
|
||||||
Format a date or datetime object into a localized string using Babel.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value (date | datetime): The date or datetime to format. If a datetime
|
|
||||||
is provided, it should be timezone-aware (e.g., UTC from a Django DB object).
|
|
||||||
format (str): The format to use. Can be one of Babel's preset formats
|
|
||||||
('short', 'medium', 'long', 'full') or a custom pattern string.
|
|
||||||
locale (str): The locale code (e.g., 'en_US', 'fr_FR') to use for
|
|
||||||
localization.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The localized, formatted date string.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
TypeError: If `value` is not a date or datetime instance.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
Locale.parse(locale)
|
|
||||||
except Exception as e:
|
|
||||||
raise ValueError(f"Invalid locale identifier: {locale}") from e
|
|
||||||
|
|
||||||
if isinstance(value, datetime):
|
|
||||||
return dates.format_datetime(value, format=format, locale=locale)
|
|
||||||
elif isinstance(value, date):
|
|
||||||
return dates.format_date(value, format=format, locale=locale)
|
|
||||||
else:
|
|
||||||
raise TypeError(f"Unsupported type {type(value)} for localize_date")
|
|
||||||
|
|
||||||
|
|
||||||
_template_environment.filters["get_cf_value"] = get_cf_value
|
|
||||||
|
|
||||||
_template_environment.filters["datetime"] = format_datetime
|
_template_environment.filters["datetime"] = format_datetime
|
||||||
|
|
||||||
_template_environment.filters["slugify"] = django_slugify
|
_template_environment.filters["slugify"] = django_slugify
|
||||||
|
|
||||||
_template_environment.filters["localize_date"] = localize_date
|
|
||||||
|
|
||||||
|
|
||||||
def create_dummy_document():
|
def create_dummy_document():
|
||||||
"""
|
"""
|
||||||
|
@@ -4,7 +4,6 @@ import tempfile
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import pytest
|
|
||||||
from auditlog.context import disable_auditlog
|
from auditlog.context import disable_auditlog
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
@@ -23,8 +22,6 @@ from documents.models import Document
|
|||||||
from documents.models import DocumentType
|
from documents.models import DocumentType
|
||||||
from documents.models import StoragePath
|
from documents.models import StoragePath
|
||||||
from documents.tasks import empty_trash
|
from documents.tasks import empty_trash
|
||||||
from documents.templating.filepath import localize_date
|
|
||||||
from documents.tests.factories import DocumentFactory
|
|
||||||
from documents.tests.utils import DirectoriesMixin
|
from documents.tests.utils import DirectoriesMixin
|
||||||
from documents.tests.utils import FileSystemAssertsMixin
|
from documents.tests.utils import FileSystemAssertsMixin
|
||||||
|
|
||||||
@@ -1589,196 +1586,3 @@ class TestFilenameGeneration(DirectoriesMixin, TestCase):
|
|||||||
generate_filename(doc),
|
generate_filename(doc),
|
||||||
Path("brussels-belgium/some-title-with-special-characters.pdf"),
|
Path("brussels-belgium/some-title-with-special-characters.pdf"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestDateLocalization:
|
|
||||||
"""
|
|
||||||
Groups all tests related to the `localize_date` function.
|
|
||||||
"""
|
|
||||||
|
|
||||||
TEST_DATE = datetime.date(2023, 10, 26)
|
|
||||||
|
|
||||||
TEST_DATETIME = datetime.datetime(
|
|
||||||
2023,
|
|
||||||
10,
|
|
||||||
26,
|
|
||||||
14,
|
|
||||||
30,
|
|
||||||
5,
|
|
||||||
tzinfo=datetime.timezone.utc,
|
|
||||||
)
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"value, format_style, locale_str, expected_output",
|
|
||||||
[
|
|
||||||
pytest.param(
|
|
||||||
TEST_DATE,
|
|
||||||
"EEEE, MMM d, yyyy",
|
|
||||||
"en_US",
|
|
||||||
"Thursday, Oct 26, 2023",
|
|
||||||
id="date-en_US-custom",
|
|
||||||
),
|
|
||||||
pytest.param(
|
|
||||||
TEST_DATE,
|
|
||||||
"dd.MM.yyyy",
|
|
||||||
"de_DE",
|
|
||||||
"26.10.2023",
|
|
||||||
id="date-de_DE-custom",
|
|
||||||
),
|
|
||||||
# German weekday and month name translation
|
|
||||||
pytest.param(
|
|
||||||
TEST_DATE,
|
|
||||||
"EEEE",
|
|
||||||
"de_DE",
|
|
||||||
"Donnerstag",
|
|
||||||
id="weekday-de_DE",
|
|
||||||
),
|
|
||||||
pytest.param(
|
|
||||||
TEST_DATE,
|
|
||||||
"MMMM",
|
|
||||||
"de_DE",
|
|
||||||
"Oktober",
|
|
||||||
id="month-de_DE",
|
|
||||||
),
|
|
||||||
# French weekday and month name translation
|
|
||||||
pytest.param(
|
|
||||||
TEST_DATE,
|
|
||||||
"EEEE",
|
|
||||||
"fr_FR",
|
|
||||||
"jeudi",
|
|
||||||
id="weekday-fr_FR",
|
|
||||||
),
|
|
||||||
pytest.param(
|
|
||||||
TEST_DATE,
|
|
||||||
"MMMM",
|
|
||||||
"fr_FR",
|
|
||||||
"octobre",
|
|
||||||
id="month-fr_FR",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_localize_date_with_date_objects(
|
|
||||||
self,
|
|
||||||
value: datetime.date,
|
|
||||||
format_style: str,
|
|
||||||
locale_str: str,
|
|
||||||
expected_output: str,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Tests `localize_date` with `date` objects across different locales and formats.
|
|
||||||
"""
|
|
||||||
assert localize_date(value, format_style, locale_str) == expected_output
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"value, format_style, locale_str, expected_output",
|
|
||||||
[
|
|
||||||
pytest.param(
|
|
||||||
TEST_DATETIME,
|
|
||||||
"yyyy.MM.dd G 'at' HH:mm:ss zzz",
|
|
||||||
"en_US",
|
|
||||||
"2023.10.26 AD at 14:30:05 UTC",
|
|
||||||
id="datetime-en_US-custom",
|
|
||||||
),
|
|
||||||
pytest.param(
|
|
||||||
TEST_DATETIME,
|
|
||||||
"dd.MM.yyyy",
|
|
||||||
"fr_FR",
|
|
||||||
"26.10.2023",
|
|
||||||
id="date-fr_FR-custom",
|
|
||||||
),
|
|
||||||
# Spanish weekday and month translation
|
|
||||||
pytest.param(
|
|
||||||
TEST_DATETIME,
|
|
||||||
"EEEE",
|
|
||||||
"es_ES",
|
|
||||||
"jueves",
|
|
||||||
id="weekday-es_ES",
|
|
||||||
),
|
|
||||||
pytest.param(
|
|
||||||
TEST_DATETIME,
|
|
||||||
"MMMM",
|
|
||||||
"es_ES",
|
|
||||||
"octubre",
|
|
||||||
id="month-es_ES",
|
|
||||||
),
|
|
||||||
# Italian weekday and month translation
|
|
||||||
pytest.param(
|
|
||||||
TEST_DATETIME,
|
|
||||||
"EEEE",
|
|
||||||
"it_IT",
|
|
||||||
"giovedì",
|
|
||||||
id="weekday-it_IT",
|
|
||||||
),
|
|
||||||
pytest.param(
|
|
||||||
TEST_DATETIME,
|
|
||||||
"MMMM",
|
|
||||||
"it_IT",
|
|
||||||
"ottobre",
|
|
||||||
id="month-it_IT",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_localize_date_with_datetime_objects(
|
|
||||||
self,
|
|
||||||
value: datetime.datetime,
|
|
||||||
format_style: str,
|
|
||||||
locale_str: str,
|
|
||||||
expected_output: str,
|
|
||||||
):
|
|
||||||
# To handle the non-breaking space in French and other locales
|
|
||||||
result = localize_date(value, format_style, locale_str)
|
|
||||||
assert result.replace("\u202f", " ") == expected_output.replace("\u202f", " ")
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"invalid_value",
|
|
||||||
[
|
|
||||||
"2023-10-26",
|
|
||||||
1698330605,
|
|
||||||
None,
|
|
||||||
[],
|
|
||||||
{},
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_localize_date_raises_type_error_for_invalid_input(self, invalid_value):
|
|
||||||
with pytest.raises(TypeError) as excinfo:
|
|
||||||
localize_date(invalid_value, "medium", "en_US")
|
|
||||||
|
|
||||||
assert f"Unsupported type {type(invalid_value)}" in str(excinfo.value)
|
|
||||||
|
|
||||||
def test_localize_date_raises_error_for_invalid_locale(self):
|
|
||||||
with pytest.raises(ValueError) as excinfo:
|
|
||||||
localize_date(self.TEST_DATE, "medium", "invalid_locale_code")
|
|
||||||
|
|
||||||
assert "Invalid locale identifier" in str(excinfo.value)
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"filename_format,expected_filename",
|
|
||||||
[
|
|
||||||
pytest.param(
|
|
||||||
"{{title}}_{{ document.created | localize_date('MMMM', 'es_ES')}}",
|
|
||||||
"My Document_octubre.pdf",
|
|
||||||
id="spanish_month_name",
|
|
||||||
),
|
|
||||||
pytest.param(
|
|
||||||
"{{title}}_{{ document.created | localize_date('EEEE', 'fr_FR')}}",
|
|
||||||
"My Document_jeudi.pdf",
|
|
||||||
id="french_day_of_week",
|
|
||||||
),
|
|
||||||
pytest.param(
|
|
||||||
"{{title}}_{{ document.created | localize_date('dd/MM/yyyy', 'en_GB')}}",
|
|
||||||
"My Document_26/10/2023.pdf",
|
|
||||||
id="uk_date_format",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_localize_date_path_building(self, filename_format, expected_filename):
|
|
||||||
document = DocumentFactory.create(
|
|
||||||
title="My Document",
|
|
||||||
mime_type="application/pdf",
|
|
||||||
storage_type=Document.STORAGE_TYPE_UNENCRYPTED,
|
|
||||||
created=self.TEST_DATE, # 2023-10-26 (which is a Thursday)
|
|
||||||
)
|
|
||||||
with override_settings(FILENAME_FORMAT=filename_format):
|
|
||||||
filename = generate_filename(document)
|
|
||||||
assert filename == Path(expected_filename)
|
|
||||||
|
4
uv.lock
generated
4
uv.lock
generated
@@ -1,5 +1,5 @@
|
|||||||
version = 1
|
version = 1
|
||||||
revision = 2
|
revision = 3
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
resolution-markers = [
|
resolution-markers = [
|
||||||
"sys_platform == 'darwin'",
|
"sys_platform == 'darwin'",
|
||||||
@@ -1911,7 +1911,6 @@ name = "paperless-ngx"
|
|||||||
version = "2.17.1"
|
version = "2.17.1"
|
||||||
source = { virtual = "." }
|
source = { virtual = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "babel", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
|
||||||
{ name = "bleach", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
{ name = "bleach", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
||||||
{ name = "celery", extra = ["redis"], marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
{ name = "celery", extra = ["redis"], marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
||||||
{ name = "channels", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
{ name = "channels", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
||||||
@@ -2045,7 +2044,6 @@ typing = [
|
|||||||
|
|
||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [
|
requires-dist = [
|
||||||
{ name = "babel", specifier = ">=2.17.0" },
|
|
||||||
{ name = "bleach", specifier = "~=6.2.0" },
|
{ name = "bleach", specifier = "~=6.2.0" },
|
||||||
{ name = "celery", extras = ["redis"], specifier = "~=5.5.1" },
|
{ name = "celery", extras = ["redis"], specifier = "~=5.5.1" },
|
||||||
{ name = "channels", specifier = "~=4.2" },
|
{ name = "channels", specifier = "~=4.2" },
|
||||||
|
Reference in New Issue
Block a user