Commit 8f3121df0c0a1e7e78a168fcc4e22d16e0520dcf
Exists in
master
and in
3 other branches
Merge branch 'refactoring' of https://github.com/amadeusproject/amadeuslms into refactoring
Showing
14 changed files
with
302 additions
and
14 deletions
Show diff stats
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 | ... | ... |
... | ... | @@ -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">×</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
... | ... | @@ -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">×</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 | ... | ... |
... | ... | @@ -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 | ... | ... |
... | ... | @@ -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 | ... | ... |