diff --git a/plinth/modules/first_boot/__init__.py b/plinth/modules/first_boot/__init__.py index 3653b5ce2..b810cca88 100644 --- a/plinth/modules/first_boot/__init__.py +++ b/plinth/modules/first_boot/__init__.py @@ -19,6 +19,11 @@ Plinth module for first boot wizard """ +from django.urls import reverse +import operator + +from plinth import module_loader + version = 1 is_essential = True @@ -35,3 +40,89 @@ first_boot_steps = [ 'order': 10 } ] + +_all_first_boot_steps = None + +_is_completed = None + + +def is_firstboot_url(path): + """Return whether a path is a firstboot step URL. + + :param path: path of url to be checked + :return: true if its a first boot URL false otherwise + """ + for step in _get_steps(): + if path.startswith(reverse(step['url'])): + return True + + return False + + +def _get_steps(): + """Return list of all firstboot steps.""" + global _all_first_boot_steps + if _all_first_boot_steps is not None: + return _all_first_boot_steps + + steps = [] + modules = module_loader.loaded_modules + for module_object in modules.values(): + if getattr(module_object, 'first_boot_steps', None): + steps.extend(module_object.first_boot_steps) + + _all_first_boot_steps = sorted(steps, key=operator.itemgetter('order')) + return _all_first_boot_steps + + +def next_step(): + """Return the resolved next first boot step URL required to go to. + + If there are no more step remaining, return index page. + """ + return next_step_or_none() or 'index' + + +def next_step_or_none(): + """Return the next first boot step required to run. + + If there are no more step remaining, return None. + """ + from plinth import kvstore + + for step in _get_steps(): + done = kvstore.get_default(step['id'], 0) + if not done: + return step.get('url') + + +def mark_step_done(id): + """Marks the status of a first boot step as done. + + :param id: id of the firstboot step + """ + from plinth import kvstore + + kvstore.set(id, 1) + if not next_step_or_none(): + kvstore.set('setup_state', 1) + + +def is_completed(): + """Return whether first boot process is completed.""" + from plinth import kvstore + + global _is_completed + if _is_completed is None: + _is_completed = kvstore.get_default('setup_state', 0) + + return _is_completed + + +def set_completed(): + """Set the first boot process as completed.""" + from plinth import kvstore + + global _is_completed + _is_completed = True + kvstore.set('setup_state', 1) diff --git a/plinth/modules/first_boot/middleware.py b/plinth/modules/first_boot/middleware.py index d56a9579a..625a6315a 100644 --- a/plinth/modules/first_boot/middleware.py +++ b/plinth/modules/first_boot/middleware.py @@ -24,13 +24,12 @@ from django.http.response import HttpResponseRedirect from django.urls import reverse from django.conf import settings import logging -from operator import itemgetter -from plinth import kvstore, module_loader + +from plinth import kvstore +from plinth.modules import first_boot LOGGER = logging.getLogger(__name__) -firstboot_steps = [] - class FirstBootMiddleware(object): """Forward to firstboot page if firstboot isn't finished yet.""" @@ -38,80 +37,39 @@ class FirstBootMiddleware(object): @staticmethod def process_request(request): """Handle a request as Django middleware request handler.""" - old_state = kvstore.get_default('firstboot_state', 0) - state = kvstore.get_default('setup_state', 0) - if state == 0 and old_state == 10: - state = 1 - kvstore.set('setup_state', 1) - - user_requests_firstboot = is_firstboot(request.path) + # Don't interfere with login page user_requests_login = request.path.startswith( reverse(settings.LOGIN_URL)) - help_index_url = reverse('help:index') - user_requests_help = request.path.startswith(help_index_url) - if not user_requests_login and not user_requests_help: - if state == 1 and user_requests_firstboot: - return HttpResponseRedirect(reverse('index')) - elif state == 0 and not user_requests_firstboot: - url = next_step() - return HttpResponseRedirect(reverse(url)) + if user_requests_login: + return + # Don't interfere with help pages + user_requests_help = request.path.startswith(reverse('help:index')) + if user_requests_help: + return -def is_firstboot(path): - """ - Returns whether the path is a firstboot step url - :param path: path of current url - :return: true if its a first boot url false otherwise - """ - steps = get_firstboot_steps() - for step in steps: - if reverse(step.get('url')) == path: - return True + state = first_boot.is_completed() - return False + # Migrate from old settings variable + if state == 0: + old_state = kvstore.get_default('firstboot_state', 0) + if old_state == 10: + state = 1 + first_boot.set_completed() + user_requests_firstboot = first_boot.is_firstboot_url(request.path) -def get_firstboot_steps(): - """Returns all firstboot steps""" - steps = [] - modules = module_loader.loaded_modules - for (module_name, module_object) in modules.items(): - if getattr(module_object, 'first_boot_steps', None): - for step in module_object.first_boot_steps: - steps.append(step) + # Redirect to first boot if requesting normal page and first + # boot is not complete. + if state == 0 and not user_requests_firstboot: + next_step = first_boot.next_step_or_none() + if next_step: + return HttpResponseRedirect(reverse(next_step)) + else: + # No more steps in first boot + first_boot.set_completed() - steps = sorted(steps, key=itemgetter('order')) - return steps - - -def next_step(): - """ Returns the next first boot step required to run """ - global firstboot_steps - if len(firstboot_steps) == 0: - firstboot_steps = get_firstboot_steps() - - for step in firstboot_steps: - done = kvstore.get_default(step.get('id'), 0) - if done == 0: - return step.get('url') - - -def mark_step_done(id): - """ - Marks the status of a first boot step is done - :param id: id of the firstboot step - """ - kvstore.set(id, 1) - global firstboot_steps - if len(firstboot_steps) == 0: - firstboot_steps = get_firstboot_steps() - - setup_done = True - for step in firstboot_steps: - done = kvstore.get_default(step.get('id'), 0) - if done == 0: - setup_done = False - break - - if setup_done: - kvstore.set('setup_state', 1) + # Redirect to index page if request firstboot after it is + # finished. + if state == 1 and user_requests_firstboot: + return HttpResponseRedirect(reverse('index')) diff --git a/plinth/modules/first_boot/templates/firstboot_welcome.html b/plinth/modules/first_boot/templates/firstboot_welcome.html index ea4951094..a98184b5b 100644 --- a/plinth/modules/first_boot/templates/firstboot_welcome.html +++ b/plinth/modules/first_boot/templates/firstboot_welcome.html @@ -36,10 +36,14 @@ alt="{{ box_name }}" width="640"/>
- +
{% blocktrans trimmed %}
diff --git a/plinth/modules/first_boot/urls.py b/plinth/modules/first_boot/urls.py
index 93fe8364f..bf1954307 100644
--- a/plinth/modules/first_boot/urls.py
+++ b/plinth/modules/first_boot/urls.py
@@ -22,7 +22,7 @@ URLs for the First Boot module
from django.conf.urls import url
from stronghold.decorators import public
-from .views import WelcomeView, complete
+from .views import WelcomeView, CompleteView
urlpatterns = [
@@ -30,5 +30,5 @@ urlpatterns = [
url(r'^firstboot/$', public(WelcomeView.as_view()), name='index'),
url(r'^firstboot/welcome/$', public(WelcomeView.as_view()),
name='welcome'),
- url(r'^firstboot/complete/$', complete, name='complete'),
+ url(r'^firstboot/complete/$', CompleteView.as_view(), name='complete'),
]
diff --git a/plinth/modules/first_boot/views.py b/plinth/modules/first_boot/views.py
index 1aae217c4..6d722a817 100644
--- a/plinth/modules/first_boot/views.py
+++ b/plinth/modules/first_boot/views.py
@@ -15,12 +15,13 @@
# along with this program. If not, see
- {% url 'first_boot:complete' as finish_firstboot_url %} - {% blocktrans trimmed %} - Skip this step if you - do not have a voucher or want to configure PageKite later with a - different domain or credentials. - {% endblocktrans %} -
++ {% url 'pagekite:firstboot-skip' as finish_firstboot_url %} + {% blocktrans trimmed %} + Skip this step if you + do not have a voucher or want to configure PageKite later with a + different domain or credentials. + {% endblocktrans %} +
-- {% blocktrans trimmed %} - You can use an already redeemed voucher but it will only work - with the initially registered subdomain. - {% endblocktrans %} -
++ {% blocktrans trimmed %} + You can use an already redeemed voucher but it will only work + with the initially registered subdomain. + {% endblocktrans %} +
-