From 569192ccf7a716b8e9f1354e40b49529f3af54ac Mon Sep 17 00:00:00 2001 From: Kerstin Humm Date: Mon, 22 Jul 2024 17:00:46 +0200 Subject: [PATCH 01/13] python3Packages.phply: init at 1.2.6 Co-authored-by: Jan Tojnar Co-authored-by: Weijia Wang <9713184+wegank@users.noreply.github.com> --- .../python-modules/phply/default.nix | 31 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 ++ 2 files changed, 33 insertions(+) create mode 100644 pkgs/development/python-modules/phply/default.nix diff --git a/pkgs/development/python-modules/phply/default.nix b/pkgs/development/python-modules/phply/default.nix new file mode 100644 index 0000000000000..5844e92d28072 --- /dev/null +++ b/pkgs/development/python-modules/phply/default.nix @@ -0,0 +1,31 @@ +{ + lib, + buildPythonPackage, + fetchPypi, + ply, + pytestCheckHook, +}: + +buildPythonPackage rec { + pname = "phply"; + version = "1.2.6"; + + src = fetchPypi { + pname = "phply"; + inherit version; + sha256 = "sha256-Cyd3TShfUHo0RYBaBfj7KZj1bXCScPeLiSCLZbDYSRc="; + }; + + dependencies = [ ply ]; + + nativeCheckInputs = [ pytestCheckHook ]; + + pythonImportsCheck = [ "phply" ]; + + meta = with lib; { + description = "Lexer and parser for PHP source implemented using PLY"; + homepage = "https://github.com/viraptor/phply"; + license = licenses.bsd3; + maintainers = with maintainers; [ erictapen ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 9abd477316782..3a8fc3bd65aad 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -10006,6 +10006,8 @@ self: super: with self; { phe = callPackage ../development/python-modules/phe { }; + phply = callPackage ../development/python-modules/phply { }; + phik = callPackage ../development/python-modules/phik { }; phone-modem = callPackage ../development/python-modules/phone-modem { }; From a41a5502744da988e3c169ae7f4c6057588093ee Mon Sep 17 00:00:00 2001 From: Kerstin Humm Date: Mon, 22 Jul 2024 17:01:59 +0200 Subject: [PATCH 02/13] python3Packages.aeidon: init at 1.15 --- .../python-modules/aeidon/default.nix | 61 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 + 2 files changed, 63 insertions(+) create mode 100644 pkgs/development/python-modules/aeidon/default.nix diff --git a/pkgs/development/python-modules/aeidon/default.nix b/pkgs/development/python-modules/aeidon/default.nix new file mode 100644 index 0000000000000..744ece58293f9 --- /dev/null +++ b/pkgs/development/python-modules/aeidon/default.nix @@ -0,0 +1,61 @@ +{ + lib, + buildPythonPackage, + fetchPypi, + gettext, + flake8, + isocodes, + pytestCheckHook, + charset-normalizer, +}: + +buildPythonPackage rec { + pname = "aeidon"; + version = "1.15"; + + src = fetchPypi { + pname = "aeidon"; + inherit version; + sha256 = "sha256-qGpGraRZFVaW1Jys24qvfPo5WDg7Q/fhvm44JH8ulVw="; + }; + + nativeBuildInputs = [ + gettext + flake8 + ]; + + dependencies = [ isocodes ]; + + installPhase = '' + runHook preInstall + python setup.py --without-gaupol install --prefix=$out + runHook postInstall + ''; + + nativeCheckInputs = [ + pytestCheckHook + charset-normalizer + ]; + + # Aeidon is looking in the wrong subdirectory for data + preCheck = '' + cp -r data aeidon/ + ''; + + pytestFlagsArray = [ "aeidon/test" ]; + + disabledTests = [ + # requires gspell to work with gobject introspection + "test_spell" + ]; + + pythonImportsCheck = [ "aeidon" ]; + + meta = with lib; { + description = "Reading, writing and manipulationg text-based subtitle files"; + homepage = "https://github.com/otsaloma/gaupol"; + license = licenses.gpl3Only; + maintainers = with maintainers; [ erictapen ]; + }; + +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 3a8fc3bd65aad..417d9ca31cc53 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -93,6 +93,8 @@ self: super: with self; { advocate = callPackage ../development/python-modules/advocate { }; + aeidon = callPackage ../development/python-modules/aeidon { }; + aemet-opendata = callPackage ../development/python-modules/aemet-opendata { }; aenum = callPackage ../development/python-modules/aenum { }; From a3645d08b40a5e3de928c89ee2ebb0ffe8b0e85d Mon Sep 17 00:00:00 2001 From: Kerstin Humm Date: Mon, 22 Jul 2024 17:03:52 +0200 Subject: [PATCH 03/13] python3Packages.translate-toolkit: init at 3.13.2 Co-authored-by: Jan Tojnar Co-authored-by: Weijia Wang <9713184+wegank@users.noreply.github.com> --- .../translate-toolkit/default.nix | 72 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 + 2 files changed, 74 insertions(+) create mode 100644 pkgs/development/python-modules/translate-toolkit/default.nix diff --git a/pkgs/development/python-modules/translate-toolkit/default.nix b/pkgs/development/python-modules/translate-toolkit/default.nix new file mode 100644 index 0000000000000..0db2168149a63 --- /dev/null +++ b/pkgs/development/python-modules/translate-toolkit/default.nix @@ -0,0 +1,72 @@ +{ + lib, + fetchPypi, + buildPythonPackage, + setuptools-scm, + lxml, + wcwidth, + pytestCheckHook, + iniparse, + vobject, + mistletoe, + phply, + pyparsing, + ruamel-yaml, + cheroot, + fluent-syntax, + aeidon, + charset-normalizer, + syrupy, + gettext, +}: + +buildPythonPackage rec { + pname = "translate-toolkit"; + version = "3.13.2"; + + pyproject = true; + build-system = [ setuptools-scm ]; + + src = fetchPypi { + pname = "translate_toolkit"; + inherit version; + sha256 = "sha256-95zIAelFSNK5+f1GY8DUgHPDQBS5K+9ULjXaSaa0wWM="; + }; + + dependencies = [ + lxml + wcwidth + ]; + + nativeCheckInputs = [ + pytestCheckHook + iniparse + vobject + mistletoe + phply + pyparsing + ruamel-yaml + cheroot + fluent-syntax + aeidon + charset-normalizer + syrupy + gettext + ]; + + disabledTests = [ + # Probably breaks because of nix sandbox + "test_timezones" + # Requires network + "test_xliff_conformance" + ]; + + pythonImportsCheck = [ "translate" ]; + + meta = with lib; { + description = "Useful localization tools for building localization & translation systems"; + homepage = "https://toolkit.translatehouse.org/"; + license = licenses.gpl2Plus; + maintainers = with maintainers; [ erictapen ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 417d9ca31cc53..de494c89bc85e 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -15797,6 +15797,8 @@ self: super: with self; { tracing = callPackage ../development/python-modules/tracing { }; + translate-toolkit = callPackage ../development/python-modules/translate-toolkit { }; + trackpy = callPackage ../development/python-modules/trackpy { }; trafilatura = callPackage ../development/python-modules/trafilatura { }; From 2a6c9913d4d0ed7343c10750f15d1127892c9f21 Mon Sep 17 00:00:00 2001 From: Kerstin Humm Date: Mon, 22 Jul 2024 17:04:35 +0200 Subject: [PATCH 04/13] python3Packages.ahocorasick-rs: init at 0.22.0 --- .../python-modules/ahocorasick-rs/default.nix | 53 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 + 2 files changed, 55 insertions(+) create mode 100644 pkgs/development/python-modules/ahocorasick-rs/default.nix diff --git a/pkgs/development/python-modules/ahocorasick-rs/default.nix b/pkgs/development/python-modules/ahocorasick-rs/default.nix new file mode 100644 index 0000000000000..3ad7ebbc44bd4 --- /dev/null +++ b/pkgs/development/python-modules/ahocorasick-rs/default.nix @@ -0,0 +1,53 @@ +{ + lib, + buildPythonPackage, + fetchPypi, + rustPlatform, + typing-extensions, + pytestCheckHook, + pyahocorasick, + hypothesis, + pytest-benchmark, +}: + +buildPythonPackage rec { + pname = "ahocorasick-rs"; + version = "0.22.0"; + + pyproject = true; + + src = fetchPypi { + inherit version; + pname = "ahocorasick_rs"; + sha256 = "sha256-lzRwODlJlymMSih3CqNIeR+HrUbgVhroM1JuHFfW848="; + }; + + cargoDeps = rustPlatform.fetchCargoTarball { + inherit src; + name = "${pname}-${version}"; + hash = "sha256-CIt/ChNcoqKln6PgeTGp9pfmIWlJj+c5SCPtBhsnT6U="; + }; + + nativeBuildInputs = with rustPlatform; [ + maturinBuildHook + cargoSetupHook + typing-extensions + ]; + + nativeCheckInputs = [ + pytest-benchmark + pytestCheckHook + pyahocorasick + hypothesis + ]; + + pythonImportsCheck = [ "ahocorasick_rs" ]; + + meta = with lib; { + description = "Fast Aho-Corasick algorithm for Python"; + homepage = "https://github.com/G-Research/ahocorasick_rs/"; + license = licenses.asl20; + maintainers = with maintainers; [ erictapen ]; + }; + +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index de494c89bc85e..9ff3eb8fc842b 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -127,6 +127,8 @@ self: super: with self; { aggdraw = callPackage ../development/python-modules/aggdraw { }; + ahocorasick-rs = callPackage ../development/python-modules/ahocorasick-rs { }; + aigpy = callPackage ../development/python-modules/aigpy { }; aio-geojson-client = callPackage ../development/python-modules/aio-geojson-client { }; From e5af89bd6995c195d4aa4471d1d71a251bf1600d Mon Sep 17 00:00:00 2001 From: Kerstin Humm Date: Mon, 22 Jul 2024 17:05:01 +0200 Subject: [PATCH 05/13] python3Packages.celery: add redis as optional dependency --- pkgs/development/python-modules/celery/default.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/development/python-modules/celery/default.nix b/pkgs/development/python-modules/celery/default.nix index abdc5fb184e48..d5c372c5d4981 100644 --- a/pkgs/development/python-modules/celery/default.nix +++ b/pkgs/development/python-modules/celery/default.nix @@ -14,6 +14,7 @@ msgpack, nixosTests, pymongo, + redis, pytest-celery, pytest-click, pytest-subtests, @@ -59,6 +60,7 @@ buildPythonPackage rec { mongodb = [ pymongo ]; msgpack = [ msgpack ]; yaml = [ pyyaml ]; + redis = [ redis ]; }; nativeCheckInputs = [ From 0f9dcc23eb6716772c97966664dc5eacd28e0aef Mon Sep 17 00:00:00 2001 From: Kerstin Humm Date: Mon, 22 Jul 2024 17:05:43 +0200 Subject: [PATCH 06/13] python3Packages.django-crispy-bootstrap3: init at 2024.1 --- .../django-crispy-bootstrap3/default.nix | 43 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 + 2 files changed, 45 insertions(+) create mode 100644 pkgs/development/python-modules/django-crispy-bootstrap3/default.nix diff --git a/pkgs/development/python-modules/django-crispy-bootstrap3/default.nix b/pkgs/development/python-modules/django-crispy-bootstrap3/default.nix new file mode 100644 index 0000000000000..caf2f6655badb --- /dev/null +++ b/pkgs/development/python-modules/django-crispy-bootstrap3/default.nix @@ -0,0 +1,43 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + django, + setuptools, + pytestCheckHook, + pytest-django, + django-crispy-forms, +}: + +buildPythonPackage rec { + pname = "django-crispy-bootstrap3"; + version = "2024.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "django-crispy-forms"; + repo = "crispy-bootstrap3"; + rev = "refs/tags/${version}"; + hash = "sha256-w5CGWf14Wa8hndpk5r4hlz6gGykvRL+1AhA5Pz5Ejtk="; + }; + + dependencies = [ + django + setuptools + ]; + + nativeCheckInputs = [ + pytest-django + pytestCheckHook + django-crispy-forms + ]; + + pythonImportsCheck = [ "crispy_bootstrap3" ]; + + meta = with lib; { + description = "Bootstrap 3 template pack for django-crispy-forms"; + homepage = "https://github.com/django-crispy-forms/crispy-bootstrap3"; + license = licenses.mit; + maintainers = with maintainers; [ erictapen ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 9ff3eb8fc842b..396eeaee8e8a8 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -3285,6 +3285,8 @@ self: super: with self; { django-countries = callPackage ../development/python-modules/django-countries { }; + django-crispy-bootstrap3 = callPackage ../development/python-modules/django-crispy-bootstrap3 { }; + django-crispy-bootstrap4 = callPackage ../development/python-modules/django-crispy-bootstrap4 { }; django-crispy-bootstrap5 = callPackage ../development/python-modules/django-crispy-bootstrap5 { }; From e59da344825589daf8bed6d78a22359fbd6ffc6a Mon Sep 17 00:00:00 2001 From: Kerstin Humm Date: Mon, 22 Jul 2024 17:06:05 +0200 Subject: [PATCH 07/13] python3Packages.pyicumessageformat: init at 1.0.0 Co-authored-by: Taeer Bar-Yam --- .../pyicumessageformat/default.nix | 32 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 ++ 2 files changed, 34 insertions(+) create mode 100644 pkgs/development/python-modules/pyicumessageformat/default.nix diff --git a/pkgs/development/python-modules/pyicumessageformat/default.nix b/pkgs/development/python-modules/pyicumessageformat/default.nix new file mode 100644 index 0000000000000..efa0969006b8e --- /dev/null +++ b/pkgs/development/python-modules/pyicumessageformat/default.nix @@ -0,0 +1,32 @@ +{ + lib, + buildPythonPackage, + fetchPypi, + setuptools, + pytestCheckHook, +}: + +buildPythonPackage rec { + pname = "pyicumessageformat"; + version = "1.0.0"; + pyproject = true; + build-system = [ setuptools ]; + + src = fetchPypi { + pname = "pyicumessageformat"; + inherit version; + hash = "sha256-s+l8DtEMKxA/DzpwGqZSlwDqCrZuDzsj3I5K7hgfyEA="; + }; + + nativeCheckInputs = [ pytestCheckHook ]; + + pythonImportsCheck = [ "pyicumessageformat" ]; + + meta = with lib; { + description = "Unopinionated Python3 parser for ICU MessageFormat"; + homepage = "https://github.com/SirStendec/pyicumessageformat/"; + license = licenses.mit; + maintainers = with maintainers; [ erictapen ]; + }; + +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 396eeaee8e8a8..2c55e691fae14 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -11545,6 +11545,8 @@ self: super: with self; { pyicu = callPackage ../development/python-modules/pyicu { }; + pyicumessageformat = callPackage ../development/python-modules/pyicumessageformat { }; + pyimpfuzzy = callPackage ../development/python-modules/pyimpfuzzy { inherit (pkgs) ssdeep; }; From c30fa9a76ce21a9e403c2065e09fadf26f994666 Mon Sep 17 00:00:00 2001 From: Kerstin Humm Date: Mon, 22 Jul 2024 17:06:36 +0200 Subject: [PATCH 08/13] python3Packages.siphashc: init at 2.4.1 Co-authored-by: Jan Tojnar Co-authored-by: Taeer Bar-Yam --- .../python-modules/siphashc/default.nix | 31 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 ++ 2 files changed, 33 insertions(+) create mode 100644 pkgs/development/python-modules/siphashc/default.nix diff --git a/pkgs/development/python-modules/siphashc/default.nix b/pkgs/development/python-modules/siphashc/default.nix new file mode 100644 index 0000000000000..76c9ea7ad5c0b --- /dev/null +++ b/pkgs/development/python-modules/siphashc/default.nix @@ -0,0 +1,31 @@ +{ + lib, + fetchPypi, + buildPythonPackage, + setuptools, + pytestCheckHook, +}: + +buildPythonPackage rec { + pname = "siphashc"; + version = "2.4.1"; + pyproject = true; + build-system = [ setuptools ]; + + src = fetchPypi { + pname = "siphashc"; + inherit version; + sha256 = "sha256-ptNpy7VkUXHbjvdir6v+eYOmtQ/j8XPXq4lj7ceS/5s="; + }; + + nativeCheckInputs = [ pytestCheckHook ]; + + pythonImportsCheck = [ "siphashc" ]; + + meta = with lib; { + description = "Python c-module for siphash"; + homepage = "https://github.com/WeblateOrg/siphashc"; + license = licenses.mit; + maintainers = with maintainers; [ erictapen ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 2c55e691fae14..1702b6855b997 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -14411,6 +14411,8 @@ self: super: with self; { sip = callPackage ../development/python-modules/sip { }; + siphashc = callPackage ../development/python-modules/siphashc { }; + sip4 = callPackage ../development/python-modules/sip/4.x.nix { }; sipyco = callPackage ../development/python-modules/sipyco { }; From 77c26ec39dfcab489c6b55f7922023db5a605b17 Mon Sep 17 00:00:00 2001 From: Kerstin Humm Date: Mon, 22 Jul 2024 17:07:29 +0200 Subject: [PATCH 09/13] python3Packages.weblate-language-data: init at 2024.5 --- .../weblate-language-data/default.nix | 35 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 ++ 2 files changed, 37 insertions(+) create mode 100644 pkgs/development/python-modules/weblate-language-data/default.nix diff --git a/pkgs/development/python-modules/weblate-language-data/default.nix b/pkgs/development/python-modules/weblate-language-data/default.nix new file mode 100644 index 0000000000000..1566f83019dce --- /dev/null +++ b/pkgs/development/python-modules/weblate-language-data/default.nix @@ -0,0 +1,35 @@ +{ + lib, + buildPythonPackage, + fetchPypi, + setuptools, + translate-toolkit, +}: + +buildPythonPackage rec { + pname = "weblate-language-data"; + version = "2024.5"; + pyproject = true; + build-system = [ setuptools ]; + + src = fetchPypi { + pname = "weblate_language_data"; + inherit version; + hash = "sha256-kDt5ZF8cFH6HoQVlGX+jbchbwVCUIvmxHsCY3hjtjDM="; + }; + + dependencies = [ translate-toolkit ]; + + # No tests + doCheck = false; + + pythonImportsCheck = [ "weblate_language_data" ]; + + meta = with lib; { + description = "Language definitions used by Weblate"; + homepage = "https://github.com/WeblateOrg/language-data"; + license = licenses.mit; + maintainers = with maintainers; [ erictapen ]; + }; + +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 1702b6855b997..2bb1518ee344f 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -17373,6 +17373,8 @@ self: super: with self; { webexteamssdk = callPackage ../development/python-modules/webexteamssdk { }; + weblate-language-data = callPackage ../development/python-modules/weblate-language-data { }; + webob = callPackage ../development/python-modules/webob { }; webrtc-noise-gain = callPackage ../development/python-modules/webrtc-noise-gain { }; From 92e0b2cf3f09dda1789fd32b67ce51db009d0089 Mon Sep 17 00:00:00 2001 From: Kerstin Humm Date: Mon, 22 Jul 2024 17:08:22 +0200 Subject: [PATCH 10/13] python3Packages.weblate-schemas: init at 2024.1 --- .../weblate-schemas/default.nix | 40 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 + 2 files changed, 42 insertions(+) create mode 100644 pkgs/development/python-modules/weblate-schemas/default.nix diff --git a/pkgs/development/python-modules/weblate-schemas/default.nix b/pkgs/development/python-modules/weblate-schemas/default.nix new file mode 100644 index 0000000000000..728612b8a103f --- /dev/null +++ b/pkgs/development/python-modules/weblate-schemas/default.nix @@ -0,0 +1,40 @@ +{ + lib, + buildPythonPackage, + fetchPypi, + fqdn, + jsonschema, + rfc3987, + strict-rfc3339, + pytestCheckHook, +}: + +buildPythonPackage rec { + pname = "weblate-schemas"; + version = "2024.1"; + + src = fetchPypi { + pname = "weblate_schemas"; + inherit version; + hash = "sha256-nYPLD3VDO1Z97HI79J6Yjj3bWp1xKB79FWPCW146iz4="; + }; + + dependencies = [ + fqdn + jsonschema + rfc3987 + strict-rfc3339 + ]; + + nativeCheckInputs = [ pytestCheckHook ]; + + pythonImportsCheck = [ "weblate_schemas" ]; + + meta = with lib; { + description = "Schemas used by Weblate"; + homepage = "https://github.com/WeblateOrg/weblate_schemas"; + license = licenses.mit; + maintainers = with maintainers; [ erictapen ]; + }; + +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 2bb1518ee344f..2bcb79d409398 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -17375,6 +17375,8 @@ self: super: with self; { weblate-language-data = callPackage ../development/python-modules/weblate-language-data { }; + weblate-schemas = callPackage ../development/python-modules/weblate-schemas { }; + webob = callPackage ../development/python-modules/webob { }; webrtc-noise-gain = callPackage ../development/python-modules/webrtc-noise-gain { }; From 1bcf1661fc3754c073412b71a80c3bde04df02c0 Mon Sep 17 00:00:00 2001 From: Kerstin Humm Date: Mon, 22 Jul 2024 17:09:40 +0200 Subject: [PATCH 11/13] python3Packages.translation-finder: init at 2.16 --- .../translation-finder/default.nix | 40 +++++++++++++++++++ .../translation-finder/fix_tests.patch | 25 ++++++++++++ pkgs/top-level/python-packages.nix | 2 + 3 files changed, 67 insertions(+) create mode 100644 pkgs/development/python-modules/translation-finder/default.nix create mode 100644 pkgs/development/python-modules/translation-finder/fix_tests.patch diff --git a/pkgs/development/python-modules/translation-finder/default.nix b/pkgs/development/python-modules/translation-finder/default.nix new file mode 100644 index 0000000000000..c31c764136467 --- /dev/null +++ b/pkgs/development/python-modules/translation-finder/default.nix @@ -0,0 +1,40 @@ +{ + lib, + buildPythonPackage, + fetchPypi, + charset-normalizer, + ruamel-yaml, + weblate-language-data, + pytestCheckHook, +}: + +buildPythonPackage rec { + pname = "translation-finder"; + version = "2.16"; + + src = fetchPypi { + pname = "translation-finder"; + inherit version; + hash = "sha256-a1C+j4Zo0DJ9BWDn5Zsu4zAftcUixfPktAWdqiFJpiU="; + }; + + patches = [ ./fix_tests.patch ]; + + dependencies = [ + charset-normalizer + ruamel-yaml + weblate-language-data + ]; + + nativeCheckInputs = [ pytestCheckHook ]; + + pythonImportsCheck = [ "translation_finder" ]; + + meta = with lib; { + description = "Translation file finder for Weblate"; + homepage = "https://github.com/WeblateOrg/translation-finder"; + license = licenses.gpl3Only; + maintainers = with maintainers; [ erictapen ]; + }; + +} diff --git a/pkgs/development/python-modules/translation-finder/fix_tests.patch b/pkgs/development/python-modules/translation-finder/fix_tests.patch new file mode 100644 index 0000000000000..caf748a771304 --- /dev/null +++ b/pkgs/development/python-modules/translation-finder/fix_tests.patch @@ -0,0 +1,25 @@ +diff --git a/translation_finder/test_api.py b/translation_finder/test_api.py +index c3b020c..9be070d 100644 +--- a/translation_finder/test_api.py ++++ b/translation_finder/test_api.py +@@ -173,6 +173,7 @@ class APITest(DiscoveryTestCase): + "filemask": "json/gotext-*.json", + "template": "json/gotext-en.json", + }, ++ {'filemask': 'linked/*.po', 'new_base': 'linked/messages.pot', 'file_format': 'po'}, + ], + ) + +diff --git a/translation_finder/test_discovery.py b/translation_finder/test_discovery.py +index 1a0ca40..14caa4f 100644 +--- a/translation_finder/test_discovery.py ++++ b/translation_finder/test_discovery.py +@@ -945,6 +945,9 @@ class JSONDiscoveryTest(DiscoveryTestCase): + "file_format": "json-nested", + "template": "src/app/[locale]/_translations/en.json", + }, ++ {'filemask': '*/app/[locale]/_translations/cs.json', 'file_format': 'json-nested'}, ++ {'filemask': '*/app/[locale]/_translations/de.json', 'file_format': 'json-nested'}, ++ {'filemask': '*/app/[locale]/_translations/en.json', 'file_format': 'json-nested'} + ], + ) diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 2bcb79d409398..a39e4ef742a65 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -15807,6 +15807,8 @@ self: super: with self; { translate-toolkit = callPackage ../development/python-modules/translate-toolkit { }; + translation-finder = callPackage ../development/python-modules/translation-finder { }; + trackpy = callPackage ../development/python-modules/trackpy { }; trafilatura = callPackage ../development/python-modules/trafilatura { }; From bdc0e7deaa6952f88041578fd2abe2dd5ccc4708 Mon Sep 17 00:00:00 2001 From: Kerstin Humm Date: Mon, 22 Jul 2024 17:10:33 +0200 Subject: [PATCH 12/13] weblate: init at 5.6.2 --- pkgs/by-name/we/weblate/cache.lock.patch | 22 +++ pkgs/by-name/we/weblate/package.nix | 180 +++++++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 pkgs/by-name/we/weblate/cache.lock.patch create mode 100644 pkgs/by-name/we/weblate/package.nix diff --git a/pkgs/by-name/we/weblate/cache.lock.patch b/pkgs/by-name/we/weblate/cache.lock.patch new file mode 100644 index 0000000000000..dc5c50cdf77e8 --- /dev/null +++ b/pkgs/by-name/we/weblate/cache.lock.patch @@ -0,0 +1,22 @@ +diff --git a/weblate/utils/lock.py b/weblate/utils/lock.py +index 53c1486bc9..a0a5fc5a74 100644 +--- a/weblate/utils/lock.py ++++ b/weblate/utils/lock.py +@@ -43,8 +43,6 @@ class WeblateLock: + self._name = self._format_template(cache_template) + self._lock = cache.lock( + key=self._name, +- expire=3600, +- auto_renewal=True, + ) + self._enter_implementation = self._enter_redis + else: +@@ -62,7 +60,7 @@ class WeblateLock: + + def _enter_redis(self): + try: +- lock_result = self._lock.acquire(timeout=self._timeout) ++ lock_result = self._lock.acquire() + except AlreadyAcquired: + return + diff --git a/pkgs/by-name/we/weblate/package.nix b/pkgs/by-name/we/weblate/package.nix new file mode 100644 index 0000000000000..3b499ce31ada8 --- /dev/null +++ b/pkgs/by-name/we/weblate/package.nix @@ -0,0 +1,180 @@ +{ + lib, + python3, + fetchFromGitHub, + pango, + harfbuzz, + librsvg, + gdk-pixbuf, + glib, + borgbackup, + writeText, + nixosTests, +}: + +let + python = python3.override { + packageOverrides = final: prev: { + django = prev.django_5.overridePythonAttrs (old: { + dependencies = old.dependencies ++ prev.django_5.optional-dependencies.argon2; + }); + sentry-sdk = prev.sentry-sdk_2; + djangorestframework = prev.djangorestframework.overridePythonAttrs (old: { + # https://github.com/encode/django-rest-framework/discussions/9342 + disabledTests = (old.disabledTests or [ ]) ++ [ "test_invalid_inputs" ]; + }); + celery = prev.celery.overridePythonAttrs (old: { + dependencies = old.dependencies ++ prev.celery.optional-dependencies.redis; + }); + python-redis-lock = prev.python-redis-lock.overridePythonAttrs (old: { + dependencies = old.dependencies ++ prev.python-redis-lock.optional-dependencies.django; + }); + }; + }; +in +python.pkgs.buildPythonApplication rec { + pname = "weblate"; + version = "5.6.2"; + + pyproject = true; + + outputs = [ + "out" + "static" + ]; + + src = fetchFromGitHub { + owner = "WeblateOrg"; + repo = "weblate"; + rev = "weblate-${version}"; + sha256 = "sha256-t/hnigsKjdWCkUd8acNWhYVFmZ7oGn74+12347MkFgM="; + }; + + patches = [ + # FIXME This shouldn't be necessary and probably has to do with some dependency mismatch. + ./cache.lock.patch + ]; + + # Relax dependency constraints + # mistletoe: https://github.com/WeblateOrg/weblate/commit/50df46a25dda2b7b39de86d4c65ecd7a685f62e6 + # borgbackup: https://github.com/WeblateOrg/weblate/commit/355c81c977c59948535a98a35a5c05d7e6909703 + # django-crispy-forms: https://github.com/WeblateOrg/weblate/commit/7b341c523ed9b3b41ecfbc5c92dd6156992e4f32 + postPatch = '' + substituteInPlace pyproject.toml \ + --replace '"mistletoe>=1.3.0,<1.4"' '"mistletoe>=1.3.0,<1.5"' \ + --replace '"borgbackup>=1.2.5,<1.3"' '"borgbackup>=1.2.5,<1.5"' \ + --replace '"django-crispy-forms>=2.1,<2.3"' '"django-crispy-forms>=2.1,<2.4"' + ''; + + build-system = with python.pkgs; [ setuptools ]; + + # Build static files into a separate output + postBuild = + let + staticSettings = writeText "static_settings.py" '' + STATIC_ROOT = os.environ["static"] + "/static" + COMPRESS_ENABLED = True + COMPRESS_OFFLINE = True + COMPRESS_ROOT = os.environ["static"] + "/compressor-cache" + # So we don't need postgres dependencies + DATABASES = {} + ''; + in + '' + mkdir $static + cat weblate/settings_example.py ${staticSettings} > weblate/settings_static.py + export DJANGO_SETTINGS_MODULE="weblate.settings_static" + ${python.pythonOnBuildForHost.interpreter} manage.py collectstatic --no-input + ${python.pythonOnBuildForHost.interpreter} manage.py compress + ''; + + dependencies = with python.pkgs; [ + aeidon + ahocorasick-rs + borgbackup + celery + certifi + charset-normalizer + django-crispy-bootstrap3 + cryptography + cssselect + cython + diff-match-patch + django-appconf + django-celery-beat + django-compressor + django-cors-headers + django-crispy-forms + django-filter + django-redis + django + djangorestframework + filelock + fluent-syntax + gitpython + hiredis + html2text + iniparse + jsonschema + lxml + misaka + mistletoe + nh3 + openpyxl + packaging + phply + pillow + pycairo + pygments + pygobject3 + pyicumessageformat + pyparsing + python-dateutil + python-redis-lock + rapidfuzz + redis + requests + ruamel-yaml + sentry-sdk + siphashc + social-auth-app-django + social-auth-core + tesserocr + translate-toolkit + translation-finder + user-agents + weblate-language-data + weblate-schemas + ]; + + optional-dependencies = { + postgres = with python.pkgs; [ psycopg ]; + }; + + # We don't just use wrapGAppsNoGuiHook because we need to expose GI_TYPELIB_PATH + GI_TYPELIB_PATH = lib.makeSearchPathOutput "out" "lib/girepository-1.0" [ + pango + harfbuzz + librsvg + gdk-pixbuf + glib + ]; + makeWrapperArgs = [ "--set GI_TYPELIB_PATH \"$GI_TYPELIB_PATH\"" ]; + + passthru = { + inherit python; + # We need to expose this so weblate can work outside of calling its bin output + inherit GI_TYPELIB_PATH; + tests = { + inherit (nixosTests) weblate; + }; + }; + + meta = with lib; { + description = "Web based translation tool with tight version control integration"; + homepage = "https://weblate.org/"; + license = licenses.gpl3Plus; + platforms = platforms.linux; + maintainers = with maintainers; [ erictapen ]; + }; +} From d96e77704c06b86baa1db654c4d9e1e067ecb631 Mon Sep 17 00:00:00 2001 From: Kerstin Humm Date: Mon, 22 Jul 2024 17:11:49 +0200 Subject: [PATCH 13/13] nixos/weblate: init module and test Co-authored-by: Taeer Bar-Yam --- nixos/modules/module-list.nix | 1 + nixos/modules/services/web-apps/weblate.nix | 388 ++++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/web-apps/weblate.nix | 104 ++++++ 4 files changed, 494 insertions(+) create mode 100644 nixos/modules/services/web-apps/weblate.nix create mode 100644 nixos/tests/web-apps/weblate.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 6b83c0bab4062..ad7f075788be8 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1484,6 +1484,7 @@ ./services/web-apps/trilium.nix ./services/web-apps/tt-rss.nix ./services/web-apps/vikunja.nix + ./services/web-apps/weblate.nix ./services/web-apps/whitebophir.nix ./services/web-apps/wiki-js.nix ./services/web-apps/windmill.nix diff --git a/nixos/modules/services/web-apps/weblate.nix b/nixos/modules/services/web-apps/weblate.nix new file mode 100644 index 0000000000000..398d634a2b928 --- /dev/null +++ b/nixos/modules/services/web-apps/weblate.nix @@ -0,0 +1,388 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.services.weblate; + + dataDir = "/var/lib/weblate"; + settingsDir = "${dataDir}/settings"; + + finalPackage = cfg.package.overridePythonAttrs (old: { + # We only support the PostgreSQL backend in this module + dependencies = old.dependencies ++ cfg.package.optional-dependencies.postgres; + # Use a settings module in dataDir, to avoid having to rebuild the package + # when user changes settings. + makeWrapperArgs = (old.makeWrapperArgs or [ ]) ++ [ + "--set PYTHONPATH \"${settingsDir}\"" + "--set DJANGO_SETTINGS_MODULE \"settings\"" + ]; + }); + inherit (finalPackage) python; + + pythonEnv = python.buildEnv.override { + extraLibs = with python.pkgs; [ + (toPythonModule finalPackage) + celery + ]; + }; + + # This extends and overrides the weblate/settings_example.py code found in upstream. + weblateConfig = + '' + # This was autogenerated by the NixOS module. + + SITE_TITLE = "Weblate" + SITE_DOMAIN = "${cfg.localDomain}" + # TLS terminates at the reverse proxy, but this setting controls how links to weblate are generated. + ENABLE_HTTPS = True + SESSION_COOKIE_SECURE = ENABLE_HTTPS + DATA_DIR = "${dataDir}" + CACHE_DIR = f"{DATA_DIR}/cache" + STATIC_ROOT = "${finalPackage.static}/static" + MEDIA_ROOT = "/var/lib/weblate/media" + COMPRESS_ROOT = "${finalPackage.static}/compressor-cache" + DEBUG = False + + DATABASES = { + "default": { + "ENGINE": "django.db.backends.postgresql", + "HOST": "/run/postgresql", + "NAME": "weblate", + "USER": "weblate", + } + } + + with open("${cfg.djangoSecretKeyFile}") as f: + SECRET_KEY = f.read().rstrip("\n") + + CACHES = { + "default": { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": "unix://${config.services.redis.servers.weblate.unixSocket}", + "OPTIONS": { + "CLIENT_CLASS": "django_redis.client.DefaultClient", + "PASSWORD": None, + "CONNECTION_POOL_KWARGS": {}, + }, + "KEY_PREFIX": "weblate", + "TIMEOUT": 3600, + }, + "avatar": { + "BACKEND": "django.core.cache.backends.filebased.FileBasedCache", + "LOCATION": "/var/lib/weblate/avatar-cache", + "TIMEOUT": 86400, + "OPTIONS": {"MAX_ENTRIES": 1000}, + } + } + + + CELERY_TASK_ALWAYS_EAGER = False + CELERY_BROKER_URL = "redis+socket://${config.services.redis.servers.weblate.unixSocket}" + CELERY_RESULT_BACKEND = CELERY_BROKER_URL + + VCS_BACKENDS = ("weblate.vcs.git.GitRepository",) + + '' + + lib.optionalString cfg.smtp.enable '' + ADMINS = (("Weblate Admin", "${cfg.smtp.user}"),) + + EMAIL_HOST = "${cfg.smtp.host}" + EMAIL_USE_TLS = True + EMAIL_HOST_USER = "${cfg.smtp.user}" + SERVER_EMAIL = "${cfg.smtp.user}" + DEFAULT_FROM_EMAIL = "${cfg.smtp.user}" + EMAIL_PORT = 587 + with open("${cfg.smtp.passwordFile}") as f: + EMAIL_HOST_PASSWORD = f.read().rstrip("\n") + + '' + + cfg.extraConfig; + settings_py = + pkgs.runCommand "weblate_settings.py" + { + inherit weblateConfig; + passAsFile = [ "weblateConfig" ]; + } + '' + mkdir -p $out + cat \ + ${finalPackage}/${python.sitePackages}/weblate/settings_example.py \ + $weblateConfigPath \ + > $out/settings.py + ''; + + environment = { + PYTHONPATH = "${settingsDir}:${pythonEnv}/${python.sitePackages}/"; + DJANGO_SETTINGS_MODULE = "settings"; + # We run Weblate through gunicorn, so we can't utilise the env var set in the wrapper. + inherit (finalPackage) GI_TYPELIB_PATH; + }; + + weblatePath = with pkgs; [ + gitSVN + + #optional + git-review + tesseract + licensee + mercurial + ]; +in +{ + + options = { + services.weblate = { + enable = lib.mkEnableOption "Weblate service"; + + package = lib.mkPackageOption pkgs "weblate" { }; + + localDomain = lib.mkOption { + description = "The domain name serving your Weblate instance."; + example = "weblate.example.org"; + type = lib.types.str; + }; + + djangoSecretKeyFile = lib.mkOption { + description = '' + Location of the Django secret key. + + This should be a path pointing to a file with secure permissions (not /nix/store). + + Can be generated with `weblate-generate-secret-key` which is available as the `weblate` user. + ''; + type = lib.types.path; + }; + + extraConfig = lib.mkOption { + type = lib.types.lines; + default = ""; + description = '' + Text to append to `settings.py` Weblate configuration file. + ''; + }; + + smtp = { + enable = lib.mkEnableOption "Weblate SMTP support"; + user = lib.mkOption { + description = "SMTP login name."; + example = "weblate@example.org"; + type = lib.types.str; + }; + + host = lib.mkOption { + description = "SMTP host used when sending emails to users."; + type = lib.types.str; + example = "127.0.0.1"; + }; + + passwordFile = lib.mkOption { + description = '' + Location of a file containing the SMTP password. + + This should be a path pointing to a file with secure permissions (not /nix/store). + ''; + type = lib.types.path; + }; + }; + + }; + }; + + config = lib.mkIf cfg.enable { + + systemd.tmpfiles.rules = [ "L+ ${settingsDir} - - - - ${settings_py}" ]; + + services.nginx = { + enable = true; + virtualHosts."${cfg.localDomain}" = { + + forceSSL = true; + enableACME = true; + + locations = { + "= /favicon.ico".alias = "${finalPackage}/${python.sitePackages}/weblate/static/favicon.ico"; + "/static/".alias = "${finalPackage.static}/static/"; + "/static/CACHE/".alias = "${finalPackage.static}/compressor-cache/CACHE/"; + "/media/".alias = "/var/lib/weblate/media/"; + "/".proxyPass = "http://unix:///run/weblate.socket"; + }; + + }; + }; + + systemd.services.weblate-postgresql-setup = { + description = "Weblate PostgreSQL setup"; + after = [ "postgresql.service" ]; + serviceConfig = { + Type = "oneshot"; + User = "postgres"; + Group = "postgres"; + ExecStart = '' + ${config.services.postgresql.package}/bin/psql weblate -c "CREATE EXTENSION IF NOT EXISTS pg_trgm" + ''; + }; + }; + + systemd.services.weblate-migrate = { + description = "Weblate migration"; + after = [ "weblate-postgresql-setup.service" ]; + requires = [ "weblate-postgresql-setup.service" ]; + # We want this to be active on boot, not just on socket activation + wantedBy = [ "multi-user.target" ]; + inherit environment; + path = weblatePath; + serviceConfig = { + Type = "oneshot"; + StateDirectory = "weblate"; + User = "weblate"; + Group = "weblate"; + ExecStart = "${finalPackage}/bin/weblate migrate --noinput"; + }; + }; + + systemd.services.weblate-celery = { + description = "Weblate Celery"; + after = [ + "network.target" + "redis.service" + "postgresql.service" + ]; + # We want this to be active on boot, not just on socket activation + wantedBy = [ "multi-user.target" ]; + environment = environment // { + CELERY_WORKER_RUNNING = "1"; + }; + path = weblatePath; + # Recommendations from: + # https://github.com/WeblateOrg/weblate/blob/main/weblate/examples/celery-weblate.service + serviceConfig = + let + # We have to push %n through systemd's replacement, therefore %%n. + pidFile = "/run/celery/weblate-%%n.pid"; + nodes = "celery notify memory backup translate"; + cmd = verb: '' + ${pythonEnv}/bin/celery multi ${verb} \ + ${nodes} \ + -A "weblate.utils" \ + --pidfile=${pidFile} \ + --logfile=/var/log/celery/weblate-%%n%%I.log \ + --loglevel=DEBUG \ + --beat:celery \ + --queues:celery=celery \ + --prefetch-multiplier:celery=4 \ + --queues:notify=notify \ + --prefetch-multiplier:notify=10 \ + --queues:memory=memory \ + --prefetch-multiplier:memory=10 \ + --queues:translate=translate \ + --prefetch-multiplier:translate=4 \ + --concurrency:backup=1 \ + --queues:backup=backup \ + --prefetch-multiplier:backup=2 + ''; + in + { + Type = "forking"; + User = "weblate"; + Group = "weblate"; + WorkingDirectory = "${finalPackage}/${python.sitePackages}/weblate/"; + RuntimeDirectory = "celery"; + RuntimeDirectoryPreserve = "restart"; + LogsDirectory = "celery"; + ExecStart = cmd "start"; + ExecReload = cmd "restart"; + ExecStop = '' + ${pythonEnv}/bin/celery multi stopwait \ + ${nodes} \ + --pidfile=${pidFile} + ''; + Restart = "always"; + }; + }; + + systemd.services.weblate = { + description = "Weblate Gunicorn app"; + after = [ + "network.target" + "weblate-migrate.service" + "weblate-celery.service" + ]; + requires = [ + "weblate-migrate.service" + "weblate-celery.service" + "weblate.socket" + ]; + inherit environment; + path = weblatePath; + serviceConfig = { + Type = "notify"; + NotifyAccess = "all"; + ExecStart = + let + gunicorn = python.pkgs.gunicorn.overridePythonAttrs (old: { + # Allows Gunicorn to set a meaningful process name + dependencies = (old.dependencies or [ ]) ++ old.optional-dependencies.setproctitle; + }); + in + '' + ${gunicorn}/bin/gunicorn \ + --name=weblate \ + --bind='unix:///run/weblate.socket' \ + weblate.wsgi + ''; + ExecReload = "kill -s HUP $MAINPID"; + KillMode = "mixed"; + PrivateTmp = true; + WorkingDirectory = dataDir; + StateDirectory = "weblate"; + RuntimeDirectory = "weblate"; + User = "weblate"; + Group = "weblate"; + }; + }; + + systemd.sockets.weblate = { + before = [ "nginx.service" ]; + wantedBy = [ "sockets.target" ]; + socketConfig = { + ListenStream = "/run/weblate.socket"; + SocketUser = "weblate"; + SocketGroup = "weblate"; + SocketMode = "770"; + }; + }; + + services.redis.servers.weblate = { + enable = true; + user = "weblate"; + unixSocket = "/run/redis-weblate/redis.sock"; + unixSocketPerm = 770; + }; + + services.postgresql = { + enable = true; + ensureUsers = [ + { + name = "weblate"; + ensureDBOwnership = true; + } + ]; + ensureDatabases = [ "weblate" ]; + }; + + users.users.weblate = { + isSystemUser = true; + group = "weblate"; + packages = [ finalPackage ] ++ weblatePath; + }; + + users.groups.weblate.members = [ config.services.nginx.user ]; + }; + + meta.maintainers = with lib.maintainers; [ erictapen ]; + +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 12f8954c40403..8fadeb88f366e 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -1072,6 +1072,7 @@ in { wastebin = handleTest ./wastebin.nix {}; watchdogd = handleTest ./watchdogd.nix {}; webhook = runTest ./webhook.nix; + weblate = handleTest ./web-apps/weblate.nix {}; wiki-js = handleTest ./wiki-js.nix {}; wine = handleTest ./wine.nix {}; wireguard = handleTest ./wireguard {}; diff --git a/nixos/tests/web-apps/weblate.nix b/nixos/tests/web-apps/weblate.nix new file mode 100644 index 0000000000000..40d60f7e5f996 --- /dev/null +++ b/nixos/tests/web-apps/weblate.nix @@ -0,0 +1,104 @@ +import ../make-test-python.nix ( + { pkgs, ... }: + + let + certs = import ../common/acme/server/snakeoil-certs.nix; + + serverDomain = certs.domain; + + admin = { + username = "admin"; + password = "snakeoilpass"; + }; + # An API token that we manually insert into the db as a valid one. + apiToken = "OVJh65sXaAfQMZ4NTcIGbFZIyBZbEZqWTi7azdDf"; + in + { + name = "weblate"; + meta.maintainers = with pkgs.lib.maintainers; [ erictapen ]; + + nodes.server = + { pkgs, lib, ... }: + { + virtualisation.memorySize = 2048; + + services.weblate = { + enable = true; + localDomain = "${serverDomain}"; + djangoSecretKeyFile = pkgs.writeText "weblate-django-secret" "thisissnakeoilsecretwithmorethan50characterscorrecthorsebatterystaple"; + extraConfig = '' + # Weblate tries to fetch Avatars from the network + ENABLE_AVATARS = False + ''; + }; + + services.nginx.virtualHosts."${serverDomain}" = { + enableACME = lib.mkForce false; + sslCertificate = certs."${serverDomain}".cert; + sslCertificateKey = certs."${serverDomain}".key; + }; + + security.pki.certificateFiles = [ certs.ca.cert ]; + + networking.hosts."::1" = [ "${serverDomain}" ]; + networking.firewall.allowedTCPPorts = [ + 80 + 443 + ]; + + users.users.weblate.shell = pkgs.bashInteractive; + }; + + nodes.client = + { pkgs, nodes, ... }: + { + environment.systemPackages = [ pkgs.wlc ]; + + environment.etc."xdg/weblate".text = '' + [weblate] + url = https://${serverDomain}/api/ + key = ${apiToken} + ''; + + networking.hosts."${nodes.server.networking.primaryIPAddress}" = [ "${serverDomain}" ]; + + security.pki.certificateFiles = [ certs.ca.cert ]; + }; + + testScript = '' + import json + + start_all() + server.wait_for_unit("weblate.socket") + server.wait_until_succeeds("curl -f https://${serverDomain}/") + server.succeed("sudo -iu weblate -- weblate createadmin --username ${admin.username} --password ${admin.password} --email weblate@example.org") + + # It's easier to replace the generated API token with a predefined one than + # to extract it at runtime. + server.succeed("sudo -iu weblate -- psql -d weblate -c \"UPDATE authtoken_token SET key = '${apiToken}' WHERE user_id = (SELECT id FROM weblate_auth_user WHERE username = 'admin');\"") + + client.wait_for_unit("multi-user.target") + + # Test the official Weblate client wlc. + client.wait_until_succeeds("REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt wlc --debug list-projects") + + def call_wl_api(arg): + (rv, result) = client.execute("curl -H \"Content-Type: application/json\" -H \"Authorization: Token ${apiToken}\" https://${serverDomain}/api/{}".format(arg)) + assert rv == 0 + print(result) + + call_wl_api("users/ --data '{}'".format( + json.dumps( + {"username": "test1", + "full_name": "test1", + "email": "test1@example.org" + }))) + + # TODO: Check sending and receiving email. + # server.wait_for_unit("postfix.service") + + # TODO: The goal is for this to succeed, but there are still some checks failing. + # server.succeed("sudo -iu weblate -- weblate check --deploy") + ''; + } +)