1{
2 stdenv,
3 lib,
4 python3Packages,
5 fetchFromGitHub,
6 makeWrapper,
7 gdal,
8 geos,
9 pnpm,
10 nodejs,
11 postgresql,
12 postgresqlTestHook,
13 playwright-driver,
14}:
15let
16
17 python = python3Packages.python.override {
18 packageOverrides = self: super: {
19 django_5 = super.django_5.override { withGdal = true; };
20 django = super.django_5;
21 # custom python module part of froide
22 dogtail = super.buildPythonPackage {
23 pname = "dogtail";
24 version = "0-unstable-2024-11-27";
25 pyproject = true;
26
27 src = fetchFromGitHub {
28 owner = "okfde";
29 repo = "dogtail";
30 rev = "d2f341cab0f05ef4e193f0158fe5a64aadc5bae6";
31 hash = "sha256-2lQZgvFXAz6q/3NpBcwckUologWxKmwXI0ZG5nylajg=";
32 };
33
34 build-system = with super; [ setuptools ];
35 };
36 };
37 };
38
39in
40python.pkgs.buildPythonApplication rec {
41 pname = "froide";
42 version = "0-unstable-2025-07-01";
43 pyproject = true;
44
45 src = fetchFromGitHub {
46 owner = "okfde";
47 repo = "froide";
48 rev = "362bddb5a8fdfe762d59cdebd29016568c9531b2";
49 hash = "sha256-c8I/FvXQSkAeacxMQJCpCMKFueNEnLI4R0ElqRbVbNg=";
50 };
51
52 patches = [ ./django_42_storages.patch ];
53
54 # Relax dependency pinning
55 # Channels: https://github.com/okfde/froide/issues/995
56 pythonRelaxDeps = [
57 "channels"
58 ];
59
60 build-system = [ python.pkgs.setuptools ];
61
62 nativeBuildInputs = [
63 makeWrapper
64 nodejs
65 pnpm.configHook
66 ];
67
68 dependencies = with python.pkgs; [
69 celery
70 celery-singleton
71 channels
72 dj-database-url
73 django
74 django-celery-beat
75 django-celery-email
76 django-configurations
77 django-contrib-comments
78 django-crossdomainmedia
79 django-elasticsearch-dsl
80 django-filingcabinet
81 django-filter
82 django-json-widget
83 django-leaflet
84 django-mfa3
85 django-oauth-toolkit
86 django-parler
87 django-storages
88 django-taggit
89 django-treebeard
90 djangorestframework
91 djangorestframework-csv
92 djangorestframework-jsonp
93 dogtail
94 drf-spectacular
95 drf-spectacular-sidecar
96 easy-thumbnails
97 elasticsearch
98 elasticsearch-dsl
99 geoip2
100 icalendar
101 markdown
102 nh3
103 phonenumbers
104 pillow
105 pikepdf
106 psycopg
107 pygtail
108 pyisemail
109 pypdf
110 python-magic
111 python-mimeparse
112 python-slugify
113 requests
114 wand
115 weasyprint
116 websockets
117 ];
118
119 pnpmDeps = pnpm.fetchDeps {
120 inherit pname version src;
121 fetcherVersion = 1;
122 hash = "sha256-g7YX2fVXGmb3Qq9NNCb294bk4/0khcIZVSskYbE8Mdw=";
123 };
124
125 postBuild = ''
126 pnpm run build
127 '';
128
129 postInstall = ''
130 cp -r build manage.py $out/${python.sitePackages}/froide/
131 makeWrapper $out/${python.sitePackages}/froide/manage.py $out/bin/froide \
132 --prefix PYTHONPATH : "${python3Packages.makePythonPath dependencies}" \
133 --set GDAL_LIBRARY_PATH "${gdal}/lib/libgdal.so" \
134 --set GEOS_LIBRARY_PATH "${geos}/lib/libgeos_c.so"
135 '';
136
137 nativeCheckInputs = with python.pkgs; [
138 (postgresql.withPackages (p: [ p.postgis ]))
139 postgresqlTestHook
140 pytest-django
141 pytest-playwright
142 pytestCheckHook
143 ];
144
145 checkInputs = with python.pkgs; [
146 beautifulsoup4
147 pytest-asyncio
148 pytest-factoryboy
149 time-machine
150 ];
151
152 disabledTests = [
153 # Requires network connection: elastic_transport.ConnectionError
154 "test_search_similar"
155 "test_search"
156 "test_list_requests"
157 "test_list_jurisdiction_requests"
158 "test_tagged_requests"
159 "test_publicbody_requests"
160 "test_feed"
161 "test_request_list_filter_pagination"
162 "test_request_list_path_filter"
163 "test_web_page"
164 "test_autocomplete"
165 "test_list_no_identical"
166 "test_set_status"
167 "test_make_not_logged_in_request"
168 "test_make_logged_in_request"
169 # TypeError: Pygtail.with_offsets() got an unexpected keyword argument
170 "test_email_signal"
171 "test_pygtail_log_append"
172 "test_bouncing_email"
173 "test_multiple_partial"
174 "test_logfile_rotation"
175 # Test hangs
176 "test_collapsed_menu"
177 "test_make_request_logged_out_with_existing_account"
178 ];
179
180 preCheck = ''
181 export PGUSER="froide"
182 export postgresqlEnableTCP=1
183 export postgresqlTestUserOptions="LOGIN SUPERUSER"
184 export GDAL_LIBRARY_PATH="${gdal}/lib/libgdal.so"
185 export GEOS_LIBRARY_PATH="${geos}/lib/libgeos_c.so"
186 ''
187 + lib.optionalString (!stdenv.hostPlatform.isRiscV) ''
188 export PLAYWRIGHT_BROWSERS_PATH="${playwright-driver.browsers}"
189 '';
190
191 # Playwright tests not supported on RiscV yet
192 doCheck = lib.meta.availableOn stdenv.hostPlatform playwright-driver.browsers;
193
194 meta = {
195 description = "Freedom of Information Portal";
196 homepage = "https://github.com/okfde/froide";
197 license = lib.licenses.mit;
198 maintainers = [ lib.maintainers.onny ];
199 mainProgram = "froide";
200 };
201}