diff --git a/LICENSES b/LICENSES
index 27ecd15dd..7581e1686 100644
--- a/LICENSES
+++ b/LICENSES
@@ -45,29 +45,22 @@ specified and linked otherwise.
- doc/scripts.mdwn :: -
- doc/security.mdwn :: -
- doc/themes.mdwn :: -
-- modules/installed/first_boot.py :: -
-- modules/installed/apps/apps.py :: -
-- modules/installed/apps/owncloud.py :: -
-- modules/installed/help/help.py :: -
-- modules/installed/lib/auth_page.py :: -
-- modules/installed/lib/auth.py :: Derived from [[http://tools.cherrypy.org/wiki/AuthenticationAndAccessRestrictions][Arnar Birisson's CherryPy wiki code]].
-- modules/installed/lib/forms.py :: [[file:modules/installed/lib/forms.py::Copyright%202011-2013%20James%20Vasile][Copyright James Vasile]]
-- modules/installed/lib/user_store.py :: -
-- modules/installed/privacy/privacy.py :: -
-- modules/installed/router/info.py :: -
-- modules/installed/router/router.py :: -
-- modules/installed/santiago/santiago.py :: -
-- modules/installed/services/services.py :: -
-- modules/installed/services/xmpp.py :: -
-- modules/installed/sharing/file_explorer.py :: -
-- modules/installed/sharing/sharing.py :: -
-- modules/installed/system/config.py :: -
-- modules/installed/system/diagnostics.py :: -
-- modules/installed/system/expert_mode.py :: -
-- modules/installed/system/system.py :: -
-- modules/installed/system/time_zones :: -
-- modules/installed/system/users.py :: -
-- modules/installed/system/wan.py :: -
+- modules/apps/apps.py :: -
+- modules/config/config.py :: -
+- modules/diagnostics/diagnostics.py :: -
+- modules/expert_mode/expert_mode.py :: -
+- modules/first_boot/first_boot.py :: -
+- modules/help/help.py :: -
+- modules/lib/auth_page.py :: -
+- modules/lib/auth.py :: Derived from [[http://tools.cherrypy.org/wiki/AuthenticationAndAccessRestrictions][Arnar Birisson's CherryPy wiki code]].
+- modules/lib/user_store.py :: -
+- modules/owncloud/owncloud.py :: -
+- modules/packages/packages.py :: -
+- modules/santiago/santiago.py :: -
+- modules/system/system.py :: -
+- modules/tor/tor.py :: -
+- modules/users/users.py :: -
+- modules/xmpp/xmpp.py :: -
- setup/86_plinth :: -
- share/apache2/plinth.conf :: -
- share/apache2/plinth-ssl.conf :: -
diff --git a/modules/apps.py b/modules/apps.py
deleted file mode 120000
index d69ec8059..000000000
--- a/modules/apps.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/apps/apps.py
\ No newline at end of file
diff --git a/modules/installed/services/templates/openid.html b/modules/apps/__init__.py
similarity index 66%
rename from modules/installed/services/templates/openid.html
rename to modules/apps/__init__.py
index 69d6ab8a6..bf5f66418 100644
--- a/modules/installed/services/templates/openid.html
+++ b/modules/apps/__init__.py
@@ -1,5 +1,3 @@
-{% extends "login_nav.html" %}
-{% comment %}
#
# This file is part of Plinth.
#
@@ -16,14 +14,12 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
#
-{% endcomment %}
-{% block main_block %}
+"""
+Plinth module for apps section page
+"""
-
One Login for Every Site
+from . import apps
-Your {{ cfg.box_name }} is also an OpenID machine. It can generate
-credentials that allow you to log in to many websites without the need
-to remember or enter a separate username and password at each one.
-{% endblock %}
+__all__ = ['apps']
diff --git a/modules/installed/apps/apps.py b/modules/apps/apps.py
similarity index 66%
rename from modules/installed/apps/apps.py
rename to modules/apps/apps.py
index 43f8fcafd..05bb7fad3 100644
--- a/modules/installed/apps/apps.py
+++ b/modules/apps/apps.py
@@ -1,6 +1,5 @@
import cherrypy
from gettext import gettext as _
-from modules.auth import require
from plugin_mount import PagePlugin
import cfg
import util
@@ -12,15 +11,8 @@ class Apps(PagePlugin):
self.register_page("apps")
self.menu = cfg.main_menu.add_item("Apps", "icon-download-alt", "/apps", 80)
self.menu.add_item("Chat", "icon-comment", "/../jwchat", 30)
- self.menu.add_item("Photo Gallery", "icon-picture", "/apps/photos", 35)
@cherrypy.expose
def index(self):
return util.render_template(template='apps',
title=_('User Applications'))
-
- @cherrypy.expose
- @require()
- def photos(self):
- return util.render_template(template='photos',
- title=_('Photo Gallery'))
diff --git a/modules/installed/apps/templates/apps.html b/modules/apps/templates/apps.html
similarity index 100%
rename from modules/installed/apps/templates/apps.html
rename to modules/apps/templates/apps.html
diff --git a/modules/auth.py b/modules/auth.py
deleted file mode 120000
index 7a4c6eccd..000000000
--- a/modules/auth.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/lib/auth.py
\ No newline at end of file
diff --git a/modules/auth_page.py b/modules/auth_page.py
deleted file mode 120000
index 7ce3ca22a..000000000
--- a/modules/auth_page.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/lib/auth_page.py
\ No newline at end of file
diff --git a/modules/config.py b/modules/config.py
deleted file mode 120000
index 2e37164c3..000000000
--- a/modules/config.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/system/config.py
\ No newline at end of file
diff --git a/modules/installed/sharing/templates/sharing_printer.html b/modules/config/__init__.py
similarity index 65%
rename from modules/installed/sharing/templates/sharing_printer.html
rename to modules/config/__init__.py
index 05ef7fb3e..aface4101 100644
--- a/modules/installed/sharing/templates/sharing_printer.html
+++ b/modules/config/__init__.py
@@ -1,5 +1,3 @@
-{% extends "login_nav.html" %}
-{% comment %}
#
# This file is part of Plinth.
#
@@ -16,22 +14,12 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
#
-{% endcomment %}
-{% block main_block %}
+"""
+Plinth module for basic system configuration
+"""
-TODO: Setup and install SAMBA
-TODO: Setup and install CUPS
+from . import config
-{% endblock %}
-{% block sidebar_right_block %}
-
-
-
-{% endblock %}
+__all__ = ['config']
diff --git a/modules/installed/system/config.py b/modules/config/config.py
similarity index 99%
rename from modules/installed/system/config.py
rename to modules/config/config.py
index 808681f2e..bda9dd2de 100644
--- a/modules/installed/system/config.py
+++ b/modules/config/config.py
@@ -28,7 +28,7 @@ import socket
import actions
import cfg
-from modules.auth import require
+from ..lib.auth import require
from plugin_mount import PagePlugin
import util
diff --git a/modules/installed/system/templates/config.html b/modules/config/templates/config.html
similarity index 100%
rename from modules/installed/system/templates/config.html
rename to modules/config/templates/config.html
diff --git a/modules/diagnostics.py b/modules/diagnostics.py
deleted file mode 120000
index 31b7abf86..000000000
--- a/modules/diagnostics.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/system/diagnostics.py
\ No newline at end of file
diff --git a/modules/installed/apps/templates/photos.html b/modules/diagnostics/__init__.py
similarity index 63%
rename from modules/installed/apps/templates/photos.html
rename to modules/diagnostics/__init__.py
index 5658a54ff..8c01bd990 100644
--- a/modules/installed/apps/templates/photos.html
+++ b/modules/diagnostics/__init__.py
@@ -1,5 +1,3 @@
-{% extends 'login_nav.html' %}
-{% comment %}
#
# This file is part of Plinth.
#
@@ -16,14 +14,12 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
#
-{% endcomment %}
-{% block main_block %}
+"""
+Plinth module to system diagnostics
+"""
-Your photos might well be the most valuable digital property you
-have, so why trust it to companies that have no investment in the
-sentimental value of your family snaps? Keep those photos local,
-backed up, easily accessed and free from the whims of some other
-websites business model.
+from . import diagnostics
-{% endblock %}
+
+__all__ = ['diagnostics']
diff --git a/modules/installed/system/diagnostics.py b/modules/diagnostics/diagnostics.py
similarity index 98%
rename from modules/installed/system/diagnostics.py
rename to modules/diagnostics/diagnostics.py
index db05738a2..e82de7d11 100644
--- a/modules/installed/system/diagnostics.py
+++ b/modules/diagnostics/diagnostics.py
@@ -21,7 +21,7 @@ Plinth module for running diagnostics
import cherrypy
from gettext import gettext as _
-from auth import require
+from ..lib.auth import require
from plugin_mount import PagePlugin
import actions
import cfg
diff --git a/modules/installed/system/templates/diagnostics.html b/modules/diagnostics/templates/diagnostics.html
similarity index 100%
rename from modules/installed/system/templates/diagnostics.html
rename to modules/diagnostics/templates/diagnostics.html
diff --git a/modules/installed/system/templates/diagnostics_test.html b/modules/diagnostics/templates/diagnostics_test.html
similarity index 100%
rename from modules/installed/system/templates/diagnostics_test.html
rename to modules/diagnostics/templates/diagnostics_test.html
diff --git a/modules/enabled/apps b/modules/enabled/apps
new file mode 120000
index 000000000..ee655a64d
--- /dev/null
+++ b/modules/enabled/apps
@@ -0,0 +1 @@
+../apps/
\ No newline at end of file
diff --git a/modules/enabled/config b/modules/enabled/config
new file mode 120000
index 000000000..408852685
--- /dev/null
+++ b/modules/enabled/config
@@ -0,0 +1 @@
+../config/
\ No newline at end of file
diff --git a/modules/enabled/diagnostics b/modules/enabled/diagnostics
new file mode 120000
index 000000000..44f76bee7
--- /dev/null
+++ b/modules/enabled/diagnostics
@@ -0,0 +1 @@
+../diagnostics/
\ No newline at end of file
diff --git a/modules/enabled/expert_mode b/modules/enabled/expert_mode
new file mode 120000
index 000000000..0006eedc0
--- /dev/null
+++ b/modules/enabled/expert_mode
@@ -0,0 +1 @@
+../expert_mode/
\ No newline at end of file
diff --git a/modules/enabled/firewall b/modules/enabled/firewall
new file mode 120000
index 000000000..ecb364d05
--- /dev/null
+++ b/modules/enabled/firewall
@@ -0,0 +1 @@
+../firewall/
\ No newline at end of file
diff --git a/modules/enabled/first_boot b/modules/enabled/first_boot
new file mode 120000
index 000000000..b977d6c94
--- /dev/null
+++ b/modules/enabled/first_boot
@@ -0,0 +1 @@
+../first_boot/
\ No newline at end of file
diff --git a/modules/enabled/help b/modules/enabled/help
new file mode 120000
index 000000000..76c213eda
--- /dev/null
+++ b/modules/enabled/help
@@ -0,0 +1 @@
+../help/
\ No newline at end of file
diff --git a/modules/enabled/lib b/modules/enabled/lib
new file mode 120000
index 000000000..5bf80bf13
--- /dev/null
+++ b/modules/enabled/lib
@@ -0,0 +1 @@
+../lib/
\ No newline at end of file
diff --git a/modules/enabled/owncloud b/modules/enabled/owncloud
new file mode 120000
index 000000000..b9d942937
--- /dev/null
+++ b/modules/enabled/owncloud
@@ -0,0 +1 @@
+../owncloud/
\ No newline at end of file
diff --git a/modules/enabled/packages b/modules/enabled/packages
new file mode 120000
index 000000000..f314f73fa
--- /dev/null
+++ b/modules/enabled/packages
@@ -0,0 +1 @@
+../packages/
\ No newline at end of file
diff --git a/modules/enabled/pagekite b/modules/enabled/pagekite
new file mode 120000
index 000000000..1c4c9c144
--- /dev/null
+++ b/modules/enabled/pagekite
@@ -0,0 +1 @@
+../pagekite/
\ No newline at end of file
diff --git a/modules/enabled/system b/modules/enabled/system
new file mode 120000
index 000000000..16f8cc2b2
--- /dev/null
+++ b/modules/enabled/system
@@ -0,0 +1 @@
+../system/
\ No newline at end of file
diff --git a/modules/enabled/tor b/modules/enabled/tor
new file mode 120000
index 000000000..f7495e4ab
--- /dev/null
+++ b/modules/enabled/tor
@@ -0,0 +1 @@
+../tor/
\ No newline at end of file
diff --git a/modules/enabled/users b/modules/enabled/users
new file mode 120000
index 000000000..db9284fbb
--- /dev/null
+++ b/modules/enabled/users
@@ -0,0 +1 @@
+../users/
\ No newline at end of file
diff --git a/modules/enabled/xmpp b/modules/enabled/xmpp
new file mode 120000
index 000000000..686474fe7
--- /dev/null
+++ b/modules/enabled/xmpp
@@ -0,0 +1 @@
+../xmpp/
\ No newline at end of file
diff --git a/modules/expert_mode.py b/modules/expert_mode.py
deleted file mode 120000
index aaa140ed1..000000000
--- a/modules/expert_mode.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/system/expert_mode.py
\ No newline at end of file
diff --git a/modules/installed/sharing/templates/sharing.html b/modules/expert_mode/__init__.py
similarity index 62%
rename from modules/installed/sharing/templates/sharing.html
rename to modules/expert_mode/__init__.py
index 020c3edfe..c638fd55e 100644
--- a/modules/installed/sharing/templates/sharing.html
+++ b/modules/expert_mode/__init__.py
@@ -1,5 +1,3 @@
-{% extends "login_nav.html" %}
-{% comment %}
#
# This file is part of Plinth.
#
@@ -16,18 +14,12 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
#
-{% endcomment %}
-{% block sidebar_right_block %}
+"""
+Plinth module for expert mode configuration
+"""
-
-
-{% endblock %}
+__all__ = ['expert_mode']
diff --git a/modules/installed/system/expert_mode.py b/modules/expert_mode/expert_mode.py
similarity index 90%
rename from modules/installed/system/expert_mode.py
rename to modules/expert_mode/expert_mode.py
index 041ce0793..50c2811e6 100644
--- a/modules/installed/system/expert_mode.py
+++ b/modules/expert_mode/expert_mode.py
@@ -1,7 +1,7 @@
import cherrypy
from django import forms
from gettext import gettext as _
-from modules.auth import require
+from ..lib.auth import require
from plugin_mount import PagePlugin
import cfg
import util
@@ -24,10 +24,10 @@ class Experts(PagePlugin):
def __init__(self, *args, **kwargs):
PagePlugin.__init__(self, *args, **kwargs)
- self.register_page('sys.config.expert')
+ self.register_page('sys.expert')
- cfg.html_root.sys.config.menu.add_item(_('Expert mode'), 'icon-cog',
- '/sys/config/expert', 10)
+ cfg.html_root.sys.menu.add_item(_('Expert Mode'), 'icon-cog',
+ '/sys/expert', 10)
@cherrypy.expose
@require()
diff --git a/modules/installed/system/templates/expert_mode.html b/modules/expert_mode/templates/expert_mode.html
similarity index 100%
rename from modules/installed/system/templates/expert_mode.html
rename to modules/expert_mode/templates/expert_mode.html
diff --git a/modules/file_explorer.py b/modules/file_explorer.py
deleted file mode 120000
index f19191667..000000000
--- a/modules/file_explorer.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/sharing/file_explorer.py
\ No newline at end of file
diff --git a/modules/firewall.py b/modules/firewall.py
deleted file mode 120000
index 1d198303f..000000000
--- a/modules/firewall.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/system/firewall.py
\ No newline at end of file
diff --git a/modules/firewall/__init__.py b/modules/firewall/__init__.py
new file mode 100644
index 000000000..33eb5d302
--- /dev/null
+++ b/modules/firewall/__init__.py
@@ -0,0 +1,25 @@
+#
+# This file is part of Plinth.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+"""
+Plinth module to configure a firewall
+"""
+
+from . import firewall
+
+
+__all__ = ['firewall']
diff --git a/modules/installed/system/firewall.py b/modules/firewall/firewall.py
similarity index 99%
rename from modules/installed/system/firewall.py
rename to modules/firewall/firewall.py
index e736627f1..ebdbf67a7 100644
--- a/modules/installed/system/firewall.py
+++ b/modules/firewall/firewall.py
@@ -24,7 +24,7 @@ from gettext import gettext as _
import actions
import cfg
-from modules.auth import require
+from ..lib.auth import require
from plugin_mount import PagePlugin
import service as service_module
import util
diff --git a/modules/installed/system/templates/firewall.html b/modules/firewall/templates/firewall.html
similarity index 100%
rename from modules/installed/system/templates/firewall.html
rename to modules/firewall/templates/firewall.html
diff --git a/modules/first_boot.py b/modules/first_boot.py
deleted file mode 120000
index ae5c55471..000000000
--- a/modules/first_boot.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/first_boot.py
\ No newline at end of file
diff --git a/modules/first_boot/__init__.py b/modules/first_boot/__init__.py
new file mode 100644
index 000000000..20e972dae
--- /dev/null
+++ b/modules/first_boot/__init__.py
@@ -0,0 +1,25 @@
+#
+# This file is part of Plinth.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+"""
+Plinth module for first boot wizard
+"""
+
+from . import first_boot
+
+
+__all__ = ['first_boot']
diff --git a/modules/installed/first_boot.py b/modules/first_boot/first_boot.py
similarity index 88%
rename from modules/installed/first_boot.py
rename to modules/first_boot/first_boot.py
index 8fdde7b31..7bcf98e27 100644
--- a/modules/installed/first_boot.py
+++ b/modules/first_boot/first_boot.py
@@ -23,10 +23,10 @@ from django import forms
from django.core import validators
from gettext import gettext as _
from plugin_mount import PagePlugin
-from modules.auth import add_user
+from ..lib.auth import add_user
+from ..config import config
from withsqlite.withsqlite import sqlite_db
import cfg
-import config
import util
@@ -100,8 +100,12 @@ class FirstBoot(PagePlugin):
message is an optional string that we can display to the
user. It's a good place to put error messages.
"""
+ try:
+ if FirstBoot._read_state() >= 5:
+ raise cherrypy.HTTPRedirect(cfg.server_dir, 302)
+ except KeyError:
+ pass
- # FIXME: reject connection attempt if db["state"] >= 5.
## Until LDAP is in place, we'll put the box key in the cfg.store_file
status = self.get_state0()
@@ -117,11 +121,8 @@ class FirstBoot(PagePlugin):
if success:
# Everything is good, permanently mark and move to page 2
- with sqlite_db(cfg.store_file, table="firstboot",
- autocommit=True) as database:
- database['state'] = 1
-
- raise cherrypy.InternalRedirect('state1')
+ FirstBoot._write_state(1)
+ raise cherrypy.HTTPRedirect('state1', 302)
else:
form = State0Form(initial=status, prefix='firstboot')
@@ -176,9 +177,21 @@ class FirstBoot(PagePlugin):
"""
# TODO complete first_boot handling
# Make sure the user is not stuck on a dead end for now.
- with sqlite_db(cfg.store_file, table='firstboot', autocommit=True) as \
- database:
- database['state'] = 5
+ FirstBoot._write_state(5)
return util.render_template(template='firstboot_state1',
title=_('Installing the Certificate'))
+
+ @staticmethod
+ def _read_state():
+ """Read the current state from database"""
+ with sqlite_db(cfg.store_file, table='firstboot',
+ autocommit=True) as database:
+ return database['state']
+
+ @staticmethod
+ def _write_state(state):
+ """Write state to database"""
+ with sqlite_db(cfg.store_file, table='firstboot',
+ autocommit=True) as database:
+ database['state'] = state
diff --git a/modules/installed/templates/firstboot_sidebar.html b/modules/first_boot/templates/firstboot_sidebar.html
similarity index 100%
rename from modules/installed/templates/firstboot_sidebar.html
rename to modules/first_boot/templates/firstboot_sidebar.html
diff --git a/modules/installed/templates/firstboot_state0.html b/modules/first_boot/templates/firstboot_state0.html
similarity index 100%
rename from modules/installed/templates/firstboot_state0.html
rename to modules/first_boot/templates/firstboot_state0.html
diff --git a/modules/installed/templates/firstboot_state1.html b/modules/first_boot/templates/firstboot_state1.html
similarity index 94%
rename from modules/installed/templates/firstboot_state1.html
rename to modules/first_boot/templates/firstboot_state1.html
index 5ea907ff9..7a40fcf1e 100644
--- a/modules/installed/templates/firstboot_state1.html
+++ b/modules/first_boot/templates/firstboot_state1.html
@@ -23,7 +23,7 @@
{% block main_block %}
Welcome screen not completely implemented yet. Press continue to see the rest of the
+ href="{{basehref }}/apps">continue to see the rest of the
web interface.
diff --git a/modules/forms.py b/modules/forms.py
deleted file mode 120000
index 4b0a50792..000000000
--- a/modules/forms.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/lib/forms.py
\ No newline at end of file
diff --git a/modules/help.py b/modules/help.py
deleted file mode 120000
index 3fc0799d2..000000000
--- a/modules/help.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/help/help.py
\ No newline at end of file
diff --git a/modules/help/__init__.py b/modules/help/__init__.py
new file mode 100644
index 000000000..9ef609e2d
--- /dev/null
+++ b/modules/help/__init__.py
@@ -0,0 +1,25 @@
+#
+# This file is part of Plinth.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+"""
+Plinth module for help pages
+"""
+
+from . import help # pylint: disable-msg=W0622
+
+
+__all__ = ['help']
diff --git a/modules/installed/help/help.py b/modules/help/help.py
similarity index 100%
rename from modules/installed/help/help.py
rename to modules/help/help.py
diff --git a/modules/installed/help/templates/about.html b/modules/help/templates/about.html
similarity index 100%
rename from modules/installed/help/templates/about.html
rename to modules/help/templates/about.html
diff --git a/modules/installed/help/templates/help.html b/modules/help/templates/help.html
similarity index 100%
rename from modules/installed/help/templates/help.html
rename to modules/help/templates/help.html
diff --git a/modules/info.py b/modules/info.py
deleted file mode 120000
index 0cc405209..000000000
--- a/modules/info.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/router/info.py
\ No newline at end of file
diff --git a/modules/installed/privacy/privacy.py b/modules/installed/privacy/privacy.py
deleted file mode 100644
index 8de533f88..000000000
--- a/modules/installed/privacy/privacy.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import cherrypy
-from gettext import gettext as _
-from plugin_mount import PagePlugin
-from modules.auth import require
-import cfg
-import util
-
-
-class Privacy(PagePlugin):
- order = 20 # order of running init in PagePlugins
- def __init__(self, *args, **kwargs):
- PagePlugin.__init__(self, *args, **kwargs)
- self.register_page("privacy")
- self.menu = cfg.main_menu.add_item("Privacy", "icon-eye-open", "/privacy", 12)
- self.menu.add_item("General Config", "icon-asterisk", "/privacy/config", 10)
- self.menu.add_item("Ad Blocking", "icon-ban-circle", "/privacy/adblock", 20)
- self.menu.add_item("HTTPS Everywhere", "icon-lock", "/privacy/https_everywhere", 30)
-
- @cherrypy.expose
- def index(self):
- #raise cherrypy.InternalRedirect('/privacy/config')
- return self.config()
-
- @cherrypy.expose
- @require()
- def config(self):
- return util.render_template(template='privacy_config',
- title=_('Privacy Control Panel'))
diff --git a/modules/installed/privacy/templates/privacy_config.html b/modules/installed/privacy/templates/privacy_config.html
deleted file mode 100644
index cc3becb15..000000000
--- a/modules/installed/privacy/templates/privacy_config.html
+++ /dev/null
@@ -1,46 +0,0 @@
-{% extends "login_nav.html" %}
-{% comment %}
-#
-# This file is part of Plinth.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-{% endcomment %}
-
-{% block main_block %}
-
-Privacy controls are not yet implemented. This page is a
-placeholder and a promise: privacy is important enough that it is a
-founding consideration, not an afterthought.
-
-{% endblock %}
-
-{% block sidebar_right_block %}
-
-
-
-{% endblock %}
diff --git a/modules/installed/router/info.py b/modules/installed/router/info.py
deleted file mode 100644
index cc9c5539a..000000000
--- a/modules/installed/router/info.py
+++ /dev/null
@@ -1,21 +0,0 @@
-import cherrypy
-from plugin_mount import PagePlugin
-from modules.auth import require
-import util
-
-
-class Info(PagePlugin):
- title = 'Info'
- order = 10
- url = 'info'
-
- def __init__(self, *args, **kwargs):
- self.register_page("router.info")
-
- @cherrypy.expose
- @require()
- def index(self):
- return util.render_template(title="Router Information", main="""
-Eventually we will display a bunch of info, graphs and logs about
-the routing functions here.
-""")
diff --git a/modules/installed/router/router.py b/modules/installed/router/router.py
deleted file mode 100644
index 2cc75d980..000000000
--- a/modules/installed/router/router.py
+++ /dev/null
@@ -1,150 +0,0 @@
-import cherrypy
-from django import forms
-from gettext import gettext as _
-from plugin_mount import PagePlugin
-from modules.auth import require
-import cfg
-import util
-
-
-class Router(PagePlugin):
- """Router page"""
- order = 9 # order of running init in PagePlugins
-
- def __init__(self, *args, **kwargs):
- PagePlugin.__init__(self, args, kwargs)
-
- self.register_page('router')
-
- self.menu = cfg.main_menu.add_item('Router', 'icon-retweet', '/router',
- 10)
- self.menu.add_item('Wireless', 'icon-signal', '/router/wireless', 12)
- self.menu.add_item('Firewall', 'icon-fire', '/router/firewall', 18)
- self.menu.add_item('Hotspot and Mesh', 'icon-map-marker',
- '/router/hotspot')
- self.menu.add_item('Info', 'icon-list-alt', '/router/info', 100)
-
- @staticmethod
- @cherrypy.expose
- def index():
- """This isn't an internal redirect, because we need the url to
- reflect that we've moved down into the submenu hierarchy.
- Otherwise, it's hard to know which menu portion to make active
- or expand or contract."""
- raise cherrypy.HTTPRedirect(cfg.server_dir + '/router/setup')
-
- @staticmethod
- @cherrypy.expose
- @require()
- def wireless():
- """Serve the wireless page"""
- return util.render_template(title="Wireless",
- main="wireless setup: essid, etc.
")
-
- @staticmethod
- @cherrypy.expose
- @require()
- def firewall():
- """Serve the firewall page"""
- return util.render_template(title="Firewall",
- main="Iptables twiddling.
")
-
- @staticmethod
- @cherrypy.expose
- @require()
- def hotspot():
- """Serve the hotspot page"""
- return util.render_template(title="Hotspot and Mesh",
- main="connection sharing setup.
")
-
-
-class WANForm(forms.Form): # pylint: disable-msg=W0232
- """WAN setup form"""
- connection_type = forms.ChoiceField(
- label=_('Connection Type'),
- choices=[('dhcp', _('DHCP')), ('static_ip', _('Static IP'))])
-
- wan_ip = forms.IPAddressField(label=_('WAN IP Address'), required=False)
-
- subnet_mask = forms.IPAddressField(label=_('Subnet Mask'), required=False)
-
- dns_1 = forms.IPAddressField(label=_('Static DNS 1'), required=False)
-
- dns_2 = forms.IPAddressField(label=_('Static DNS 2'), required=False)
-
- dns_3 = forms.IPAddressField(label=_('Static DNS 3'), required=False)
-
-
-class Setup(PagePlugin):
- """Router setup page"""
- def __init__(self, *args, **kwargs):
- PagePlugin.__init__(self, args, kwargs)
-
- self.register_page('router.setup')
-
- self.menu = cfg.html_root.router.menu.add_item(
- 'General Setup', 'icon-cog', '/router/setup', 10)
- self.menu.add_item('Dynamic DNS', 'icon-flag', '/router/setup/ddns',
- 20)
- self.menu.add_item('MAC Address Clone', 'icon-barcode',
- '/router/setup/mac_address', 30)
-
- @cherrypy.expose
- @require()
- def index(self, **kwargs):
- """Return the setup page"""
- status = self.get_status()
-
- form = None
- messages = []
-
- if kwargs:
- form = WANForm(kwargs, prefix='router')
- # pylint: disable-msg=E1101
- if form.is_valid():
- self._apply_changes(status, form.cleaned_data, messages)
- status = self.get_status()
- form = WANForm(initial=status, prefix='router')
- else:
- form = WANForm(initial=status, prefix='router')
-
- return util.render_template(template='router_setup',
- title=_('General Router Setup'),
- form=form, messages=messages)
-
- @staticmethod
- @cherrypy.expose
- @require()
- def ddns():
- """Return the DDNS page"""
- return util.render_template(title="Dynamic DNS",
- main="Masquerade setup
")
-
- @staticmethod
- @cherrypy.expose
- @require()
- def mac_address():
- """Return the MAC address page"""
- return util.render_template(
- title="MAC Address Cloning",
- main="Your router can pretend to have a different MAC address \
-on any interface.
")
-
- @staticmethod
- def get_status():
- """Return the current status"""
- store = util.filedict_con(cfg.store_file, 'router')
- return {'connection_type': store.get('connection_type', 'dhcp')}
-
- @staticmethod
- def _apply_changes(old_status, new_status, messages):
- """Apply the changes"""
- print 'Apply changes - %s, %s', old_status, new_status
- if old_status['connection_type'] == new_status['connection_type']:
- return
-
- store = util.filedict_con(cfg.store_file, 'router')
- store['connection_type'] = new_status['connection_type']
-
- messages.append(('success', _('Connection type set')))
- messages.append(('info', _('IP address settings unimplemented')))
diff --git a/modules/installed/router/templates/router_setup.html b/modules/installed/router/templates/router_setup.html
deleted file mode 100644
index c484c5585..000000000
--- a/modules/installed/router/templates/router_setup.html
+++ /dev/null
@@ -1,117 +0,0 @@
-{% extends "login_nav.html" %}
-{% comment %}
-#
-# This file is part of Plinth.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-{% endcomment %}
-
-{% block main_block %}
-
-{% if cfg.users.expert %}
-
- WAN Connection
-
- {% include 'messages.html' %}
-
-
-
-{% else %}
-
- In basic mode, you don't need to do any router setup before you
- can go online. Just plug your {{ cfg.product_name }} in to your
- cable or DSL modem and the router will try to get you on the
- internet using DHCP.
-
- If that fails, you might need to resort to the expert options.
- Enable expert mode in the "{{ cfg.product_name }} / System /
- Configure" menu.
-
-{% endif %}
-
-{% endblock %}
-
-{% block sidebar_right_block %}
-
-
-
-{% endblock %}
-
-{% block js_block %}
- {{ js|safe }}
-
-
-
-{% endblock %}
diff --git a/modules/installed/services/services.py b/modules/installed/services/services.py
deleted file mode 100644
index 0bf5fb698..000000000
--- a/modules/installed/services/services.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import cherrypy
-from modules.auth import require
-from plugin_mount import PagePlugin
-import cfg
-import util
-
-
-class Services(PagePlugin):
- order = 9 # order of running init in PagePlugins
- def __init__(self, *args, **kwargs):
- PagePlugin.__init__(self, *args, **kwargs)
- self.register_page("services")
- self.menu = cfg.main_menu.add_item("Services", "icon-list", "/services", 90)
- self.menu.add_item("Open ID", "icon-user", "/services/openid", 35)
-
- @cherrypy.expose
- def index(self):
- return self.openid()
-
- @cherrypy.expose
- @require()
- def openid(self):
- return util.render_template(template='openid', title="Open ID")
diff --git a/modules/installed/sharing/file_explorer.py b/modules/installed/sharing/file_explorer.py
deleted file mode 100644
index c56cdb504..000000000
--- a/modules/installed/sharing/file_explorer.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import cherrypy
-from gettext import gettext as _
-from modules.auth import require
-from plugin_mount import PagePlugin
-import cfg
-import util
-
-
-class FileExplorer(PagePlugin):
- def __init__(self, *args, **kwargs):
- PagePlugin.__init__(self, *args, **kwargs)
- self.register_page("sharing.explorer")
- cfg.html_root.sharing.menu.add_item("File Explorer", "icon-folder-open", "/sharing/explorer", 30)
-
- @cherrypy.expose
- @require()
- def index(self):
- return util.render_template(template='file_explorer',
- title=_('File Explorer'))
diff --git a/modules/installed/sharing/sharing.py b/modules/installed/sharing/sharing.py
deleted file mode 100644
index 81e004c20..000000000
--- a/modules/installed/sharing/sharing.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import cherrypy
-from gettext import gettext as _
-from modules.auth import require
-from plugin_mount import PagePlugin
-import cfg
-import util
-
-
-class Sharing(PagePlugin):
- order = 9 # order of running init in PagePlugins
-
- def __init__(self, *args, **kwargs):
- PagePlugin.__init__(self, *args, **kwargs)
- self.register_page("sharing")
- self.menu = cfg.main_menu.add_item("Sharing", "icon-share-alt", "/sharing", 35)
- self.menu.add_item("File Server", "icon-inbox", "/sharing/files", 10)
-
- @cherrypy.expose
- def index(self):
- """This isn't an internal redirect, because we need the url to
- reflect that we've moved down into the submenu hierarchy.
- Otherwise, it's hard to know which menu portion to make active
- or expand or contract."""
- raise cherrypy.HTTPRedirect(cfg.server_dir + '/sharing/files')
-
- @cherrypy.expose
- @require()
- def files(self):
- return util.render_template(template='sharing',
- title=_('File Server'))
-
-
-#TODO: move PrinterSharing to another file, as it should be an optional module (most people don't care about printer sharing)
-class PrinterSharing(PagePlugin):
- def __init__(self, *args, **kwargs):
- PagePlugin.__init__(self, *args, **kwargs)
- self.register_page("sharing.printer")
- cfg.html_root.sharing.menu.add_item("Printer Sharing", "icon-print", "/sharing/printer", 35)
-
- @cherrypy.expose
- @require()
- def index(self):
- return util.render_template(template='sharing_printer',
- title=_('Printer Sharing'))
diff --git a/modules/installed/sharing/templates/file_explorer.html b/modules/installed/sharing/templates/file_explorer.html
deleted file mode 100644
index a7f98b232..000000000
--- a/modules/installed/sharing/templates/file_explorer.html
+++ /dev/null
@@ -1,42 +0,0 @@
-{% extends 'login_nav.html' %}
-{% comment %}
-#
-# This file is part of Plinth.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-{% endcomment %}
-
-{% block main_block %}
-
-File explorer for users that also have shell accounts.
Until
-that is written (and it will be a while), we should
-install mollify
-or ajaxplorer,
-but of which seem to have some support for playing media files in the
-browser (as opposed to forcing users to download and play them
-locally). The downsides to third-party explorers are: they're don't
-fit within our theme system, they require separate login, and they're
-written in php, which will make integrating them hard.
-
-There are, of course, many other options for php-based file
-explorers. These were the ones I saw that might do built-in media
-players.
-
-For python-friendly options, check out FileManager.
-It appears to be mostly javascript with some bindings to make it
-python-friendly.
-
-{% endblock %}
diff --git a/modules/installed/system/templates/wan.html b/modules/installed/system/templates/wan.html
deleted file mode 100644
index ea83226d0..000000000
--- a/modules/installed/system/templates/wan.html
+++ /dev/null
@@ -1,52 +0,0 @@
-{% extends "login_nav.html" %}
-{% comment %}
-#
-# This file is part of Plinth.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-{% endcomment %}
-
-{% load bootstrap %}
-
-{% block main_block %}
-
-{% if cfg.users.expert %}
-
- {% include 'messages.html' %}
-
- For security reasons, neither WAN Administration nor WAN SSH is
- available to the `admin` user account.
-
- TODO: in expert mode, tell user they can ssh in to enable admin
- from WAN, do their business, then disable it. It would be good to
- enable the option and autodisable it when the ssh connection
- dies.
-
-
-
-{% else %}
-
- This page is available only in expert mode.
-
-{% endif %}
-
-{% endblock %}
diff --git a/modules/installed/system/wan.py b/modules/installed/system/wan.py
deleted file mode 100644
index 962fe806f..000000000
--- a/modules/installed/system/wan.py
+++ /dev/null
@@ -1,85 +0,0 @@
-import cherrypy
-from django import forms
-from gettext import gettext as _
-from modules.auth import require
-from plugin_mount import PagePlugin
-import cfg
-import util
-
-
-class WanForm(forms.Form): # pylint: disable-msg=W0232
- """Form to configure wan settings"""
-
- wan_admin = forms.BooleanField(
- label=_('Allow access to Plinth from WAN'),
- required=False,
- help_text=_('If you check this box, this front end will be reachable \
-from the WAN. If your {{ box_name }} connects you to the internet, that \
-means you\'ll be able to log in to the front end from the internet. This \
-might be convenient, but it is also dangerous, since it can \
-enable attackers to gain access to your {{ box_name }} from the outside \
-world. All they\'ll need is your username and passphrase, which they might \
-guess or they might simply try every posible combination of letters and \
-numbers until they get in. If you enable the WAN administration option, you \
-must use long and complex passphrases.').format(
- box_name=cfg.box_name))
-
- lan_ssh = forms.BooleanField(
- label=_('Allow SSH access from LAN'),
- required=False)
-
- wan_ssh = forms.BooleanField(
- label=_('Allow SSH access from WAN'),
- required=False)
-
- # XXX: Only present due to issue with submitting empty form
- dummy = forms.CharField(label='Dummy', initial='dummy',
- widget=forms.HiddenInput())
-
-
-class Wan(PagePlugin):
- order = 60
-
- def __init__(self, *args, **kwargs):
- PagePlugin.__init__(self, *args, **kwargs)
- self.register_page('sys.config.wan')
-
- cfg.html_root.sys.config.menu.add_item(_('WAN'), 'icon-cog',
- '/sys/config/wan', 20)
-
- @cherrypy.expose
- @require()
- def index(self, **kwargs):
- """Serve the configuration form"""
- status = self.get_status()
-
- form = None
- messages = []
-
- if kwargs and cfg.users.expert():
- form = WanForm(kwargs, prefix='wan')
- # pylint: disable-msg=E1101
- if form.is_valid():
- self._apply_changes(form.cleaned_data, messages)
- status = self.get_status()
- form = WanForm(initial=status, prefix='wan')
- else:
- form = WanForm(initial=status, prefix='wan')
-
- title = _('Accessing the {box_name}').format(box_name=cfg.box_name)
- return util.render_template(template='wan', title=title, form=form,
- messages=messages)
-
- @staticmethod
- def get_status():
- """Return the current status"""
- return util.filedict_con(cfg.store_file, 'sys')
-
- @staticmethod
- def _apply_changes(new_status, messages):
- """Apply the changes after form submission"""
- store = util.filedict_con(cfg.store_file, 'sys')
- for field in ['wan_admin', 'wan_ssh', 'lan_ssh']:
- store[field] = new_status[field]
-
- messages.append(('success', _('Setting updated')))
diff --git a/modules/lib/__init__.py b/modules/lib/__init__.py
new file mode 100644
index 000000000..ab399cd3f
--- /dev/null
+++ b/modules/lib/__init__.py
@@ -0,0 +1,29 @@
+#
+# This file is part of Plinth.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+"""
+Plinth library modules
+"""
+
+from . import auth
+from . import auth_page
+from . import user_store
+
+
+__all__ = ['auth',
+ 'auth_page',
+ 'user_store']
diff --git a/modules/installed/lib/auth.py b/modules/lib/auth.py
similarity index 100%
rename from modules/installed/lib/auth.py
rename to modules/lib/auth.py
diff --git a/modules/installed/lib/auth_page.py b/modules/lib/auth_page.py
similarity index 100%
rename from modules/installed/lib/auth_page.py
rename to modules/lib/auth_page.py
diff --git a/modules/installed/lib/user_store.py b/modules/lib/user_store.py
similarity index 100%
rename from modules/installed/lib/user_store.py
rename to modules/lib/user_store.py
diff --git a/modules/owncloud.py b/modules/owncloud.py
deleted file mode 120000
index 4ae17c8be..000000000
--- a/modules/owncloud.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/apps/owncloud.py
\ No newline at end of file
diff --git a/modules/owncloud/__init__.py b/modules/owncloud/__init__.py
new file mode 100644
index 000000000..544b2ebc7
--- /dev/null
+++ b/modules/owncloud/__init__.py
@@ -0,0 +1,25 @@
+#
+# This file is part of Plinth.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+"""
+Plinth module to configure ownCloud
+"""
+
+from . import owncloud
+
+
+__all__ = ['owncloud']
diff --git a/modules/installed/apps/owncloud.py b/modules/owncloud/owncloud.py
similarity index 98%
rename from modules/installed/apps/owncloud.py
rename to modules/owncloud/owncloud.py
index 7ed4dfcdb..535ba019b 100644
--- a/modules/installed/apps/owncloud.py
+++ b/modules/owncloud/owncloud.py
@@ -1,7 +1,7 @@
import cherrypy
from django import forms
from gettext import gettext as _
-from modules.auth import require
+from ..lib.auth import require
from plugin_mount import PagePlugin
import actions
import cfg
diff --git a/modules/installed/apps/templates/owncloud.html b/modules/owncloud/templates/owncloud.html
similarity index 100%
rename from modules/installed/apps/templates/owncloud.html
rename to modules/owncloud/templates/owncloud.html
diff --git a/modules/packages.py b/modules/packages.py
deleted file mode 120000
index fa4dedfc6..000000000
--- a/modules/packages.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/system/packages.py
\ No newline at end of file
diff --git a/modules/packages/__init__.py b/modules/packages/__init__.py
new file mode 100644
index 000000000..f84ac44c1
--- /dev/null
+++ b/modules/packages/__init__.py
@@ -0,0 +1,25 @@
+#
+# This file is part of Plinth.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+"""
+Plinth module to manage packages
+"""
+
+from . import packages
+
+
+__all__ = ['packages']
diff --git a/modules/installed/system/packages.py b/modules/packages/packages.py
similarity index 99%
rename from modules/installed/system/packages.py
rename to modules/packages/packages.py
index 63df8cab0..89fe69676 100644
--- a/modules/installed/system/packages.py
+++ b/modules/packages/packages.py
@@ -1,7 +1,7 @@
import cherrypy
from django import forms
from gettext import gettext as _
-from auth import require
+from ..lib.auth import require
from plugin_mount import PagePlugin
import actions
import cfg
diff --git a/modules/installed/system/templates/packages.html b/modules/packages/templates/packages.html
similarity index 100%
rename from modules/installed/system/templates/packages.html
rename to modules/packages/templates/packages.html
diff --git a/modules/pagekite.py b/modules/pagekite.py
deleted file mode 120000
index 2981955ca..000000000
--- a/modules/pagekite.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/router/pagekite.py
\ No newline at end of file
diff --git a/modules/pagekite/__init__.py b/modules/pagekite/__init__.py
new file mode 100644
index 000000000..fa247ab25
--- /dev/null
+++ b/modules/pagekite/__init__.py
@@ -0,0 +1,25 @@
+#
+# This file is part of Plinth.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+"""
+Plinth module to configure PageKite
+"""
+
+from . import pagekite
+
+
+__all__ = ['pagekite']
diff --git a/modules/installed/router/pagekite.py b/modules/pagekite/pagekite.py
similarity index 96%
rename from modules/installed/router/pagekite.py
rename to modules/pagekite/pagekite.py
index 799a8860d..cc7791a2d 100644
--- a/modules/installed/router/pagekite.py
+++ b/modules/pagekite/pagekite.py
@@ -26,7 +26,7 @@ from gettext import gettext as _
import actions
import cfg
-from modules.auth import require
+from ..lib.auth import require
from plugin_mount import PagePlugin
import util
@@ -38,10 +38,10 @@ class PageKite(PagePlugin):
def __init__(self, *args, **kwargs):
PagePlugin.__init__(self, *args, **kwargs)
- self.register_page("router.setup.pagekite")
- cfg.html_root.router.setup.menu.add_item(
+ self.register_page("apps.pagekite")
+ cfg.html_root.apps.menu.add_item(
_("Public Visibility (PageKite)"), "icon-flag",
- "/router/setup/pagekite", 50)
+ "/apps/pagekite", 50)
@staticmethod
@cherrypy.expose
@@ -51,7 +51,7 @@ class PageKite(PagePlugin):
del kwargs # Unused
menu = {'title': _('PageKite'),
- 'items': [{'url': '/router/setup/pagekite/configure',
+ 'items': [{'url': '/apps/pagekite/configure',
'text': _('Configure PageKite')}]}
sidebar_right = util.render_template(template='menu_block', menu=menu)
@@ -112,7 +112,7 @@ class Configure(PagePlugin): # pylint: disable-msg=C0103
def __init__(self, *args, **kwargs):
PagePlugin.__init__(self, *args, **kwargs)
- self.register_page("router.setup.pagekite.configure")
+ self.register_page("apps.pagekite.configure")
@cherrypy.expose
@require()
diff --git a/modules/installed/router/templates/pagekite_configure.html b/modules/pagekite/templates/pagekite_configure.html
similarity index 100%
rename from modules/installed/router/templates/pagekite_configure.html
rename to modules/pagekite/templates/pagekite_configure.html
diff --git a/modules/installed/router/templates/pagekite_introduction.html b/modules/pagekite/templates/pagekite_introduction.html
similarity index 96%
rename from modules/installed/router/templates/pagekite_introduction.html
rename to modules/pagekite/templates/pagekite_introduction.html
index f6619c9a1..f22e1ec35 100644
--- a/modules/installed/router/templates/pagekite_introduction.html
+++ b/modules/pagekite/templates/pagekite_introduction.html
@@ -49,7 +49,7 @@ there. In future, it might be possible to use your buddy's
Configure
+ href="{{ basehref }}/apps/pagekite/configure">Configure
PageKite
diff --git a/modules/privacy.py b/modules/privacy.py
deleted file mode 120000
index 07f303ee7..000000000
--- a/modules/privacy.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/privacy/privacy.py
\ No newline at end of file
diff --git a/modules/router.py b/modules/router.py
deleted file mode 120000
index 7239c9f3b..000000000
--- a/modules/router.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/router/router.py
\ No newline at end of file
diff --git a/modules/santiago/__init__.py b/modules/santiago/__init__.py
new file mode 100644
index 000000000..abe7409d6
--- /dev/null
+++ b/modules/santiago/__init__.py
@@ -0,0 +1,25 @@
+#
+# This file is part of Plinth.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+"""
+Plinth module to configure santiago port
+"""
+
+from . import santiago
+
+
+__all__ = ['santiago']
diff --git a/modules/installed/santiago/santiago.py b/modules/santiago/santiago.py
similarity index 100%
rename from modules/installed/santiago/santiago.py
rename to modules/santiago/santiago.py
diff --git a/modules/services.py b/modules/services.py
deleted file mode 120000
index 806ae4f9f..000000000
--- a/modules/services.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/services/services.py
\ No newline at end of file
diff --git a/modules/sharing.py b/modules/sharing.py
deleted file mode 120000
index e2323fb26..000000000
--- a/modules/sharing.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/sharing/sharing.py
\ No newline at end of file
diff --git a/modules/system.py b/modules/system.py
deleted file mode 120000
index 6eddf3e2d..000000000
--- a/modules/system.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/system/system.py
\ No newline at end of file
diff --git a/modules/system/__init__.py b/modules/system/__init__.py
new file mode 100644
index 000000000..bd46fa10c
--- /dev/null
+++ b/modules/system/__init__.py
@@ -0,0 +1,25 @@
+#
+# This file is part of Plinth.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+"""
+Plinth module for system section page
+"""
+
+from . import system
+
+
+__all__ = ['system']
diff --git a/modules/installed/system/system.py b/modules/system/system.py
similarity index 100%
rename from modules/installed/system/system.py
rename to modules/system/system.py
diff --git a/modules/installed/system/templates/system.html b/modules/system/templates/system.html
similarity index 100%
rename from modules/installed/system/templates/system.html
rename to modules/system/templates/system.html
diff --git a/modules/tor.py b/modules/tor.py
deleted file mode 120000
index 28c310568..000000000
--- a/modules/tor.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/privacy/tor.py
\ No newline at end of file
diff --git a/modules/tor/__init__.py b/modules/tor/__init__.py
new file mode 100644
index 000000000..4b42293f9
--- /dev/null
+++ b/modules/tor/__init__.py
@@ -0,0 +1,25 @@
+#
+# This file is part of Plinth.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+"""
+Plinth module to configure Tor
+"""
+
+from . import tor
+
+
+__all__ = ['tor']
diff --git a/modules/installed/privacy/templates/tor.html b/modules/tor/templates/tor.html
similarity index 100%
rename from modules/installed/privacy/templates/tor.html
rename to modules/tor/templates/tor.html
diff --git a/modules/installed/privacy/tor.py b/modules/tor/tor.py
similarity index 85%
rename from modules/installed/privacy/tor.py
rename to modules/tor/tor.py
index 404553629..9e64240f8 100644
--- a/modules/installed/privacy/tor.py
+++ b/modules/tor/tor.py
@@ -22,18 +22,19 @@ Plinth module for configuring Tor
import cherrypy
from gettext import gettext as _
from plugin_mount import PagePlugin
-from modules.auth import require
+from ..lib.auth import require
import actions
import cfg
import util
class tor(PagePlugin):
- order = 30 # order of running init in PagePlugins
+ order = 60 # order of running init in PagePlugins
def __init__(self, *args, **kwargs):
PagePlugin.__init__(self, *args, **kwargs)
- self.register_page("privacy.tor")
- cfg.html_root.privacy.menu.add_item("Tor", "icon-eye-close", "/privacy/tor", 30)
+ self.register_page("apps.tor")
+ cfg.html_root.apps.menu.add_item("Tor", "icon-eye-close", "/apps/tor",
+ 30)
@cherrypy.expose
@require()
diff --git a/modules/user_store.py b/modules/user_store.py
deleted file mode 120000
index 09e8f90fe..000000000
--- a/modules/user_store.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/lib/user_store.py
\ No newline at end of file
diff --git a/modules/users.py b/modules/users.py
deleted file mode 120000
index 4b7ce2010..000000000
--- a/modules/users.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/system/users.py
\ No newline at end of file
diff --git a/modules/users/__init__.py b/modules/users/__init__.py
new file mode 100644
index 000000000..7cb056bb5
--- /dev/null
+++ b/modules/users/__init__.py
@@ -0,0 +1,25 @@
+#
+# This file is part of Plinth.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+"""
+Plinth module to manage users
+"""
+
+from . import users
+
+
+__all__ = ['users']
diff --git a/modules/installed/system/templates/users_add.html b/modules/users/templates/users_add.html
similarity index 100%
rename from modules/installed/system/templates/users_add.html
rename to modules/users/templates/users_add.html
diff --git a/modules/installed/system/templates/users_edit.html b/modules/users/templates/users_edit.html
similarity index 100%
rename from modules/installed/system/templates/users_edit.html
rename to modules/users/templates/users_edit.html
diff --git a/modules/installed/system/users.py b/modules/users/users.py
similarity index 97%
rename from modules/installed/system/users.py
rename to modules/users/users.py
index 1b7550405..5722271b7 100644
--- a/modules/installed/system/users.py
+++ b/modules/users/users.py
@@ -2,8 +2,7 @@ import cherrypy
from django import forms
from django.core import validators
from gettext import gettext as _
-import auth
-from auth import require
+from ..lib.auth import require, add_user
from plugin_mount import PagePlugin
import cfg
from model import User
@@ -86,8 +85,8 @@ class UserAdd(PagePlugin):
username=data['username'])))
return
- auth.add_user(data['username'], data['password'], data['full_name'],
- data['email'], False)
+ add_user(data['username'], data['password'], data['full_name'],
+ data['email'], False)
messages.append(
('success', _('User "{username}" added').format(
username=data['username'])))
diff --git a/modules/wan.py b/modules/wan.py
deleted file mode 120000
index 5a68efd0d..000000000
--- a/modules/wan.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/system/wan.py
\ No newline at end of file
diff --git a/modules/xmpp.py b/modules/xmpp.py
deleted file mode 120000
index f31c66cd0..000000000
--- a/modules/xmpp.py
+++ /dev/null
@@ -1 +0,0 @@
-installed/services/xmpp.py
\ No newline at end of file
diff --git a/modules/xmpp/__init__.py b/modules/xmpp/__init__.py
new file mode 100644
index 000000000..a55e739c3
--- /dev/null
+++ b/modules/xmpp/__init__.py
@@ -0,0 +1,25 @@
+#
+# This file is part of Plinth.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+"""
+Plinth module to configure XMPP server
+"""
+
+from . import xmpp
+
+
+__all__ = ['xmpp']
diff --git a/modules/installed/services/templates/xmpp_configure.html b/modules/xmpp/templates/xmpp_configure.html
similarity index 100%
rename from modules/installed/services/templates/xmpp_configure.html
rename to modules/xmpp/templates/xmpp_configure.html
diff --git a/modules/installed/services/templates/xmpp_register.html b/modules/xmpp/templates/xmpp_register.html
similarity index 100%
rename from modules/installed/services/templates/xmpp_register.html
rename to modules/xmpp/templates/xmpp_register.html
diff --git a/modules/installed/services/xmpp.py b/modules/xmpp/xmpp.py
similarity index 93%
rename from modules/installed/services/xmpp.py
rename to modules/xmpp/xmpp.py
index 767411432..ab80118c2 100644
--- a/modules/installed/services/xmpp.py
+++ b/modules/xmpp/xmpp.py
@@ -1,7 +1,7 @@
import cherrypy
from django import forms
from gettext import gettext as _
-from modules.auth import require
+from ..lib.auth import require
from plugin_mount import PagePlugin
import cfg
import actions
@@ -10,19 +10,21 @@ import util
SIDE_MENU = {'title': _('XMPP'),
- 'items': [{'url': '/services/xmpp/configure',
+ 'items': [{'url': '/apps/xmpp/configure',
'text': 'Configure XMPP Server'},
- {'url': '/services/xmpp/register',
+ {'url': '/apps/xmpp/register',
'text': 'Register XMPP Account'}]}
class XMPP(PagePlugin):
"""XMPP Page"""
+ order = 60
+
def __init__(self, *args, **kwargs):
PagePlugin.__init__(self, *args, **kwargs)
- self.register_page('services.xmpp')
- cfg.html_root.services.menu.add_item('XMPP', 'icon-comment',
- '/services/xmpp', 40)
+ self.register_page('apps.xmpp')
+ cfg.html_root.apps.menu.add_item('XMPP', 'icon-comment',
+ '/apps/xmpp', 40)
self.client_service = service.Service(
'xmpp-client', _('Chat Server - client connections'),
@@ -62,10 +64,11 @@ allowed to register an account through an XMPP client'))
class Configure(PagePlugin):
"""Configuration page"""
+ order = 65
def __init__(self, *args, **kwargs):
PagePlugin.__init__(self, *args, **kwargs)
- self.register_page("services.xmpp.configure")
+ self.register_page("apps.xmpp.configure")
@cherrypy.expose
@require()
@@ -143,10 +146,11 @@ class RegisterForm(forms.Form): # pylint: disable-msg=W0232
class Register(PagePlugin):
"""User registration page"""
+ order = 65
def __init__(self, *args, **kwargs):
PagePlugin.__init__(self, *args, **kwargs)
- self.register_page('services.xmpp.register')
+ self.register_page('apps.xmpp.register')
@cherrypy.expose
@require()
diff --git a/plinth.py b/plinth.py
index b5b5af526..e3d8666a9 100755
--- a/plinth.py
+++ b/plinth.py
@@ -4,8 +4,10 @@ import os, stat, sys, argparse
from gettext import gettext as _
import cfg
import django.conf
+import importlib
if not os.path.join(cfg.file_root, "vendor") in sys.path:
sys.path.append(os.path.join(cfg.file_root, "vendor"))
+import re
import cherrypy
from cherrypy import _cpserver
@@ -70,24 +72,24 @@ class Root(plugin_mount.PagePlugin):
cfg.log("First Boot state = %d" % db['state'])
raise cherrypy.InternalRedirect('firstboot/state%d' % db['state'])
if cherrypy.session.get(cfg.session_key, None):
- raise cherrypy.InternalRedirect('router')
+ raise cherrypy.InternalRedirect('apps')
else:
raise cherrypy.InternalRedirect('help/about')
+
def load_modules():
- """Import all the symlinked .py files in the modules directory and
- all the .py files in directories linked in the modules directory
- (but don't dive deeper than that). Also, ignore the installed
- directory."""
- for name in os.listdir("modules"):
- if name.endswith(".py") and not name.startswith('.'):
- cfg.log.info("importing modules/%s" % name)
- try:
- __import__("modules.%s" % (name[:-3]))
- except ImportError, e:
- cfg.log.error(_("Couldn't import modules/%s: %s") % (name, e))
- else:
- cfg.log("skipping %s" % name)
+ """
+ Read names of enabled modules in modules/enabled directory and
+ import them from modules directory.
+ """
+ for name in os.listdir('modules/enabled'):
+ cfg.log.info('Importing modules/%s' % name)
+ try:
+ importlib.import_module('modules.{module}'.format(module=name))
+ except ImportError as exception:
+ cfg.log.error(
+ 'Could not import modules/{module}: {exception}'
+ .format(module=name, exception=exception))
def get_template_directories():
@@ -96,13 +98,8 @@ def get_template_directories():
core_directory = os.path.join(directory, 'templates')
directories = set((core_directory,))
- for name in os.listdir('modules'):
- if not name.endswith(".py") or name.startswith('.'):
- continue
-
- real_name = os.path.realpath(os.path.join('modules', name))
- directory = os.path.dirname(real_name)
- directories.add(os.path.join(directory, 'templates'))
+ for name in os.listdir('modules/enabled'):
+ directories.add(os.path.join('modules', name, 'templates'))
cfg.log.info('Template directories - %s' % directories)
diff --git a/plugin_mount.py b/plugin_mount.py
index e3ef5db41..38ac1e313 100644
--- a/plugin_mount.py
+++ b/plugin_mount.py
@@ -1,7 +1,4 @@
-import cherrypy
-from modules.auth import require
import cfg
-import util
class PluginMount(type):