freedombox Debian release 24.4

-----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCgA0FiEEfWrbdQ+RCFWJSEvmd8DHXntlCAgFAmXK4hQWHGp2YWxsZXJv
 eUBtYWlsYm94Lm9yZwAKCRB3wMdee2UICE3iD/47DgwgOFHyLGI6hL6GHrB0m529
 nZCM+RY9UMORhKvk/1i5PKgeFyIF1IrMXq8bBzrTkbRYtbuoQu3gxXmlaguLlvN1
 1NNCogaEIsic0EPZC0LG2d+Jwf1e+VUm6qDjRmSEl5HGmtCiUrAp3ueYX+kp80eL
 UllzQJIj+t4ogz1j07h89dZQ4hUBqle6Kr6SoRuhTMtjkF+H52YkmrwNh6p9c+oo
 ap4ihYkf3IkCrlUCnuupsvNpz63EnBeweMebhCiFim4YyyqXHQ0pMGrivsGONNMM
 6q6NYnrvmbtsdegccEngJY37yKznBgh22Gy2Eymddr403Og/pKVVzgqkAnxIYKQ7
 4LxEEb89rqodHd19hAPRT8LbajbpBb4vluMF/bNWw6N9oun9akN/730sk+WKmFSW
 skUffvFdWyqUxX4CmRV+vYXidhKDKRxy5DOvm/gymUGwAzXnASyWngzJwhQXYGBn
 3/hZg6ol3DDCDh+kZzqi4OWrzRPnl7nIsZre4S1cYRWfM3TUHJTTXKmFHl5o7Yly
 K7COBa+w0LuoA8aNYD0TpU6KMq0p7feN6h+2o7s5+oZLiM8hL8aiQgIF8QfBYhLf
 J8nqO+4aWO84fxifWsBv2v6fRFnZ85vS1YKJmbOOXb7p1N+wvfrVAE9xW2obgRJs
 MrlO2BWKw+3sdYPexQ==
 =niEJ
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCgA0FiEEfWrbdQ+RCFWJSEvmd8DHXntlCAgFAmXSKZoWHGp2YWxsZXJv
 eUBtYWlsYm94Lm9yZwAKCRB3wMdee2UICP0WEADSD1yyC8CkT32rZ4fyqIb3Uroi
 K5sou1WbkDyWBdgG1OWKotferX7rz0Gyr7TrQo7rJqnItikNWQfiE/zUfRhf3C4N
 Sq8eRAuQwnnC+uLaZ6czAc2jojbYjAxfg7CJztyzU4sA9pRh7wClvD1Qr7QfkyFe
 8cthNjh4Tt3n+4dHQwkku2rLfMcoU1SuSbWY001Fu0kX/DX0kJV1f+1QVM5ymfFb
 dnF//YSIIFtqJkXDOyhLg+MZ52dnuNsJM59MOex0JTbGqy4xqcZDkp5f41+mBuCo
 Lje1aZftjlMSPVFN5EKT0pmF3ZuVqHK9rPp8KD5mklOXi8yQCa+i1jWBnSHunhj9
 2ZNGEMaubXX2FuT0tXEzQ16O2r7H7aGb86ONE9DArSFcVL3yjPBz8ndwxXbUWOGf
 FAe7ttaIHg5wzFVH6vad7TfV4fEj0G3SPCKM/wnyd2xmEqLiW7hEMK76wp5gJBCy
 xXv9qbLsn44Bcivw526UYmitiR1/Fm5Resf5DEPnW/KGCvd8jDH4tPU+DHXLXJmr
 gxzJqU1YwRwgVeMUWsIAcfqW+QEwEfk1lbG915HfTnsMwUk9bNF1olM1wm/UWALg
 Mm9aUDgt8SFuKyC01zZ1Z47X7bflCHi5ZlaIl4pI/khtvQQyISkC725qF6WmuFVH
 mtTS6k6gUJl4kZN4WQ==
 =X3DH
 -----END PGP SIGNATURE-----

Merge tag 'v24.4' into debian/bookworm-backports

freedombox Debian release 24.4
This commit is contained in:
James Valleroy 2024-02-18 11:00:25 -05:00
commit b4db509204
66 changed files with 73762 additions and 76091 deletions

View File

