#!@GUILE@ \ --no-auto-compile -s !# ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2020, 2021 Ricardo Wurmus ;;; Copyright © 2021 Sarah Morgensen ;;; Copyright © 2021 Xinglu Chen ;;; Copyright © 2022 Maxim Cournoyer ;;; ;;; This file is part of GNU Guix. ;;; ;;; GNU Guix is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; GNU Guix is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with GNU Guix. If not, see . ;;; Commentary: ;; This script stages and commits changes to package definitions. ;;; Code: (use-modules ((sxml xpath) #:prefix xpath:) (srfi srfi-1) (srfi srfi-2) (srfi srfi-9) (srfi srfi-11) (srfi srfi-26) (ice-9 format) (ice-9 popen) (ice-9 match) (ice-9 rdelim) (ice-9 regex) (ice-9 textual-ports) (guix gexp)) (define* (break-string str #:optional (max-line-length 70)) "Break the string STR into lines that are no longer than MAX-LINE-LENGTH. Return a single string." (define (restore-line words) (string-join (reverse words) " ")) (if (<= (string-length str) max-line-length) str (let ((words+lengths (map (lambda (word) (cons word (string-length word))) (string-tokenize str))))
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016 Hartmut Goebel <h.goebel@crazy-compilers.com>
;;; Copyright © 2016, 2019, 2020, 2021 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2017 Nikita <nikita@n0.is>
;;; Copyright © 2017, 2018, 2019 Tobias Geerinckx-Rice <me@tobias.gr>
;;; Copyright © 2017, 2025 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2018 Vijayalakshmi Vedantham <vijimay12@gmail.com>
;;; Copyright © 2019 Sam <smbaines8@gmail.com>
;;; Copyright © 2020, 2021, 2022, 2023 Marius Bakke <marius@gnu.org>
;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2021 Luis Felipe López Acevedo <luis.felipe.la@protonmail.com>
;;; Copyright © 2022 Pradana Aumars <paumars@courrier.dev>
;;; Copyright © 2024 Wojtek Kosior <koszko@koszko.org>
;;; Additions and modifications by Wojtek Kosior are additionally
;;; dual-licensed under the Creative Commons Zero v1.0.
;;; Copyright © 2025 Sharlatan Hellseher <sharlatanus@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu packages django)
  #:use-module ((guix licenses) #:prefix license:)
  #:use-module (guix packages)
  #:use-module (guix download)
  #:use-module (guix git-download)
  #:use-module (guix gexp)
  #:use-module (guix build-system pyproject)
  #:use-module (guix build-system python)
  #:use-module (guix deprecation)
  #:use-module (guix search-paths)
  #:use-module (gnu packages)
  #:use-module (gnu packages base)
  #:use-module (gnu packages compression)
  #:use-module (gnu packages databases)
  #:use-module (gnu packages check)
  #:use-module (gnu packages finance)
  #:use-module (gnu packages geo)
  #:use-module (gnu packages openldap)
  #:use-module (gnu packages python)
  #:use-module (gnu packages python-build)
  #:use-module (gnu packages python-check)
  #:use-module (gnu packages python-crypto)
  #:use-module (gnu packages python-web)
  #:use-module (gnu packages python-xyz)
  #:use-module (gnu packages security-token)
  #:use-module (gnu packages sphinx)
  #:use-module (gnu packages time)
  #:use-module (gnu packages xml))

