diff --git a/.coveragerc b/.coveragerc index a67507a..e0242aa 100644 --- a/.coveragerc +++ b/.coveragerc @@ -6,6 +6,7 @@ source = search static templates + theme users omit = media/tests/*.py diff --git a/med/settings.py b/med/settings.py index de2ef98..cc1a25f 100644 --- a/med/settings.py +++ b/med/settings.py @@ -29,6 +29,9 @@ ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ + # Theme overrides Django Admin templates + 'theme', + # External apps 'bootstrap3', 'reversion', @@ -177,7 +180,6 @@ LOGIN_REDIRECT_URL = '/' SITE_NAME = "Med" # Association information -LOGO_PATH = "static_files/logo.png" ASSO_NAME = "Med" ASSO_ADDRESS_LINE1 = "61 Avenue du président Wilson" ASSO_ADDRESS_LINE2 = "94230 Cachan" @@ -185,9 +187,6 @@ ASSO_SIRET = "" ASSO_EMAIL = "med@lists.crans.org" ASSO_PHONE = "01 02 03 04 05" -services_urls = { -} - # Number of hours a token remains valid after having been created. Numeric and string # versions should have the same meaning. REQ_EXPIRE_HRS = 48 diff --git a/med/templates/med/index.html b/med/templates/med/index.html index 097844a..04001e9 100644 --- a/med/templates/med/index.html +++ b/med/templates/med/index.html @@ -1,26 +1,6 @@ {% extends "med/sidebar.html" %} {% comment %} -Re2o est un logiciel d'administration développé initiallement au rezometz. Il -se veut agnostique au réseau considéré, de manière à être installable en -quelques clics. - -Copyright © 2017 Gabriel Détraz -Copyright © 2017 Goulven Kermarec -Copyright © 2017 Augustin Lemesle - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 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 General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +SPDX-License-Identifier: GPL-3.0-or-later {% endcomment %} {% load bootstrap3 %} @@ -30,15 +10,16 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block content %}

Bienvenue sur {{ site_name }}, notre base de données.

+

Welcome to procrastination heaven !

-

Welcome to procrastination heaven !

- -
-
-logo -
-
- +

+ Le site va subir progressivement des mises à jour pendant ces vacances. + Si vous rencontrez des instabilités, + veuillez nous faire remonter les problèmes au webmaster. +

+
+ Poulpy +
{% endblock %} diff --git a/med/urls.py b/med/urls.py index 18cefaf..e0c4957 100644 --- a/med/urls.py +++ b/med/urls.py @@ -4,17 +4,32 @@ from django.conf.urls import include, url from django.contrib import admin -from django.contrib.auth import views as auth_views +from django.shortcuts import render +from django.views.generic import RedirectView + + +def index(request): + """ + Static home page + """ + return render(request, 'med/index.html', {}) -from .views import index urlpatterns = [ - url(r'^$', index), - url('^logout/', auth_views.logout, {'next_page': '/'}), - url('^', include('django.contrib.auth.urls')), - url(r'^admin/', include(admin.site.urls)), + url(r'^$', index, name='index'), + + # Include project routers url(r'^users/', include('users.urls', namespace='users')), url(r'^media/', include('media.urls', namespace='media')), url(r'^search/', include('search.urls', namespace='search')), url(r'^logs/', include('logs.urls', namespace='logs')), + + # Include Django Contrib and Core routers + # admin/login/ is redirected to the non-admin login page + url(r'^i18n/', include('django.conf.urls.i18n')), + url(r'^accounts/', include('django.contrib.auth.urls')), + url(r'^accounts/profile/', + RedirectView.as_view(pattern_name='index')), + url(r'^admin/doc/', include('django.contrib.admindocs.urls')), + url(r'^admin/', admin.site.urls), ] diff --git a/med/views.py b/med/views.py deleted file mode 100644 index 00f8c19..0000000 --- a/med/views.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay -# SPDX-License-Identifier: GPL-3.0-or-later - -from django.shortcuts import render -from django.template.context_processors import csrf - -from med.settings import services_urls - - -def form(ctx, template, request): - c = ctx - c.update(csrf(request)) - return render(request, template, c) - - -def index(request): - i = 0 - services = [{}] - for key, s in services_urls.items(): - if len(services) <= i: - services += [{}] - services[i][key] = s - i = i + 1 if i < 2 else 0 - - return form({'services_urls': services}, 'med/index.html', request) diff --git a/static/logo/logo.png b/static/logo/logo.png deleted file mode 100644 index 5fddb4f..0000000 Binary files a/static/logo/logo.png and /dev/null differ diff --git a/theme/__init__.py b/theme/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/theme/locale/fr/LC_MESSAGES/django.po b/theme/locale/fr/LC_MESSAGES/django.po new file mode 100644 index 0000000..e70bbc7 --- /dev/null +++ b/theme/locale/fr/LC_MESSAGES/django.po @@ -0,0 +1,87 @@ +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-02 15:17+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: templates/admin/base_site.html:22 +msgid "Welcome," +msgstr "" + +#: templates/admin/base_site.html:27 templates/registration/logged_out.html:9 +#: templates/registration/password_change_done.html:9 +#: templates/registration/password_change_form.html:9 +#: templates/registration/password_reset_complete.html:9 +#: templates/registration/password_reset_confirm.html:9 +#: templates/registration/password_reset_done.html:9 +#: templates/registration/password_reset_form.html:9 +msgid "Home" +msgstr "" + +#: templates/admin/base_site.html:32 templates/admin/base_site.html:51 +msgid "View admin" +msgstr "Administration" + +#: templates/admin/base_site.html:44 +msgid "Documentation" +msgstr "" + +#: templates/admin/base_site.html:53 +msgid "Log out" +msgstr "" + +#: templates/registration/logged_out.html:14 +msgid "Thanks for spending some quality time with the Web site today." +msgstr "" + +#: templates/registration/logged_out.html:15 +msgid "Log in again" +msgstr "" + +#: templates/registration/login.html:8 +msgid "Log in" +msgstr "" + +#: templates/registration/password_change_done.html:9 +#: templates/registration/password_change_form.html:9 +msgid "Password change" +msgstr "" + +#: templates/registration/password_reset_complete.html:9 +#: templates/registration/password_reset_done.html:9 +#: templates/registration/password_reset_form.html:9 +msgid "Password reset" +msgstr "" + +#: templates/registration/password_reset_confirm.html:9 +msgid "Password reset confirmation" +msgstr "" + +#: templates/registration/password_reset_email.html:2 +#, python-format +msgid "" +"You're receiving this email because you requested a password reset for your " +"user account at %(site_name)s." +msgstr "" + +#: templates/registration/password_reset_email.html:4 +msgid "Please go to the following page and choose a new password:" +msgstr "" + +#: templates/registration/password_reset_email.html:9 +msgid "Thanks for using our site!" +msgstr "" + +#: templates/registration/password_reset_email.html:11 +#, python-format +msgid "The %(site_name)s team" +msgstr "" diff --git a/theme/static/css/admin.css b/theme/static/css/admin.css new file mode 100644 index 0000000..876a2ff --- /dev/null +++ b/theme/static/css/admin.css @@ -0,0 +1,140 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Copyright © 2019 Alexandre Iooss + * + * This is the custom style for Django Contrib Admin + */ + +/* Colors */ +#header { + background-color: #151515; + border-bottom: solid 5px #d8660f; +} + +.module h2, .module caption, .inline-group h2 { + background: #e6e0d8; + color: #222; +} + +a.section:link, a.section:visited { + color: #222; +} + +#user-tools a { + border-bottom: none; + font-weight: bold; +} + +div.breadcrumbs { + background: #3c3c3c; +} + +.button, input[type=submit], input[type=button], .submit-row input, a.button { + background: #d8a456; +} + +.button:active, input[type=submit]:active, input[type=button]:active, .button:focus, input[type=submit]:focus, +input[type=button]:focus, .button:hover, input[type=submit]:hover, input[type=button]:hover { + background: #b98d4a; +} + +.button.default, input[type=submit].default, .submit-row input.default { + background: #b98d4a; +} + +.button.default:active, input[type=submit].default:active, .button.default:focus, input[type=submit].default:focus, +.button.default:hover, input[type=submit].default:hover { + background: #a7752b; +} + +/* User tools top menu */ +#user-tools .dropdown:hover > a, #user-tools .dropdown:focus > a { + color: #79aec8; +} + +#user-tools .dropdown { + position: relative; /* needed to position the dropdown content */ + display: inline-block; +} + +#user-tools .dropdown-content { + display: block; + position: absolute; + background-color: #444444; + min-width: 180px; + box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2); + z-index: 2000; + text-align: left; + + /* Hide menu by making it transparent */ + transition: opacity 100ms, visibility 100ms; + opacity: 0; + visibility: hidden; +} + +#user-tools .dropdown-content a { + color: #fff; + padding: 7px 8px; + text-decoration: none; + display: block; + line-height: 16px; +} + +#user-tools .dropdown-content a:hover { + background-color: #636363; +} + +#user-tools .dropdown:hover .dropdown-content { + opacity: 1; + visibility: visible; +} + +/* Fix navigation hidden */ +#header { + overflow: visible; +} + +.login #header { + overflow: hidden; +} + +/* Footer */ +#footer { + padding: 20px 40px; + color: #999; +} + +.login #footer { + padding: 10px; + font-size: 10pt; +} + +#footer a { + color: #777; +} + +#footer select { + height: 24px; + padding: 0; +} + +/* Pull footer to bottom */ +#content { + min-height: calc(100vh - 190px); +} + +.login #content { + min-height: 0; +} + +/* Recenter login button */ +.login .submit-row { + padding: 1em 0 0 0 !important; + text-align: center !important; +} + +/* Dashboard should take all page */ +.dashboard #content { + width: auto; +} diff --git a/theme/static/favicon/android-chrome-192x192.png b/theme/static/favicon/android-chrome-192x192.png new file mode 100644 index 0000000..3567f32 Binary files /dev/null and b/theme/static/favicon/android-chrome-192x192.png differ diff --git a/theme/static/favicon/android-chrome-256x256.png b/theme/static/favicon/android-chrome-256x256.png new file mode 100644 index 0000000..9c45020 Binary files /dev/null and b/theme/static/favicon/android-chrome-256x256.png differ diff --git a/theme/static/favicon/apple-touch-icon.png b/theme/static/favicon/apple-touch-icon.png new file mode 100644 index 0000000..dd53e7d Binary files /dev/null and b/theme/static/favicon/apple-touch-icon.png differ diff --git a/theme/static/favicon/browserconfig.xml b/theme/static/favicon/browserconfig.xml new file mode 100644 index 0000000..61ae5bd --- /dev/null +++ b/theme/static/favicon/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #da532c + + + diff --git a/theme/static/favicon/favicon-16x16.png b/theme/static/favicon/favicon-16x16.png new file mode 100644 index 0000000..44b8646 Binary files /dev/null and b/theme/static/favicon/favicon-16x16.png differ diff --git a/theme/static/favicon/favicon-32x32.png b/theme/static/favicon/favicon-32x32.png new file mode 100644 index 0000000..5cc7941 Binary files /dev/null and b/theme/static/favicon/favicon-32x32.png differ diff --git a/theme/static/favicon/favicon.ico b/theme/static/favicon/favicon.ico new file mode 100644 index 0000000..6b21e09 Binary files /dev/null and b/theme/static/favicon/favicon.ico differ diff --git a/theme/static/favicon/mstile-150x150.png b/theme/static/favicon/mstile-150x150.png new file mode 100644 index 0000000..f632061 Binary files /dev/null and b/theme/static/favicon/mstile-150x150.png differ diff --git a/theme/static/favicon/safari-pinned-tab.svg b/theme/static/favicon/safari-pinned-tab.svg new file mode 100644 index 0000000..d2e957c --- /dev/null +++ b/theme/static/favicon/safari-pinned-tab.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/static/favicon/site.webmanifest b/theme/static/favicon/site.webmanifest new file mode 100644 index 0000000..6d25c20 --- /dev/null +++ b/theme/static/favicon/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "android-chrome-256x256.png", + "sizes": "256x256", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/theme/static/images/logo.png b/theme/static/images/logo.png new file mode 100644 index 0000000..2dce654 Binary files /dev/null and b/theme/static/images/logo.png differ diff --git a/theme/static/images/splash.png b/theme/static/images/splash.png new file mode 100644 index 0000000..27b2655 Binary files /dev/null and b/theme/static/images/splash.png differ diff --git a/theme/templates/admin/base_site.html b/theme/templates/admin/base_site.html new file mode 100644 index 0000000..3418233 --- /dev/null +++ b/theme/templates/admin/base_site.html @@ -0,0 +1,96 @@ +{% extends "admin/base.html" %} +{% comment %} +SPDX-License-Identifier: GPL-3.0-or-later +{% endcomment %} + +{% load i18n staticfiles %} + +{% block title %}{{ title }} | {{ request.site.name }}{% endblock %} + +{% block branding %} + + + {{ request.site.name }} + + +{% endblock %} + +{% block usertools %} + {% if user.is_authenticated %} +
+ {% block welcome-msg %} + {% trans 'Welcome,' %} + {% firstof user.get_short_name user.get_username %}. + {% endblock %} + {% block userlinks %} + {# Link to our apps outside of admin #} + {% trans 'Home' %} / + + {% if available_apps %} + {# When in admin site, list all admin pages and documentation #} + + {% trans 'View admin' %} + + {% for app in available_apps %} + {% for model in app.models %} + {% if model.admin_url %} + {{ model.name }} + {% endif %} + {% endfor %} + {% endfor %} + {% if user.is_active and user.is_superuser %} + {% url 'django-admindocs-docroot' as docsroot %} + {% if docsroot %} + {% trans 'Documentation' %} + {% endif %} + {% endif %} + + / + {% elif user.is_staff %} + {# When not in admin site, but user is staff then add a link #} + {% trans 'View admin' %} / + {% endif %} + {% trans 'Log out' %} + {% endblock %} +
+ {% endif %} +{% endblock %} + +{% block extrastyle %} + + + {# Favicon #} + + + + + + + + + +{% endblock %} + +{% block footer %} + {% if not is_popup %} + + {% endif %} +{% endblock %} diff --git a/theme/templates/registration/logged_out.html b/theme/templates/registration/logged_out.html new file mode 100644 index 0000000..48949e8 --- /dev/null +++ b/theme/templates/registration/logged_out.html @@ -0,0 +1,16 @@ +{% extends "registration/logged_out.html" %} +{% comment %} +SPDX-License-Identifier: GPL-3.0-or-later +{% endcomment %} +{% load i18n %} + +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} +

{% trans "Thanks for spending some quality time with the Web site today." %}

+

{% trans 'Log in again' %}

+{% endblock %} \ No newline at end of file diff --git a/theme/templates/registration/login.html b/theme/templates/registration/login.html new file mode 100644 index 0000000..8d10a1b --- /dev/null +++ b/theme/templates/registration/login.html @@ -0,0 +1,8 @@ +{% extends "admin/login.html" %} +{% comment %} +SPDX-License-Identifier: GPL-2.0-or-later +{% endcomment %} + +{% load i18n %} + +{% block title %}{% trans "Log in" %}{% endblock %} \ No newline at end of file diff --git a/theme/templates/registration/password_change_done.html b/theme/templates/registration/password_change_done.html new file mode 100644 index 0000000..d42fbfd --- /dev/null +++ b/theme/templates/registration/password_change_done.html @@ -0,0 +1,11 @@ +{% extends "registration/password_change_done.html" %} +{% comment %} +SPDX-License-Identifier: GPL-3.0-or-later +{% endcomment %} +{% load i18n %} + +{% block breadcrumbs %} + +{% endblock %} diff --git a/theme/templates/registration/password_change_form.html b/theme/templates/registration/password_change_form.html new file mode 100644 index 0000000..07ab38c --- /dev/null +++ b/theme/templates/registration/password_change_form.html @@ -0,0 +1,11 @@ +{% extends "registration/password_change_form.html" %} +{% comment %} +SPDX-License-Identifier: GPL-3.0-or-later +{% endcomment %} +{% load i18n %} + +{% block breadcrumbs %} + +{% endblock %} diff --git a/theme/templates/registration/password_reset_complete.html b/theme/templates/registration/password_reset_complete.html new file mode 100644 index 0000000..f0ec4b8 --- /dev/null +++ b/theme/templates/registration/password_reset_complete.html @@ -0,0 +1,11 @@ +{% extends "registration/password_reset_complete.html" %} +{% comment %} +SPDX-License-Identifier: GPL-3.0-or-later +{% endcomment %} +{% load i18n %} + +{% block breadcrumbs %} + +{% endblock %} diff --git a/theme/templates/registration/password_reset_confirm.html b/theme/templates/registration/password_reset_confirm.html new file mode 100644 index 0000000..62a761d --- /dev/null +++ b/theme/templates/registration/password_reset_confirm.html @@ -0,0 +1,11 @@ +{% extends "registration/password_reset_confirm.html" %} +{% comment %} +SPDX-License-Identifier: GPL-3.0-or-later +{% endcomment %} +{% load i18n %} + +{% block breadcrumbs %} + +{% endblock %} diff --git a/theme/templates/registration/password_reset_done.html b/theme/templates/registration/password_reset_done.html new file mode 100644 index 0000000..ea67e59 --- /dev/null +++ b/theme/templates/registration/password_reset_done.html @@ -0,0 +1,11 @@ +{% extends "registration/password_reset_done.html" %} +{% comment %} +SPDX-License-Identifier: GPL-3.0-or-later +{% endcomment %} +{% load i18n %} + +{% block breadcrumbs %} + +{% endblock %} diff --git a/theme/templates/registration/password_reset_email.html b/theme/templates/registration/password_reset_email.html new file mode 100644 index 0000000..f43d80c --- /dev/null +++ b/theme/templates/registration/password_reset_email.html @@ -0,0 +1,13 @@ +{% load i18n %}{% autoescape off %} +{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %} + +{% trans "Please go to the following page and choose a new password:" %} +{% block reset_link %} +{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %} +{% endblock %} + +{% trans "Thanks for using our site!" %} + +{% blocktrans %}The {{ site_name }} team{% endblocktrans %} + +{% endautoescape %} diff --git a/theme/templates/registration/password_reset_form.html b/theme/templates/registration/password_reset_form.html new file mode 100644 index 0000000..865d516 --- /dev/null +++ b/theme/templates/registration/password_reset_form.html @@ -0,0 +1,11 @@ +{% extends "registration/password_reset_form.html" %} +{% comment %} +SPDX-License-Identifier: GPL-3.0-or-later +{% endcomment %} +{% load i18n %} + +{% block breadcrumbs %} + +{% endblock %} diff --git a/theme/tests/__init__.py b/theme/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/theme/tests/test_templates.py b/theme/tests/test_templates.py new file mode 100644 index 0000000..6d00c14 --- /dev/null +++ b/theme/tests/test_templates.py @@ -0,0 +1,44 @@ +# -*- mode: python; coding: utf-8 -*- +# SPDX-License-Identifier: GPL-3.0-or-later + +from django.contrib.auth.models import User +from django.test import TestCase + +""" +Test that every themed page still works +""" + + +class TemplateLoggedOutTests(TestCase): + def test_login_page(self): + response = self.client.get('/admin/login/') + self.assertEqual(response.status_code, 200) + + +class TemplateLoggedInTests(TestCase): + def setUp(self): + self.user = User.objects.create_superuser( + username="admin", + password="adminadmin", + email="admin@example.com", + ) + self.client.force_login(self.user) + + def test_login_page(self): + """ + Login page should redirect + """ + response = self.client.get('/admin/login/') + self.assertEqual(response.status_code, 302) + + def test_admin_index(self): + response = self.client.get('/admin/') + self.assertEqual(response.status_code, 200) + + def test_accounts_password_reset(self): + response = self.client.get('/accounts/password_reset/') + self.assertEqual(response.status_code, 200) + + def test_logout_page(self): + response = self.client.get('/accounts/logout/') + self.assertEqual(response.status_code, 200)