@ -16,31 +16,25 @@ code-quality:
stage: test
needs: []
script:
- python3 -m flake8 container plinth actions/*
- make check-code
static-type-check:
stage: test
needs: []
before_script:
- apt-get update
- apt-get install -y mypy
script:
- mypy .
- make check-type
unit-tests:
stage: test
needs: []
before_script:
- export DEBIAN_FRONTEND=noninteractive
- apt-get update
- apt-get build-dep -y . # Dependencies of the freedombox Debian package
- apt-get install -y $(./run --list-dependencies) # Module dependencies
- make provision-dev
script:
- adduser tester --gecos "First Last,RoomNumber,WorkPhone,HomePhone" --disabled-password
- echo "tester:password" | chpasswd
- cp -r . /home/tester/plinth
- chown -R tester:tester /home/tester/plinth
- su -c "cd ~/plinth;PYTHONPATH='.' py.test-3 --cov=plinth --cov-report=html:/home/tester/plinth/htmlcov --cov-report=term" tester
- su -c "cd ~/plinth; make check-tests-cov" tester
- cp -r /home/tester/plinth/htmlcov test-coverage-report
coverage: '/^TOTAL\s+.*\s+(\d+\.\d+%)$/'
artifacts:
@ -51,7 +45,7 @@ doc-tests:
stage: test
needs: []
script:
- doc/scripts/wikiparser.py
- make check-doc
app-server-stable:
variables:

View File

@ -136,7 +136,7 @@ you will need to run the following to install those files properly on to the
system and their changes to reflect properly.
```bash
guest$ sudo ./setup.py install
guest$ sudo make build install
```
Note: This development container has automatic upgrades disabled by default.
@ -367,7 +367,7 @@ you will need to run the following to install those files properly on to the
system and their changes to reflect properly.
```bash
vm$ sudo ./setup.py install
vm$ sudo make build install
```
Note: This development virtual machine has automatic upgrades disabled by

View File

@ -24,7 +24,7 @@ FreedomBox [Manual](https://wiki.debian.org/FreedomBox/Manual/)'s
install FreedomBox Service (Plinth) itself.
```
$ sudo python3 setup.py install
$ sudo make build install
```
2. Run FreedomBox Service (Plinth):

193
Makefile Normal file
View File

@ -0,0 +1,193 @@
DJANGO_ADMIN := django-admin
INSTALL := install
PYTHON := python3
PYTEST_ARGS :=
CP_ARGS := --no-dereference --preserve=mode,timestamps --reflink=auto
ENABLED_APPS_PATH := $(DESTDIR)/usr/share/freedombox/modules-enabled
DISABLED_APPS_TO_REMOVE := \
apps \
coquelicot \
diaspora \
monkeysphere \
owncloud \
system \
xmpp \
disks \
udiskie \
restore \
repro \
tahoe \
mldonkey
APP_FILES_TO_REMOVE := $(foreach app,$(DISABLED_APPS_TO_REMOVE),$(ENABLED_APPS_PATH)/$(app))
REMOVED_FILES := \
$(DESTDIR)/etc/apt/preferences.d/50freedombox3.pref \
$(DESTDIR)/etc/apache2/sites-available/plinth.conf \
$(DESTDIR)/etc/apache2/sites-available/plinth-ssl.conf \
$(DESTDIR)/etc/security/access.d/10freedombox-performance.conf \
$(DESTDIR)/etc/security/access.d/10freedombox-security.conf
DIRECTORIES_TO_CREATE := \
$(DESTDIR)/var/lib/plinth \
$(DESTDIR)/var/lib/plinth/sessions
STATIC_FILES_DIRECTORY := $(DESTDIR)/usr/share/plinth/static
BIN_DIR := $(DESTDIR)/usr/bin
FIND_ARGS := \
-not -iname "*.log" \
-not -iname "*.pid" \
-not -iname "*.py.bak" \
-not -iname "*.pyc" \
-not -iname "*.pytest_cache" \
-not -iname "*.sqlite3" \
-not -iname "*.swp" \
-not -iname "\#*" \
-not -iname ".*" \
-not -iname "sessionid*" \
-not -iname "~*" \
-not -iname "django-secret.key"
ROOT_DATA_FILES := $(shell find data -type f $(FIND_ARGS))
MODULE_DATA_FILES := $(shell find $(wildcard plinth/modules/*/data) -type f $(FIND_ARGS))
update-translations:
cd plinth; $(DJANGO_ADMIN) makemessages --all --domain django --keep-pot --verbosity=1
configure:
# Nothing to do
build:
# Compile translations
$(DJANGO_ADMIN) compilemessages --verbosity=1
# Build documentation
$(MAKE) -C doc -j 8
# Build .whl package
$(PYTHON) -m build --no-isolation --skip-dependency-check --wheel
install:
# Drop removed apps
rm -f $(APP_FILES_TO_REMOVE)
# Drop removed configuration files
rm -f $(REMOVED_FILES)
# Create data directories
for directory in $(DIRECTORIES_TO_CREATE) ; do \
$(INSTALL) -d $$directory ; \
done
# Python package
temp=$$(mktemp -d) && \
lib_dir=$$($(PYTHON) -c 'import sysconfig; print(sysconfig.get_paths(scheme="deb_system")["purelib"])') && \
$(PYTHON) -m pip install dist/plinth-*.whl --break-system-packages \
--no-deps --no-compile --no-warn-script-location \
--ignore-installed --target=$${temp} && \
$(INSTALL) -d $(DESTDIR)$${lib_dir} && \
rm -rf $(DESTDIR)$${lib_dir}/plinth $(DESTDIR)$${lib_dir}/plinth*.dist-info && \
mv $${temp}/plinth $${temp}/plinth*.dist-info $(DESTDIR)$${lib_dir} && \
rm -f $(DESTDIR)$${lib_dir}/plinth*.dist-info/COPYING.md && \
rm -f $(DESTDIR)$${lib_dir}/plinth*.dist-info/direct_url.json && \
$(INSTALL) -D -t $(BIN_DIR) bin/plinth
# Actions
$(INSTALL) -D -t $(DESTDIR)/usr/share/plinth/actions actions/actions
# Static web server files
rm -rf $(STATIC_FILES_DIRECTORY)
$(INSTALL) -d $(STATIC_FILES_DIRECTORY)
cp $(CP_ARGS) --recursive static/* $(STATIC_FILES_DIRECTORY)
# System data files
for file in $(ROOT_DATA_FILES) ; do \
target=$$(dirname $(DESTDIR)$$(echo $${file} | sed -e 's|^data||')) ; \
$(INSTALL) --directory --mode=755 $${target} ; \
cp $(CP_ARGS) $${file} $${target} ; \
done
for file in $(MODULE_DATA_FILES) ; do \
target=$$(dirname $(DESTDIR)$$(echo $${file} | sed -e 's|^plinth/modules/[^/]*/data||')) ; \
$(INSTALL) --directory --mode=755 $${target} ; \
cp $(CP_ARGS) $${file} $${target} ; \
done
# Documentation
$(MAKE) -C doc install
check: check-type check-code check-doc check-tests
# Run the main test suite
check-tests:
$(PYTHON) -m pytest $(PYTEST_ARGS)
# Tests with coverage report
check-tests-cov:
$(PYTHON) -m pytest $(PYTEST_ARGS) --cov=plinth \
--cov-report=html:./htmlcov --cov-report=term
# Code quality checking using flake8
check-code:
$(PYTHON) -m flake8 plinth actions/actions container
# Static type checking using mypy
check-type:
$(PYTHON) -m mypy .
# Use doctest for check the wikiparser in doc directory
check-doc:
$(PYTHON) -m doctest doc/scripts/wikiparser.py
clean:
make -C doc clean
rm -rf Plinth.egg-info
find plinth/locale -name *.mo -delete
# Run basic setup for a developer environment (VM or container)
provision-dev:
# Install newer build dependencies if any
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get build-dep --yes .
# Install latest code over .deb
$(MAKE) build install
# Reload newer systemd units, ignore failure
-systemctl daemon-reload
# Stop any ongoing upgrade, ignore failure
-killall -9 unattended-upgr
# Fix any broken packages
dpkg --configure -a
apt-get -f install
apt-get update
# Install new packages needed by essential apps. Don't uninstall
# freedombox in case new dependencies conflict with old dependencies
apt-mark hold freedombox
DEBIAN_FRONTEND=noninteractive apt-get install --no-upgrade --yes \
$$(sudo -u plinth ./run --develop --list-dependencies)
apt-mark unhold freedombox
# Install additional packages
DEBIAN_FRONTEND=noninteractive apt-get install --yes ncurses-term \
sshpass bash-completion
.PHONY: \
build \
check \
check-code \
check-doc \
check-type \
check-tests \
check-tests-cov \
clean \
configure \
install \
provision \
update-translations

