# Copyright 1999-2026 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 EAPI=8 PYTHON_COMPAT=( python3_{13..15} ) DISTUTILS_USE_PEP517=uv-build DISTUTILS_SINGLE_IMPL=yes inherit distutils-r1 systemd DESCRIPTION="Open source video conferencing app powered by LiveKit" HOMEPAGE=" https://visio.numerique.gouv.fr/ https://github.com/suitenumerique/meet/" # Deps tarballs generated with app-portage/nodebuild::2xsaiko. SRC_URI=" https://github.com/suitenumerique/meet/archive/refs/tags/v${PV}.tar.gz -> ${P}.tar.gz https://dblsaiko.net/pub/dist/${P}-frontend-deps.tar.xz https://dblsaiko.net/pub/dist/${P}-mail-deps.tar.xz" PATCHES=( "${FILESDIR}"/unrestrict-uv-version.patch ) S="${WORKDIR}/meet-${PV}" LICENSE="MIT" SLOT="0" KEYWORDS="~amd64" RDEPEND=" =www-servers/gunicorn-26.2.0 $(python_gen_cond_dep ' >=dev-python/boto3-1.43.56[${PYTHON_USEDEP}] >=dev-python/brotlicffi-1.2.0[${PYTHON_USEDEP}] >=dev-python/dj-database-url-3.1.2[${PYTHON_USEDEP}] >=dev-python/django-configurations-2.5.1[${PYTHON_USEDEP}] >=dev-python/django-cors-headers-4.9.0[${PYTHON_USEDEP}] >=dev-python/redis-5.2.1[${PYTHON_USEDEP}] >=dev-python/django-redis-7.0.0[${PYTHON_USEDEP}] >=dev-python/django-timezone-field-5.1[${PYTHON_USEDEP}] >=dev-python/django-5.2.16[${PYTHON_USEDEP}] >=dev-python/djangorestframework-3.17.1[${PYTHON_USEDEP}] >=dev-python/easy-thumbnails-2.10.1[${PYTHON_USEDEP}] >=www-servers/gunicorn-26.2.0[${PYTHON_USEDEP}] >=dev-python/jsonschema-4.26.0[${PYTHON_USEDEP}] >=dev-python/markdown-3.10.2[${PYTHON_USEDEP}] >=dev-python/posthog-7.29.0[${PYTHON_USEDEP}] >=dev-python/psycopg-3.3.4[${PYTHON_USEDEP}] >=dev-python/pydantic-2.13.4[${PYTHON_USEDEP}] >=dev-python/pyjwt-2.13.0[${PYTHON_USEDEP}] >=dev-python/python-frontmatter-1.3.0[${PYTHON_USEDEP}] >=dev-python/python-magic-0.4.27[${PYTHON_USEDEP}] >=dev-python/requests-2.34.2[${PYTHON_USEDEP}] >=dev-python/sentry-sdk-2.66.1[${PYTHON_USEDEP}] >=dev-python/whitenoise-6.12.0[${PYTHON_USEDEP}] >=dev-python/aiohttp-3.14.3[${PYTHON_USEDEP}] >=dev-python/urllib3-2.7.0[${PYTHON_USEDEP}] >=dev-python/phonenumbers-9.0.24[${PYTHON_USEDEP}] >=dev-python/cryptography-50.0.0[${PYTHON_USEDEP}] >=dev-python/brevo-python-1.2.0:1[${PYTHON_USEDEP}] >=dev-python/celery-5.6.3[${PYTHON_USEDEP}] dev-python/redis[${PYTHON_USEDEP}] >=dev-python/django-countries-9.0.0[${PYTHON_USEDEP}] >=dev-python/django-filter-26.1[${PYTHON_USEDEP}] >=dev-python/django-lasuite-0.0.27[${PYTHON_USEDEP}] >=dev-python/celery-5.0[${PYTHON_USEDEP}] >=dev-python/django-configurations-2.5.1[${PYTHON_USEDEP}] >=dev-python/django-parler-2.4[${PYTHON_USEDEP}] >=dev-python/django-storages-1.14.6[${PYTHON_USEDEP}] >=dev-python/boto3-1.4.4[${PYTHON_USEDEP}] >=dev-python/django-pydantic-field-0.5.4[${PYTHON_USEDEP}] >=dev-python/drf-spectacular-0.30.0[${PYTHON_USEDEP}] >=dev-python/dockerflow-2026.3.4[${PYTHON_USEDEP}] >=dev-python/factory-boy-3.3.3[${PYTHON_USEDEP}] >=dev-python/nested-multipart-parser-1.6.0[${PYTHON_USEDEP}] >=dev-python/mozilla-django-oidc-5.0.2[${PYTHON_USEDEP}] >=dev-python/livekit-api-1.2.0[${PYTHON_USEDEP}] >=dev-python/django-extensions-4.2_pre20261031[${PYTHON_USEDEP}] >=dev-python/drf-spectacular-sidecar-2026.9.1[${PYTHON_USEDEP}] >=dev-python/freezegun-1.5.5[${PYTHON_USEDEP}] >=dev-python/joserfc-1.7.5[${PYTHON_USEDEP}]')" DEPEND="${RDEPEND}" BDEPEND=" net-libs/nodejs[npm] test? ( ${RDEPEND} dev-db/redis dev-db/postgresql )" EPYTEST_PLUGINS=( pytest-{django,cov} ) EPYTEST_DESELECT=( # Needs an s3 server core/tests/commands/test_clean_pending_files.py::test_clean_pending_files_recent_pending_not_deleted core/tests/commands/test_clean_pending_files.py::test_clean_pending_files_old_pending_deleted core/tests/commands/test_clean_pending_files.py::test_clean_pending_files_custom_hours core/tests/files/test_api_files_media_auth.py::test_api_files_media_get_own core/tests/files/test_api_files_media_auth.py::test_api_files_media_auth_own_file_deleted core/tests/files/test_api_files_media_auth.py::test_api_files_media_auth_custom_original_url_header core/tests/files/test_api_files_upload_ended.py::test_api_file_upload_ended_success core/tests/files/test_api_files_upload_ended.py::test_api_file_upload_ended_mimetype_not_allowed_not_checking_mimetype core/tests/files/test_api_files_upload_ended.py::test_api_upload_ended_mismatch_mimetype_with_object_storage core/tests/recording/test_api_recordings_media_auth.py::test_api_recordings_media_auth_success_owner core/tests/recording/test_api_recordings_media_auth.py::test_api_recordings_media_auth_success_administrator core/tests/commands/test_purge_deleted_files.py::test_purge_deleted_files_success core/tests/files/test_api_files_upload_ended.py::test_api_file_upload_ended_mimetype_not_allowed core/tests/files/test_api_files_upload_ended.py::test_api_upload_ended_file_size_exceeded core/tests/files/test_api_files_upload_ended.py::test_api_file_upload_ended_concurrent_calls_are_serialized # Works but expects French text instead of English core/tests/recording/event/test_notification.py::test_notify_user_by_email_success # Other core/tests/recording/event/test_notification.py::test_notify_summary_service_post_args_with_metadata core/tests/test_external_api_rooms.py::test_api_rooms_list_with_invalid_rs_token core/tests/test_external_api_rooms.py::test_api_rooms_retrieve_with_invalid_rs_token core/tests/test_external_api_rooms.py::test_api_rooms_create_with_invalid_rs_token ) distutils_enable_tests pytest src_unpack() { unpack "${P}.tar.gz" cd "${S}"/src/frontend unpack "${P}-frontend-deps.tar.xz" cd "${S}"/src/mail unpack "${P}-mail-deps.tar.xz" } src_compile() { cd "${S}"/src/frontend npm --offline --verbose run build || die "npm build failed" cd "${S}"/src/mail npm --offline --verbose run build || die "npm build failed" cd "${S}"/src/backend distutils-r1_src_compile export DJANGO_DATA_DIR="${WORKDIR}"/data "${EPYTHON}" manage.py collectstatic --noinput --clear || die } python_test() { cd "${S}"/src/backend # Tests expect a running redis server, so let's provide it exec 3< <(redis-server /dev/null) local redis_pid=$! # Wait until it's ready while IFS= read -r line <&3 || die "failed to start redis server"; do echo "$line" [[ "$line" =~ "Ready to accept connections" ]] && break done cat <&3 & # Same for postgres initdb -D "${WORKDIR}/pgdata" --username=dinum --pwfile=<(echo 'pass') --auth=trust --locale=C.UTF-8 || die printf "unix_socket_directories = '%s'\n" "${WORKDIR}" >> "${WORKDIR}"/pgdata/postgresql.conf pg_ctl -D "${WORKDIR}/pgdata" start || die local -x DJANGO_SETTINGS_MODULE=meet.settings local -x DJANGO_CONFIGURATION=Test local -x DJANGO_SECRET_KEY=DummyKey local -x REDIS_URL="redis://localhost:6379/1" local -x CELERY_BROKER_URL="redis://localhost:6379/0" local -x AWS_S3_ENDPOINT_URL="http://localhost:9000" local -x AWS_S3_ACCESS_KEY_ID=meet local -x AWS_S3_SECRET_ACCESS_KEY=meet-secret-access-key local -x AWS_S3_REGION_NAME=us-east-1 local -x OIDC_OP_JWKS_ENDPOINT="http://localhost:8083/realms/meet/protocol/openid-connect/certs" local -x OIDC_OP_TOKEN_ENDPOINT="http://localhost:8083/realms/meet/protocol/openid-connect/token" local -x OIDC_OP_USER_ENDPOINT="http://localhost:8083/realms/meet/protocol/openid-connect/userinfo" local -x OIDC_OP_INTROSPECTION_ENDPOINT="http://localhost:8083/realms/meet/protocol/openid-connect/token/introspect" nonfatal epytest local epytest_result=$? kill -INT $redis_pid wait $redis_pid pg_ctl -D "${WORKDIR}/pgdata" stop || die (( epytest_result == 0 )) || die "pytest failed with ${EPYTHON}" } src_install() { dodir /usr/share/"${PN}" cp -r src/frontend/dist "${ED}"/usr/share/"${PN}"/www cp -r "${WORKDIR}"/data/static "${ED}"/usr/share/"${PN}"/www/static chmod +x src/backend/manage.py python_fix_shebang src/backend/manage.py dodir /usr/libexec cp -r src/backend "${ED}"/usr/libexec/"${PN}" python_optimize "${ED}"/usr/libexec/"${PN}" dobin "${FILESDIR}/${PN}-manage" systemd_dounit "${FILESDIR}"/lasuite-meet.service insinto /etc/default insopts -m0600 newins "${FILESDIR}"/lasuite-meet.conf lasuite-meet exeinto /usr/libexec doexe "${FILESDIR}"/lasuite-meet-launch dodoc "${FILESDIR}"/Caddyfile }