Merge branch 'master' into i18n

This commit is contained in:
Santiago Lamora 2020-01-23 17:49:46 +01:00
commit d3848d0633
11 changed files with 112 additions and 33 deletions

View File

@ -17,5 +17,6 @@ class LoginForm(AuthenticationForm):
else: else:
self.username = username self.username = username
self.token = orchestra.auth_token self.token = orchestra.auth_token
self.user = orchestra.retrieve_profile()
return self.cleaned_data return self.cleaned_data

View File

@ -5,6 +5,8 @@ from django.utils.dateparse import parse_datetime
from django.utils.html import format_html from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from . import settings as musician_settings
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -107,14 +109,20 @@ class UserAccount(OrchestraModel):
@classmethod @classmethod
def new_from_json(cls, data, **kwargs): def new_from_json(cls, data, **kwargs):
billing = None billing = None
language = None
last_login = None last_login = None
if 'billcontact' in data: if 'billcontact' in data:
billing = BillingContact.new_from_json(data['billcontact']) billing = BillingContact.new_from_json(data['billcontact'])
# Django expects that language code is lowercase
if 'language' in data:
language = data['language'].lower()
if 'last_login' in data: if 'last_login' in data:
last_login = parse_datetime(data['last_login']) last_login = parse_datetime(data['last_login'])
return super().new_from_json(data=data, billing=billing, last_login=last_login)
return super().new_from_json(data=data, billing=billing, language=language, last_login=last_login)
class DatabaseUser(OrchestraModel): class DatabaseUser(OrchestraModel):
@ -250,9 +258,8 @@ class MailinglistService(OrchestraModel):
return "{}@{}".format(self.data['address_name'], self.data['address_domain']['name']) return "{}@{}".format(self.data['address_name'], self.data['address_domain']['name'])
@property @property
def configure(self): def manager_url(self):
# TODO(@slamora): build mailtran absolute URL return musician_settings.URL_MAILTRAIN
return format_html('<a href="#TODO">Mailtrain</a>')
class SaasService(OrchestraModel): class SaasService(OrchestraModel):
@ -267,6 +274,17 @@ class SaasService(OrchestraModel):
} }
@property
def manager_url(self):
URLS = {
'gitlab': musician_settings.URL_SAAS_GITLAB,
'owncloud': musician_settings.URL_SAAS_OWNCLOUD,
'wordpress': musician_settings.URL_SAAS_WORDPRESS,
}
return URLS.get(self.service, '#none')
class WebSite(OrchestraModel): class WebSite(OrchestraModel):
api_name = 'website' api_name = 'website'
param_defaults = { param_defaults = {

View File

@ -1,14 +1,41 @@
# allowed resources limit hardcoded because cannot be retrieved from the API. from django.conf import settings
ALLOWED_RESOURCES = {
'INDIVIDUAL':
{ def getsetting(name):
# 'disk': 1024, value = getattr(settings, name, None)
# 'traffic': 2048, return value or DEFAULTS.get(name)
'mailbox': 2,
DEFAULTS = {
# allowed resources limit hardcoded because cannot be retrieved from the API.
"ALLOWED_RESOURCES": {
'INDIVIDUAL':
{
# 'disk': 1024,
# 'traffic': 2048,
'mailbox': 2,
},
'ASSOCIATION': {
# 'disk': 5 * 1024,
# 'traffic': 20 * 1024,
'mailbox': 10,
}
}, },
'ASSOCIATION': { "URL_DB_PHPMYADMIN": "https://www.phpmyadmin.net/",
# 'disk': 5 * 1024, "URL_MAILTRAIN": "https://mailtrain.org/",
# 'traffic': 20 * 1024, "URL_SAAS_GITLAB": "https://gitlab.org/",
'mailbox': 10, "URL_SAAS_OWNCLOUD": "https://owncloud.org/",
} "URL_SAAS_WORDPRESS": "https://wordpress.org/",
} }
ALLOWED_RESOURCES = getsetting("ALLOWED_RESOURCES")
URL_DB_PHPMYADMIN = getsetting("URL_DB_PHPMYADMIN")
URL_MAILTRAIN = getsetting("URL_MAILTRAIN")
URL_SAAS_GITLAB = getsetting("URL_SAAS_GITLAB")
URL_SAAS_OWNCLOUD = getsetting("URL_SAAS_OWNCLOUD")
URL_SAAS_WORDPRESS = getsetting("URL_SAAS_WORDPRESS")

View File

@ -43,6 +43,9 @@ a:hover {
min-width: 280px; min-width: 280px;
max-width: 280px; max-width: 280px;
min-height: 100vh; min-height: 100vh;
position: fixed;
z-index: 999;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -127,6 +130,7 @@ a:hover {
background-position: right 5% top 10%; background-position: right 5% top 10%;
color: #343434; color: #343434;
padding-left: 2rem; padding-left: 2rem;
margin-left: 280px; /** sidebar width **/
} }
/** services **/ /** services **/

View File

@ -16,11 +16,11 @@
</colgroup> </colgroup>
<thead class="thead-dark"> <thead class="thead-dark">
<tr> <tr>
<th scope="col">Number</th> <th scope="col">{% trans "Number" %}</th>
<th scope="col">Bill date</th> <th scope="col">{% trans "Bill date" %}</th>
<th scope="col">Type</th> <th scope="col">{% trans "Type" %}</th>
<th scope="col">Total</th> <th scope="col">{% trans "Total" %}</th>
<th scope="col">Download PDF</th> <th scope="col">{% trans "Download PDF" %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -66,9 +66,9 @@
<p class="card-text"><i class="fas fa-envelope fa-3x"></i></p> <p class="card-text"><i class="fas fa-envelope fa-3x"></i></p>
<p class="card-text text-dark"> <p class="card-text text-dark">
{{ domain.mails|length }} {% trans "mail addresses created" %} {{ domain.mails|length }} {% trans "mail addresses created" %}
{% if domain.address_left.alert_level %} {% if domain.addresses_left.alert_level %}
<br/> <br/>
<span class="text-{{ domain.address_left.alert_level }}">{{ domain.address_left.count }} {% trans "mail address left" %}</span> <span class="text-{{ domain.addresses_left.alert_level }}">{{ domain.addresses_left.count }} {% trans "mail address left" %}</span>
{% endif %} {% endif %}
</p> </p>
<a class="stretched-link" href="{% url 'musician:mails' %}?domain={{ domain.id }}"></a> <a class="stretched-link" href="{% url 'musician:mails' %}?domain={{ domain.id }}"></a>

View File

@ -37,7 +37,7 @@
{% endif %} {% endif %}
<td>{{ resource.address_name}}</td> <td>{{ resource.address_name}}</td>
<td>{{ resource.admin_email }}</td> <td>{{ resource.admin_email }}</td>
<td><a href="#TODO-{{ resource.manager_url }}" target="_blank" rel="noopener noreferrer">Mailtrain</a></td> <td><a href="{{ resource.manager_url }}" target="_blank" rel="noopener noreferrer">Mailtrain <i class="fas fa-external-link-alt"></i></a></td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>

View File

@ -8,7 +8,7 @@
<div class="card-deck"> <div class="card-deck">
<div class="card card-profile"> <div class="card card-profile">
<h5 class="card-header">User information</h5> <h5 class="card-header">{% trans "User information" %}</h5>
<div class="card-body row"> <div class="card-body row">
<div class="col-md"> <div class="col-md">
<div class="border-primary rounded-circle d-inline-block p-1" style="background-color: white; border: 5px solid grey"> <div class="border-primary rounded-circle d-inline-block p-1" style="background-color: white; border: 5px solid grey">
@ -18,12 +18,12 @@
<div class="col-md-9"> <div class="col-md-9">
<p class="card-text">{{ profile.username }}</p> <p class="card-text">{{ profile.username }}</p>
<p class="card-text">{{ profile.type }}</p> <p class="card-text">{{ profile.type }}</p>
<p class="card-text">Preferred language: {{ profile.language }}</p> <p class="card-text">{% trans "Preferred language:" %} {{ profile.language|language_name_local }}</p>
</div> </div>
{% comment %} {% comment %}
<!-- disabled until set_password is implemented --> <!-- disabled until set_password is implemented -->
<div class="col-md-12 text-right"> <div class="col-md-12 text-right">
<a class="btn btn-primary pl-5 pr-5" href="#">Set new password</a> <a class="btn btn-primary pl-5 pr-5" href="#">{% trans "Set new password" %}</a>
</div> </div>
{% endcomment %} {% endcomment %}
</div> </div>
@ -31,7 +31,7 @@
{% with profile.billing as contact %} {% with profile.billing as contact %}
<div class="card card-profile"> <div class="card card-profile">
<h5 class="card-header">Billing information</h5> <h5 class="card-header">{% trans "Billing information" %}</h5>
<div class="card-body"> <div class="card-body">
<div class="form-group">{{ contact.name }}</div> <div class="form-group">{{ contact.name }}</div>
<div class="form-group">{{ contact.address }}</div> <div class="form-group">{{ contact.address }}</div>
@ -45,7 +45,7 @@
</div> </div>
<!-- payment method --> <!-- payment method -->
<div class="form-group"> <div class="form-group">
payment method: {{ payment.method }} {% trans "payment method:" %} {{ payment.method }}
</div> </div>
<div class="form-group"> <div class="form-group">
{% if payment.method == 'SEPADirectDebit' %} {% if payment.method == 'SEPADirectDebit' %}

View File

@ -34,7 +34,7 @@
</div> </div>
<div class="col-md-5 text-right"> <div class="col-md-5 text-right">
<div class="service-manager-link"> <div class="service-manager-link">
<a class="btn btn-primary" href="#open-service">{% trans "Open service admin panel" %} <i class="fas fa-external-link-alt"></i></a> <a class="btn btn-primary" href="{{ saas.manager_url }}" target="_blank" rel="noopener noreferrer">{% trans "Open service admin panel" %} <i class="fas fa-external-link-alt"></i></a>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,9 +1,11 @@
from itertools import groupby from itertools import groupby
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render from django.shortcuts import render
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils import translation
from django.utils.http import is_safe_url from django.utils.http import is_safe_url
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views import View from django.views import View
@ -305,7 +307,15 @@ class LoginView(FormView):
def form_valid(self, form): def form_valid(self, form):
"""Security check complete. Log the user in.""" """Security check complete. Log the user in."""
auth_login(self.request, form.username, form.token) auth_login(self.request, form.username, form.token)
return HttpResponseRedirect(self.get_success_url())
# set user language as active language
user_language = form.user.language
translation.activate(user_language)
response = HttpResponseRedirect(self.get_success_url())
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, user_language)
return response
def get_success_url(self): def get_success_url(self):
url = self.get_redirect_url() url = self.get_redirect_url()

View File

@ -13,8 +13,8 @@ https://docs.djangoproject.com/en/2.2/ref/settings/
import os import os
from decouple import config, Csv from decouple import config, Csv
from dj_database_url import parse as db_url
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from dj_database_url import parse as db_url
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
@ -59,6 +59,7 @@ INSTALLED_APPS = [
MIDDLEWARE = [ MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
@ -130,7 +131,13 @@ SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
# https://docs.djangoproject.com/en/2.2/topics/i18n/ # https://docs.djangoproject.com/en/2.2/topics/i18n/
# Fallback language # Fallback language
LANGUAGE_CODE = 'ca' LANGUAGE_CODE = config('LANGUAGE_CODE', 'en-us')
LANGUAGES = [
('ca', _('Catalan')),
('en', _('English')),
('es', _('Spanish')),
]
TIME_ZONE = 'Europe/Madrid' TIME_ZONE = 'Europe/Madrid'
@ -157,3 +164,15 @@ STATIC_ROOT = config('STATIC_ROOT')
# Backend API configuration # Backend API configuration
API_BASE_URL = config('API_BASE_URL') API_BASE_URL = config('API_BASE_URL')
# External services URLs
URL_DB_PHPMYADMIN = config('URL_DB_PHPMYADMIN', None)
URL_MAILTRAIN = config('URL_MAILTRAIN', None)
URL_SAAS_GITLAB = config('URL_SAAS_GITLAB', None)
URL_SAAS_OWNCLOUD = config('URL_SAAS_OWNCLOUD', None)
URL_SAAS_WORDPRESS = config('URL_SAAS_WORDPRESS', None)