15
Vagrantfile vendored
View File

@ -23,19 +23,8 @@ Vagrant.configure(2) do |config|
SHELL
config.vm.provision "shell", inline: <<-SHELL
cd /freedombox/
./setup.py install
systemctl daemon-reload
# Stop any ongoing upgrade
killall -9 unattended-upgr
dpkg --configure -a
apt -f install
apt-get update
# In case new dependencies conflict with old dependencies
apt-mark hold freedombox
DEBIAN_FRONTEND=noninteractive apt-get install --no-upgrade -y $(sudo -u plinth ./run --develop --list-dependencies)
apt-mark unhold freedombox
# Install ncurses-term
DEBIAN_FRONTEND=noninteractive apt-get install -y ncurses-term
make provision-dev
echo 'alias freedombox-develop="cd /freedombox; sudo -u plinth /freedombox/run --develop"' >> /home/vagrant/.bashrc
SHELL
config.vm.provision "tests", run: "never", type: "shell", path: "plinth/tests/functional/install.sh"

View File

@ -1,9 +0,0 @@
#!/usr/bin/python3
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Legacy configuration helper for Dynamic DNS, kept for compatibility.
Cron jobs in the earlier implementation used to call into this script with the
sub-commands 'update' and 'success'. This action script now allows for any
arbitrary sub-command to be called and does nothing. It can be removed after
the release of Debian 12 (bookworm).
"""

View File

@ -1,9 +0,0 @@
#!/usr/bin/python3
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Legacy configuration helper for Let's Encrypt, kept for compatibility.
LE configuration in the earlier implementation used to call into this script
with the sub-commands 'run-pre-hooks', 'run-renew-hooks' and 'run-post-hooks'.
This action script now allows for any arbitrary sub-command to be called and
does nothing. It can be removed after the release of Debian 12 (bookworm).
"""

View File

@ -1,10 +0,0 @@
#!/usr/bin/python3
# -*- mode: python -*-
# SPDX-License-Identifier: AGPL-3.0-or-later
"""
Helper to test whether action scripts use the correct PYTHONPATH.
"""
import plinth
print(plinth.__file__)

View File

@ -7,7 +7,6 @@ import importlib
import os
import pathlib
import sys
from unittest.mock import patch
import pytest

View File

@ -159,24 +159,7 @@ set -xe pipefail
cd /freedombox/
sudo apt-get update
if [ $(lsb_release --release --short) != '10' ]; then
sudo DEBIAN_FRONTEND=noninteractive apt-get build-dep \
--no-install-recommends --yes .
fi
sudo ./setup.py install
sudo systemctl daemon-reload
# In case new dependencies conflict with old dependencies
sudo apt-mark hold freedombox
sudo DEBIAN_FRONTEND=noninteractive apt-get install --no-upgrade --yes \
$(sudo -u plinth /freedombox/run --develop --list-dependencies)
sudo apt-mark unhold freedombox
# Install additional packages
sudo DEBIAN_FRONTEND=noninteractive apt-get install --yes ncurses-term \
sshpass bash-completion
sudo make provision-dev
echo 'alias freedombox-develop="cd /freedombox; sudo -u plinth /freedombox/run --develop"' \
>> /home/fbx/.bashrc

