diff --git a/plinth/app.py b/plinth/app.py
index 63f0b4e4d..727db85db 100644
--- a/plinth/app.py
+++ b/plinth/app.py
@@ -552,7 +552,7 @@ def _initialize_module(module_name, module):
cls for _, cls in module_classes if issubclass(cls, App)
]
for app_class in app_classes:
- module.app = app_class()
+ app_class()
except Exception as exception:
logger.exception('Exception while running init for %s: %s', module,
exception)
diff --git a/plinth/modules/apache/__init__.py b/plinth/modules/apache/__init__.py
index 6d3e56158..ca567090e 100644
--- a/plinth/modules/apache/__init__.py
+++ b/plinth/modules/apache/__init__.py
@@ -15,8 +15,6 @@ from plinth.modules.letsencrypt.components import LetsEncrypt
from plinth.package import Packages
from plinth.utils import format_lazy, is_valid_user_name
-app = None
-
class ApacheApp(app_module.App):
"""FreedomBox app for Apache web server."""
diff --git a/plinth/modules/avahi/__init__.py b/plinth/modules/avahi/__init__.py
index 7c2d9b96f..f06bbf271 100644
--- a/plinth/modules/avahi/__init__.py
+++ b/plinth/modules/avahi/__init__.py
@@ -32,8 +32,6 @@ _description = [
'hostile local network.'), box_name=_(cfg.box_name))
]
-app = None
-
class AvahiApp(app_module.App):
"""FreedomBox app for Avahi."""
diff --git a/plinth/modules/backups/__init__.py b/plinth/modules/backups/__init__.py
index 34bdb79ad..0583af152 100644
--- a/plinth/modules/backups/__init__.py
+++ b/plinth/modules/backups/__init__.py
@@ -31,8 +31,6 @@ MANIFESTS_FOLDER = '/var/lib/plinth/backups-manifests/'
# session variable name that stores when a backup file should be deleted
SESSION_PATH_VARIABLE = 'fbx-backups-upload-path'
-app = None
-
class BackupsApp(app_module.App):
"""FreedomBox app for backup and restore."""
diff --git a/plinth/modules/backups/views.py b/plinth/modules/backups/views.py
index feb9b0fbe..4cb7fbfc0 100644
--- a/plinth/modules/backups/views.py
+++ b/plinth/modules/backups/views.py
@@ -20,6 +20,7 @@ from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy
from django.views.generic import FormView, TemplateView, View
+from plinth import app as app_module
from plinth.errors import PlinthError
from plinth.modules import backups, storage
@@ -40,7 +41,7 @@ class IndexView(TemplateView):
def get_context_data(self, **kwargs):
"""Return additional context for rendering the template."""
context = super().get_context_data(**kwargs)
- context['app_info'] = backups.app.info
+ context['app_info'] = app_module.App.get('backups').info
context['repositories'] = [
repository.get_view_content() for repository in get_repositories()
]
diff --git a/plinth/modules/bepasty/__init__.py b/plinth/modules/bepasty/__init__.py
index f1fda08f3..e97e8caf9 100644
--- a/plinth/modules/bepasty/__init__.py
+++ b/plinth/modules/bepasty/__init__.py
@@ -32,8 +32,6 @@ _description = [
'their password from the list.'),
]
-app = None
-
PERMISSIONS = {
'read': _('Read a file, if a web link to the file is available'),
'create': _('Create or upload files'),
diff --git a/plinth/modules/bind/__init__.py b/plinth/modules/bind/__init__.py
index ec267fe31..ff61d51f4 100644
--- a/plinth/modules/bind/__init__.py
+++ b/plinth/modules/bind/__init__.py
@@ -58,8 +58,6 @@ listen-on-v6 { any; };
};
'''
-app = None
-
class BindApp(app_module.App):
"""FreedomBox app for Bind."""
diff --git a/plinth/modules/calibre/__init__.py b/plinth/modules/calibre/__init__.py
index dcfcc9828..93aeb164d 100644
--- a/plinth/modules/calibre/__init__.py
+++ b/plinth/modules/calibre/__init__.py
@@ -36,8 +36,6 @@ _description = [
'the app. All users with access can use all the libraries.')
]
-app = None
-
LIBRARY_NAME_PATTERN = r'[a-zA-Z0-9 _-]+'
diff --git a/plinth/modules/calibre/tests/test_views.py b/plinth/modules/calibre/tests/test_views.py
index 24ede010d..d1ee16747 100644
--- a/plinth/modules/calibre/tests/test_views.py
+++ b/plinth/modules/calibre/tests/test_views.py
@@ -100,7 +100,7 @@ def test_create_library_invalid_name(rf):
assert response.status_code == 200
-@patch('plinth.modules.calibre.app')
+@patch('plinth.app.App.get')
def test_delete_library_confirmation_view(_app, rf):
"""Test that deleting library confirmation shows correct name."""
response, _ = make_request(rf.get(''), views.delete_library,
@@ -110,7 +110,7 @@ def test_delete_library_confirmation_view(_app, rf):
@patch('plinth.modules.calibre.delete_library')
-@patch('plinth.modules.calibre.app')
+@patch('plinth.app.App.get')
def test_delete_library(_app, delete_library, rf):
"""Test that deleting a library works."""
response, messages = make_request(rf.post(''), views.delete_library,
diff --git a/plinth/modules/calibre/views.py b/plinth/modules/calibre/views.py
index 7e52b09c6..d8a9e6e5b 100644
--- a/plinth/modules/calibre/views.py
+++ b/plinth/modules/calibre/views.py
@@ -12,7 +12,9 @@ from django.urls import reverse_lazy
from django.utils.translation import gettext as _
from django.views.generic.edit import FormView
-from plinth import actions, views
+from plinth import actions
+from plinth import app as app_module
+from plinth import views
from plinth.modules import calibre
from . import forms
@@ -70,6 +72,6 @@ def delete_library(request, name):
return redirect(reverse_lazy('calibre:index'))
return TemplateResponse(request, 'calibre-delete-library.html', {
- 'title': calibre.app.info.name,
+ 'title': app_module.App.get('calibre').info.name,
'name': name
})
diff --git a/plinth/modules/cockpit/__init__.py b/plinth/modules/cockpit/__init__.py
index ff5b704e8..53a89ec1b 100644
--- a/plinth/modules/cockpit/__init__.py
+++ b/plinth/modules/cockpit/__init__.py
@@ -35,8 +35,6 @@ _description = [
box_name=_(cfg.box_name), users_url=reverse_lazy('users:index')),
]
-app = None
-
class CockpitApp(app_module.App):
"""FreedomBox app for Cockpit."""
diff --git a/plinth/modules/config/__init__.py b/plinth/modules/config/__init__.py
index f80c8c1d9..80d2adb9e 100644
--- a/plinth/modules/config/__init__.py
+++ b/plinth/modules/config/__init__.py
@@ -34,8 +34,6 @@ FREEDOMBOX_APACHE_CONFIG = os.path.join(APACHE_CONF_ENABLED_DIR,
'freedombox.conf')
ADVANCED_MODE_KEY = 'advanced_mode'
-app = None
-
class ConfigApp(app_module.App):
"""FreedomBox app for basic system configuration."""
diff --git a/plinth/modules/coturn/__init__.py b/plinth/modules/coturn/__init__.py
index 69311891b..71498f5e8 100644
--- a/plinth/modules/coturn/__init__.py
+++ b/plinth/modules/coturn/__init__.py
@@ -38,8 +38,6 @@ _description = [
e_url=reverse_lazy('ejabberd:index')),
]
-app = None
-
logger = logging.getLogger(__name__)
diff --git a/plinth/modules/coturn/views.py b/plinth/modules/coturn/views.py
index 07073968a..25e6e46b7 100644
--- a/plinth/modules/coturn/views.py
+++ b/plinth/modules/coturn/views.py
@@ -7,6 +7,7 @@ from django.contrib import messages
from django.utils.translation import gettext_lazy as _
import plinth.modules.coturn as coturn
+from plinth import app as app_module
from plinth import views
from . import forms
@@ -35,7 +36,8 @@ class CoturnAppView(views.AppView):
data = form.cleaned_data
if coturn.get_domain() != data['domain']:
coturn.set_domain(data['domain'])
- coturn.app.get_component('letsencrypt-coturn').setup_certificates()
+ app = app_module.App.get('coturn')
+ app.get_component('letsencrypt-coturn').setup_certificates()
messages.success(self.request, _('Configuration updated'))
return super().form_valid(form)
diff --git a/plinth/modules/datetime/__init__.py b/plinth/modules/datetime/__init__.py
index 5962fdba3..e51cd50cd 100644
--- a/plinth/modules/datetime/__init__.py
+++ b/plinth/modules/datetime/__init__.py
@@ -20,8 +20,6 @@ _description = [
'in synchronization with servers on the Internet.')
]
-app = None
-
class DateTimeApp(app_module.App):
"""FreedomBox app for date and time if time syncronization is unmanaged."""
diff --git a/plinth/modules/deluge/__init__.py b/plinth/modules/deluge/__init__.py
index 9a6967edf..d6c65a743 100644
--- a/plinth/modules/deluge/__init__.py
+++ b/plinth/modules/deluge/__init__.py
@@ -24,8 +24,6 @@ _description = [
'change it immediately after enabling this service.')
]
-app = None
-
SYSTEM_USER = 'debian-deluged'
diff --git a/plinth/modules/diagnostics/__init__.py b/plinth/modules/diagnostics/__init__.py
index 6931e7162..169f917de 100644
--- a/plinth/modules/diagnostics/__init__.py
+++ b/plinth/modules/diagnostics/__init__.py
@@ -25,8 +25,6 @@ _description = [
'expected.')
]
-app = None
-
logger = logging.Logger(__name__)
running_task = None
diff --git a/plinth/modules/diagnostics/views.py b/plinth/modules/diagnostics/views.py
index cff4451f1..3f2d66146 100644
--- a/plinth/modules/diagnostics/views.py
+++ b/plinth/modules/diagnostics/views.py
@@ -27,7 +27,7 @@ def index(request):
return TemplateResponse(
request, 'diagnostics.html', {
- 'app_info': diagnostics.app.info,
+ 'app_info': App.get('diagnostics').info,
'is_running': is_running,
'results': results,
'refresh_page_sec': 3 if is_running else None
diff --git a/plinth/modules/dynamicdns/__init__.py b/plinth/modules/dynamicdns/__init__.py
index a87629454..79688396f 100644
--- a/plinth/modules/dynamicdns/__init__.py
+++ b/plinth/modules/dynamicdns/__init__.py
@@ -45,8 +45,6 @@ _description = [
'target=\'_blank\'>freedns.afraid.org.'),
]
-app = None
-
class DynamicDNSApp(app_module.App):
"""FreedomBox app for Dynamic DNS."""
@@ -221,6 +219,7 @@ def _update_dns_for_domain(domain):
def update_dns(_data):
"""For all configured domains, check and up to date DNS records."""
config = get_config()
+ app = app_module.App.get('dynamicdns')
if not app.is_enabled():
return
diff --git a/plinth/modules/ejabberd/__init__.py b/plinth/modules/ejabberd/__init__.py
index 43d2b39b3..1e768b019 100644
--- a/plinth/modules/ejabberd/__init__.py
+++ b/plinth/modules/ejabberd/__init__.py
@@ -46,8 +46,6 @@ _description = [
logger = logging.getLogger(__name__)
-app = None
-
class EjabberdApp(app_module.App):
"""FreedomBox app for ejabberd."""
@@ -162,6 +160,7 @@ def on_pre_hostname_change(sender, old_hostname, new_hostname, **kwargs):
"""
del sender # Unused
del kwargs # Unused
+ app = app_module.App.get('ejabberd')
if app.needs_setup():
return
@@ -175,6 +174,7 @@ def on_post_hostname_change(sender, old_hostname, new_hostname, **kwargs):
"""Update ejabberd config after hostname change."""
del sender # Unused
del kwargs # Unused
+ app = app_module.App.get('ejabberd')
if app.needs_setup():
return
@@ -187,6 +187,7 @@ def on_post_hostname_change(sender, old_hostname, new_hostname, **kwargs):
def get_domains():
"""Return the list of domains configured for ejabberd.
"""
+ app = app_module.App.get('ejabberd')
if app.needs_setup():
return []
@@ -197,6 +198,7 @@ def get_domains():
def on_domain_added(sender, domain_type, name='', description='',
services=None, **kwargs):
"""Update ejabberd config after domain name change."""
+ app = app_module.App.get('ejabberd')
if not name or app.needs_setup():
return
@@ -208,6 +210,7 @@ def on_domain_added(sender, domain_type, name='', description='',
def set_domains(domains):
"""Configure ejabberd to have this list of domains."""
+ app = app_module.App.get('ejabberd')
if not domains or app.needs_setup():
return
@@ -220,6 +223,7 @@ def set_domains(domains):
def update_turn_configuration(config: TurnConfiguration, managed=True,
force=False):
"""Update ejabberd's STUN/TURN server configuration."""
+ app = app_module.App.get('ejabberd')
if not force and app.needs_setup():
return
diff --git a/plinth/modules/ejabberd/tests/test_turn_config.py b/plinth/modules/ejabberd/tests/test_turn_config.py
index b48ddf67d..055a01db5 100644
--- a/plinth/modules/ejabberd/tests/test_turn_config.py
+++ b/plinth/modules/ejabberd/tests/test_turn_config.py
@@ -5,7 +5,7 @@ Test module for ejabberd STUN/TURN configuration.
import pathlib
import shutil
-from unittest.mock import patch
+from unittest.mock import Mock, patch
import pytest
@@ -59,7 +59,9 @@ def fixture_test_configuration(call_action, conf_file):
The module state is patched to be 'up-to-date'.
"""
with patch('plinth.actions.superuser_run',
- call_action), patch('plinth.modules.ejabberd.app') as app:
+ call_action), patch('plinth.app.App.get') as app_get:
+ app = Mock()
+ app_get.return_value = app
app.needs_setup.return_value = False
yield
diff --git a/plinth/modules/email/__init__.py b/plinth/modules/email/__init__.py
index c3eb7d48f..71abd5097 100644
--- a/plinth/modules/email/__init__.py
+++ b/plinth/modules/email/__init__.py
@@ -44,7 +44,6 @@ _description = [
'uninstalled.')
]
-app = None
logger = logging.getLogger(__name__)
@@ -215,6 +214,7 @@ def _get_first_admin():
def on_domain_added(sender, domain_type, name, description='', services=None,
**kwargs):
"""Handle addition of a new domain."""
+ app = plinth.app.App.get('email')
if app.needs_setup():
return
@@ -223,6 +223,7 @@ def on_domain_added(sender, domain_type, name, description='', services=None,
def on_domain_removed(sender, domain_type, name='', **kwargs):
"""Handle removal of a domain."""
+ app = plinth.app.App.get('email')
if app.needs_setup():
return
diff --git a/plinth/modules/firewall/__init__.py b/plinth/modules/firewall/__init__.py
index 8b2dee8a9..e4ddae2fb 100644
--- a/plinth/modules/firewall/__init__.py
+++ b/plinth/modules/firewall/__init__.py
@@ -31,8 +31,6 @@ _description = [
_port_details = {}
-app = None
-
logger = logging.getLogger(__name__)
_DBUS_NAME = 'org.fedoraproject.FirewallD1'
diff --git a/plinth/modules/gitweb/__init__.py b/plinth/modules/gitweb/__init__.py
index 70fd80743..f6e958377 100644
--- a/plinth/modules/gitweb/__init__.py
+++ b/plinth/modules/gitweb/__init__.py
@@ -34,8 +34,6 @@ _description = [
'Git tutorial.')
]
-app = None
-
class GitwebApp(app_module.App):
"""FreedomBox app for Gitweb."""
@@ -160,7 +158,7 @@ class GitwebBackupRestore(BackupRestore):
def restore_post(self, packet):
"""Update access after restoration of backups."""
super().restore_post(packet)
- app.update_service_access()
+ self.app.update_service_access()
def repo_exists(name):
diff --git a/plinth/modules/gitweb/tests/test_views.py b/plinth/modules/gitweb/tests/test_views.py
index 28a12466c..ce69dc507 100644
--- a/plinth/modules/gitweb/tests/test_views.py
+++ b/plinth/modules/gitweb/tests/test_views.py
@@ -4,7 +4,7 @@ Tests for gitweb views.
"""
import json
-from unittest.mock import patch
+from unittest.mock import Mock, patch
import pytest
from django import urls
@@ -70,7 +70,7 @@ def action_run(*args, **kwargs):
def gitweb_patch():
"""Patch gitweb."""
with patch('plinth.modules.gitweb.get_repo_list') as get_repo_list, \
- patch('plinth.modules.gitweb.app') as gitweb_app, \
+ patch('plinth.app.App.get') as app_get, \
patch('plinth.actions.superuser_run', side_effect=action_run), \
patch('plinth.actions.run', side_effect=action_run):
get_repo_list.return_value = [{
@@ -78,7 +78,9 @@ def gitweb_patch():
}, {
'name': EXISTING_REPOS[1]['name']
}]
- gitweb_app.update_service_access.return_value = None
+ app = Mock()
+ app_get.return_value = app
+ app.update_service_access.return_value = None
yield
diff --git a/plinth/modules/gitweb/views.py b/plinth/modules/gitweb/views.py
index 2b82eb4b5..6404649be 100644
--- a/plinth/modules/gitweb/views.py
+++ b/plinth/modules/gitweb/views.py
@@ -12,7 +12,9 @@ from django.urls import reverse_lazy
from django.utils.translation import gettext as _
from django.views.generic import FormView
-from plinth import actions, views
+from plinth import actions
+from plinth import app as app_module
+from plinth import views
from plinth.errors import ActionError
from plinth.modules import gitweb
@@ -69,7 +71,7 @@ class CreateRepoView(SuccessMessageMixin, FormView):
_('An error occurred while creating the repository.'),
error_text))
else:
- gitweb.app.update_service_access()
+ app_module.App.get('gitweb').update_service_access()
return super().form_valid(form)
@@ -115,7 +117,7 @@ class EditRepoView(SuccessMessageMixin, FormView):
except ActionError:
messages.error(self.request,
_('An error occurred during configuration.'))
- gitweb.app.update_service_access()
+ app_module.App.get('gitweb').update_service_access()
return super().form_valid(form)
@@ -132,6 +134,7 @@ def delete(request, name):
else:
raise Http404
+ app = app_module.App.get('gitweb')
if request.method == 'POST':
try:
gitweb.delete_repo(name)
@@ -142,11 +145,11 @@ def delete(request, name):
_('Could not delete {name}: {error}').format(
name=name, error=error),
)
- gitweb.app.update_service_access()
+ app.update_service_access()
return redirect(reverse_lazy('gitweb:index'))
return TemplateResponse(request, 'gitweb_delete.html', {
- 'title': gitweb.app.info.name,
+ 'title': app.info.name,
'name': name
})
diff --git a/plinth/modules/help/__init__.py b/plinth/modules/help/__init__.py
index 26e317e72..0acfa765f 100644
--- a/plinth/modules/help/__init__.py
+++ b/plinth/modules/help/__init__.py
@@ -14,8 +14,6 @@ from plinth import cfg, menu, web_server
logger = logging.getLogger(__name__)
-app = None
-
class HelpApp(app_module.App):
"""FreedomBox app for showing help."""
diff --git a/plinth/modules/i2p/__init__.py b/plinth/modules/i2p/__init__.py
index e70bd3360..aad01f1e1 100644
--- a/plinth/modules/i2p/__init__.py
+++ b/plinth/modules/i2p/__init__.py
@@ -35,8 +35,6 @@ tunnels_to_manage = {
'Irc2P': 'i2p-irc-freedombox'
}
-app = None
-
class I2PApp(app_module.App):
"""FreedomBox app for I2P."""
diff --git a/plinth/modules/ikiwiki/__init__.py b/plinth/modules/ikiwiki/__init__.py
index c9b8edde8..f237a6657 100644
--- a/plinth/modules/ikiwiki/__init__.py
+++ b/plinth/modules/ikiwiki/__init__.py
@@ -31,8 +31,6 @@ _description = [
users_url=reverse_lazy('users:index'))
]
-app = None
-
class IkiwikiApp(app_module.App):
"""FreedomBox app for Ikiwiki."""
diff --git a/plinth/modules/ikiwiki/views.py b/plinth/modules/ikiwiki/views.py
index 0959bfc04..b7f7c4e20 100644
--- a/plinth/modules/ikiwiki/views.py
+++ b/plinth/modules/ikiwiki/views.py
@@ -9,20 +9,23 @@ from django.template.response import TemplateResponse
from django.urls import reverse_lazy
from django.utils.translation import gettext as _
-from plinth import actions, views
-from plinth.modules import ikiwiki
+from plinth import actions
+from plinth import app as app_module
+from plinth import views
from .forms import IkiwikiCreateForm
class IkiwikiAppView(views.AppView):
"""Serve configuration page."""
+
app_id = 'ikiwiki'
template_name = 'ikiwiki_configure.html'
def get_context_data(self, **kwargs):
"""Return the context data for rendering the template view."""
- sites = ikiwiki.app.refresh_sites()
+ app = app_module.App.get('ikiwiki')
+ sites = app.refresh_sites()
sites = [name for name in sites if name != '']
context = super().get_context_data(**kwargs)
@@ -34,6 +37,7 @@ def create(request):
"""Form to create a wiki or blog."""
form = None
+ app = app_module.App.get('ikiwiki')
if request.method == 'POST':
form = IkiwikiCreateForm(request.POST, prefix='ikiwiki')
if form.is_valid():
@@ -46,16 +50,16 @@ def create(request):
form.cleaned_data['admin_name'],
form.cleaned_data['admin_password'])
- ikiwiki.app.refresh_sites()
- if ikiwiki.app.is_enabled():
- ikiwiki.app.set_enabled(True)
+ app.refresh_sites()
+ if app.is_enabled():
+ app.set_enabled(True)
return redirect(reverse_lazy('ikiwiki:index'))
else:
form = IkiwikiCreateForm(prefix='ikiwiki')
return TemplateResponse(request, 'ikiwiki_create.html', {
- 'title': ikiwiki.app.info.name,
+ 'title': app.info.name,
'form': form
})
@@ -92,11 +96,12 @@ def delete(request, name):
On GET, display a confirmation page.
On POST, delete the wiki/blog.
"""
- title = ikiwiki.app.components['shortcut-ikiwiki-' + name].name
+ app = app_module.App.get('ikiwiki')
+ title = app.components['shortcut-ikiwiki-' + name].name
if request.method == 'POST':
try:
actions.superuser_run('ikiwiki', ['delete', '--name', name])
- ikiwiki.app.remove_shortcut(name)
+ app.remove_shortcut(name)
messages.success(request,
_('{title} deleted.').format(title=title))
except actions.ActionError as error:
@@ -108,6 +113,6 @@ def delete(request, name):
return redirect(reverse_lazy('ikiwiki:index'))
return TemplateResponse(request, 'ikiwiki_delete.html', {
- 'title': ikiwiki.app.info.name,
+ 'title': app.info.name,
'name': title
})
diff --git a/plinth/modules/infinoted/__init__.py b/plinth/modules/infinoted/__init__.py
index 2fff6db6c..315b18161 100644
--- a/plinth/modules/infinoted/__init__.py
+++ b/plinth/modules/infinoted/__init__.py
@@ -26,8 +26,6 @@ _description = [
box_name=_(cfg.box_name)),
]
-app = None
-
class InfinotedApp(app_module.App):
"""FreedomBox app for infinoted."""
diff --git a/plinth/modules/janus/__init__.py b/plinth/modules/janus/__init__.py
index 9fc39be3e..e5e0bf4e3 100644
--- a/plinth/modules/janus/__init__.py
+++ b/plinth/modules/janus/__init__.py
@@ -27,8 +27,6 @@ _description = [
'use Janus.'), coturn_url=reverse_lazy('coturn:index')),
]
-app = None
-
class JanusApp(app_module.App):
"""FreedomBox app for janus."""
diff --git a/plinth/modules/janus/views.py b/plinth/modules/janus/views.py
index 849a4da64..a86d1f636 100644
--- a/plinth/modules/janus/views.py
+++ b/plinth/modules/janus/views.py
@@ -5,7 +5,7 @@ Views for the Janus app.
from django.views.generic import TemplateView
-from plinth.modules import janus
+from plinth import app as app_module
class JanusRoomView(TemplateView):
@@ -14,7 +14,8 @@ class JanusRoomView(TemplateView):
def get_context_data(self, *args, **kwargs):
"""Add user's TURN server information to view context."""
- config = janus.app.get_component('turn-janus').get_configuration()
+ app = app_module.App.get('janus')
+ config = app.get_component('turn-janus').get_configuration()
context = super().get_context_data(*args, **kwargs)
context['user_turn_config'] = config.to_json()
return context
diff --git a/plinth/modules/jsxc/__init__.py b/plinth/modules/jsxc/__init__.py
index 806fc0c31..45024989d 100644
--- a/plinth/modules/jsxc/__init__.py
+++ b/plinth/modules/jsxc/__init__.py
@@ -24,8 +24,6 @@ _description = [
logger = logging.getLogger(__name__)
-app = None
-
class JSXCApp(app_module.App):
"""FreedomBox app for JSXC."""
diff --git a/plinth/modules/letsencrypt/__init__.py b/plinth/modules/letsencrypt/__init__.py
index 4fc307aa0..a0ae8fd2b 100644
--- a/plinth/modules/letsencrypt/__init__.py
+++ b/plinth/modules/letsencrypt/__init__.py
@@ -42,8 +42,6 @@ LIVE_DIRECTORY = '/etc/letsencrypt/live/'
CERTIFICATE_CHECK_DELAY = 120
logger = logging.getLogger(__name__)
-app = None
-
class LetsEncryptApp(app_module.App):
"""FreedomBox app for Let's Encrypt."""
diff --git a/plinth/modules/letsencrypt/views.py b/plinth/modules/letsencrypt/views.py
index 0bf67a38e..b9b215b6f 100644
--- a/plinth/modules/letsencrypt/views.py
+++ b/plinth/modules/letsencrypt/views.py
@@ -12,6 +12,7 @@ from django.urls import reverse_lazy
from django.utils.translation import gettext as _
from django.views.decorators.http import require_POST
+from plinth import app as app_module
from plinth.errors import ActionError
from plinth.modules import letsencrypt
@@ -21,13 +22,14 @@ logger = logging.getLogger(__name__)
def index(request):
"""Serve configuration page."""
status = letsencrypt.get_status()
+ app = app_module.App.get('letsencrypt')
return TemplateResponse(
request, 'letsencrypt.html', {
'app_id': 'letsencrypt',
- 'app_info': letsencrypt.app.info,
+ 'app_info': app.info,
'status': status,
'has_diagnostics': True,
- 'is_enabled': letsencrypt.app.is_enabled(),
+ 'is_enabled': app.is_enabled(),
})
diff --git a/plinth/modules/matrixsynapse/__init__.py b/plinth/modules/matrixsynapse/__init__.py
index 5349b3e1c..c007994df 100644
--- a/plinth/modules/matrixsynapse/__init__.py
+++ b/plinth/modules/matrixsynapse/__init__.py
@@ -51,8 +51,6 @@ REGISTRATION_CONF_PATH = CONF_DIR + 'freedombox-registration.yaml'
TURN_CONF_PATH = CONF_DIR + 'freedombox-turn.yaml'
OVERRIDDEN_TURN_CONF_PATH = CONF_DIR + 'turn.yaml'
-app = None
-
class MatrixSynapseApp(app_module.App):
"""FreedomBox app for Matrix Synapse."""
@@ -158,6 +156,7 @@ def upgrade():
def setup_domain(domain_name):
"""Configure a domain name for matrixsynapse."""
+ app = app_module.App.get('matrixsynapse')
app.get_component('letsencrypt-matrixsynapse').setup_certificates(
[domain_name])
actions.superuser_run('matrixsynapse',
@@ -212,6 +211,7 @@ def get_public_registration_status() -> bool:
def get_certificate_status():
"""Return the status of certificate for the configured domain."""
+ app = app_module.App.get('matrixsynapse')
status = app.get_component('letsencrypt-matrixsynapse').get_status()
if not status:
return 'no-domains'
@@ -222,6 +222,7 @@ def get_certificate_status():
def update_turn_configuration(config: TurnConfiguration, managed=True,
force=False):
"""Update the STUN/TURN server configuration."""
+ app = app_module.App.get('matrixsynapse')
if not force and app.needs_setup():
return
diff --git a/plinth/modules/matrixsynapse/tests/test_turn_config.py b/plinth/modules/matrixsynapse/tests/test_turn_config.py
index 28f5bb834..2f48705f0 100644
--- a/plinth/modules/matrixsynapse/tests/test_turn_config.py
+++ b/plinth/modules/matrixsynapse/tests/test_turn_config.py
@@ -3,7 +3,7 @@
Test module for Matrix Synapse STUN/TURN configuration.
"""
-from unittest.mock import patch
+from unittest.mock import patch, Mock
import pytest
@@ -51,7 +51,9 @@ def fixture_test_configuration(call_action, managed_turn_conf_file,
overridden_turn_conf_file),
patch('plinth.modules.matrixsynapse.is_setup', return_value=True),
patch('plinth.actions.superuser_run', call_action),
- patch('plinth.modules.matrixsynapse.app') as app):
+ patch('plinth.app.App.get') as app_get):
+ app = Mock()
+ app_get.return_value = app
app.needs_setup.return_value = False
yield
diff --git a/plinth/modules/matrixsynapse/views.py b/plinth/modules/matrixsynapse/views.py
index 1198d8aa9..3d8ba9a30 100644
--- a/plinth/modules/matrixsynapse/views.py
+++ b/plinth/modules/matrixsynapse/views.py
@@ -10,6 +10,7 @@ from django.utils.translation import gettext_lazy as _
from django.views.generic import FormView
from plinth import actions
+from plinth import app as app_module
from plinth.forms import DomainSelectionForm
from plinth.modules import matrixsynapse, names
from plinth.modules.coturn.components import TurnConfiguration
@@ -33,9 +34,10 @@ class SetupView(FormView):
def get_context_data(self, *args, **kwargs):
"""Provide context data to the template."""
context = super().get_context_data(**kwargs)
+ app = app_module.App.get('matrixsynapse')
- context['title'] = matrixsynapse.app.info.name
- context['app_info'] = matrixsynapse.app.info
+ context['title'] = app.info.name
+ context['app_info'] = app.info
context['domain_names'] = names.components.DomainName.list_names(
'matrix-synapse-plinth')
diff --git a/plinth/modules/mediawiki/__init__.py b/plinth/modules/mediawiki/__init__.py
index 7e7608ee8..b2575cb4a 100644
--- a/plinth/modules/mediawiki/__init__.py
+++ b/plinth/modules/mediawiki/__init__.py
@@ -34,8 +34,6 @@ _description = [
'logged in can make changes to the content.')
]
-app = None
-
STATIC_CONFIG_FILE = '/etc/mediawiki/FreedomBoxStaticSettings.php'
USER_CONFIG_FILE = '/etc/mediawiki/FreedomBoxSettings.php'
diff --git a/plinth/modules/mediawiki/views.py b/plinth/modules/mediawiki/views.py
index 524c322ab..15e3e7b06 100644
--- a/plinth/modules/mediawiki/views.py
+++ b/plinth/modules/mediawiki/views.py
@@ -8,7 +8,9 @@ import logging
from django.contrib import messages
from django.utils.translation import gettext as _
-from plinth import actions, views
+from plinth import actions
+from plinth import app as app_module
+from plinth import views
from plinth.errors import ActionError
from plinth.modules import mediawiki
@@ -87,7 +89,8 @@ class MediaWikiAppView(views.AppView):
actions.superuser_run('mediawiki', ['private-mode', 'disable'])
messages.success(self.request, _('Private mode disabled'))
- shortcut = mediawiki.app.get_component('shortcut-mediawiki')
+ app = app_module.App.get('mediawiki')
+ shortcut = app.get_component('shortcut-mediawiki')
shortcut.login_required = new_config['enable_private_mode']
if is_changed('default_skin'):
diff --git a/plinth/modules/minetest/__init__.py b/plinth/modules/minetest/__init__.py
index 822dae826..87f112a1a 100644
--- a/plinth/modules/minetest/__init__.py
+++ b/plinth/modules/minetest/__init__.py
@@ -42,8 +42,6 @@ _description = [
CONFIG_FILE = '/etc/minetest/minetest.conf'
AUG_PATH = '/files' + CONFIG_FILE + '/.anon'
-app = None
-
class MinetestApp(app_module.App):
"""FreedomBox app for Minetest."""
diff --git a/plinth/modules/minidlna/__init__.py b/plinth/modules/minidlna/__init__.py
index f7eaf27aa..8dc6c462b 100644
--- a/plinth/modules/minidlna/__init__.py
+++ b/plinth/modules/minidlna/__init__.py
@@ -4,8 +4,9 @@ FreedomBox app to configure minidlna.
"""
from django.utils.translation import gettext_lazy as _
-import plinth.app as app_module
-from plinth import actions, frontpage, menu
+from plinth import actions
+from plinth import app as app_module
+from plinth import frontpage, menu
from plinth.daemon import Daemon
from plinth.modules.apache.components import Webserver
from plinth.modules.backups.components import BackupRestore
@@ -27,8 +28,6 @@ _description = [
'such as PS3 and Xbox 360) or applications such as totem and Kodi.')
]
-app = None
-
class MiniDLNAApp(app_module.App):
"""Freedombox app managing miniDlna"""
diff --git a/plinth/modules/mumble/__init__.py b/plinth/modules/mumble/__init__.py
index 9eb4a1332..b18ce5d4d 100644
--- a/plinth/modules/mumble/__init__.py
+++ b/plinth/modules/mumble/__init__.py
@@ -29,8 +29,6 @@ _description = [
'from your desktop and mobile devices are available.')
]
-app = None
-
class MumbleApp(app_module.App):
"""FreedomBox app for Mumble."""
@@ -100,7 +98,7 @@ class MumbleApp(app_module.App):
if not old_version:
self.enable()
- app.get_component('letsencrypt-mumble').setup_certificates()
+ self.get_component('letsencrypt-mumble').setup_certificates()
def force_upgrade(self, packages):
"""Force upgrade mumble-server to resolve conffile prompts."""
diff --git a/plinth/modules/mumble/views.py b/plinth/modules/mumble/views.py
index d7406b61a..a6c96dabb 100644
--- a/plinth/modules/mumble/views.py
+++ b/plinth/modules/mumble/views.py
@@ -6,6 +6,7 @@ Views for mumble app.
from django.contrib import messages
from django.utils.translation import gettext_lazy as _
+from plinth import app as app_module
from plinth.modules import mumble
from plinth.modules.mumble.forms import MumbleForm
from plinth.views import AppView
@@ -31,7 +32,8 @@ class MumbleAppView(AppView):
if mumble.get_domain() != new_config['domain']:
privileged.set_domain(new_config['domain'])
- mumble.app.get_component('letsencrypt-mumble').setup_certificates()
+ app = app_module.App.get('mumble')
+ app.get_component('letsencrypt-mumble').setup_certificates()
messages.success(self.request, _('Configuration updated'))
password = new_config.get('super_user_password')
diff --git a/plinth/modules/names/__init__.py b/plinth/modules/names/__init__.py
index 948486b80..07c9e06e7 100644
--- a/plinth/modules/names/__init__.py
+++ b/plinth/modules/names/__init__.py
@@ -26,8 +26,6 @@ _description = [
'connections through the given name.'), box_name=(cfg.box_name))
]
-app = None
-
class NamesApp(app_module.App):
"""FreedomBox app for names."""
diff --git a/plinth/modules/names/views.py b/plinth/modules/names/views.py
index b043b5ca3..4c0cb51d6 100644
--- a/plinth/modules/names/views.py
+++ b/plinth/modules/names/views.py
@@ -5,7 +5,7 @@ FreedomBox app for name services.
from django.template.response import TemplateResponse
-from plinth.modules import names
+from plinth import app as app_module
from . import components
@@ -15,7 +15,7 @@ def index(request):
status = get_status()
return TemplateResponse(request, 'names.html', {
- 'app_info': names.app.info,
+ 'app_info': app_module.App.get('names').info,
'status': status
})
diff --git a/plinth/modules/networks/__init__.py b/plinth/modules/networks/__init__.py
index eb345c85f..df6485ae3 100644
--- a/plinth/modules/networks/__init__.py
+++ b/plinth/modules/networks/__init__.py
@@ -40,8 +40,6 @@ _description = [
logger = Logger(__name__)
-app = None
-
class NetworksApp(app_module.App):
"""FreedomBox app for Networks."""
diff --git a/plinth/modules/networks/views.py b/plinth/modules/networks/views.py
index 4dbe18bb8..c799dadb0 100644
--- a/plinth/modules/networks/views.py
+++ b/plinth/modules/networks/views.py
@@ -12,6 +12,7 @@ from django.utils.translation import gettext_lazy
from django.views.decorators.http import require_POST
from django.views.generic.edit import FormView
+from plinth import app as app_module
from plinth import network
from plinth.modules import first_boot, networks
@@ -123,7 +124,7 @@ def index(request):
return TemplateResponse(
request, 'networks_configuration.html', {
'app_id': 'networks',
- 'app_info': networks.app.info,
+ 'app_info': app_module.App.get('networks').info,
'title': _('Network Connections'),
'has_diagnostics': True,
'is_enabled': True,
diff --git a/plinth/modules/openvpn/__init__.py b/plinth/modules/openvpn/__init__.py
index 7bad2f710..4ec97d813 100644
--- a/plinth/modules/openvpn/__init__.py
+++ b/plinth/modules/openvpn/__init__.py
@@ -31,8 +31,6 @@ _description = [
'for added security and anonymity.'), box_name=_(cfg.box_name))
]
-app = None
-
SERVER_CONFIGURATION_FILE = '/etc/openvpn/server/freedombox.conf'
diff --git a/plinth/modules/openvpn/views.py b/plinth/modules/openvpn/views.py
index 7ebdcfa43..903093bd6 100644
--- a/plinth/modules/openvpn/views.py
+++ b/plinth/modules/openvpn/views.py
@@ -10,6 +10,7 @@ from django.shortcuts import redirect
from django.views.decorators.http import require_POST
from plinth import actions
+from plinth import app as app_module
from plinth.modules import config, openvpn
from plinth.views import AppView
@@ -37,7 +38,7 @@ def setup(_):
if not openvpn.is_setup():
actions.superuser_run('openvpn', ['setup'], run_in_background=True)
- openvpn.app.enable()
+ app_module.App.get('openvpn').enable()
return redirect('openvpn:index')
diff --git a/plinth/modules/pagekite/__init__.py b/plinth/modules/pagekite/__init__.py
index f0a45354c..d959a0286 100644
--- a/plinth/modules/pagekite/__init__.py
+++ b/plinth/modules/pagekite/__init__.py
@@ -42,8 +42,6 @@ _description = [
box_name=_(cfg.box_name))
]
-app = None
-
class PagekiteApp(app_module.App):
"""FreedomBox app for Pagekite."""
diff --git a/plinth/modules/pagekite/utils.py b/plinth/modules/pagekite/utils.py
index f551beea9..8b00cf7b6 100644
--- a/plinth/modules/pagekite/utils.py
+++ b/plinth/modules/pagekite/utils.py
@@ -7,6 +7,7 @@ import os
from django.utils.translation import gettext_lazy as _
from plinth import actions
+from plinth import app as app_module
from plinth.signals import domain_added, domain_removed
LOGGER = logging.getLogger(__name__)
@@ -172,8 +173,7 @@ def update_names_module(is_enabled=None):
if is_enabled is False:
return
- from plinth.modules.pagekite import app
- if is_enabled is None and not app.is_enabled():
+ if is_enabled is None and not app_module.App.get('pagekite').is_enabled():
return
config = get_config()
diff --git a/plinth/modules/performance/__init__.py b/plinth/modules/performance/__init__.py
index 1dbdbe71f..6fa9f5cf0 100644
--- a/plinth/modules/performance/__init__.py
+++ b/plinth/modules/performance/__init__.py
@@ -24,8 +24,6 @@ _description = [
'viewed using the Cockpit app.'),
]
-app = None
-
class PerformanceApp(app_module.App):
"""FreedomBox app for Performance."""
diff --git a/plinth/modules/power/__init__.py b/plinth/modules/power/__init__.py
index 489fc580d..8137456ee 100644
--- a/plinth/modules/power/__init__.py
+++ b/plinth/modules/power/__init__.py
@@ -13,8 +13,6 @@ from . import manifest
_description = [_('Restart or shut down the system.')]
-app = None
-
class PowerApp(app_module.App):
"""FreedomBox app for power controls."""
diff --git a/plinth/modules/power/views.py b/plinth/modules/power/views.py
index fad662eca..9b59380a1 100644
--- a/plinth/modules/power/views.py
+++ b/plinth/modules/power/views.py
@@ -8,16 +8,18 @@ from django.shortcuts import redirect
from django.template.response import TemplateResponse
from django.urls import reverse
-from plinth import actions, package
-from plinth.modules import power
+from plinth import actions
+from plinth import app as app_module
+from plinth import package
def index(request):
"""Serve power controls page."""
+ app = app_module.App.get('power')
return TemplateResponse(
request, 'power.html', {
- 'title': power.app.info.name,
- 'app_info': power.app.info,
+ 'title': app.info.name,
+ 'app_info': app.info,
'pkg_manager_is_busy': package.is_package_manager_busy()
})
@@ -30,12 +32,13 @@ def restart(request):
actions.superuser_run('power', ['restart'], run_in_background=True)
return redirect(reverse('apps'))
+ app = app_module.App.get('power')
form = Form(prefix='power')
return TemplateResponse(
request, 'power_restart.html', {
- 'title': power.app.info.name,
+ 'title': app.info.name,
'form': form,
- 'manual_page': power.app.info.manual_page,
+ 'manual_page': app.info.manual_page,
'pkg_manager_is_busy': package.is_package_manager_busy()
})
@@ -48,11 +51,12 @@ def shutdown(request):
actions.superuser_run('power', ['shutdown'], run_in_background=True)
return redirect(reverse('apps'))
+ app = app_module.App.get('power')
form = Form(prefix='power')
return TemplateResponse(
request, 'power_shutdown.html', {
- 'title': power.app.info.name,
+ 'title': app.info.name,
'form': form,
- 'manual_page': power.app.info.manual_page,
+ 'manual_page': app.info.manual_page,
'pkg_manager_is_busy': package.is_package_manager_busy()
})
diff --git a/plinth/modules/privoxy/__init__.py b/plinth/modules/privoxy/__init__.py
index ad7e590e9..75dc3f6c6 100644
--- a/plinth/modules/privoxy/__init__.py
+++ b/plinth/modules/privoxy/__init__.py
@@ -35,8 +35,6 @@ _description = [
box_name=_(cfg.box_name)),
]
-app = None
-
class PrivoxyApp(app_module.App):
"""FreedomBox app for Privoxy."""
diff --git a/plinth/modules/quassel/__init__.py b/plinth/modules/quassel/__init__.py
index fdd6026b4..0405e9cb9 100644
--- a/plinth/modules/quassel/__init__.py
+++ b/plinth/modules/quassel/__init__.py
@@ -38,8 +38,6 @@ _description = [
'are available.'),
]
-app = None
-
class QuasselApp(app_module.App):
"""FreedomBox app for Quassel."""
diff --git a/plinth/modules/quassel/views.py b/plinth/modules/quassel/views.py
index 90d2ca56b..8636cfdbb 100644
--- a/plinth/modules/quassel/views.py
+++ b/plinth/modules/quassel/views.py
@@ -3,6 +3,7 @@
from django.contrib import messages
from django.utils.translation import gettext_lazy as _
+from plinth import app as app_module
from plinth.forms import TLSDomainForm
from plinth.modules import quassel
from plinth.views import AppView
@@ -23,8 +24,8 @@ class QuasselAppView(AppView):
data = form.cleaned_data
if quassel.get_domain() != data['domain']:
quassel.set_domain(data['domain'])
- quassel.app.get_component(
- 'letsencrypt-quassel').setup_certificates()
+ app = app_module.App.get('quassel')
+ app.get_component('letsencrypt-quassel').setup_certificates()
messages.success(self.request, _('Configuration updated'))
return super().form_valid(form)
diff --git a/plinth/modules/radicale/__init__.py b/plinth/modules/radicale/__init__.py
index f55100f67..118f60164 100644
--- a/plinth/modules/radicale/__init__.py
+++ b/plinth/modules/radicale/__init__.py
@@ -37,8 +37,6 @@ logger = logging.getLogger(__name__)
CONFIG_FILE = '/etc/radicale/config'
-app = None
-
class RadicaleApp(app_module.App):
"""FreedomBox app for Radicale."""
diff --git a/plinth/modules/roundcube/__init__.py b/plinth/modules/roundcube/__init__.py
index e29fbf4d8..86e6ee0c2 100644
--- a/plinth/modules/roundcube/__init__.py
+++ b/plinth/modules/roundcube/__init__.py
@@ -33,8 +33,6 @@ _description = [
'>https://www.google.com/settings/security/lesssecureapps).'),
]
-app = None
-
class RoundcubeApp(app_module.App):
"""FreedomBox app for Roundcube."""
diff --git a/plinth/modules/rssbridge/__init__.py b/plinth/modules/rssbridge/__init__.py
index 5a9ff331d..460d833f8 100644
--- a/plinth/modules/rssbridge/__init__.py
+++ b/plinth/modules/rssbridge/__init__.py
@@ -30,8 +30,6 @@ _description = [
ttrss_url=reverse_lazy('ttrss:index'), box_name=cfg.box_name),
]
-app = None
-
class RSSBridgeApp(app_module.App):
"""FreedomBox app for RSS-Bridge."""
diff --git a/plinth/modules/samba/__init__.py b/plinth/modules/samba/__init__.py
index cd72af27d..3730da2fd 100644
--- a/plinth/modules/samba/__init__.py
+++ b/plinth/modules/samba/__init__.py
@@ -39,8 +39,6 @@ _description = [
'own private space.'),
]
-app = None
-
class SambaApp(app_module.App):
"""FreedomBox app for Samba file sharing."""
diff --git a/plinth/modules/searx/__init__.py b/plinth/modules/searx/__init__.py
index 1c685ecd4..27b8fe9cb 100644
--- a/plinth/modules/searx/__init__.py
+++ b/plinth/modules/searx/__init__.py
@@ -25,8 +25,6 @@ _description = [
'It stores no cookies by default.')
]
-app = None
-
class SearxApp(app_module.App):
"""FreedomBox app for Searx."""
@@ -131,6 +129,7 @@ def is_public_access_enabled():
def enable_public_access():
"""Allow Searx app to be accessed by anyone with access."""
actions.superuser_run('searx', ['enable-public-access'])
+ app = app_module.App.get('searx')
app.get_component('webserver-searx-auth').disable()
app.set_shortcut_login_required(False)
@@ -138,5 +137,6 @@ def enable_public_access():
def disable_public_access():
"""Allow Searx app to be accessed by logged-in users only."""
actions.superuser_run('searx', ['disable-public-access'])
+ app = app_module.App.get('searx')
app.get_component('webserver-searx-auth').enable()
app.set_shortcut_login_required(True)
diff --git a/plinth/modules/searx/views.py b/plinth/modules/searx/views.py
index 3a8e8f8ea..dbe80e658 100644
--- a/plinth/modules/searx/views.py
+++ b/plinth/modules/searx/views.py
@@ -6,7 +6,9 @@ Django views for Searx.
from django.contrib import messages
from django.utils.translation import gettext as _
-from plinth import actions, views
+from plinth import actions
+from plinth import app as app_module
+from plinth import views
from plinth.errors import ActionError
from plinth.modules import searx
@@ -23,7 +25,7 @@ class SearxAppView(views.AppView):
initial = super().get_initial()
initial['safe_search'] = searx.get_safe_search_setting()
initial['public_access'] = searx.is_public_access_enabled() and \
- searx.app.is_enabled()
+ app_module.App.get('searx').is_enabled()
return initial
def form_valid(self, form):
diff --git a/plinth/modules/security/__init__.py b/plinth/modules/security/__init__.py
index dcfe24007..915afd98b 100644
--- a/plinth/modules/security/__init__.py
+++ b/plinth/modules/security/__init__.py
@@ -24,8 +24,6 @@ ACCESS_CONF_SNIPPET = '-:ALL EXCEPT root fbx plinth (admin) (sudo):ALL'
OLD_ACCESS_CONF_SNIPPET = '-:ALL EXCEPT root fbx (admin) (sudo):ALL'
ACCESS_CONF_SNIPPETS = [OLD_ACCESS_CONF_SNIPPET, ACCESS_CONF_SNIPPET]
-app = None
-
class SecurityApp(app_module.App):
"""FreedomBox app for security."""
diff --git a/plinth/modules/security/views.py b/plinth/modules/security/views.py
index d284098df..3c21eb631 100644
--- a/plinth/modules/security/views.py
+++ b/plinth/modules/security/views.py
@@ -8,6 +8,7 @@ from django.template.response import TemplateResponse
from django.utils.translation import gettext as _
from plinth import action_utils, actions
+from plinth import app as app_module
from plinth.modules import security
from plinth.modules.upgrades import is_backports_requested
@@ -31,7 +32,7 @@ def index(request):
return TemplateResponse(
request, 'security.html', {
- 'app_info': security.app.info,
+ 'app_info': app_module.App.get('security').info,
'form': form,
'is_backports_requested': is_backports_requested(),
})
diff --git a/plinth/modules/shaarli/__init__.py b/plinth/modules/shaarli/__init__.py
index 585d3511c..ed7f054f2 100644
--- a/plinth/modules/shaarli/__init__.py
+++ b/plinth/modules/shaarli/__init__.py
@@ -20,8 +20,6 @@ _description = [
'need to setup on the initial visit.'),
]
-app = None
-
class ShaarliApp(app_module.App):
"""FreedomBox app for Shaarli."""
diff --git a/plinth/modules/shadowsocks/__init__.py b/plinth/modules/shadowsocks/__init__.py
index fd1b68af6..b91cb6e47 100644
--- a/plinth/modules/shadowsocks/__init__.py
+++ b/plinth/modules/shadowsocks/__init__.py
@@ -31,8 +31,6 @@ _description = [
'device, browser or application to http://freedombox_address:1080/')
]
-app = None
-
class ShadowsocksApp(app_module.App):
"""FreedomBox app for Shadowsocks."""
diff --git a/plinth/modules/sharing/__init__.py b/plinth/modules/sharing/__init__.py
index 94ebf1635..c716b13b5 100644
--- a/plinth/modules/sharing/__init__.py
+++ b/plinth/modules/sharing/__init__.py
@@ -22,8 +22,6 @@ _description = [
box_name=_(cfg.box_name))
]
-app = None
-
class SharingApp(app_module.App):
"""FreedomBox app for sharing files."""
diff --git a/plinth/modules/sharing/views.py b/plinth/modules/sharing/views.py
index 1bca8f15f..26c0b75b8 100644
--- a/plinth/modules/sharing/views.py
+++ b/plinth/modules/sharing/views.py
@@ -12,6 +12,7 @@ from django.utils.translation import gettext_lazy as _
from django.views.decorators.http import require_POST
from django.views.generic import FormView, TemplateView
+from plinth import app as app_module
from plinth.modules import sharing
from .forms import AddShareForm
@@ -24,8 +25,9 @@ class IndexView(TemplateView):
def get_context_data(self, **kwargs):
"""Return additional context for rendering the template."""
context = super().get_context_data(**kwargs)
- context['title'] = sharing.app.info.name
- context['app_info'] = sharing.app.info
+ app = app_module.App.get('sharing')
+ context['title'] = app.info.name
+ context['app_info'] = app.info
context['shares'] = sharing.list_shares()
return context
diff --git a/plinth/modules/snapshot/__init__.py b/plinth/modules/snapshot/__init__.py
index 2396e2c7a..015bac1f5 100644
--- a/plinth/modules/snapshot/__init__.py
+++ b/plinth/modules/snapshot/__init__.py
@@ -36,8 +36,6 @@ DEFAULT_FILE = '/etc/default/snapper'
fs_types_supported = ['btrfs']
-app = None
-
class SnapshotApp(app_module.App):
"""FreedomBox app for snapshots."""
diff --git a/plinth/modules/snapshot/views.py b/plinth/modules/snapshot/views.py
index 70a3ce678..960383b9f 100644
--- a/plinth/modules/snapshot/views.py
+++ b/plinth/modules/snapshot/views.py
@@ -15,6 +15,7 @@ from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy
from plinth import actions
+from plinth import app as app_module
from plinth.errors import ActionError
from plinth.modules import snapshot as snapshot_module
from plinth.modules import storage
@@ -43,9 +44,10 @@ subsubmenu = [
def not_supported_view(request):
"""Show that snapshots are not supported on the system."""
+ app = app_module.App.get('snapshot')
template_data = {
- 'app_info': snapshot_module.app.info,
- 'title': snapshot_module.app.info.name,
+ 'app_info': app.info,
+ 'title': app.info.name,
'fs_type': storage.get_filesystem_type(),
'fs_types_supported': snapshot_module.fs_types_supported,
}
@@ -68,10 +70,11 @@ def index(request):
else:
form = SnapshotForm(initial=status)
+ app = app_module.App.get('snapshot')
return TemplateResponse(
request, 'snapshot.html', {
- 'app_info': snapshot_module.app.info,
- 'title': snapshot_module.app.info.name,
+ 'app_info': app.info,
+ 'title': app.info.name,
'subsubmenu': subsubmenu,
'form': form
})
@@ -103,10 +106,11 @@ def manage(request):
if not snapshot['is_default'] and not snapshot['is_active']
])
+ app = app_module.App.get('snapshot')
return TemplateResponse(
request, 'snapshot_manage.html', {
- 'title': snapshot_module.app.info.name,
- 'app_info': snapshot_module.app.info,
+ 'title': app.info.name,
+ 'app_info': app.info,
'snapshots': snapshots,
'has_deletable_snapshots': has_deletable_snapshots,
'subsubmenu': subsubmenu,
diff --git a/plinth/modules/ssh/__init__.py b/plinth/modules/ssh/__init__.py
index bcafea98e..13e358aa6 100644
--- a/plinth/modules/ssh/__init__.py
+++ b/plinth/modules/ssh/__init__.py
@@ -26,8 +26,6 @@ _description = [
'using such connections.')
]
-app = None
-
class SSHApp(app_module.App):
"""FreedomBox app for SSH."""
diff --git a/plinth/modules/sso/__init__.py b/plinth/modules/sso/__init__.py
index a70b05937..8a3aeddb5 100644
--- a/plinth/modules/sso/__init__.py
+++ b/plinth/modules/sso/__init__.py
@@ -9,8 +9,6 @@ from plinth import actions
from plinth import app as app_module
from plinth.package import Packages
-app = None
-
class SSOApp(app_module.App):
"""FreedomBox app for single sign on."""
diff --git a/plinth/modules/storage/__init__.py b/plinth/modules/storage/__init__.py
index bf138f952..a823ccba6 100644
--- a/plinth/modules/storage/__init__.py
+++ b/plinth/modules/storage/__init__.py
@@ -31,8 +31,6 @@ _description = [
logger = logging.getLogger(__name__)
-app = None
-
class StorageApp(app_module.App):
"""FreedomBox app for storage."""
diff --git a/plinth/modules/syncthing/__init__.py b/plinth/modules/syncthing/__init__.py
index c6a5afb49..2f0a9eb88 100644
--- a/plinth/modules/syncthing/__init__.py
+++ b/plinth/modules/syncthing/__init__.py
@@ -37,8 +37,6 @@ _description = [
SYSTEM_USER = 'syncthing'
-app = None
-
class SyncthingApp(app_module.App):
"""FreedomBox app for Syncthing."""
diff --git a/plinth/modules/tor/__init__.py b/plinth/modules/tor/__init__.py
index ecded31f8..8ab11904a 100644
--- a/plinth/modules/tor/__init__.py
+++ b/plinth/modules/tor/__init__.py
@@ -35,8 +35,6 @@ _description = [
'networks on TCP port 9050.'), box_name=_(cfg.box_name))
]
-app = None
-
class TorApp(app_module.App):
"""FreedomBox app for Tor."""
@@ -97,7 +95,7 @@ class TorApp(app_module.App):
def post_init(self):
"""Perform post initialization operations."""
# Register hidden service name with Name Services module.
- if (not app.needs_setup() and self.is_enabled()
+ if (not self.needs_setup() and self.is_enabled()
and app_is_running(self)):
status = utils.get_status(initialized=False)
hostname = status['hs_hostname']
diff --git a/plinth/modules/tor/tests/test_tor.py b/plinth/modules/tor/tests/test_tor.py
index 7efff89a8..de0939a9a 100644
--- a/plinth/modules/tor/tests/test_tor.py
+++ b/plinth/modules/tor/tests/test_tor.py
@@ -13,6 +13,7 @@ from plinth.modules.tor import forms, utils
class TestTor:
"""Test cases for testing the Tor module."""
+
@staticmethod
@pytest.mark.usefixtures('needs_root')
def test_is_apt_transport_tor_enabled():
@@ -22,9 +23,9 @@ class TestTor:
utils.is_apt_transport_tor_enabled()
@staticmethod
- @patch('plinth.modules.tor.app')
+ @patch('plinth.app.App.get')
@pytest.mark.usefixtures('needs_root', 'load_cfg')
- def test_get_status(_app):
+ def test_get_status(_app_get):
"""Test that get_status does not raise any unhandled exceptions.
This should work regardless of whether tor is installed, or
@@ -35,6 +36,7 @@ class TestTor:
class TestTorForm:
"""Test whether Tor configration form works."""
+
@staticmethod
def test_bridge_validator():
"""Test upstream bridges' form field validator."""
diff --git a/plinth/modules/tor/utils.py b/plinth/modules/tor/utils.py
index 292d2925c..935e48a85 100644
--- a/plinth/modules/tor/utils.py
+++ b/plinth/modules/tor/utils.py
@@ -10,8 +10,8 @@ import json
import augeas
from plinth import actions
+from plinth import app as app_module
from plinth.daemon import app_is_running
-from plinth.modules import tor
from plinth.modules.names.components import DomainName
APT_SOURCES_URI_PATHS = ('/files/etc/apt/sources.list/*/uri',
@@ -42,9 +42,10 @@ def get_status(initialized=True):
or status['bridge_relay_enabled']
}
+ app = app_module.App.get('tor')
return {
- 'enabled': tor.app.is_enabled() if initialized else False,
- 'is_running': app_is_running(tor.app) if initialized else False,
+ 'enabled': app.is_enabled() if initialized else False,
+ 'is_running': app_is_running(app) if initialized else False,
'use_upstream_bridges': status['use_upstream_bridges'],
'upstream_bridges': status['upstream_bridges'],
'relay_enabled': status['relay_enabled'],
diff --git a/plinth/modules/tor/views.py b/plinth/modules/tor/views.py
index 2d9871af2..f4c42d32d 100644
--- a/plinth/modules/tor/views.py
+++ b/plinth/modules/tor/views.py
@@ -7,6 +7,7 @@ from django.template.response import TemplateResponse
from django.utils.translation import gettext as _
from plinth import actions
+from plinth import app as app_module
from plinth.errors import ActionError
from plinth.modules import tor
from plinth.modules.firewall.components import (Firewall,
@@ -36,18 +37,19 @@ def index(request):
else:
form = TorForm(initial=status, prefix='tor')
+ app = app_module.App.get('tor')
return TemplateResponse(
request, 'tor.html', {
'app_id': 'tor',
- 'app_info': tor.app.info,
+ 'app_info': app.info,
'status': status,
'config_running': bool(config_process),
'form': form,
- 'firewall': tor.app.get_components_of_type(Firewall),
+ 'firewall': app.get_components_of_type(Firewall),
'has_diagnostics': True,
'is_enabled': status['enabled'],
'is_running': status['is_running'],
- 'port_forwarding_info': get_port_forwarding_info(tor.app),
+ 'port_forwarding_info': get_port_forwarding_info(app),
'refresh_page_sec': 3 if bool(config_process) else None,
})
@@ -116,10 +118,11 @@ def __apply_changes(request, old_status, new_status):
arg_value = 'enable' if new_status['enabled'] else 'disable'
arguments.extend(['--service', arg_value])
# XXX: Perform app enable/disable within the background process
+ app = app_module.App.get('tor')
if new_status['enabled']:
- tor.app.enable()
+ app.enable()
else:
- tor.app.disable()
+ app.disable()
config_process = actions.superuser_run('tor',
['configure'] + arguments,
diff --git a/plinth/modules/transmission/__init__.py b/plinth/modules/transmission/__init__.py
index d778ac40c..10208cad3 100644
--- a/plinth/modules/transmission/__init__.py
+++ b/plinth/modules/transmission/__init__.py
@@ -42,8 +42,6 @@ _description = [
sharing_url=reverse_lazy('sharing:index'))
]
-app = None
-
SYSTEM_USER = 'debian-transmission'
diff --git a/plinth/modules/ttrss/__init__.py b/plinth/modules/ttrss/__init__.py
index 78c5ab4cd..f17aca2e1 100644
--- a/plinth/modules/ttrss/__init__.py
+++ b/plinth/modules/ttrss/__init__.py
@@ -33,8 +33,6 @@ _description = [
'the URL /tt-rss-app for connecting.'))
]
-app = None
-
class TTRSSApp(app_module.App):
"""FreedomBox app for TT-RSS."""
diff --git a/plinth/modules/upgrades/__init__.py b/plinth/modules/upgrades/__init__.py
index a73bfafb2..9eba07745 100644
--- a/plinth/modules/upgrades/__init__.py
+++ b/plinth/modules/upgrades/__init__.py
@@ -44,8 +44,6 @@ _description = [
'unavailable briefly.')
]
-app = None
-
BACKPORTS_REQUESTED_KEY = 'upgrades_backports_requested'
DIST_UPGRADE_ENABLED_KEY = 'upgrades_dist_upgrade_enabled'
diff --git a/plinth/modules/users/__init__.py b/plinth/modules/users/__init__.py
index a03ff3e19..4f4d18784 100644
--- a/plinth/modules/users/__init__.py
+++ b/plinth/modules/users/__init__.py
@@ -37,8 +37,6 @@ _description = [
box_name=_(cfg.box_name))
]
-app = None
-
class UsersApp(app_module.App):
"""FreedomBox app for users and groups management."""
diff --git a/plinth/modules/wireguard/__init__.py b/plinth/modules/wireguard/__init__.py
index 9b78f114d..0dc632196 100644
--- a/plinth/modules/wireguard/__init__.py
+++ b/plinth/modules/wireguard/__init__.py
@@ -29,8 +29,6 @@ _description = [
box_name=_(cfg.box_name))
]
-app = None
-
SERVER_INTERFACE = 'wg0'
diff --git a/plinth/modules/wordpress/__init__.py b/plinth/modules/wordpress/__init__.py
index f55c205c0..ae1edd000 100644
--- a/plinth/modules/wordpress/__init__.py
+++ b/plinth/modules/wordpress/__init__.py
@@ -40,8 +40,6 @@ _description = [
'be installed and upgraded at your own risk.'),
]
-app = None
-
class WordPressApp(app_module.App):
"""FreedomBox app for WordPress."""
diff --git a/plinth/modules/zoph/__init__.py b/plinth/modules/zoph/__init__.py
index 0e3cc898f..71ac501a1 100644
--- a/plinth/modules/zoph/__init__.py
+++ b/plinth/modules/zoph/__init__.py
@@ -40,8 +40,6 @@ _description = [
box_name=_(cfg.box_name))
]
-app = None
-
class ZophApp(app_module.App):
"""FreedomBox app for Zoph."""
diff --git a/plinth/modules/zoph/views.py b/plinth/modules/zoph/views.py
index bb7ddc972..485fa30b5 100644
--- a/plinth/modules/zoph/views.py
+++ b/plinth/modules/zoph/views.py
@@ -12,6 +12,7 @@ from django.urls import reverse_lazy
from django.utils.translation import gettext as _
from django.views.generic import TemplateView
+from plinth import app as app_module
from plinth import views
from plinth.errors import ActionError
from plinth.modules import zoph
@@ -29,8 +30,9 @@ class SetupView(TemplateView):
def get_context_data(self, *args, **kwargs):
"""Provide context data to the template."""
context = super().get_context_data(**kwargs)
- context['title'] = zoph.app.info.name
- context['app_info'] = zoph.app.info
+ app = app_module.App.get('zoph')
+ context['title'] = app.info.name
+ context['app_info'] = app.info
return context
def post(self, _request, *args, **kwargs):