Commit 8f3121df0c0a1e7e78a168fcc4e22d16e0520dcf

Authored by Felipe Henrique de Almeida Bormann
2 parents dd225fed d7541a25

Merge branch 'refactoring' of https://github.com/amadeusproject/amadeuslms into refactoring

amadeus/static/css/base/amadeus.css
... ... @@ -960,3 +960,24 @@ ul, li {
960 960  
961 961 /* subjects app ends */
962 962  
  963 +/* Themes */
  964 +.page_selector h4 {
  965 + margin-bottom: 20px;
  966 + border-bottom: 1px solid #e5e5e5;
  967 +}
  968 +.page_selector:hover, .page_selector:focus {
  969 + text-decoration: none;
  970 +}
  971 +
  972 +.filedrag{
  973 + display: none;
  974 + font-weight: bold;
  975 + text-align: center;
  976 + padding: 1em 0;
  977 + margin: 1em 0;
  978 + color: #555;
  979 + border: 2px dashed #555;
  980 + border-radius: 7px;
  981 + cursor: pointer;
  982 +}
  983 +/* End Themes */
963 984 \ No newline at end of file
... ...
amadeus/static/js/themes.js 0 → 100644
... ... @@ -0,0 +1,37 @@
  1 +// check if browser supports drag n drop
  2 +// call initialization file
  3 +if (window.File && window.FileList && window.FileReader) {
  4 + Init();
  5 +}
  6 +
  7 +// initialize
  8 +function Init() {
  9 + var small = $("#id_small_logo"),
  10 + large = $("#id_large_logo"),
  11 + filedrag = $(".filedrag"),
  12 + common = $(".common-file-input");
  13 +
  14 + // file select
  15 + small.on("change", FileSelectHandler);
  16 + large.on("change", FileSelectHandler);
  17 +
  18 + // is XHR2 available?
  19 + var xhr = new XMLHttpRequest();
  20 + if (xhr.upload) {
  21 + // file drop
  22 + filedrag.on("drop", FileSelectHandler);
  23 + filedrag.attr('style', 'display:block');
  24 + common.attr('style', 'display:none');
  25 + }
  26 +}
  27 +
  28 +// file selection
  29 +function FileSelectHandler(e) {
  30 + var files = e.target.files || e.dataTransfer.files,
  31 + parent = $(e.target.offsetParent);
  32 +
  33 + // process all File objects
  34 + for (var i = 0, f; f = files[i]; i++) {
  35 + parent.find('.filedrag').html(f.name);
  36 + }
  37 +}
0 38 \ No newline at end of file
... ...
amadeus/templates/base.html
... ... @@ -115,7 +115,7 @@
115 115 <ul class="submenu">
116 116 <li><a href="{% url 'mailsender:update' %}">{% trans 'Mail Sender' %}</a></li>
117 117 <li><a href="{% url 'security:update' %}">{% trans 'Security' %}</a></li>
118   - <li><a href="{% url 'categories:index' %}">{% trans 'Theme' %}</a></li>
  118 + <li><a href="{% url 'themes:manage' %}">{% trans 'Theme' %}</a></li>
119 119 </ul>
120 120 </div>
121 121 </div>
... ...
amadeus/urls.py
... ... @@ -29,6 +29,7 @@ urlpatterns = [
29 29 url(r'^subjects/', include('subjects.urls', namespace = 'subjects')),
30 30 url(r'^mailsender/', include('mailsender.urls', namespace = 'mailsender')),
31 31 url(r'^security/', include('security.urls', namespace = 'security')),
  32 + url(r'^themes/', include('themes.urls', namespace = 'themes')),
32 33 #API
33 34 url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
34 35 #S3Direct
... ...
security/models.py
... ... @@ -3,7 +3,7 @@ from django.utils.translation import ugettext_lazy as _
3 3  
4 4 class Security(models.Model):
5 5 allow_register = models.BooleanField(_("Don't allow users to self-register"), default = False)
6   - maintence = models.BooleanField(_("Put system in maintence mode"), default = False)
  6 + maintence = models.BooleanField(_("Put system in maintenance mode"), default = False)
7 7  
8 8 class Meta:
9 9 verbose_name = _('Security configuration')
... ...
security/templates/security/update.html
... ... @@ -16,10 +16,25 @@
16 16 <form method="post" action="" enctype="multipart/form-data">
17 17 {% csrf_token %}
18 18 {% for field in form %}
19   - <div class="checkbox">
20   - <label for="{{ field.auto_id }}">
21   - {% render_field field %} {{field.label}}
22   - </label>
  19 + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">
  20 + <div class="checkbox">
  21 + <label for="{{ field.auto_id }}">
  22 + {% render_field field %} {{field.label}}
  23 + </label>
  24 + </div>
  25 + <span id="helpBlock" class="help-block">{{ field.help_text }}</span>
  26 + {% if field.errors %}
  27 + <div class="alert alert-danger alert-dismissible" role="alert">
  28 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  29 + <span aria-hidden="true">&times;</span>
  30 + </button>
  31 + <ul>
  32 + {% for error in field.errors %}
  33 + <li>{{ error }}</li>
  34 + {% endfor %}
  35 + </ul>
  36 + </div>
  37 + {% endif %}
23 38 </div>
24 39 {% endfor %}
25 40 <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12">
... ...
themes/forms.py
... ... @@ -3,7 +3,7 @@ from django import forms
3 3  
4 4 from .models import Themes
5 5  
6   -class BasciElemetsForm(forms.ModelForm):
  6 +class BasicElemetsForm(forms.ModelForm):
7 7  
8 8 class Meta:
9 9 model = Themes
... ...
themes/templates/themes/basic_update.html 0 → 100644
... ... @@ -0,0 +1,88 @@
  1 +{% extends 'themes/index.html' %}
  2 +
  3 +{% load static i18n %}
  4 +{% load widget_tweaks %}
  5 +{% load django_bootstrap_breadcrumbs %}
  6 +
  7 +{% block breadcrumbs %}
  8 + {{ block.super }}
  9 + {% breadcrumb 'Basic Elements' 'themes:basic' %}
  10 +{% endblock %}
  11 +
  12 +{% block content %}
  13 + <div class="card">
  14 + <div class="card-content">
  15 + <div class="card-body">
  16 + <a href="{% url 'themes:basic' %}" class="page_selector"><h4><i class="fa fa-angle-down"></i> {% trans 'Basic Elements' %}</h4></a>
  17 +
  18 + <form method="post" action="" enctype="multipart/form-data">
  19 + {% csrf_token %}
  20 + {% for field in form %}
  21 + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">
  22 + {% if field.auto_id == 'id_small_logo' or field.auto_id == 'id_large_logo' %}
  23 + {% if field.field.required %}
  24 + <label for="{{ field.auto_id }}">{{ field.label }} <span>*</span></label>
  25 + {% else %}
  26 + <label for="{{ field.auto_id }}">{{ field.label }}</label>
  27 + {% endif %}
  28 +
  29 + {% render_field field class='form-control' %}
  30 +
  31 + <div class="input-group common-file-input">
  32 + <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your photo...' %}">
  33 + <span class="input-group-btn input-group-sm">
  34 + <button type="button" class="btn btn-fab btn-fab-mini">
  35 + <i class="material-icons">attach_file</i>
  36 + </button>
  37 + </span>
  38 + </div>
  39 + <div class="filedrag">{% trans 'Click or drop files here' %}</div>
  40 +
  41 + {% elif field.auto_id == 'id_footer_note' %}
  42 + {% if field.field.required %}
  43 + <label for="{{ field.auto_id }}">{{ field.label }} <span>*</span></label>
  44 + {% else %}
  45 + <label for="{{ field.auto_id }}">{{ field.label }}</label>
  46 + {% endif %}
  47 +
  48 + {% render_field field class='form-control text_wysiwyg' %}
  49 + {% else %}
  50 + {% if field.field.required %}
  51 + <label for="{{ field.auto_id }}">{{ field.label }} <span>*</span></label>
  52 + {% else %}
  53 + <label for="{{ field.auto_id }}">{{ field.label }}</label>
  54 + {% endif %}
  55 +
  56 + {% render_field field class='form-control' %}
  57 + {% endif %}
  58 +
  59 + <span id="helpBlock" class="help-block">{{ field.help_text }}</span>
  60 + {% if field.errors %}
  61 + <div class="alert alert-danger alert-dismissible" role="alert">
  62 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  63 + <span aria-hidden="true">&times;</span>
  64 + </button>
  65 + <ul>
  66 + {% for error in field.errors %}
  67 + <li>{{ error }}</li>
  68 + {% endfor %}
  69 + </ul>
  70 + </div>
  71 + {% endif %}
  72 + </div>
  73 + {% endfor %}
  74 + <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12">
  75 + <div class="text-center">
  76 + <input type="submit" value="{% trans 'Save' %}" class="btn btn-raised btn-primary" />
  77 + </div>
  78 + </div>
  79 + </form>
  80 +
  81 + <a href="{% url 'themes:css' %}" class="page_selector"><h4><i class="fa fa-angle-right"></i> {% trans 'CSS Selector' %}</h4></a>
  82 + </div>
  83 + </div>
  84 + </div>
  85 + <br clear="all" />
  86 + <br clear="all" />
  87 + <script type="text/javascript" src="{% static 'js/themes.js' %}"></script>
  88 +{% endblock %}
0 89 \ No newline at end of file
... ...
themes/templates/themes/css_update.html 0 → 100644
themes/templates/themes/index.html 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +{% extends 'base.html' %}
  2 +
  3 +{% load static i18n %}
  4 +{% load widget_tweaks %}
  5 +{% load django_bootstrap_breadcrumbs %}
  6 +
  7 +{% block breadcrumbs %}
  8 + {{ block.super }}
  9 + {% breadcrumb 'Settings: Themes' 'themes:manage' %}
  10 +{% endblock %}
  11 +
  12 +{% block content %}
  13 + <div class="card">
  14 + <div class="card-content">
  15 + <div class="card-body">
  16 + <a href="{% url 'themes:basic' %}" class="page_selector"><h4><i class="fa fa-angle-right"></i> {% trans 'Basic Elements' %}</h4></a>
  17 + <a href="{% url 'themes:css' %}" class="page_selector"><h4><i class="fa fa-angle-right"></i> {% trans 'CSS Selector' %}</h4></a>
  18 + </div>
  19 + </div>
  20 + </div>
  21 + <br clear="all" />
  22 + <br clear="all" />
  23 +{% endblock %}
0 24 \ No newline at end of file
... ...
themes/urls.py 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +from django.conf.urls import url
  2 +from . import views
  3 +
  4 +urlpatterns = [
  5 + url(r'^$', views.IndexView.as_view(), name = 'manage'),
  6 + url(r'^basic_elements$', views.BasicElementsSettings.as_view(), name = 'basic'),
  7 + url(r'^css_selector$', views.CSSStyleSettings.as_view(), name = 'css'),
  8 +]
0 9 \ No newline at end of file
... ...
themes/views.py
  1 +from django.views import generic
1 2 from django.shortcuts import render
  3 +from django.contrib import messages
  4 +from django.core.urlresolvers import reverse, reverse_lazy
  5 +from django.utils.translation import ugettext_lazy as _
2 6  
3   -# Create your views here.
  7 +from braces import views as braces_mixins
  8 +
  9 +from .models import Themes
  10 +from .forms import BasicElemetsForm, CSSStyleForm
  11 +
  12 +class IndexView(braces_mixins.LoginRequiredMixin, braces_mixins.StaffuserRequiredMixin, generic.TemplateView):
  13 + login_url = reverse_lazy("users:login")
  14 + redirect_field_name = 'next'
  15 +
  16 + template_name = 'themes/index.html'
  17 +
  18 + def get_context_data(self, **kwargs):
  19 + context = super(IndexView, self).get_context_data(**kwargs)
  20 +
  21 + context['title'] = _('Themes')
  22 + context['settings_menu_active'] = "settings_menu_active"
  23 +
  24 + return context
  25 +
  26 +class BasicElementsSettings(braces_mixins.LoginRequiredMixin, braces_mixins.StaffuserRequiredMixin, generic.UpdateView):
  27 + login_url = reverse_lazy("users:login")
  28 + redirect_field_name = 'next'
  29 +
  30 + template_name = 'themes/basic_update.html'
  31 + model = Themes
  32 + form_class = BasicElemetsForm
  33 + success_url = reverse_lazy("subjects:home")
  34 +
  35 + def get_object(self, queryset = None):
  36 + return Themes.objects.get(id = 1)
  37 +
  38 + def form_valid(self, form):
  39 + form.save()
  40 +
  41 + messages.success(self.request, _("Theme settings updated successfully!"))
  42 +
  43 + return super(BasicElementsSettings, self).form_valid(form)
  44 +
  45 + def get_context_data(self, **kwargs):
  46 + context = super(BasicElementsSettings, self).get_context_data(**kwargs)
  47 +
  48 + context['title'] = _('Basic Elements')
  49 + context['settings_menu_active'] = "settings_menu_active"
  50 +
  51 + return context
  52 +
  53 +
  54 +class CSSStyleSettings(braces_mixins.LoginRequiredMixin, braces_mixins.StaffuserRequiredMixin, generic.UpdateView):
  55 + login_url = reverse_lazy("users:login")
  56 + redirect_field_name = 'next'
  57 +
  58 + template_name = 'themes/css_update.html'
  59 + model = Themes
  60 + form_class = CSSStyleForm
  61 + success_url = reverse_lazy("subjects:home")
  62 +
  63 + def get_object(self, queryset = None):
  64 + return Themes.objects.get(id = 1)
  65 +
  66 + def form_valid(self, form):
  67 + form.save()
  68 +
  69 + messages.success(self.request, _("Theme settings updated successfully!"))
  70 +
  71 + return super(CSSStyleSettings, self).form_valid(form)
  72 +
  73 + def get_context_data(self, **kwargs):
  74 + context = super(CSSStyleSettings, self).get_context_data(**kwargs)
  75 +
  76 + context['title'] = _('CSS Selector')
  77 + context['settings_menu_active'] = "settings_menu_active"
  78 +
  79 + return context
... ...
users/templates/users/login.html
... ... @@ -59,9 +59,11 @@
59 59 <div class="col-md-6 col-xs-6 col-sm-6 col-lg-6 text-center">
60 60 <button type="submite" class="btn btn-success btn-raised btn-block" form="form-login" style="position: initial;"> {% trans 'Log in' %} </button>
61 61 </div>
62   - <div class="col-md-6 col-xs-6 col-sm-6 col-lg-6 text-center">
63   - <a class="btn btn-default btn-raised btn-block" href="{% url 'users:signup' %}" formaction="#" style="position: initial;">{% trans 'Sign Up' %}</a>
64   - </div>
  62 + {% if not deny_register %}
  63 + <div class="col-md-6 col-xs-6 col-sm-6 col-lg-6 text-center">
  64 + <a class="btn btn-default btn-raised btn-block" href="{% url 'users:signup' %}" formaction="#" style="position: initial;">{% trans 'Sign Up' %}</a>
  65 + </div>
  66 + {% endif %}
65 67 </div>
66 68 </div>
67 69 <div class="row">
... ...
users/views.py
... ... @@ -9,6 +9,8 @@ from django.db.models import Q
9 9  
10 10 from braces import views as braces_mixins
11 11  
  12 +from security.models import Security
  13 +
12 14 from .models import User
13 15 from .utils import has_dependencies
14 16 from .forms import RegisterUserForm, ProfileForm, UserForm, ChangePassForm, PassResetRequest, SetPasswordForm
... ... @@ -302,6 +304,14 @@ class RegisterUser(generic.edit.CreateView):
302 304  
303 305 return super(RegisterUser, self).form_valid(form)
304 306  
  307 + def dispatch(self, request, *args, **kwargs):
  308 + security = Security.objects.get(id = 1)
  309 +
  310 + if security.allow_register:
  311 + return redirect(reverse_lazy('users:login'))
  312 +
  313 + return super(RegisterUser, self).dispatch(request, *args, **kwargs)
  314 +
305 315 class ForgotPassword(generic.FormView):
306 316 template_name = "users/forgot_password.html"
307 317 success_url = reverse_lazy('users:login')
... ... @@ -399,21 +409,28 @@ class PasswordResetConfirmView(generic.FormView):
399 409 def login(request):
400 410 context = {}
401 411 context['title'] = _('Log In')
  412 + security = Security.objects.get(id = 1)
  413 +
  414 + context['deny_register'] = security.allow_register
402 415  
403 416 if request.POST:
404 417 username = request.POST['email']
405 418 password = request.POST['password']
406 419 user = authenticate(username=username, password=password)
  420 +
407 421 if user is not None:
408   - login_user(request, user)
409   - return redirect(reverse("home"))
  422 + if not security.maintence or user.is_staff:
  423 + login_user(request, user)
  424 + return redirect(reverse("home"))
  425 + else:
  426 + messages.error(request, _('System under maintenance. Try again later'))
410 427 else:
411 428 messages.error(request, _('E-mail or password are incorrect.'))
412 429 context["username"] = username
413 430 elif request.user.is_authenticated:
414 431 return redirect(reverse('home'))
415 432  
416   - return render(request,"users/login.html",context)
  433 + return render(request, "users/login.html", context)
417 434  
418 435  
419 436 # API VIEWS
... ...