134
debian/changelog vendored
View File

@ -1,3 +1,137 @@
freedombox (24.4) unstable; urgency=medium
[ Johannes Keyser ]
* Translated using Weblate (German)
[ Burak Yavuz ]
* Translated using Weblate (Turkish)
[ 大王叫我来巡山 ]
* Translated using Weblate (Chinese (Simplified))
[ bittin1ddc447d824349b2 ]
* Translated using Weblate (Swedish)
[ Ihor Hordiichuk ]
* Translated using Weblate (Ukrainian)
[ gallegonovato ]
* Translated using Weblate (Spanish)
[ Faraaz M.d ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ Kesava Manikanta ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ SAI MANIKANTA ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ Soumika Devarakonda ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ Sarath Chandra ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ Latheesh kumar ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ Vijay Gopu ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ Mahi Reddy ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ Nistchal sri ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ Likhil Chowdary ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ Sri Harsha ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ Muntha Veera ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ Aswith Varma ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ visruth vardhan thokala ]
* Translated using Weblate (Telugu)
[ Bhavishya nitha ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ ABHI RAM POTNURU ]
* Translated using Weblate (Telugu)
[ VINAY K.V.N.S ]
* Translated using Weblate (Telugu)
* Translated using Weblate (Telugu)
[ M Jagadeesh ]
* Translated using Weblate (Telugu)
[ Sreehitha Velivela ]
* Translated using Weblate (Telugu)
[ James Valleroy ]
* Translated using Weblate (Telugu)
* debian: Remove lintian override for init script
* locale: Update translation strings
* doc: Fetch latest manual
[ Dietmar ]
* Translated using Weblate (German)
[ Sunil Mohan Adapa ]
* Translated using Weblate (Telugu)
* d/copyright: Update copyright year
* help: tests: Run tests using doc in current dir instead of /usr
* actions: Drop legacy placeholders for unused actions
* doc: Install man1 page using Makefile
* pyproject.toml: Move project meta data from setup.py
* *: Introduce make file based build, eliminate setup.py
* doc: dev: Update all references to setup.py
* Makefile: Move most of the provision process into build system
* Makefile: Move various tests into build system
[ Besnik Bleta ]
* Translated using Weblate (Albanian)
* Translated using Weblate (Albanian)
-- James Valleroy <jvalleroy@mailbox.org> Mon, 12 Feb 2024 21:24:20 -0500
freedombox (24.3~bpo12+1) bookworm-backports; urgency=medium
* Rebuild for bookworm-backports.

5
debian/control vendored
View File

@ -18,10 +18,12 @@ Build-Depends:
e2fsprogs,
gir1.2-nm-1.0,
libjs-bootstrap4,
pybuild-plugin-pyproject,
python3-all:any,
python3-apt,
python3-augeas,
python3-bootstrapform,
python3-build,
python3-cherrypy3,
python3-configobj,
python3-dbus,
@ -35,9 +37,11 @@ Build-Depends:
python3-flake8,
python3-gi,
python3-markupsafe,
python3-mypy,
python3-openssl,
python3-pampy,
python3-paramiko,
python3-pip,
python3-psutil,
python3-pytest,
python3-pytest-cov,
@ -49,6 +53,7 @@ Build-Depends:
python3-setuptools-git,
# python3-tomli is not available in Bullseye
python3-tomli | python3-coverage (<< 6.0),
python3-typeshed,
python3-yaml,
sshpass,
xmlto,

4
debian/copyright vendored
View File

