diff --git a/plinth/modules/help/help.py b/plinth/modules/help/help.py index c9e20c452..cdba80c50 100644 --- a/plinth/modules/help/help.py +++ b/plinth/modules/help/help.py @@ -20,12 +20,15 @@ Help app for FreedomBox. import mimetypes import os +import pathlib import subprocess from apt.cache import Cache from django.core.files.base import File -from django.http import Http404, HttpResponse +from django.http import Http404, HttpResponse, HttpResponseRedirect from django.template.response import TemplateResponse +from django.urls import reverse +from django.utils.translation import get_language_from_request from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_lazy @@ -118,15 +121,27 @@ def about(request): return TemplateResponse(request, 'help_about.html', context) -def manual(request, page='freedombox-manual.part.html'): +def manual(request, lang=None, page=None): """Serve the manual page from the 'doc' directory""" - try: - page = '{}.part.html'.format( - page) if not page.endswith('html') else page - with open(os.path.join(cfg.doc_dir, page), 'r', - encoding='utf-8') as input_file: - content = input_file.read() - except IOError: + language_code = get_language_from_request(request) + + if not lang or lang == '-': + kwargs = {'lang': language_code} + if page: + return HttpResponseRedirect( + reverse('help:manual-page', kwargs=dict(kwargs, page=page))) + + return HttpResponseRedirect(reverse('help:manual', kwargs=kwargs)) + + def read_file(language_code, page): + """Read the page from disk and return contents or None.""" + page_file = pathlib.Path(cfg.doc_dir) / 'manual' / language_code / page + return page_file.read_text() if page_file.exists() else None + + page = page or 'freedombox-manual' + page = f'{page}.part.html' + content = read_file(language_code, page) or read_file(language_code, 'en') + if not content: raise Http404 return TemplateResponse( @@ -138,17 +153,26 @@ def manual(request, page='freedombox-manual.part.html'): def download_manual(request): """Serve the PDF version of the manual from the 'doc' directory""" - files = [ - os.path.join(cfg.doc_dir, file_name) - for file_name in ['freedombox-manual.pdf.gz', 'freedombox-manual.pdf'] - if os.path.isfile(os.path.join(cfg.doc_dir, file_name)) - ] + language_code = get_language_from_request(request) - if not files: + def get_manual_file_name(language_code): + for file_name in ['freedombox-manual.pdf.gz', 'freedombox-manual.pdf']: + name = os.path.join(cfg.doc_dir, 'manual', language_code, + file_name) + if os.path.isfile(name): + return name + + return None + + manual_file_name = get_manual_file_name( + language_code) or get_manual_file_name('en') + + if not manual_file_name: raise Http404 - (content_type, encoding) = mimetypes.guess_type(files[0]) - with open(files[0], 'rb') as file_handle: + (content_type, encoding) = mimetypes.guess_type(manual_file_name) + + with open(manual_file_name, 'rb') as file_handle: response = HttpResponse(File(file_handle), content_type=content_type) if encoding: response['Content-Encoding'] = encoding diff --git a/plinth/modules/help/urls.py b/plinth/modules/help/urls.py index 461d28f2b..960b3279d 100644 --- a/plinth/modules/help/urls.py +++ b/plinth/modules/help/urls.py @@ -32,10 +32,12 @@ urlpatterns = [ url(r'^help/contribute/$', non_admin_view(views.contribute), name='contribute'), url(r'^help/manual/$', non_admin_view(views.manual), name='manual'), - url(r'^help/manual/download/$', non_admin_view(views.download_manual), + url(r'^help/manual/(?P\w*(-\w*)?)/$', non_admin_view(views.manual), + name='manual'), + url(r'^help/manual/(?P\w*(-\w*)?)/(?P[\w-]+)$', + non_admin_view(views.manual), name='manual-page'), + url(r'^help/manual-download/$', non_admin_view(views.download_manual), name='download-manual'), - url(r'^help/manual/(?P[\w-]+)?/?$', non_admin_view(views.manual), - name='manual-page'), url(r'^help/status-log/$', non_admin_view(views.status_log), name='status-log'), ] diff --git a/plinth/modules/power/templates/power_restart.html b/plinth/modules/power/templates/power_restart.html index 5d1803eb1..6f5526bd9 100644 --- a/plinth/modules/power/templates/power_restart.html +++ b/plinth/modules/power/templates/power_restart.html @@ -38,7 +38,7 @@ {% if manual_page %}

- + {% trans 'Learn more...' %}

diff --git a/plinth/modules/power/templates/power_shutdown.html b/plinth/modules/power/templates/power_shutdown.html index b5f19b683..6ce896b10 100644 --- a/plinth/modules/power/templates/power_shutdown.html +++ b/plinth/modules/power/templates/power_shutdown.html @@ -37,7 +37,7 @@ {% if manual_page %}

- + {% trans 'Learn more...' %}

diff --git a/plinth/templates/app.html b/plinth/templates/app.html index 727a0e56c..d3077de16 100644 --- a/plinth/templates/app.html +++ b/plinth/templates/app.html @@ -39,7 +39,7 @@ {% if manual_page %}

- + {% trans 'Learn more...' %}

diff --git a/plinth/templates/setup.html b/plinth/templates/setup.html index 476b6a2f7..60bf8c64e 100644 --- a/plinth/templates/setup.html +++ b/plinth/templates/setup.html @@ -44,7 +44,7 @@ {% if setup_helper.module.manual_page %}

- + {% trans 'Learn more...' %}

diff --git a/plinth/templates/simple_app.html b/plinth/templates/simple_app.html index 2dcf75043..b812b752c 100644 --- a/plinth/templates/simple_app.html +++ b/plinth/templates/simple_app.html @@ -34,7 +34,7 @@ {% if manual_page %}

- + {% trans 'Learn more...' %}

diff --git a/plinth/web_server.py b/plinth/web_server.py index 1e8410501..a05679d3d 100644 --- a/plinth/web_server.py +++ b/plinth/web_server.py @@ -71,10 +71,12 @@ def init(): _mount_static_directory('/usr/share/javascript', '/javascript') - manual_dir = os.path.join(cfg.doc_dir, 'images') - manual_url = '/'.join([cfg.server_dir, 'help/manual/images']) \ - .replace('//', '/') - _mount_static_directory(manual_dir, manual_url) + langs = os.listdir(os.path.join(cfg.doc_dir, 'manual')) + for lang in langs: + manual_dir = os.path.join(cfg.doc_dir, 'manual', lang, 'images') + manual_url = '/'.join([cfg.server_dir, f'help/manual/{lang}/images']) \ + .replace('//', '/') + _mount_static_directory(manual_dir, manual_url) for module_name, module in module_loader.loaded_modules.items(): module_path = os.path.dirname(module.__file__)