statics and theme management (#7070)

Templates and statics upload to organization dir
This commit is contained in:
Serghei Mihai 2015-05-17 17:01:30 +02:00
parent 1b6c172710
commit f4843b93ea
16 changed files with 220 additions and 7 deletions

View File

@ -23,4 +23,6 @@ METADATAS_DIR = os.path.join(VAR_DIR, 'metadatas')
SECRET_KEY = file('/etc/%s/secret' % PROJECT_NAME).read()
ORGANIZATIONS_DIR = os.path.join(VAR_DIR, 'organizations')
execfile(os.path.join(ETC_DIR, 'settings.py'))

View File

@ -9,10 +9,11 @@ server {
access_log /var/log/nginx/u-auth.example.org-access.log combined;
error_log /var/log/nginx/u-auth.example.org-error.log;
location ~ ^/static/(.+)$ {
location ~ ^(.*)/static/(.+)$ {
root /;
try_files /var/lib/u-auth/static/$1
/var/lib/u-auth/collectstatic/$1
try_files /var/lib/u-auth/organizations/$1/static/$2
/var/lib/u-auth/static/$2
/var/lib/u-auth/collectstatic/$2
=404;
}

1
debian/u-auth.dirs vendored
View File

@ -1,5 +1,6 @@
/etc/u-auth
/usr/lib/u-auth
/var/lib/u-auth/organizations
/var/lib/u-auth/collectstatic
/var/lib/u-auth/static
/var/lib/u-auth/templates

View File

@ -0,0 +1,14 @@
import os
from django.conf import settings
from django.template.loader import get_template, TemplateDoesNotExist
def theme_base(request):
if request.session.get('organization'):
try:
base = get_template('base.html', [os.path.join(settings.ORGANIZATIONS_DIR,
request.session['organization'], 'templates')])
except TemplateDoesNotExist:
base = get_template('uauth/base.html')
return {'theme_base': base}

View File

@ -31,3 +31,10 @@ class LocalAccountCreateForm(LocalAccountForm):
class UsersImportForm(forms.Form):
users_file = forms.FileField(_('Users file'))
class TemplateForm(forms.Form):
template_file = forms.FileField(_('Template file'))
class StaticForm(forms.Form):
static_file = forms.FileField(_('Static file'))

View File

@ -4,5 +4,6 @@
{% block content %}
<ul class="apps">
<li class="users"><a href="{% url 'manage-users' organization.slug %}">{% trans 'Users' %}</a></li>
<li class="theme"><a href="{% url 'manage-theme' organization.slug %}">{% trans 'Theme' %}</a></li>
</ul>
{% endblock %}

View File

@ -0,0 +1,45 @@
{% extends "organization/base.html" %}
{% load i18n %}
{% block page-title %}
{% trans 'Theme management' %}
{% endblock %}
{% block appbar %}
<h2>{% trans "Theme" %}</h2>
<a href="{% url "static-upload" organization.slug %}" rel="popup">{% trans "Upload static" %}</a>
<a href="{% url "template-upload" organization.slug %}" rel="popup">{% trans "Upload template" %}</a>
<h3>{% trans "Templates" %}</h3>
<form action='{% url "template-delete" organization.slug %}'>
<table>
<thead>
<tr><td>{% trans "Filename" %}</td><td></td></tr>
</thead>
<tbody>
{% for template in templates %}
<tr><td>{{ template }}</td><td> <button name="template" value="{{ template }}" class="icon-delete">{% trans "Remove" %}</button></td></tr>
{% empty %}
<tr><td colspan=2>{% trans "No templates uploaded yet" %}</td></tr>
{% endfor %}
</tbody>
</table>
</form>
<h3>{% trans "Statics" %}</h3>
<form action='{% url "static-delete" organization.slug %}'>
<table>
<thead>
<tr><td>{% trans "Filename" %}</td><td></td></tr>
</thead>
<tbody>
{% for static in statics %}
<tr><td>{{ static }}</td><td><button name="static" value="{{ static }}" class="icon-delete">{% trans "Remove" %}</button></td></tr>
{% empty %}
<tr><td>{% trans "No statics uploaded yet" %}</td></tr>
{% endfor %}
</tbody>
</table>
</form>
{% endblock %}

View File

@ -0,0 +1,21 @@
{% extends "organization/base.html" %}
{% load i18n %}
{% block more-user-links %}
{{ block.super }}
<a href="{% url "manage-theme" organization.slug %}">{% trans 'Theme' %}</a>
{% endblock %}
{% block appbar %}
<h2>{% trans "Theme" %}</h2>
<a href="{% url "static-upload" organization.slug %}" rel="popup">{% trans "Upload static" %}</a>
<a href="{% url "template-upload" organization.slug %}" rel="popup">{% trans "Upload template" %}</a>
{% endblock %}
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<p><button name="upload">{% trans "Upload" %}</button>
</form>
{% endblock %}

View File

@ -9,4 +9,9 @@ urlpatterns = patterns('',
url(r'^users/import$', import_users, name='import-users'),
url(r'^users/(?P<pk>[\w]+)/$', view_user, name='view-user'),
url(r'^users/(?P<pk>[\w]+)/edit$', edit_user, name='edit-user'),
url(r'^theme/?$', theme, name='manage-theme'),
url(r'^theme/template/upload$', template_upload, name='template-upload'),
url(r'^theme/template/delete$', template_delete, name='template-delete'),
url(r'^theme/static/upload$', static_upload, name='static-upload'),
url(r'^theme/static/delete$', static_delete, name='static-delete'),
)

View File

@ -1,6 +1,8 @@
import os
import csv
import datetime
from django.conf import settings
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import render, redirect
@ -15,7 +17,7 @@ from django_tables2 import RequestConfig
from .utils import create_user, create_or_update_users
from .models import LocalAccount, Organization
from .forms import LocalAccountCreateForm, LocalAccountForm, UsersImportForm
from .forms import *
from .tables import AccountTable
@ -153,3 +155,111 @@ class ImportUsersView(OrganizationMixin, TemplateView):
return self.render_to_response(context)
import_users = ImportUsersView.as_view()
class ThemeView(OrganizationMixin, TemplateView):
template_name = 'organization/theme.html'
def get_success_url(self):
return reverse_lazy('manage-theme', kwargs={'organization_slug': self.kwargs['organization_slug']})
def get_context_data(self, **kwargs):
ctx = super(ThemeView, self).get_context_data(**kwargs)
organization = ctx['organization']
templates_dir = os.path.join(settings.ORGANIZATIONS_DIR,
organization.slug, 'templates')
statics_dir = os.path.join(settings.ORGANIZATIONS_DIR,
organization.slug, 'static')
ctx['templates'] = []
ctx['statics'] = []
if os.path.exists(templates_dir):
ctx['templates'] = os.listdir(templates_dir)
if os.path.exists(statics_dir):
ctx['statics'] = os.listdir(statics_dir)
ctx['templates_dir'] = templates_dir
ctx['statics_dir'] = statics_dir
return ctx
theme = ThemeView.as_view()
class UploadMixin(object):
template_name = "organization/upload.html"
def get_context_data(self, **kwargs):
ctx = super(UploadMixin, self).get_context_data(**kwargs)
ctx['form'] = self.form_class()
return ctx
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request.FILES)
context = self.get_context_data(**kwargs)
context['form'] = form
organization = context['organization']
destination_dir = os.path.join(settings.ORGANIZATIONS_DIR,
organization.slug, self.upload_dir)
if form.is_valid():
data = form.cleaned_data[self.filename_param]
if not os.path.exists(destination_dir):
os.makedirs(destination_dir)
try:
with open(os.path.join(destination_dir, data.name), 'w') as template:
template.write(data.read())
messages.info(request, _('File "%s" successfully uploaded') % data.name)
except OSError:
messages.error(request, _('An error occured while uploading file "%s"') % data.name)
return redirect(self.get_success_url())
else:
return self.render_to_response(context)
class TemplateUpload(UploadMixin, ThemeView):
form_class = TemplateForm
filename_param = 'template_file'
upload_dir = 'templates'
template_upload = TemplateUpload.as_view()
class TemplateDelete(ThemeView):
def get(self, request, *args, **kwargs):
ctx = self.get_context_data(**kwargs)
template = request.GET.get('template')
if os.path.exists(os.path.join(ctx['templates_dir'], template)):
try:
os.remove(os.path.join(ctx['templates_dir'], template))
messages.info(request, _('Template %s successfully removed') % template)
except IOError:
messages.error(request, _('An error occured while removing file %s') % template)
else:
messages.error(request, _('Unknown template %s') % template)
return redirect(self.get_success_url())
template_delete = TemplateDelete.as_view()
class StaticUpload(UploadMixin, ThemeView):
form_class = StaticForm
filename_param = 'static_file'
upload_dir = 'static'
static_upload = StaticUpload.as_view()
class StaticDelete(ThemeView):
def get(self, request, *args, **kwargs):
ctx = self.get_context_data(**kwargs)
static = request.GET.get('static')
if os.path.exists(os.path.join(ctx['statics_dir'], static)):
try:
os.remove(os.path.join(ctx['statics_dir'], static))
messages.info(request, _('Static file %s successfully removed') % static)
except IOError:
messages.error(request, _('An error occured while removing file %s') % static)
else:
messages.error(request, _('Unknown static %s') % static)
return redirect(self.get_success_url())
static_delete = StaticDelete.as_view()

View File

@ -54,7 +54,9 @@ MIDDLEWARE_CLASSES = (
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + ('django.core.context_processors.request',)
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + \
('django.core.context_processors.request',
'uauth.context_processors.theme_base',)
ROOT_URLCONF = 'uauth.urls'
@ -97,6 +99,8 @@ LDAP_CONF = {
'dn': 'ou=radius,dc=entrouvert,dc=org',
}
ORGANIZATIONS_DIR = os.path.join(BASE_DIR, 'organizations')
AUTHENTICATION_BACKENDS = global_settings.AUTHENTICATION_BACKENDS + (
'mellon.backends.SAMLBackend',
'uauth.backends.LocalAccountPasswordBackend',

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -74,4 +74,5 @@ div.example {
}
/* icons */
li.users a {background-image: url(icons/icon-personnes.png);}
li.users a {background-image: url(icons/icon-personnes.png);}
li.theme a {background-image: url(icons/icon-ressources.png);}

View File

@ -1,4 +1,4 @@
{% extends "uauth/base.html" %}
{% extends theme_base %}
{% load i18n %}
{% block more-user-links %}

View File

@ -77,6 +77,7 @@ class OrganizationPageView(LoginMixin, FormView):
context = super(OrganizationPageView, self).get_context_data(**kwargs)
idps = get_idp_list()
organization = Organization.objects.get(slug=self.kwargs['organization_slug'])
self.request.session['organization'] = organization.slug
self.request.session[organization.slug] = self.request.GET.urlencode()
relay = signing.dumps({'organization': organization.slug})
context.update({'idps': idps,