@ -2,7 +2,7 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: https://salsa.debian.org/freedombox-team/freedombox
Files: *
Copyright: 2011-2023 FreedomBox Authors
Copyright: 2011-2024 FreedomBox Authors
License: AGPL-3+
Files: plinth/modules/jsxc/static/icons/jsxc.png
@ -317,7 +317,7 @@ License: OFL-1.1
Files: debian/*
Copyright: 2013 Tzafrir Cohen
2013-2023 FreedomBox Authors
2013-2024 FreedomBox Authors
License: GPL-2+
License: AGPL-3+

View File

@ -16,11 +16,6 @@ freedombox binary: non-standard-apache2-configuration-name *
# that requires significant effort.
freedombox binary: web-application-works-only-with-apache
# FreedomBox adds systemd security features for other daemons in Debian. There
# is no equivalent for this in sysvinit. Sometimes, FreedomBox provide service
# files for packages that do not provide them. FreedomBox does not support
# sysvinit so no init.d equivalent is provided.
freedombox: package-supports-alternative-init-but-no-init.d-script [usr/lib/systemd/system/*]
# Not documentation
freedombox: package-contains-documentation-outside-usr-share-doc [usr/share/plinth/static/jslicense.html]
freedombox: package-contains-documentation-outside-usr-share-doc [usr/lib/python3/dist-packages/plinth-*.dist-info/top_level.txt]

13
debian/rules vendored
View File

@ -2,6 +2,12 @@
export DH_VERBOSE=1
export PYBUILD_DESTDIR=debian/tmp
export PYBUILD_SYSTEM=custom
export PYBUILD_CONFIGURE_ARGS=make configure
export PYBUILD_BUILD_ARGS=make PYTHON={interpreter} build
export PYBUILD_INSTALL_ARGS=make PYTHON={interpreter} DESTDIR={destdir} install
export PYBUILD_CLEAN_ARGS=make clean
export PYBUILD_TEST_ARGS=make PYTHON={interpreter} check-tests
%:
dh $@ --with python3 --buildsystem=pybuild
@ -13,13 +19,6 @@ override_dh_auto_install-indep:
# Ensure the list of dependencies is not empty.
test -s debian/freedombox.substvars || exit 1
# pybuild can run pytest. However, when the top level directory is included in
# the path (done using manage.py), it results in import problems.
# https://www.mail-archive.com/debian-python@lists.debian.org/msg17997.html
override_dh_auto_test:
PYBUILD_SYSTEM=custom \
PYBUILD_TEST_ARGS="{interpreter} -m pytest" dh_auto_test
override_dh_installsystemd:
# Do not enable or start any service other than FreedomBox service. Use
# of --tmpdir is a hack to workaround an issue with dh_installsystemd

View File

@ -1,21 +1,19 @@
#!/usr/bin/make -f
# SPDX-License-Identifier: AGPL-3.0-or-later
OUTPUTS=freedombox-manual.pdf plinth.1 manual-pages
MANUAL_LANGUAGES=en es
MANUAL_URL="https://wiki.debian.org/{lang-fragment}FreedomBox/Manual?action=show&mimetype=text%2Fdocbook"
MANUAL_URL_RAW="https://wiki.debian.org/{lang-fragment}FreedomBox/Manual?action=raw"
MANUAL_PAGE_URL_RAW="https://wiki.debian.org/{page}?action=raw"
DESTDIR=
INSTALL_DIR=$(DESTDIR)/usr/share/freedombox
MAN_INSTALL_DIR=$(DESTDIR)/usr/share/man
SCRIPTS_DIR=scripts
manual-pdfs=$(foreach lang,$(MANUAL_LANGUAGES),manual/$(lang)/freedombox-manual.pdf)
manual-xmls=$(patsubst %.pdf,%.xml,$(manual-pdfs))
OUTPUTS=$(manual-pdfs) plinth.1 manual-pages
OUTPUTS=$(manual-pdfs) plinth.1
INSTALL_OPTS=-D --mode=644
@ -32,9 +30,10 @@ ifneq ($(DEBUG),)
endif
.PHONY: all install
all: $(OUTPUTS)
all: $(OUTPUTS) manual-pages
install: all
install $(INSTALL_OPTS) -t $(MAN_INSTALL_DIR)/man1 plinth.1
for file in $(manual-pages-part-html) $(manual-pdfs); do \
install $(INSTALL_OPTS) -t $(INSTALL_DIR)/$$(dirname $${file}) \
$${file} ; \
@ -67,7 +66,7 @@ fetch: $(fetch-main-list) $(fetch-pages-list)
# Remove raw wiki pages and images before fetching to drop items deleted
# upstream.
featch-cleanup-%: lang = $*
fetch-cleanup-%: lang = $*
$(fetch-cleanup-list): fetch-cleanup-%:
rm -f manual/$(lang)/*.raw.wiki
rm -f manual/$(lang)/images/*.png manual/$(lang)/images/*.jpg

View File

@ -40,11 +40,11 @@ in a step-by-step manner::
The file ``__init__.py`` indicates that the directory in which it is present is
a Python module. For now, it is an empty file.
FreedomBox's setup script ``setup.py`` will automatically install the
FreedomBox's build system will automatically install the
``plinth/modules/transmission`` directory (along with other files described
later) to an appropriate location. If you are creating an app that stays
independent and outside of FreedomBox source tree, then ``setup.py`` script in
your source tree will need to install it to a proper location on the system. The
independent and outside of FreedomBox source tree, then build system in your
source tree will need to install it to a proper location on the system. The
``plinth/modules/`` directory is a Python3 `namespace package
<https://www.python.org/dev/peps/pep-0420/>`_. So, you can install it with the
``plinth/modules/`` directory structure into any Python path and still be
@ -64,12 +64,11 @@ us create this file ``transmission``:
plinth.modules.transmission
This file is automatically installed to
``/usr/share/freedombox/modules-enabled/`` by FreedomBox's installation script
``setup.py``. If we are writing a module that resides independently outside the
FreedomBox's source code, the setup script will need to copy it to the target
location. Further, it is not necessary for the app to be part of the
``plinth.modules`` namespace. It can, for example, be
``freedombox_transmission``.
``/usr/share/freedombox/modules-enabled/`` by FreedomBox's build system. If we
are writing a module that resides independently outside the FreedomBox's source
code, the setup script will need to copy it to the target location. Further, it
is not necessary for the app to be part of the ``plinth.modules`` namespace. It
can, for example, be ``freedombox_transmission``.
Creating the App class
^^^^^^^^^^^^^^^^^^^^^^

View File

@ -8,6 +8,25 @@ For more technical details, see the [[https://salsa.debian.org/freedombox-team/f
The following are the release notes for each !FreedomBox version.
== FreedomBox 24.4 (2024-02-12) ==
=== Highlights ===
* locale: Update translations for Albanian, Chinese (Simplified), German, Spanish, Swedish, Telugu, Turkish, Ukrainian
=== Other Changes ===
* *: Introduce make file based build, eliminate setup.py
* Makefile: Move most of the provision process into build system
* Makefile: Move various tests into build system
* actions: Drop legacy placeholders for unused actions
* d/copyright: Update copyright year
* debian: Remove lintian override for init script
* doc: Install man1 page using Makefile
* doc: dev: Update all references to setup.py
* help: tests: Run tests using doc in current dir instead of /usr
* pyproject.toml: Move project meta data from setup.py
== FreedomBox 24.3 (2024-01-29) ==
=== Highlights ===

View File

@ -22,7 +22,7 @@ Shaarli is personal (single-user) bookmarking application to install on your !Fr
=== External links ===
* Usage documentation: https://shaarli.readthedocs.io/en/master/Usage/
* Usage documentation: https://shaarli.readthedocs.io/en/master/Usage.html
## END_INCLUDE

View File

@ -8,6 +8,25 @@ For more technical details, see the [[https://salsa.debian.org/freedombox-team/f
The following are the release notes for each !FreedomBox version.
== FreedomBox 24.4 (2024-02-12) ==
=== Highlights ===
* locale: Update translations for Albanian, Chinese (Simplified), German, Spanish, Swedish, Telugu, Turkish, Ukrainian
=== Other Changes ===
* *: Introduce make file based build, eliminate setup.py
* Makefile: Move most of the provision process into build system
* Makefile: Move various tests into build system
* actions: Drop legacy placeholders for unused actions
* d/copyright: Update copyright year
* debian: Remove lintian override for init script
* doc: Install man1 page using Makefile
* doc: dev: Update all references to setup.py
* help: tests: Run tests using doc in current dir instead of /usr
* pyproject.toml: Move project meta data from setup.py
== FreedomBox 24.3 (2024-01-29) ==
=== Highlights ===

View File

@ -3,4 +3,4 @@
Package init file.
"""
__version__ = '24.3'
__version__ = '24.4'

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -89,8 +89,8 @@ def _get_modules_enabled_files_to_read():
if module_files:
return module_files.values()
# './setup.py install' has not been executed yet. Pickup files to load
# from local module directories.
# 'make build install' has not been executed yet. Pickup files to load from
# local module directories.
directory = pathlib.Path(__file__).parent
glob_pattern = 'modules/*/data/usr/share/freedombox/modules-enabled/*'
return list(directory.glob(glob_pattern))
@ -124,7 +124,7 @@ def get_module_import_path(module_name: str) -> str:
import_path_file = None
if not import_path_file:
# './setup.py install' has not been executed yet. Pickup files to load
# 'make build install' has not been executed yet. Pickup files to load
# from local module directories.
directory = pathlib.Path(__file__).parent
import_path_file = (directory /

View File

@ -19,7 +19,7 @@ from django import urls
from django.conf import settings
from django.http import Http404
from plinth import module_loader
from plinth import cfg, module_loader
from plinth.modules.help import views
# For all tests, use plinth.urls instead of urls configured for testing
@ -42,6 +42,12 @@ def fixture_app_urls():
yield
@pytest.fixture(autouse=True, scope='module')
def fixture_developer_configuration():
"""Make sure docs are read from current directory instead of /usr."""
cfg.read_file(cfg.get_develop_config_path())
@pytest.mark.parametrize("view_name, view", (
('feedback', views.feedback),
('support', views.support),

View File

@ -1,3 +1,122 @@
[project]
name = "plinth"
description = "A web front end for administering FreedomBox"
license = {file = "COPYING.md"}
dynamic = ["version"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: No Input/Output (Daemon)",
"Environment :: Web Environment",
"Framework :: Django",
"Intended Audience :: End Users/Desktop",
"License :: DFSG approved",
"License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
"Natural Language :: English",
"Operating System :: POSIX :: Linux",
"Programming Language :: JavaScript",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Topic :: Communications",
"Topic :: Communications :: Chat",
"Topic :: Communications :: Chat :: Internet Relay Chat",
"Topic :: Communications :: Conferencing",
"Topic :: Communications :: Email",
"Topic :: Communications :: Email :: Filters",
"Topic :: Communications :: Email :: Mail Transport Agents",
"Topic :: Communications :: Email :: Post-Office",
"Topic :: Communications :: Email :: Post-Office :: IMAP",
"Topic :: Communications :: Email :: Post-Office :: POP3",
"Topic :: Communications :: File Sharing",
"Topic :: Internet",
"Topic :: Internet :: Name Service (DNS)",
"Topic :: Internet :: Proxy Servers",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content :: News/Diary",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Wiki",
"Topic :: Internet :: WWW/HTTP :: HTTP Servers",
"Topic :: Internet :: WWW/HTTP :: Indexing/Search",
"Topic :: Internet :: WWW/HTTP :: WSGI",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
"Topic :: Internet :: XMPP",
"Topic :: Office/Business",
"Topic :: Office/Business :: Scheduling",
"Topic :: Security",
"Topic :: Software Development :: Version Control",
"Topic :: Software Development :: Version Control :: Git",
"Topic :: System",
"Topic :: System :: Archiving",
"Topic :: System :: Archiving :: Backup",
"Topic :: System :: Distributed Computing",
"Topic :: System :: Filesystems",
"Topic :: System :: Installation/Setup",
"Topic :: System :: Networking",
"Topic :: System :: Networking :: Firewalls",
"Topic :: System :: Networking :: Time Synchronization",
"Topic :: System :: Operating System",
"Topic :: System :: Software Distribution",
"Topic :: System :: Systems Administration",
"Topic :: System :: Systems Administration :: Authentication/Directory",
"Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP",
"Topic :: System :: System Shells",
]
dependencies = [
"cherrypy >= 3.0",
"configobj",
"django >= 1.11.0",
"django-bootstrap-form",
"django-simple-captcha",
"django-stronghold >= 0.3.0",
"psutil",
"python-apt",
"python-augeas",
"requests",
"ruamel.yaml",
]
[[project.authors]]
name = "FreedomBox Authors"
email = "freedombox-discuss@lists.alioth.debian.org"
[project.optional-dependencies]
test = [
"pytest",
"pytest-cov",
"pytest-django",
"flake8",
"requests",
"tomli",
]
[project.urls]
homepage = "https://freedombox.org"
projectpage = "https://salsa.debian.org/freedombox-team/freedombox"
manual = "https://wiki.debian.org/FreedomBox/Manual/"
documentation = "https://docs.freedombox.org/"
changelog = "https://salsa.debian.org/freedombox-team/freedombox/-/blob/master/debian/changelog"
readme = "https://salsa.debian.org/freedombox-team/freedombox/-/blob/master/README.md"
support = "https://freedombox.org/#community"
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project.scripts]
plinth = "plinth.__main__:main"
[tool.setuptools.dynamic]
version = {attr = "plinth.__version__"}
[tool.setuptools.packages.find]
include = ["plinth", "plinth.*"]
[tool.setuptools.package-data]
"*" = ["templates/*", "static/**", "locale/*/LC_MESSAGES/*.mo"]
[tool.setuptools.exclude-package-data]
"*" = ["*/data/*"]
[tool.isort]
known_first_party = ["plinth"]

337
setup.py
View File

@ -1,337 +0,0 @@
#!/usr/bin/python3
# SPDX-License-Identifier: AGPL-3.0-or-later
"""
FreedomBox Service setup file.
isort:skip_file
"""
import collections
import glob
import os
import pathlib
import re
import shutil
import subprocess
import setuptools
from setuptools.command.install import install
from distutils import log
from distutils.command.build import build
from distutils.command.clean import clean
from distutils.command.install_data import install_data
from distutils.core import Command
from distutils.dir_util import remove_tree
from distutils.util import change_root
from plinth import __version__
DIRECTORIES_TO_CREATE = [
'/var/lib/plinth',
'/var/lib/plinth/sessions',
]
DIRECTORIES_TO_COPY = [
('/usr/share/plinth/static', 'static'),
]
ENABLED_APPS_PATH = "/usr/share/freedombox/modules-enabled/"
DISABLED_APPS_TO_REMOVE = [
'apps',
'coquelicot',
'diaspora',
'monkeysphere',
'owncloud',
'system',
'xmpp',
'disks',
'udiskie',
'restore',
'repro',
'tahoe',
'mldonkey',
]
REMOVED_FILES = [
'/etc/apt/preferences.d/50freedombox3.pref',
'/etc/apache2/sites-available/plinth.conf',
'/etc/apache2/sites-available/plinth-ssl.conf',
'/etc/security/access.d/10freedombox-performance.conf',
'/etc/security/access.d/10freedombox-security.conf',
]
LOCALE_PATHS = ['plinth/locale']
class DjangoCommand(Command):
"""Setup command to run a Django management command."""
user_options: list = []
def initialize_options(self):
"""Declare the options for this command."""
pass
def finalize_options(self):
"""Declare options dependent on others."""
pass
def run(self):
"""Execute the command."""
import django
from django.conf import settings
settings.configure(LOCALE_PATHS=LOCALE_PATHS)
django.setup()
# Trick the commands to use the settings properly
os.environ['DJANGO_SETTINGS_MODULE'] = 'x-never-used'
class CompileTranslations(DjangoCommand):
"""New command to compile .po translation files."""
description = "compile .po translation files into .mo files" ""
def run(self):
"""Execute the command."""
DjangoCommand.run(self)
from django.core.management import call_command
call_command('compilemessages', verbosity=1)
class UpdateTranslations(DjangoCommand):
"""New command to update .po translation files."""
description = "update .po translation files from source code" ""
def run(self):
"""Execute the command."""
DjangoCommand.run(self)
from django.core.management import call_command
call_command('makemessages', all=True, domain='django', keep_pot=True,
verbosity=1)
class CustomBuild(build):
"""Override build command to add a subcommand for translations."""
sub_commands = [('compile_translations', None)] + build.sub_commands
class CustomClean(clean):
"""Override clean command to clean doc, locales, and egg-info."""
def run(self):
"""Execute clean command"""
subprocess.check_call(['rm', '-rf', 'Plinth.egg-info/'])
subprocess.check_call(['make', '-C', 'doc', 'clean'])
for dir_path, dir_names, file_names in os.walk('plinth/locale/'):
for file_name in file_names:
if file_name.endswith('.mo'):
file_path = os.path.join(dir_path, file_name)
log.info("removing '%s'", file_path)
subprocess.check_call(['rm', '-f', file_path])
clean.run(self)
class CustomInstall(install):
"""Override install command."""
def run(self):
for app in DISABLED_APPS_TO_REMOVE:
file_path = pathlib.Path(ENABLED_APPS_PATH) / app
if file_path.exists():
log.info("removing '%s'", str(file_path))
subprocess.check_call(['rm', '-f', str(file_path)])
for path in REMOVED_FILES:
if pathlib.Path(path).exists():
log.info('removing %s', path)
subprocess.check_call(['rm', '-f', path])
install.run(self)
class CustomInstallData(install_data):
"""Override install command to allow directory creation and copy"""
def _run_doc_install(self):
"""Install documentation"""
command = ['make', '-j', '8', '-C', 'doc', 'install']
if self.root:
root = os.path.abspath(self.root)
command.append(f'DESTDIR={root}')
subprocess.check_call(command)
def run(self):
"""Execute install command"""
self._run_doc_install()
install_data.run(self) # Old style base class
# Create empty directories
for directory in DIRECTORIES_TO_CREATE:
if self.root:
directory = change_root(self.root, directory)
if not os.path.exists(directory):
log.info("creating directory '%s'", directory)
os.makedirs(directory)
# Recursively overwrite directories
for target, source in DIRECTORIES_TO_COPY:
if self.root:
target = change_root(self.root, target)
if os.path.exists(target):
remove_tree(target)
log.info("recursive copy '%s' to '%s'", source, target)
shutil.copytree(source, target, symlinks=True)
def _ignore_data_file(file_name):
"""Ignore common patterns in data files and directories."""
ignore_patterns = [
r'\.log$', r'\.pid$', r'\.py.bak$', r'\.pyc$', r'\.pytest_cache$',
r'\.sqlite3$', r'\.swp$', r'^#', r'^\.', r'^__pycache__$',
r'^sessionid\w*$', r'~$', r'django-secret.key'
]
for pattern in ignore_patterns:
if re.match(pattern, file_name):
return True
return False
def _gather_data_files():
"""Return a list data files are required by setuptools.setup().
- Automatically infer the target directory by looking at the relative path
of a file.
- Allow each app to have it's own folder for data files.
- Ignore common backup files.
"""
data_files = collections.defaultdict(list)
crawl_directories = ['data']
with os.scandir('plinth/modules/') as iterator:
for entry in iterator:
if entry.is_dir():
crawl_directories.append(os.path.join(entry.path, 'data'))
for crawl_directory in crawl_directories:
crawl_directory = crawl_directory.rstrip('/')
for path, _, file_names in os.walk(crawl_directory):
target_directory = path[len(crawl_directory):]
if _ignore_data_file(os.path.basename(path)):
continue
for file_name in file_names:
if _ignore_data_file(file_name):
continue
data_files[target_directory].append(
os.path.join(path, file_name))
return list(data_files.items())
find_packages = setuptools.PEP420PackageFinder.find
setuptools.setup(
name='Plinth',
version=__version__,
description='A web front end for administering FreedomBox',
author='FreedomBox Authors',
author_email='freedombox-discuss@lists.alioth.debian.org',
url='https://freedombox.org',
packages=find_packages(include=['plinth', 'plinth.*'],
exclude=['*.templates']),
scripts=['bin/plinth'],
license='COPYING.md',
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Framework :: Django',
'Intended Audience :: End Users/Desktop',
'License :: DFSG approved',
'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)',
'Natural Language :: English',
'Operating System :: POSIX :: Linux',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Unix Shell',
'Topic :: Communications',
'Topic :: Communications :: Chat',
'Topic :: Communications :: Chat :: Internet Relay Chat',
'Topic :: Communications :: File Sharing',
'Topic :: Internet',
'Topic :: Internet :: Name Service (DNS)'
'Topic :: Internet :: Proxy Servers',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Wiki',
'Topic :: Internet :: WWW/HTTP :: WSGI',
'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
'Topic :: Office/Business',
'Topic :: Office/Business :: Scheduling',
'Topic :: Security',
'Topic :: System'
'Topic :: System :: Archiving',
'Topic :: System :: Archiving :: Backup',
'Topic :: System :: Distributed Computing'
'Topic :: System :: Filesystems',
'Topic :: System :: Installation/Setup',
'Topic :: System :: Networking',
'Topic :: System :: Networking :: Firewalls',
'Topic :: System :: Operating System',
'Topic :: System :: Software Distribution'
'Topic :: System :: Systems Administration',
'Topic :: System :: Systems Administration :: Authentication/Directory',
'Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP ',
'Topic :: System :: System Shells',
],
setup_requires=['pytest-runner', 'setuptools-git'],
install_requires=[
'cherrypy >= 3.0',
'configobj',
'django >= 1.11.0',
'django-bootstrap-form',
'django-simple-captcha',
'django-stronghold >= 0.3.0',
'psutil',
'python-apt',
'python-augeas',
'requests',
'ruamel.yaml',
],
tests_require=[
'pytest',
'pytest-cov',
'pytest-django',
'flake8',
'requests',
'tomli',
],
package_data={
'': ['templates/*', 'static/**', 'locale/*/LC_MESSAGES/*.mo']
},
exclude_package_data={'': ['*/data/*']},
data_files=_gather_data_files() +
[('/usr/share/plinth/actions', glob.glob(os.path.join('actions',
'[a-z]*'))),
('/usr/share/man/man1', ['doc/plinth.1'])],
cmdclass={
'install': CustomInstall,
'build': CustomBuild,
'clean': CustomClean,
'compile_translations': CompileTranslations,
'install_data': CustomInstallData,
'update_translations': UpdateTranslations,
},
)