lol
1{
2 lib,
3 buildNpmPackage,
4 fetchFromGitHub,
5 fetchPypi,
6 nodejs,
7 python3,
8 gettext,
9 nixosTests,
10 pretix,
11 plugins ? [ ],
12}:
13
14let
15 python = python3.override {
16 self = python;
17 packageOverrides = self: super: {
18 django = super.django_4;
19
20 django-oauth-toolkit = super.django-oauth-toolkit.overridePythonAttrs (oldAttrs: {
21 version = "2.3.0";
22 src = fetchFromGitHub {
23 inherit (oldAttrs.src) owner repo;
24 rev = "refs/tags/v${version}";
25 hash = "sha256-oGg5MD9p4PSUVkt5pGLwjAF4SHHf4Aqr+/3FsuFaybY=";
26 };
27 });
28
29 stripe = super.stripe.overridePythonAttrs rec {
30 version = "7.9.0";
31
32 src = fetchPypi {
33 pname = "stripe";
34 inherit version;
35 hash = "sha256-hOXkMINaSwzU/SpXzjhTJp0ds0OREc2mtu11LjSc9KE=";
36 };
37 };
38
39 pretix = self.toPythonModule pretix;
40 pretix-plugin-build = self.callPackage ./plugin-build.nix { };
41 };
42 };
43
44 pname = "pretix";
45 version = "2025.8.0";
46
47 src = fetchFromGitHub {
48 owner = "pretix";
49 repo = "pretix";
50 rev = "refs/tags/v${version}";
51 hash = "sha256-89BAQZpXyyTg6T9hxm4EV8QHZDcD3FcnGKxAulxziyg=";
52 };
53
54 npmDeps = buildNpmPackage {
55 pname = "pretix-node-modules";
56 inherit version src;
57
58 sourceRoot = "${src.name}/src/pretix/static/npm_dir";
59 npmDepsHash = "sha256-E2K9SYqRbhpQi83va8D02cwPnf51haoKv4P/ppU2m08=";
60
61 dontBuild = true;
62
63 installPhase = ''
64 runHook preInstall
65
66 mkdir $out
67 cp -R node_modules $out/
68
69 runHook postInstall
70 '';
71 };
72in
73python.pkgs.buildPythonApplication rec {
74 inherit pname version src;
75 pyproject = true;
76
77 patches = [
78 # Discover pretix.plugin entrypoints during build and add them into
79 # INSTALLED_APPS, so that their static files are collected.
80 ./plugin-build.patch
81 ];
82
83 pythonRelaxDeps = [
84 "beautifulsoup4"
85 "celery"
86 "css-inline"
87 "django-bootstrap3"
88 "django-formset-js-improved"
89 "django-i18nfield"
90 "django-localflavor"
91 "django-phonenumber-field"
92 "dnspython"
93 "drf_ujson2"
94 "importlib-metadata"
95 "kombu"
96 "markdown"
97 "oauthlib"
98 "phonenumberslite"
99 "pillow"
100 "protobuf"
101 "pycparser"
102 "pycryptodome"
103 "pyjwt"
104 "pypdf"
105 "python-bidi"
106 "qrcode"
107 "redis"
108 "reportlab"
109 "requests"
110 "sentry-sdk"
111 "sepaxml"
112 "ua-parser"
113 "webauthn"
114 ];
115
116 pythonRemoveDeps = [
117 "vat_moss_forked" # we provide a patched vat-moss package
118 ];
119
120 postPatch = ''
121 NODE_PREFIX=src/pretix/static.dist/node_prefix
122 mkdir -p $NODE_PREFIX
123 cp -R ${npmDeps}/node_modules $NODE_PREFIX/
124 chmod -R u+w $NODE_PREFIX/
125
126 # unused
127 sed -i "/setuptools-rust/d" pyproject.toml
128
129 substituteInPlace pyproject.toml \
130 --replace-fail '"backend"' '"setuptools.build_meta"' \
131 --replace-fail 'backend-path = ["_build"]' ""
132
133 # npm ci would remove and try to reinstall node_modules
134 substituteInPlace src/pretix/_build.py \
135 --replace-fail "npm ci" "npm install"
136 '';
137
138 build-system = with python.pkgs; [
139 gettext
140 nodejs
141 setuptools
142 tomli
143 ];
144
145 dependencies =
146 with python.pkgs;
147 [
148 arabic-reshaper
149 babel
150 beautifulsoup4
151 bleach
152 celery
153 chardet
154 cryptography
155 css-inline
156 defusedcsv
157 django
158 django-bootstrap3
159 django-compressor
160 django-countries
161 django-filter
162 django-formset-js-improved
163 django-formtools
164 django-hierarkey
165 django-hijack
166 django-i18nfield
167 django-libsass
168 django-localflavor
169 django-markup
170 django-oauth-toolkit
171 django-otp
172 django-phonenumber-field
173 django-redis
174 django-scopes
175 django-statici18n
176 djangorestframework
177 dnspython
178 drf-ujson2
179 geoip2
180 importlib-metadata
181 isoweek
182 jsonschema
183 kombu
184 libsass
185 lxml
186 markdown
187 mt-940
188 oauthlib
189 openpyxl
190 packaging
191 paypalrestsdk
192 paypal-checkout-serversdk
193 pyjwt
194 phonenumberslite
195 pillow
196 pretix-plugin-build
197 protobuf
198 psycopg2-binary
199 pycountry
200 pycparser
201 pycryptodome
202 pypdf
203 python-bidi
204 python-dateutil
205 pytz
206 pytz-deprecation-shim
207 pyuca
208 qrcode
209 redis
210 reportlab
211 requests
212 sentry-sdk
213 sepaxml
214 stripe
215 text-unidecode
216 tlds
217 tqdm
218 ua-parser
219 vat-moss
220 vobject
221 webauthn
222 zeep
223 ]
224 ++ django.optional-dependencies.argon2
225 ++ plugins;
226
227 optional-dependencies = with python.pkgs; {
228 memcached = [
229 pylibmc
230 ];
231 };
232
233 postInstall = ''
234 mkdir -p $out/bin
235 cp ./src/manage.py $out/${python.sitePackages}/pretix/manage.py
236 makeWrapper $out/${python.sitePackages}/pretix/manage.py $out/bin/pretix-manage \
237 --prefix PYTHONPATH : "$PYTHONPATH"
238
239 # Trim packages size
240 rm -rfv $out/${python.sitePackages}/pretix/static.dist/node_prefix
241 '';
242
243 dontStrip = true; # no binaries
244
245 nativeCheckInputs =
246 with python.pkgs;
247 [
248 pytestCheckHook
249 pytest-xdist
250 pytest-mock
251 pytest-django
252 pytest-asyncio
253 pytest-rerunfailures
254 freezegun
255 fakeredis
256 responses
257 ]
258 ++ lib.flatten (lib.attrValues optional-dependencies);
259
260 pytestFlags = [
261 "--reruns=3"
262 ];
263
264 disabledTests = [
265 # unreliable around day changes
266 "test_order_create_invoice"
267
268 # outdated translation files
269 # https://github.com/pretix/pretix/commit/c4db2a48b6ac81763fa67475d8182aee41c31376
270 "test_different_dates_spanish"
271 "test_same_day_spanish"
272 "test_same_month_spanish"
273 "test_same_year_spanish"
274
275 # broken with fakeredis>=2.27.0
276 "test_waitinglist_cache_separation"
277 "test_waitinglist_item_active"
278 "test_waitinglist_variation_active"
279 ];
280
281 preCheck = ''
282 export PYTHONPATH=$(pwd)/src:$PYTHONPATH
283 export DJANGO_SETTINGS_MODULE=tests.settings
284 '';
285
286 passthru = {
287 inherit
288 npmDeps
289 python
290 ;
291 plugins = lib.recurseIntoAttrs (
292 lib.packagesFromDirectoryRecursive {
293 inherit (python.pkgs) callPackage;
294 directory = ./plugins;
295 }
296 );
297 tests = {
298 inherit (nixosTests) pretix;
299 };
300 };
301
302 meta = with lib; {
303 description = "Ticketing software that cares about your event—all the way";
304 homepage = "https://github.com/pretix/pretix";
305 license = with licenses; [
306 agpl3Only
307 # 3rd party components below src/pretix/static
308 bsd2
309 isc
310 mit
311 ofl # fontawesome
312 unlicense
313 # all other files below src/pretix/static and src/pretix/locale and aux scripts
314 asl20
315 ];
316 maintainers = with maintainers; [ hexa ];
317 mainProgram = "pretix-manage";
318 platforms = platforms.linux;
319 };
320}