(define-public python-django-4.2
  (package
    (name "python-django")
    (version "4.2.16")
    (source (origin
              (method url-fetch)
              (uri (pypi-uri "Django" version))
              (sha256
               (base32
                "1b8xgwg3gjr974j60x3vgcpp85cg5dwhzqdpdbl8qh3cg311c5kg"))))
    (build-system pyproject-build-system)
    (arguments
     '(#:test-flags
       (list
        ;; By default tests run in parallel, which may cause various race
        ;; conditions.  Run sequentially for consistent results.
        "--parallel=1"
        ;; The test suite fails as soon as a single test fails.
        "--failfast")
       #:phases
       (modify-phases %standard-phases
         (add-before 'check 'pre-check
           (lambda* (#:key inputs #:allow-other-keys)
             ;; The test-suite tests timezone-dependent functions, thus tzdata
             ;; needs to be available.
             (setenv "TZDIR"
                     (search-input-directory inputs "share/zoneinfo"))

             ;; Disable test for incorrect timezone: it only raises the
             ;; expected error when /usr/share/zoneinfo exists, even though
             ;; the machinery gracefully falls back to TZDIR.  According to
             ;; django/conf/__init__.py, lack of /usr/share/zoneinfo is
             ;; harmless, so just ignore this test.
             (substitute* "tests/settings_tests/tests.py"
               ((".*def test_incorrect_timezone.*" all)
                (string-append "    @unittest.skip('Disabled by Guix')\n"
                               all)))))
         (replace 'check
           (lambda* (#:key tests? test-flags #:allow-other-keys)
             (if tests?
                 (with-directory-excursion "tests"
                   ;; Tests expect PYTHONPATH to contain the root directory.
                   (setenv "PYTHONPATH" "..")
                   (apply invoke "python" "runtests.py" test-flags))
                 (format #t "test suite not run~%"))))
         ;; XXX: The 'wrap' phase adds native inputs as runtime dependencies,
         ;; see <https://bugs.gnu.org/25235>.  The django-admin script typically
         ;; runs in an environment that has Django and its dependencies on
         ;; PYTHONPATH, so just disable the wrapper to reduce the size from
         ;; ~710 MiB to ~203 MiB.
         (delete 'wrap))))
    ;; TODO: Install extras/django_bash_completion.
    (native-inputs
     (list tzdata-for-tests
           ;; Remaining packages are test requirements taken from
           ;; tests/requirements/py3.txt
           python-docutils
           ;; optional for tests: python-geoip2
           ;; optional for tests: python-memcached
           python-numpy
           python-pillow
           python-pyyaml
           python-setuptools
           ;; optional for tests: python-selenium
           python-tblib
           python-wheel))
    (propagated-inputs
     (list python-asgiref
           python-sqlparse
           ;; Optional dependencies.
           python-argon2-cffi
           python-bcrypt
           ;; This input is not strictly required, but in practice many Django
           ;; libraries need it for test suites and similar.
           python-jinja2))
    (native-search-paths
     ;; Set TZDIR when 'tzdata' is available so that timezone functionality
     ;; works (mostly) out of the box in containerized environments.
     ;; Note: This search path actually belongs to 'glibc'.
     (list $TZDIR))
    (home-page "https://www.djangoproject.com/")
    (synopsis "High-level Python Web framework")
    (description
     "Django is a high-level Python Web framework that encourages rapid
development and clean, pragmatic design.  It provides many tools for building
any Web site.  Django focuses on automating as much as possible and adhering
to the @dfn{don't repeat yourself} (DRY) principle.")
    (license license:bsd-3)
    (properties `((cpe-name . "django")
                  ;; This CVE seems fixed since 4.2.1.
                  (lint-hidden-cve . ("CVE-2023-31047"))))))

(define-public python-django-3.2
  (package
    (inherit python-django-4.2)
    (version "3.2.21")
    (source (origin
              (method url-fetch)
              (uri (pypi-uri "Django" version))
              (sha256
               (base32
                "0g3zm2glh76g31q06g6fwkwvkrphjj3mnap5sgk1hx3v9r44rpm5"))))
    (native-search-paths '())           ;no need for TZDIR
    (propagated-inputs
     (modify-inputs (package-propagated-inputs python-django-4.2)
       ;; Django 4.0 deprecated pytz in favor of Pythons built-in zoneinfo.
       (append python-pytz)))))

;; archivebox requires django>=3.1.3,<3.2
(define-public python-django-3.1.14
  (package
    (inherit python-django-3.2)
    (version "3.1.14")
    (source (origin
              (method url-fetch)
              (uri (pypi-uri "Django" version))
              (sha256
               (base32
                "0ix3v2wlnplv78zxjrlw8z3hiap2d5mxvk0ny2fc65526shsb93j"))))
    (propagated-inputs
     (modify-inputs (package-propagated-inputs python-django-3.2)
       ;; Django 4.0 deprecated pytz in favor of Pythons built-in zoneinfo.
       (append python-pytz)))))

(define-public python-django python-django-4.2)

(define-public python-django-cache-url
  (package
    (name "python-django-cache-url")
    (version "3.4.4")
    (source (origin
              (method url-fetch)
              (uri (pypi-uri "django-cache-url" version))
              (sha256
               (base32
                "0dpx2wmcclmd3jkprdljz3makq12vd0sjv3xnvlj5vk1lg7glb7g"))))
    (build-system pyproject-build-system)
    (native-inputs
     (list python-django python-setuptools python-wheel))
    (home-page "https://github.com/epicserve/django-cache-url")
    (synopsis "Configure Django cache settings from URLs")
    (description
     "This package provides a facility for configuring Django cache settings
with a @var{CACHE_URL} environment variable.")
    (license license:expat)))

(define-public python-django-configurations
  (package
    (name "python-django-configurations")
    (version "2.4.1")
    (source (origin
              (method url-fetch)
              (uri (pypi-uri "django-configurations" version))
              (sha256
               (base32
                "11chll26iqqy5chyx62hya20cadk10nm2la7sch7pril70a5rhm6"))))
    (build-system pyproject-build-system)
    (arguments
     (list #:phases
           #~(modify-phases %standard-phases
               (replace 'check
                 (lambda* (#:key tests? #:allow-other-keys)
                   (when tests?
                     ;; Taken from tox.ini.
                     (setenv "DJANGO_SETTINGS_MODULE" "tests.settings.main")
                     (setenv "DJANGO_CONFIGURATION" "Test")
                     (setenv "PYTHONPATH"
                             (string-append ".:" (getenv "GUIX_PYTHONPATH")))
                     (invoke "django-cadmin" "test" "-v2")))))))
    (propagated-inputs
     (list python-django))
    (native-inputs
     (list python-dj-database-url
           python-dj-email-url
           python-dj-search-url
           python-django-cache-url
           python-setuptools
           python-setuptools-scm
           python-wheel))
    (home-page "https://django-configurations.readthedocs.io/")
    (synopsis "Helper module for organizing Django settings")
    (description
     "@code{django-configurations} helps you organize the configuration of
your Django project by providing glue code to bridge between Django'smodule
based settings system and programming patterns like mixins, facades, factories
and adapters that are useful for non-trivial configuration scenarios.")
    (license license:bsd-3)))

(define-public python-django-extensions
  (package
    (name "python-django-extensions")
    (version "3.0.6")
    (source
     (origin
       (method git-fetch)
       ;; Fetch from the git repository, so that the tests can be run.
       (uri (git-reference
             (url "https://github.com/django-extensions/django-extensions")
             (commit version)))
       (file-name (string-append name "-" version))
       (sha256
        (base32
         "0sra6hazqvspxd1pnx5cj7gia1rkaz3hn06ib4wd0frc167f5afy"))))
    (build-system python-build-system)
    (arguments
     '(#:tests? #f)) ;XXX: requires a Postgres or MySQL database
    (propagated-inputs
     (list python-six python-vobject python-werkzeug python-dateutil
           python-django))
    (native-inputs
     (list python-mock
           python-factory-boy
           python-tox
           python-pytest
           python-pytest-cov
           python-pytest-django
           python-shortuuid))
    (home-page
     "https://github.com/django-extensions/django-extensions")
    (synopsis "Custom management extensions for Django")
    (description
     "Django-extensions extends Django providing, for example, management
commands, additional database fields and admin extensions.")
    (license license:expat)))

(define-public python-django-localflavor
  (package
    (name "python-django-localflavor")
    (version "3.1")
    (source
     (origin
       (method url-fetch)
       (uri (pypi-uri "django-localflavor" version))
       (sha256
        (base32 "0i1s0ijfd9rv2cp5x174jcyjpwn7fyg7s1wpbvlwm96bpdvs6bxc"))))
    (build-system pyproject-build-system)
    (arguments
     (list
      #:test-flags '(list "--settings=tests.settings" "tests")
      #:phases
      #~(modify-phases %standard-phases
          (replace 'check
            (lambda* (#:key tests? test-flags #:allow-other-keys)
              (if tests?
                  (apply invoke "python" "-m" "django" "test" test-flags)
                  (format #t "test suite not run~%")))))))
    (native-inputs
     (list python-setuptools python-wheel))
    (propagated-inputs
     (list python-django python-stdnum))
    (home-page "https://django-localflavor.readthedocs.io/en/latest/")
    (synopsis "Country-specific Django helpers")
    (description "Django-LocalFlavor is a collection of assorted pieces of code
that are useful for particular countries or cultures.")
    (license license:bsd-3)))

(define-public python-django-simple-math-captcha
  (package
    (name "python-django-simple-math-captcha")
    (version "2.0.0")
    (home-page "https://github.com/alsoicode/django-simple-math-captcha")
    (source (origin
              (method git-fetch)
              (uri (git-reference
                    (url home-page)
                    (commit version)))
              (file-name (git-file-name name version))
              (sha256
               (base32
                "1pqriqvg1bfx36p8hxzh47zl5qk911vgf3xaxfvhkjyi611rbxzy"))))
    (build-system pyproject-build-system)
    (arguments
     (list
      #:phases
      '(modify-phases %standard-phases
         (add-after 'unpack 'compatibility
           (lambda _
             (substitute* "test_simplemathcaptcha/form_tests.py"
               (("label for=\"id_captcha_0\"") "label"))
             (substitute* "simplemathcaptcha/widgets.py"
               (("ugettext_lazy") "gettext_lazy"))))
         (replace 'check
           (lambda* (#:key tests? #:allow-other-keys)
             (when tests?
               (invoke "python" "runtests.py")))))))
    (native-inputs
     (list python-mock python-setuptools python-wheel))
    (propagated-inputs
     (list python-django python-six))
    (synopsis "Easy-to-use math fi