Commit f9103c4b27ec969ea6f8d8753cd68fb281d66c3d

Authored by ailsoncgt
2 parents c9c4a9fb e4ae9d4b

Merge

Showing 44 changed files with 462 additions and 247 deletions   Show diff stats
amadeus/settings.py
@@ -46,6 +46,7 @@ INSTALLED_APPS = [ @@ -46,6 +46,7 @@ INSTALLED_APPS = [
46 'rest_framework', 46 'rest_framework',
47 'django_bootstrap_breadcrumbs', 47 'django_bootstrap_breadcrumbs',
48 's3direct', 48 's3direct',
  49 + 'django_summernote',
49 50
50 'users', 51 'users',
51 'core', 52 'core',
@@ -225,7 +226,59 @@ S3DIRECT_DESTINATIONS = { @@ -225,7 +226,59 @@ S3DIRECT_DESTINATIONS = {
225 # FILE UPLOAD 226 # FILE UPLOAD
226 MAX_UPLOAD_SIZE = 10485760 227 MAX_UPLOAD_SIZE = 10485760
227 228
  229 +SUMMERNOTE_CONFIG = {
  230 + # Using SummernoteWidget - iframe mode
  231 + 'iframe': True, # or set False to use SummernoteInplaceWidget - no iframe mode
  232 +
  233 + # Using Summernote Air-mode
  234 + 'airMode': False,
  235 +
  236 + # Use native HTML tags (`<b>`, `<i>`, ...) instead of style attributes
  237 + # (Firefox, Chrome only)
  238 + 'styleWithTags': True,
  239 +
  240 + # Set text direction : 'left to right' is default.
  241 + 'direction': 'ltr',
  242 +
  243 + # Change editor size
  244 + 'width': '100%',
  245 + 'height': '480',
  246 +
  247 + # Use proper language setting automatically (default)
  248 + 'lang': None,
  249 +
  250 + # Or, set editor language/locale forcely
  251 + 'lang_matches': {
  252 + 'pt': 'pt-BR',
  253 + },
  254 +
  255 + # Customize toolbar buttons
  256 + 'toolbar': [
  257 + ['style', ['style']],
  258 + ['font', ['bold', 'italic', 'underline', 'superscript', 'subscript',
  259 + 'strikethrough', 'clear']],
  260 + ['fontname', ['fontname']],
  261 + ['fontsize', ['fontsize']],
  262 + ['color', ['color']],
  263 + ['para', ['ul', 'ol', 'paragraph']],
  264 + ['height', ['height']],
  265 + ['table', ['table']],
  266 + ['insert', ['link', 'picture', 'video', 'hr']],
  267 + ['view', ['fullscreen', 'codeview']],
  268 + ['help', ['help']],
  269 + ],
  270 +
  271 + # Need authentication while uploading attachments.
  272 + 'attachment_require_authentication': True,
  273 +
  274 + # Set `upload_to` function for attachments.
  275 + #'attachment_upload_to': my_custom_upload_to_func(),
  276 +
  277 +
  278 +
  279 +}
  280 +
228 try: 281 try:
229 from .local_settings import * 282 from .local_settings import *
230 except ImportError: 283 except ImportError:
231 - pass 284 - pass
  285 + pass
232 \ No newline at end of file 286 \ No newline at end of file
amadeus/urls.py
@@ -28,6 +28,7 @@ urlpatterns = [ @@ -28,6 +28,7 @@ urlpatterns = [
28 28
29 #S3Direct 29 #S3Direct
30 url(r'^s3direct/', include('s3direct.urls')), 30 url(r'^s3direct/', include('s3direct.urls')),
  31 + url(r'^summernote/', include('django_summernote.urls')),
31 ] 32 ]
32 33
33 urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT) 34 urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
@@ -4,17 +4,14 @@ from django.views import View @@ -4,17 +4,14 @@ from django.views import View
4 from rolepermissions.mixins import HasRoleMixin 4 from rolepermissions.mixins import HasRoleMixin
5 from django.contrib.auth.mixins import LoginRequiredMixin 5 from django.contrib.auth.mixins import LoginRequiredMixin
6 from django.core.urlresolvers import reverse_lazy 6 from django.core.urlresolvers import reverse_lazy
7 -from core.mixins import LogMixin, NotificationMixin 7 +from core.mixins import NotificationMixin
8 from core.models import Notification, Action, Resource, Action_Resource 8 from core.models import Notification, Action, Resource, Action_Resource
9 from users.models import User 9 from users.models import User
10 from .models import EmailBackend 10 from .models import EmailBackend
11 from .forms import EmailBackendForm 11 from .forms import EmailBackendForm
12 from courses.models import Course 12 from courses.models import Course
13 13
14 -class AppIndex(LoginRequiredMixin, LogMixin, ListView, NotificationMixin):  
15 - log_action = "Acessar"  
16 - log_resource = "Home"  
17 - 14 +class AppIndex(LoginRequiredMixin, ListView, NotificationMixin):
18 login_url = reverse_lazy("core:home") 15 login_url = reverse_lazy("core:home")
19 redirect_field_name = 'next' 16 redirect_field_name = 'next'
20 17
@@ -46,7 +43,7 @@ class AppIndex(LoginRequiredMixin, LogMixin, ListView, NotificationMixin): @@ -46,7 +43,7 @@ class AppIndex(LoginRequiredMixin, LogMixin, ListView, NotificationMixin):
46 43
47 return self.response_class(request = self.request, template = self.template_name, context = context, using = self.template_engine, **response_kwargs) 44 return self.response_class(request = self.request, template = self.template_name, context = context, using = self.template_engine, **response_kwargs)
48 45
49 -class AmadeusSettings(LoginRequiredMixin, HasRoleMixin, View): 46 +class AmadeusSettings(LoginRequiredMixin, HasRoleMixin, View):
50 allowed_roles = ['system_admin'] 47 allowed_roles = ['system_admin']
51 login_url = reverse_lazy("core:home") 48 login_url = reverse_lazy("core:home")
52 redirect_field_name = 'next' 49 redirect_field_name = 'next'
core/decorators.py
1 from django.conf import settings 1 from django.conf import settings
  2 +import json
2 from functools import wraps 3 from functools import wraps
3 from .models import Action, Resource, Action_Resource, Log, Notification 4 from .models import Action, Resource, Action_Resource, Log, Notification
4 5
5 -def log_decorator(log_action = '', log_resource = ''): 6 +def log_decorator(log_component = '', log_action = '', log_resource = ''):
6 7
7 def _log_decorator(view_function): 8 def _log_decorator(view_function):
8 9
@@ -10,7 +11,7 @@ def log_decorator(log_action = &#39;&#39;, log_resource = &#39;&#39;): @@ -10,7 +11,7 @@ def log_decorator(log_action = &#39;&#39;, log_resource = &#39;&#39;):
10 11
11 response = view_function(request, *args, **kwargs) 12 response = view_function(request, *args, **kwargs)
12 13
13 - if request.user.is_authenticated and request.POST: 14 + if request.user.is_authenticated:
14 action = Action.objects.filter(name = log_action) 15 action = Action.objects.filter(name = log_action)
15 resource = Resource.objects.filter(name = log_resource) 16 resource = Resource.objects.filter(name = log_resource)
16 17
@@ -36,6 +37,8 @@ def log_decorator(log_action = &#39;&#39;, log_resource = &#39;&#39;): @@ -36,6 +37,8 @@ def log_decorator(log_action = &#39;&#39;, log_resource = &#39;&#39;):
36 37
37 log = Log() 38 log = Log()
38 log.user = request.user 39 log.user = request.user
  40 + log.component = log_component
  41 + log.context = json.dumps(request.log_context)
39 log.action_resource = action_resource 42 log.action_resource = action_resource
40 43
41 log.save() 44 log.save()
core/migrations/0003_auto_20161101_1457.py 0 → 100644
@@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-11-01 17:57
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations, models
  6 +
  7 +
  8 +class Migration(migrations.Migration):
  9 +
  10 + dependencies = [
  11 + ('core', '0002_auto_20161024_1559'),
  12 + ]
  13 +
  14 + operations = [
  15 + migrations.AddField(
  16 + model_name='log',
  17 + name='component',
  18 + field=models.TextField(default='', verbose_name='Component (Module / App)'),
  19 + preserve_default=False,
  20 + ),
  21 + migrations.AddField(
  22 + model_name='log',
  23 + name='context',
  24 + field=models.TextField(blank=True, verbose_name='Context'),
  25 + ),
  26 + ]
core/mixins.py
1 from django.conf import settings 1 from django.conf import settings
  2 +import json
  3 +
2 from .models import Action, Resource, Action_Resource, Log, Notification 4 from .models import Action, Resource, Action_Resource, Log, Notification
3 from users.models import User 5 from users.models import User
4 6
5 class LogMixin(object): 7 class LogMixin(object):
  8 + log_component = ""
  9 + log_context = {}
6 log_action = "" 10 log_action = ""
7 log_resource = "" 11 log_resource = ""
8 12
9 - def dispatch(self, request, *args, **kwargs):  
10 - action = Action.objects.filter(name = self.log_action)  
11 - resource = Resource.objects.filter(name = self.log_resource) 13 + def createLog(self, actor = None, component = '', log_action = '', log_resource = '', context = {}):
  14 + action = Action.objects.filter(name = log_action)
  15 + resource = Resource.objects.filter(name = log_resource)
12 16
13 if not action: 17 if not action:
14 - action = Action(name = self.log_action) 18 + action = Action(name = log_action)
15 action.save() 19 action.save()
16 else: 20 else:
17 action = action[0] 21 action = action[0]
18 22
19 if not resource: 23 if not resource:
20 - resource = Resource(name = self.log_resource) 24 + resource = Resource(name = log_resource)
21 resource.save() 25 resource.save()
22 else: 26 else:
23 resource = resource[0] 27 resource = resource[0]
@@ -30,12 +34,18 @@ class LogMixin(object): @@ -30,12 +34,18 @@ class LogMixin(object):
30 else: 34 else:
31 action_resource = action_resource[0] 35 action_resource = action_resource[0]
32 36
  37 + print(context)
  38 + print(json.dumps(context))
  39 +
33 log = Log() 40 log = Log()
34 - log.user = request.user 41 + log.user = actor
  42 + log.context = json.dumps(context)
  43 + log.component = component
35 log.action_resource = action_resource 44 log.action_resource = action_resource
36 45
37 log.save() 46 log.save()
38 47
  48 + def dispatch(self, request, *args, **kwargs):
39 return super(LogMixin, self).dispatch(request, *args, **kwargs) 49 return super(LogMixin, self).dispatch(request, *args, **kwargs)
40 50
41 class NotificationMixin(object): 51 class NotificationMixin(object):
core/models.py
@@ -101,10 +101,15 @@ class Notification(models.Model): @@ -101,10 +101,15 @@ class Notification(models.Model):
101 return self.message 101 return self.message
102 102
103 class Log(models.Model): 103 class Log(models.Model):
104 - datetime = models.DateTimeField(_("Date and Time of action"), auto_now_add = True)  
105 - user = models.ForeignKey(User, verbose_name = _('Actor')) 104 + component = models.TextField(_('Component (Module / App)'))
  105 + context = models.TextField(_('Context'), blank = True)
106 action_resource = models.ForeignKey(Action_Resource, verbose_name = _('Action_Resource')) 106 action_resource = models.ForeignKey(Action_Resource, verbose_name = _('Action_Resource'))
  107 + user = models.ForeignKey(User, verbose_name = _('Actor'))
  108 + datetime = models.DateTimeField(_("Date and Time of action"), auto_now_add = True)
107 109
108 class Meta: 110 class Meta:
109 verbose_name = _('Log') 111 verbose_name = _('Log')
110 verbose_name_plural = _('Logs') 112 verbose_name_plural = _('Logs')
  113 +
  114 + def __str__(self):
  115 + return self.context
core/static/css/base/amadeus.css
@@ -420,7 +420,28 @@ ul, li { @@ -420,7 +420,28 @@ ul, li {
420 .course, .subject, .topic{ padding-top: 0px; padding-bottom: 0px; } 420 .course, .subject, .topic{ padding-top: 0px; padding-bottom: 0px; }
421 .course-detail{padding-top: 10px; padding-bottom: 10px;} 421 .course-detail{padding-top: 10px; padding-bottom: 10px;}
422 422
  423 +.course-card{
  424 + margin-bottom: 0.4% !important;
  425 +}
  426 +
  427 +.course-card-group{
  428 + margin-bottom: 1%;
  429 +}
  430 +
  431 +.category-course-link{
  432 + font-size: 24px;
  433 + color: black !important;
  434 +}
  435 +
423 /* Menu link remove radius */ 436 /* Menu link remove radius */
424 .nav-pills > li > a { 437 .nav-pills > li > a {
425 border-radius: 0px; 438 border-radius: 0px;
426 } 439 }
  440 +
  441 +.float-button{
  442 + float: right;
  443 + position: fixed;
  444 + bottom: 5%;
  445 + right: 5%;
  446 + font-size: 20px;
  447 +}
core/templates/base.html
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 20
21 <!-- Bootstrap and themes (material) --> 21 <!-- Bootstrap and themes (material) -->
22 <link rel="stylesheet" type="text/css" href="{% static 'bootstrap-3.3.7/css/bootstrap.css' %}"> 22 <link rel="stylesheet" type="text/css" href="{% static 'bootstrap-3.3.7/css/bootstrap.css' %}">
23 - 23 +
24 <link rel="stylesheet" type="text/css" href="{% static 'material/css/bootstrap-material-design.min.css' %}"> 24 <link rel="stylesheet" type="text/css" href="{% static 'material/css/bootstrap-material-design.min.css' %}">
25 <link rel="stylesheet" type="text/css" href="{% static 'material/css/ripples.css' %}"> 25 <link rel="stylesheet" type="text/css" href="{% static 'material/css/ripples.css' %}">
26 <link rel="stylesheet" type="text/css" href="{% static 'material/css/ripples.min.css' %}"> 26 <link rel="stylesheet" type="text/css" href="{% static 'material/css/ripples.min.css' %}">
@@ -79,7 +79,7 @@ @@ -79,7 +79,7 @@
79 <input type="text" class="form-control" placeholder="{% trans 'Search Files (.pdf, others) and/or activities' %}" name="search"></div> 79 <input type="text" class="form-control" placeholder="{% trans 'Search Files (.pdf, others) and/or activities' %}" name="search"></div>
80 <span class="input-group-btn input-group-sm"> 80 <span class="input-group-btn input-group-sm">
81 <button type="submit" class="btn btn-fab btn-fab-mini"> 81 <button type="submit" class="btn btn-fab btn-fab-mini">
82 - <i class="fa fa-search" aria-hidden="true"></i> 82 + <i class="glyphicon glyphicon-search" aria-hidden="true" style="color:#93C741"></i>
83 </button> 83 </button>
84 </span> 84 </span>
85 </div> 85 </div>
core/templates/guest.html
@@ -107,6 +107,7 @@ @@ -107,6 +107,7 @@
107 </div> 107 </div>
108 <div class="col-xs-10 col-sm-10 col-md-10 col-lg-10 col-xl-10"> 108 <div class="col-xs-10 col-sm-10 col-md-10 col-lg-10 col-xl-10">
109 {% block breadcrumbs %} 109 {% block breadcrumbs %}
  110 +
110 <div class="col-md-12"> 111 <div class="col-md-12">
111 <form id="searchform" action="{% url 'course:manage' %}" method="get" accept-charset="utf-8"> 112 <form id="searchform" action="{% url 'course:manage' %}" method="get" accept-charset="utf-8">
112 <div class="input-group"> 113 <div class="input-group">
@@ -121,46 +122,34 @@ @@ -121,46 +122,34 @@
121 </form> 122 </form>
122 </div> 123 </div>
123 124
124 - <div class="col-md-10">  
125 - <div class="btn-group btn-group-justified btn-group-raised">  
126 - <a href="?category=all" class="btn btn-raised btn-info">{% trans 'All' %}</a>  
127 - {% for category in categories %}  
128 - <a href="?category={{category.name}}" class="btn btn-raised btn-primary">{{category.name}}</a>  
129 - {% endfor %}  
130 - </div>  
131 - </div>  
132 -  
133 {% endblock %} 125 {% endblock %}
134 {% block render_breadcrumbs %}{% endblock %} 126 {% block render_breadcrumbs %}{% endblock %}
135 <div> 127 <div>
136 </div> 128 </div>
137 <div class="col-xs-12 col-sm-12 col-md-10 col-lg-10 col-xl-12"> 129 <div class="col-xs-12 col-sm-12 col-md-10 col-lg-10 col-xl-12">
138 {% block content %} 130 {% block content %}
139 - {% for course in courses %}  
140 - <div class="panel panel-info panel_{{ course.id }}">  
141 - <div class="panel-heading">  
142 - <a href="{{ course.get_absolute_url }}" class="panel-title">{{course.name}}</a>  
143 - {% if user|show_course_subscribe:course %}  
144 - <a onclick="subscribe($(this), '{% url 'course:subscribe' course.slug %}', {{ course.id}}, '{% trans 'Are you sure you want to subscribe to this course?' %}')" class="btn btn-sm btn-primary btn-raised pull-right" style="margin-top:-4px">{% trans 'Subscribe' %}</a>  
145 - {% endif %}  
146 - </div>  
147 -  
148 - <div class="panel-body">  
149 - <p><b>{% trans 'Course Name' %}: </b>{{course.name}}</p>  
150 - <p><b>{% trans 'Begining' %}: </b>{{course.init_date}}</p>  
151 - <p><b>{% trans 'End' %}: </b>{{course.end_date}}</p>  
152 - <p><b>{% trans 'Professor' %}: </b>{{course.professors.name}}</p>  
153 - <p>  
154 - <b>{% trans 'Description' %}:</b>  
155 - <i>  
156 - {{course.content}}  
157 - </i>  
158 - </p>  
159 - </div>  
160 - </div>  
161 - {% endfor %}  
162 131
163 - {% pagination request paginator page_obj %} 132 + <div class="col-md-12 cards-content">
  133 + {% for category in categorys_courses %}
  134 + <div class="panel-group">
  135 + <div class="panel panel-default">
  136 + <div class="panel-heading">
  137 + <h4 class="panel-title">
  138 + <a class="category-course-link" data-toggle="collapse" href="#{{category.slug}}">{{category.name}}</a>
  139 + </h4>
  140 +
  141 + </div>
  142 + <div id="{{category.slug}}" class="panel-collapse collapse">
  143 + {% for course in category.course_category.all %}
  144 + {%if course.public == True %}
  145 + {% include "course/course_card.html" %}
  146 + {% endif %}
  147 + {% endfor %}
  148 + </div>
  149 + </div>
  150 + </div>
  151 + {% endfor %}
  152 + </div>
164 {% endblock %} 153 {% endblock %}
165 </div> 154 </div>
166 </div> 155 </div>
@@ -68,7 +68,6 @@ def remember_password(request): @@ -68,7 +68,6 @@ def remember_password(request):
68 context['danger'] = 'E-mail does not send' 68 context['danger'] = 'E-mail does not send'
69 return render(request, "remember_password.html",context) 69 return render(request, "remember_password.html",context)
70 70
71 -@log_decorator('Acessar', 'Sistema')  
72 def login(request): 71 def login(request):
73 context = {} 72 context = {}
74 73
@@ -87,17 +86,12 @@ def login(request): @@ -87,17 +86,12 @@ def login(request):
87 86
88 return render(request,"index.html",context) 87 return render(request,"index.html",context)
89 88
90 -  
91 -  
92 def processNotification(self, notificationId): 89 def processNotification(self, notificationId):
93 notification = Notification.objects.get(id= notificationId) 90 notification = Notification.objects.get(id= notificationId)
94 notification.read = True 91 notification.read = True
95 notification.save() 92 notification.save()
96 return redirect(notification.action_resource.resource.url) 93 return redirect(notification.action_resource.resource.url)
97 94
98 -  
99 -  
100 -  
101 def getNotifications(request): 95 def getNotifications(request):
102 context = {} 96 context = {}
103 if request.user.is_authenticated: 97 if request.user.is_authenticated:
@@ -133,5 +127,5 @@ class GuestView (ListView): @@ -133,5 +127,5 @@ class GuestView (ListView):
133 127
134 def get_context_data (self, **kwargs): 128 def get_context_data (self, **kwargs):
135 context = super(GuestView, self).get_context_data(**kwargs) 129 context = super(GuestView, self).get_context_data(**kwargs)
136 - context['categories'] = CourseCategory.objects.all()  
137 - return context 130 + context['categorys_courses'] = CourseCategory.objects.all()
  131 + return context
138 \ No newline at end of file 132 \ No newline at end of file
courses/forms.py
@@ -2,7 +2,7 @@ from django import forms @@ -2,7 +2,7 @@ from django import forms
2 from django.utils.translation import ugettext_lazy as _ 2 from django.utils.translation import ugettext_lazy as _
3 from .models import CourseCategory, Course, Subject, Topic, ActivityFile, Activity, FileMaterial, LinkMaterial 3 from .models import CourseCategory, Course, Subject, Topic, ActivityFile, Activity, FileMaterial, LinkMaterial
4 from s3direct.widgets import S3DirectWidget 4 from s3direct.widgets import S3DirectWidget
5 - 5 +from django_summernote.widgets import SummernoteWidget
6 6
7 class CategoryCourseForm(forms.ModelForm): 7 class CategoryCourseForm(forms.ModelForm):
8 8
@@ -19,24 +19,24 @@ class CategoryCourseForm(forms.ModelForm): @@ -19,24 +19,24 @@ class CategoryCourseForm(forms.ModelForm):
19 19
20 class CourseForm(forms.ModelForm): 20 class CourseForm(forms.ModelForm):
21 def clean_end_register_date(self): 21 def clean_end_register_date(self):
22 - init_register_date = self.data['init_register_date']  
23 - end_register_date = self.data['end_register_date'] 22 + init_register_date = self.cleaned_data['init_register_date']
  23 + end_register_date = self.cleaned_data['end_register_date']
24 24
25 if init_register_date and end_register_date and end_register_date < init_register_date: 25 if init_register_date and end_register_date and end_register_date < init_register_date:
26 raise forms.ValidationError(_('The end date may not be before the start date.')) 26 raise forms.ValidationError(_('The end date may not be before the start date.'))
27 return end_register_date 27 return end_register_date
28 28
29 def clean_init_date(self): 29 def clean_init_date(self):
30 - end_register_date = self.data['end_register_date']  
31 - init_date = self.data['init_date'] 30 + end_register_date = self.cleaned_data['end_register_date']
  31 + init_date = self.cleaned_data['init_date']
32 32
33 if end_register_date and init_date and init_date <= end_register_date: 33 if end_register_date and init_date and init_date <= end_register_date:
34 raise forms.ValidationError(_('The course start date must be after the end of registration.')) 34 raise forms.ValidationError(_('The course start date must be after the end of registration.'))
35 return init_date 35 return init_date
36 36
37 def clean_end_date(self): 37 def clean_end_date(self):
38 - init_date = self.data['init_date']  
39 - end_date = self.data['end_date'] 38 + init_date = self.cleaned_data['init_date']
  39 + end_date = self.cleaned_data['end_date']
40 40
41 if init_date and end_date and end_date < init_date: 41 if init_date and end_date and end_date < init_date:
42 raise forms.ValidationError(_('The end date may not be before the start date.')) 42 raise forms.ValidationError(_('The end date may not be before the start date.'))
@@ -79,8 +79,8 @@ class CourseForm(forms.ModelForm): @@ -79,8 +79,8 @@ class CourseForm(forms.ModelForm):
79 79
80 widgets = { 80 widgets = {
81 'categoy': forms.Select(), 81 'categoy': forms.Select(),
82 - 'objectivies': forms.Textarea(attrs={'cols': 80, 'rows': 5}),  
83 - 'content': forms.Textarea(attrs={'cols': 80, 'rows': 5}), 82 + 'objectivies': SummernoteWidget(attrs={'cols': 80, 'rows': 5}),
  83 + 'content': SummernoteWidget(attrs={'cols': 80, 'rows': 5}),
84 } 84 }
85 85
86 class UpdateCourseForm(CourseForm): 86 class UpdateCourseForm(CourseForm):
@@ -120,8 +120,8 @@ class UpdateCourseForm(CourseForm): @@ -120,8 +120,8 @@ class UpdateCourseForm(CourseForm):
120 } 120 }
121 widgets = { 121 widgets = {
122 'categoy': forms.Select(), 122 'categoy': forms.Select(),
123 - 'objectivies': forms.Textarea(attrs={'cols': 80, 'rows': 5}),  
124 - 'content': forms.Textarea(attrs={'cols': 80, 'rows': 5}), 123 + 'objectivies': SummernoteWidget(attrs={'cols': 80, 'rows': 5}),
  124 + 'content': SummernoteWidget(attrs={'cols': 80, 'rows': 5}),
125 } 125 }
126 126
127 class SubjectForm(forms.ModelForm): 127 class SubjectForm(forms.ModelForm):
@@ -143,6 +143,9 @@ class SubjectForm(forms.ModelForm): @@ -143,6 +143,9 @@ class SubjectForm(forms.ModelForm):
143 'end_date': _('End date of the subject'), 143 'end_date': _('End date of the subject'),
144 'visible': _('Is the subject visible?'), 144 'visible': _('Is the subject visible?'),
145 } 145 }
  146 + widgets = {
  147 + 'description':SummernoteWidget(),
  148 + }
146 149
147 class TopicForm(forms.ModelForm): 150 class TopicForm(forms.ModelForm):
148 151
@@ -157,6 +160,9 @@ class TopicForm(forms.ModelForm): @@ -157,6 +160,9 @@ class TopicForm(forms.ModelForm):
157 'name': _("Topic's name"), 160 'name': _("Topic's name"),
158 'description': _("Topic's description"), 161 'description': _("Topic's description"),
159 } 162 }
  163 + widgets = {
  164 + 'description':SummernoteWidget(),
  165 + }
160 166
161 class ActivityFileForm(forms.ModelForm): 167 class ActivityFileForm(forms.ModelForm):
162 name = forms.CharField( 168 name = forms.CharField(
courses/static/js/topic_editation_presentation.js
@@ -5,7 +5,8 @@ function show_editation(id_topic){ @@ -5,7 +5,8 @@ function show_editation(id_topic){
5 $(".presentation_"+ id_topic).css('display','none'); 5 $(".presentation_"+ id_topic).css('display','none');
6 $(".editation_"+ id_topic).css('display','block'); 6 $(".editation_"+ id_topic).css('display','block');
7 }; 7 };
8 - function show_presentation(id_topic){ 8 +
  9 +function show_presentation(id_topic){
9 $(".editation_"+ id_topic).css('display','none'); 10 $(".editation_"+ id_topic).css('display','none');
10 $(".presentation_"+ id_topic).css('display','block'); 11 $(".presentation_"+ id_topic).css('display','block');
11 }; 12 };
courses/templates/category/create.html
@@ -31,13 +31,12 @@ @@ -31,13 +31,12 @@
31 </div> 31 </div>
32 <div class="panel-body"> 32 <div class="panel-body">
33 <ul class="nav nav-pills nav-stacked"> 33 <ul class="nav nav-pills nav-stacked">
34 - <li><a href="javascript:void(0)">{% trans 'Replicate Course' %}</a></li>  
35 <li><a href="{% url 'course:create' %}">{% trans 'Create Course' %}</a></li> 34 <li><a href="{% url 'course:create' %}">{% trans 'Create Course' %}</a></li>
36 - <li><a href="{% url 'course:create_cat' %}">{% trans 'Create Category' %}</a></li>  
37 </ul> 35 </ul>
38 </div> 36 </div>
39 </div> 37 </div>
40 38
  39 +
41 <div class="panel panel-primary navigation"> 40 <div class="panel panel-primary navigation">
42 <div class="panel-heading"> 41 <div class="panel-heading">
43 <h3 class="panel-title">{% trans 'Category' %}</h3> 42 <h3 class="panel-title">{% trans 'Category' %}</h3>
courses/templates/category/delete.html
1 -{% load static i18n permission_tags %}  
2 1
3 -<!-- Modal (remember to change the ids!!!) -->  
4 -<div class="modal fade" id="category" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">  
5 - <div class="modal-dialog" role="document">  
6 - <div class="modal-content">  
7 - <!-- Modal Header -->  
8 - <div class="modal-header"> 2 +{% extends 'course/view.html' %}
9 3
10 - <h4 class="modal-title" id="myModalLabel">{% trans "Delete Category" %}</h4>  
11 - </div>  
12 - <!-- Modal Body -->  
13 - <div class="modal-body">  
14 - <!-- Put ONLY your content here!!! -->  
15 - <form id="delete_form" action="" method="post">  
16 - {% csrf_token %}  
17 - <p>{% trans 'Are you sure you want to delete the subject' %} "{{category.name}}"?</p>  
18 - </form>  
19 - </div>  
20 - <!-- Modal Footer -->  
21 - <div class="modal-footer">  
22 - <!-- Don't remove that!!! -->  
23 - <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans "Close" %}</button>  
24 - <button type="submit" id="button" form="delete_form" class="btn btn-primary btn-raised">{% trans "Delete" %}</button>  
25 - <script>  
26 - $("#delete_form").submit(function(event) {  
27 - Submite.remove("{% url 'course:delete_cat' category.slug %}",$(this).serialize(),"#category_{{category.slug}}");  
28 - event.preventDefault();  
29 - });  
30 - </script>  
31 - </div>  
32 - </div> 4 +{% load static i18n %}
  5 +
  6 +{% block breadcrumbs %}
  7 + <ol class="breadcrumb">
  8 + <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>
  9 + <li><a href="{% url 'course:view' course.slug %}">{{ course }}</a></li>
  10 + </ol>
  11 +{% endblock %}
  12 +
  13 +{% block content %}
  14 +<div class="panel panel-default">
  15 + <div class="panel-body">
  16 + <form action="" method="post">
  17 + {% csrf_token %}
  18 + <h2>{% trans 'Are you sure you want to delete the course' %} "{{course}}"?</h2>
  19 + <input type="submit" class="btn btn-raised btn-success btn-lg" value="{% trans 'Yes' %}" />
  20 + <a href="{% url 'course:view' course.slug%}" class="btn btn-raised btn-danger btn-lg">{% trans 'No' %}</a>
  21 + </form>
33 </div> 22 </div>
34 </div> 23 </div>
35 -<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>  
36 -<script src="{% static 'js/modal_category.js' %}"></script> 24 +{% endblock %}
37 \ No newline at end of file 25 \ No newline at end of file
courses/templates/category/index.html
@@ -32,9 +32,7 @@ @@ -32,9 +32,7 @@
32 </div> 32 </div>
33 <div class="panel-body"> 33 <div class="panel-body">
34 <ul class="nav nav-pills nav-stacked"> 34 <ul class="nav nav-pills nav-stacked">
35 - <li><a href="javascript:void(0)">{% trans 'Replicate Course' %}</a></li>  
36 - <li><a href="{% url 'course:creates' %}">{% trans 'Create Course' %}</a></li>  
37 - <li><a href="{% url 'course:create_cat' %}">{% trans 'Create Category' %}</a></li> 35 + <li><a href="{% url 'course:create' %}">{% trans 'Create Course' %}</a></li>
38 </ul> 36 </ul>
39 </div> 37 </div>
40 </div> 38 </div>
@@ -71,16 +69,15 @@ @@ -71,16 +69,15 @@
71 <div class="panel panel-info"> 69 <div class="panel panel-info">
72 <div class="panel-heading" role="tab"> 70 <div class="panel-heading" role="tab">
73 <div class="row"> 71 <div class="row">
74 - <div class="col-xs-9 col-md-10 titleTopic"> 72 + <div class="col-xs-9 col-md-11 titleTopic">
75 <h4 style="color:white; margin-left: 20px;">{{category}}</h4> 73 <h4 style="color:white; margin-left: 20px;">{{category}}</h4>
76 </div> 74 </div>
77 -  
78 - <div class="col-xs-4 col-md-2" id="divMoreActions"> 75 + <div class="col-xs-4 col-md-1" id="divMoreActions">
79 <div class="btn-group"> 76 <div class="btn-group">
80 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 77 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
81 <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> 78 <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>
82 </button> 79 </button>
83 - <ul class="dropdown-menu" aria-labelledby="moreActions"> 80 + <ul class="dropdown-menu pull-right" aria-labelledby="moreActions">
84 <li><a href="{% url 'course:update_cat' category.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>{% trans 'Update' %}</a></li> 81 <li><a href="{% url 'course:update_cat' category.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>{% trans 'Update' %}</a></li>
85 <li><a href="javascript:modal.get('{% url 'course:delete_cat' category.slug %}','#category','#modal_category');"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>{% trans 'Remover' %}</a></li> 82 <li><a href="javascript:modal.get('{% url 'course:delete_cat' category.slug %}','#category','#modal_category');"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>{% trans 'Remover' %}</a></li>
86 </ul> 83 </ul>
courses/templates/category/update.html
@@ -32,9 +32,7 @@ @@ -32,9 +32,7 @@
32 </div> 32 </div>
33 <div class="panel-body"> 33 <div class="panel-body">
34 <ul class="nav nav-pills nav-stacked"> 34 <ul class="nav nav-pills nav-stacked">
35 - <li><a href="javascript:void(0)">{% trans 'Replicate Course' %}</a></li>  
36 <li><a href="{% url 'course:create' %}">{% trans 'Create Course' %}</a></li> 35 <li><a href="{% url 'course:create' %}">{% trans 'Create Course' %}</a></li>
37 - <li><a href="{% url 'course:create_cat' %}">{% trans 'Create Category' %}</a></li>  
38 </ul> 36 </ul>
39 </div> 37 </div>
40 </div> 38 </div>
courses/templates/course/course_card.html
1 {% load static i18n permission_tags %} 1 {% load static i18n permission_tags %}
2 {% load django_bootstrap_breadcrumbs %} 2 {% load django_bootstrap_breadcrumbs %}
3 -<div class="group"> 3 +<div class="group course-card ">
4 <div class="panel panel-info"> 4 <div class="panel panel-info">
5 <div class="panel-heading course"> 5 <div class="panel-heading course">
6 <div class="row"> 6 <div class="row">
@@ -38,7 +38,7 @@ @@ -38,7 +38,7 @@
38 <p> 38 <p>
39 <b>{% trans 'Description' %}:</b> 39 <b>{% trans 'Description' %}:</b>
40 <i> 40 <i>
41 - {{course.content}} 41 + {{course.content | safe }}
42 </i> 42 </i>
43 </p> 43 </p>
44 </div> 44 </div>
courses/templates/course/create.html
1 -{% extends 'course/view.html' %} 1 +{% extends 'home.html' %}
2 2
3 {% load static i18n %} 3 {% load static i18n %}
4 {% load widget_tweaks %} 4 {% load widget_tweaks %}
@@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
19 <div class="form-group {% if form.has_error %} has-error {% endif %} is-fileinput"> 19 <div class="form-group {% if form.has_error %} has-error {% endif %} is-fileinput">
20 <label for="{{ field.auto_id }}">{{ field.label }}</label> 20 <label for="{{ field.auto_id }}">{{ field.label }}</label>
21 {% if field.auto_id == 'id_init_register_date' or field.auto_id == 'id_end_register_date' or field.auto_id == 'id_init_date' or field.auto_id == 'id_end_date'%} 21 {% if field.auto_id == 'id_init_register_date' or field.auto_id == 'id_end_register_date' or field.auto_id == 'id_init_date' or field.auto_id == 'id_end_date'%}
22 - <input type="text" class="form-control date-picker" name="{{field.name}}" value="{{field.value|date:'SHORT_DATE_FORMAT'}}" min="{{now|date:'Y-m-d'}}"> 22 + <input type="text" class="form-control date-picker" name="{{field.name}}" value="{{field.value|date:'SHORT_DATE_FORMAT'}}" min="{{now|date:'SHORT_DATE_FORMAT'}}">
23 {% elif field.auto_id == 'id_image' %} 23 {% elif field.auto_id == 'id_image' %}
24 {% render_field field class='form-control' %} 24 {% render_field field class='form-control' %}
25 <div class="input-group"> 25 <div class="input-group">
courses/templates/course/delete.html
1 -{% extends 'course/view.html' %} 1 +{% load static i18n permission_tags %}
2 2
3 -{% load static i18n %} 3 +<!-- Modal (remember to change the ids!!!) -->
  4 +<div class="modal fade" id="course" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  5 + <div class="modal-dialog" role="document">
  6 + <div class="modal-content">
  7 + <!-- Modal Header -->
  8 + <div class="modal-header">
4 9
5 -{% block breadcrumbs %}  
6 - <ol class="breadcrumb">  
7 - <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li>  
8 - <li><a href="{% url 'course:view' course.slug %}">{{ course }}</a></li>  
9 - </ol>  
10 -{% endblock %}  
11 -  
12 -{% block content %}  
13 -<div class="panel panel-default">  
14 - <div class="panel-body">  
15 - <form action="" method="post">  
16 - {% csrf_token %}  
17 - <h2>{% trans 'Are you sure you want to delete the course' %} "{{course}}"?</h2>  
18 - <input type="submit" class="btn btn-raised btn-success btn-lg" value="{% trans 'Yes' %}" />  
19 - <a href="{% url 'course:view' course.slug%}" class="btn btn-raised btn-danger btn-lg">{% trans 'No' %}</a> 10 + <h4 class="modal-title" id="myModalLabel">{% trans "Delete Course" %}</h4>
  11 + </div>
  12 + <!-- Modal Body -->
  13 + <div class="modal-body">
  14 + <!-- Put ONLY your content here!!! -->
  15 + <form id="delete_form" action="" method="post">
  16 + {% csrf_token %}
  17 + <p>{% trans 'Are you sure you want to delete the course' %} "{{course.name}}"?</p>
20 </form> 18 </form>
21 - </div> 19 + </div>
  20 + <!-- Modal Footer -->
  21 + <div class="modal-footer">
  22 + <!-- Don't remove that!!! -->
  23 + <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
  24 + <button type="submit" id="button" form="delete_form" class="btn btn-primary btn-raised">{% trans "Delete" %}</button>
  25 + <script>
  26 + $("#delete_form").submit(function(event) {
  27 + RemoverCurso.remove("{% url 'course:delete' course.slug %}",$(this).serialize(),"#course_{{course.slug}}");
  28 + event.preventDefault();
  29 + });
  30 + </script>
  31 + </div>
  32 + </div>
  33 + </div>
22 </div> 34 </div>
23 -{% endblock %} 35 +<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  36 +<script src="{% static 'js/course.js' %}"></script>
courses/templates/course/index.html
@@ -42,7 +42,6 @@ @@ -42,7 +42,6 @@
42 </ul> 42 </ul>
43 </div> 43 </div>
44 </div> 44 </div>
45 -  
46 {% if user|has_role:'professor' or user|has_role:'system_admin' %} 45 {% if user|has_role:'professor' or user|has_role:'system_admin' %}
47 <div class="panel panel-primary"> 46 <div class="panel panel-primary">
48 <div class="panel-heading"> 47 <div class="panel-heading">
@@ -110,21 +109,34 @@ @@ -110,21 +109,34 @@
110 109
111 </fieldset> 110 </fieldset>
112 <div class="col-md-12 cards-content"> 111 <div class="col-md-12 cards-content">
113 - {% if courses|length > 0 %}  
114 - {% if request.GET.category == '' or aparece or request.GET.q == '' %}  
115 - {% for course in list_courses %}  
116 - {% include "course/course_card.html" %}  
117 - {% endfor %}  
118 - {% endif %}  
119 - {% if request.GET.category or request.GET.q %}  
120 - {% for course in courses %}  
121 - {% include "course/course_card.html" %}  
122 - {% endfor %}  
123 - {% endif %}  
124 - {% else %}  
125 - {% trans 'No courses found' %}  
126 - {% endif %} 112 + {% for category in categorys_courses %}
  113 + <div class="panel-group course-card-group">
  114 + <div class="panel panel-default">
  115 + <div class="panel-heading">
  116 + <div class="row">
  117 + <div class="col-md-12">
  118 + <h4 class="panel-title">
  119 + <a class="category-course-link" data-toggle="collapse" href="#{{category.slug}}">{{category.name}}</a>
  120 + </h4>
  121 + </div>
  122 + </div>
  123 + </div>
  124 + <div id="{{category.slug}}" class="panel-collapse collapse">
  125 + {% for course in category.course_category.all %}
  126 + {% if user in course.students.all or user in course.professors.all or user|has_role:'system_admin' %}
  127 + {% include "course/course_card.html" %}
  128 + {% endif %}
  129 + {% endfor %}
  130 + </div>
  131 + </div>
  132 + </div>
  133 +
  134 +
  135 + {% endfor %}
127 </div> 136 </div>
  137 + {% if user|has_role:'professor' or user|has_role:'system_admin' %}
  138 + <a href="{% url 'course:create' %}" class="btn btn-primary btn-fab float-button"><i class="fa fa-plus material-icons"></i></a>
  139 + {% endif %}
128 <div class="col-md-12"> 140 <div class="col-md-12">
129 <nav aria-label="Page navigation"> 141 <nav aria-label="Page navigation">
130 <ul class="pagination"> 142 <ul class="pagination">
@@ -145,6 +157,7 @@ @@ -145,6 +157,7 @@
145 {% endif %} 157 {% endif %}
146 </ul> 158 </ul>
147 </nav> 159 </nav>
  160 + <div class="row" id="modal_course">
148 </div> 161 </div>
149 <script type="text/javascript" src="{% static 'js/course.js' %}"></script> 162 <script type="text/javascript" src="{% static 'js/course.js' %}"></script>
150 {% endblock %} 163 {% endblock %}
courses/templates/course/replicate.html
@@ -57,7 +57,7 @@ @@ -57,7 +57,7 @@
57 <label for="id_init_register_date">{% trans 'Course registration start date' %}</label> 57 <label for="id_init_register_date">{% trans 'Course registration start date' %}</label>
58 58
59 59
60 - <input type="date" class="form-control" name="init_register_date" value="None" min="2016-10-24"> 60 + <input type="text" class="form-control date-picker" name="init_register_date" value="{{field.value|date:'SHORT_DATE_FORMAT'}}" min="{{now|date:'SHORT_DATE_FORMAT'}}">
61 61
62 <span class="help-block">{% trans 'Date that starts the registration period of the course (dd/mm/yyyy)' %}</span> 62 <span class="help-block">{% trans 'Date that starts the registration period of the course (dd/mm/yyyy)' %}</span>
63 63
@@ -67,7 +67,7 @@ @@ -67,7 +67,7 @@
67 <label for="id_end_register_date">{% trans 'Course registration end date' %}</label> 67 <label for="id_end_register_date">{% trans 'Course registration end date' %}</label>
68 68
69 69
70 - <input type="date" class="form-control" name="end_register_date" value="None" min="2016-10-24"> 70 + <input type="text" class="form-control date-picker" name="end_register_date" value="{{field.value|date:'SHORT_DATE_FORMAT'}}" min="{{now|date:'SHORT_DATE_FORMAT'}}">
71 71
72 <span class="help-block">{% trans 'Date that ends the registration period of the course (dd/mm/yyyy)' %}</span> 72 <span class="help-block">{% trans 'Date that ends the registration period of the course (dd/mm/yyyy)' %}</span>
73 73
@@ -77,7 +77,7 @@ @@ -77,7 +77,7 @@
77 <label for="id_init_date">{% trans 'Course start date' %}</label> 77 <label for="id_init_date">{% trans 'Course start date' %}</label>
78 78
79 79
80 - <input type="date" class="form-control" name="init_date" value="None" min="2016-10-24"> 80 + <input type="text" class="form-control date-picker" name="init_date" value="{{field.value|date:'SHORT_DATE_FORMAT'}}" min="{{now|date:'SHORT_DATE_FORMAT'}}">
81 81
82 <span class="help-block">{% trans 'Date that the course starts (dd/mm/yyyy)' %}</span> 82 <span class="help-block">{% trans 'Date that the course starts (dd/mm/yyyy)' %}</span>
83 83
@@ -87,7 +87,7 @@ @@ -87,7 +87,7 @@
87 <label for="id_end_date">{% trans 'Course end date' %}</label> 87 <label for="id_end_date">{% trans 'Course end date' %}</label>
88 88
89 89
90 - <input type="date" class="form-control" name="end_date" value="None" min="2016-10-24"> 90 + <input type="text" class="form-control date-picker" name="end_date" value="{{field.value|date:'SHORT_DATE_FORMAT'}}" min="{{now|date:'SHORT_DATE_FORMAT'}}">
91 91
92 <span class="help-block">{% trans 'Date that the course ends (dd/mm/yyyy)' %}</span> 92 <span class="help-block">{% trans 'Date that the course ends (dd/mm/yyyy)' %}</span>
93 93
courses/templates/course/view.html
@@ -29,7 +29,24 @@ @@ -29,7 +29,24 @@
29 <li><a href="{% url 'core:home' %}">{% trans "Home" %}</a></li> 29 <li><a href="{% url 'core:home' %}">{% trans "Home" %}</a></li>
30 <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li> 30 <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li>
31 <li><a href="{% url 'course:manage' %}">{% trans 'My Courses' %}</a></li> 31 <li><a href="{% url 'course:manage' %}">{% trans 'My Courses' %}</a></li>
32 - <li><a href="{% url 'core:guest' %}">{% trans 'All Courses' %}</a></li> 32 + <li><a href="{% url 'course:all_courses' %}">{% trans 'All Courses' %}</a></li>
  33 + <li><a href="{% url 'core:guest' %}">{% trans 'Courses' %}</a></li>
  34 + {# <li><a href="{% url 'course:participants' %}">{% trans 'Participants' %}</a></li> #}
  35 + {% if user|has_role:'system_admin' %}
  36 + <li> <a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li>
  37 + {% endif %}
  38 + {% if user|has_role:'system_admin' or user|has_role:'professor' %}
  39 + <li>
  40 + <a href="#courses_list" class="accordion" data-toggle="collapse">{% trans 'Manage Courses' %}</a>
  41 + <div id="courses_list" class="collapse">
  42 + <ul class="nav nav-pill nav-stacked accordion_list">
  43 + {% for course in courses_list %}
  44 + <li><a href="{% url 'course:view' course.slug %}">{{ course }}</a></li>
  45 + {% endfor %}
  46 + </ul>
  47 + </div>
  48 + </li>
  49 + {% endif %}
33 </ul> 50 </ul>
34 </div> 51 </div>
35 </div> 52 </div>
@@ -55,20 +72,19 @@ @@ -55,20 +72,19 @@
55 <div class="panel panel-info"> 72 <div class="panel panel-info">
56 <div class="panel-heading course-detail"> 73 <div class="panel-heading course-detail">
57 <div class="row"> 74 <div class="row">
58 - <div class="col-xs-8 col-md-4 .titleTopic-detail"> 75 + <div class="col-xs-8 col-md-11 .titleTopic-detail">
59 <h4>{{course.name}}</h4> 76 <h4>{{course.name}}</h4>
60 </div> 77 </div>
61 - {% if user|has_role:'professor' and user in course.professors or user|has_role:'system_admin' %}  
62 - <div class="col-xs-4 col-md-8" id="divMoreActions"> 78 + {% if user|has_role:'professor' or user|has_role:'system_admin' %}
  79 + <div class="col-xs-4 col-md-1" id="divMoreActions">
63 <div class="btn-group"> 80 <div class="btn-group">
64 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 81 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
65 <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> 82 <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>
66 <div class="ripple-container"></div></button> 83 <div class="ripple-container"></div></button>
67 - <ul class="dropdown-menu" aria-labelledby="moreActions">  
68 - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#createSubject"><i class="fa fa-plus-square-o" aria-hidden="true"></i>&nbsp; {% trans "Create Subject" %}</a></li>  
69 - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal4"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Replicate" %}</a></li> 84 + <ul class="dropdown-menu pull-right" aria-labelledby="moreActions">
  85 + <li><a href="{% url 'course:replicate_course' course.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Replicate" %}</a></li>
70 <li><a href="{% url 'course:update' course.slug %}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Edit" %}</a></li> 86 <li><a href="{% url 'course:update' course.slug %}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Edit" %}</a></li>
71 - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal2"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Remove" %}</a></li> 87 + <li><a href="javascript:javascript:delete_course('{% url 'course:delete' course.slug %}', '{{ course.slug }}', '{% trans "Are you sure you want to delete this course?" %}', '{% url 'course:manage' %}')" data-toggle="modal" data-target="#myModal2"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp; {% trans "Remove" %}</a></li>
72 </ul> 88 </ul>
73 </div> 89 </div>
74 </div> 90 </div>
@@ -81,7 +97,7 @@ @@ -81,7 +97,7 @@
81 <p> 97 <p>
82 <b>{% trans 'Description' %}:</b> 98 <b>{% trans 'Description' %}:</b>
83 <i> 99 <i>
84 - {{ course.objectivies }} 100 + {{ course.objectivies |safe }}
85 </i> 101 </i>
86 </p> 102 </p>
87 103
@@ -142,20 +158,20 @@ @@ -142,20 +158,20 @@
142 <div class="col-md-1 moreAccordion" data-toggle="collapse" data-parent="#accordion-{{subject.slug}}" href=".collapseSubject-{{subject.slug}}" aria-expanded="false" aria-controls="collapseSubject-{{subject.slug}}"> 158 <div class="col-md-1 moreAccordion" data-toggle="collapse" data-parent="#accordion-{{subject.slug}}" href=".collapseSubject-{{subject.slug}}" aria-expanded="false" aria-controls="collapseSubject-{{subject.slug}}">
143 <button class="btn btn-default btn-sm caret-square"><i class="fa fa-caret-square-o-down fa-2x" aria-hidden="true"></i></button> 159 <button class="btn btn-default btn-sm caret-square"><i class="fa fa-caret-square-o-down fa-2x" aria-hidden="true"></i></button>
144 </div> 160 </div>
145 - <div class="col-xs-9 col-md-4 titleTopic"> 161 + <div class="col-xs-9 col-md-10 titleTopic">
146 <a role="button" href="{% url 'course:view_subject' subject.slug %}"> 162 <a role="button" href="{% url 'course:view_subject' subject.slug %}">
147 <h4>{{subject.name}}</h4> 163 <h4>{{subject.name}}</h4>
148 </a> 164 </a>
149 </div> 165 </div>
150 - {% if user|has_role:'professor' and user in subject.professors or user|has_role:'system_admin' %}  
151 - <div class="col-xs-3 col-md-6" id="divMoreActions"> 166 + {% if user|has_role:'professor' or user|has_role:'system_admin' %}
  167 + <div class="col-xs-3 col-md-1" id="divMoreActions">
152 <div class="btn-group"> 168 <div class="btn-group">
153 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 169 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
154 <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> 170 <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>
155 </button> 171 </button>
156 - <ul class="dropdown-menu" aria-labelledby="moreActions"> 172 + <ul class="dropdown-menu pull-right" aria-labelledby="moreActions">
157 <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal3"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>&nbsp; {% trans 'Replicate' %}</a></li> 173 <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal3"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>&nbsp; {% trans 'Replicate' %}</a></li>
158 - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#removeSubject2"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp; {% trans 'Remove' %}</a></li> 174 + <li><a href="javascript:subject.get('{% url 'course:delete_subject' subject.slug %}','#subject','#modal_subject');" data-toggle="modal" data-target="#removeSubject"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>&nbsp; {% trans 'Remove' %}</a></li>
159 </ul> 175 </ul>
160 </div> 176 </div>
161 </div> 177 </div>
@@ -178,7 +194,7 @@ @@ -178,7 +194,7 @@
178 <p> 194 <p>
179 <b>{% trans "Description" %}: </b> 195 <b>{% trans "Description" %}: </b>
180 <i> 196 <i>
181 - {{subject.description}} 197 + {{subject.description | safe}}
182 </i> 198 </i>
183 </p> 199 </p>
184 <div class="row"> 200 <div class="row">
@@ -202,27 +218,6 @@ @@ -202,27 +218,6 @@
202 </div> 218 </div>
203 {% endif %} 219 {% endif %}
204 220
205 -<!-- MODAL REMOVE -->  
206 - <div class="modal" id="removeSubject2">  
207 - <div class="modal-dialog">  
208 - <div class="modal-content">  
209 - <div class="modal-header">  
210 - <button type="button" class="close" data-dismiss="modal" aria-hidden="true">X</button>  
211 - <h4 class="modal-title"></h4>  
212 - </div>  
213 - <div class="modal-body">  
214 - <p> {% trans "Are you sure you want to remove this subject?" %}</p>  
215 - </div>  
216 - <div class="modal-footer">  
217 -  
218 - <a href="http://127.0.0.1:8080/html/screens/users/teacher/home_course_teacher.html" target="_self"><button type="button" class="btn btn-primary">{% trans "Confirm" %}</button></a>  
219 -  
220 - </div>  
221 - </div>  
222 - </div>  
223 - </div>  
224 -  
225 -  
226 </div> 221 </div>
227 </div> 222 </div>
228 </div> 223 </div>
courses/templates/subject/form_view_student.html
@@ -27,7 +27,7 @@ @@ -27,7 +27,7 @@
27 <div class="presentation"> 27 <div class="presentation">
28 <p> 28 <p>
29 <i> 29 <i>
30 - {{topic.description|linebreaks}} 30 + {{topic.description|safe}}
31 </i> 31 </i>
32 </p> 32 </p>
33 33
courses/templates/subject/form_view_teacher.html
@@ -19,11 +19,6 @@ @@ -19,11 +19,6 @@
19 </div><!--column --> 19 </div><!--column -->
20 <div class="col-xs-3 col-md-2 divMoreActions"> 20 <div class="col-xs-3 col-md-2 divMoreActions">
21 <div class="btn-group"> 21 <div class="btn-group">
22 - <button type="button" class="btn btn-default btn-sm eye" data-toggle="tooltip" data-placement="bottom" title="Visible">  
23 - <i class="fa fa-eye fa-2x" aria-hidden="true"></i>  
24 - </button>  
25 - </div>  
26 - <div class="btn-group">  
27 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 22 <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
28 <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> 23 <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i>
29 </button> 24 </button>
@@ -44,7 +39,7 @@ @@ -44,7 +39,7 @@
44 <div class="presentation_{{topic.slug}}"> 39 <div class="presentation_{{topic.slug}}">
45 <p> 40 <p>
46 <i> 41 <i>
47 - {{topic.description|linebreaks}} 42 + {{topic.description|safe}}
48 </i> 43 </i>
49 </p> 44 </p>
50 </div> 45 </div>
courses/templates/subject/index.html
@@ -23,6 +23,7 @@ @@ -23,6 +23,7 @@
23 <li><a href="{% url 'course:manage' %}">{% trans 'My courses' %}</a></li> 23 <li><a href="{% url 'course:manage' %}">{% trans 'My courses' %}</a></li>
24 <li><a href="{% url 'core:guest' %}">{% trans 'All Courses' %}</a></li> 24 <li><a href="{% url 'core:guest' %}">{% trans 'All Courses' %}</a></li>
25 {% endif %} 25 {% endif %}
  26 + <li><a href="{% url 'core:guest' %}">{% trans 'Courses' %}</a></li>
26 {% if user|has_role:'system_admin' %} 27 {% if user|has_role:'system_admin' %}
27 <li> <a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li> 28 <li> <a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li>
28 {% endif %} 29 {% endif %}
@@ -74,7 +75,7 @@ @@ -74,7 +75,7 @@
74 {{professor}}{% if forloop.last %}.{% endif %}{% endfor %}</p> 75 {{professor}}{% if forloop.last %}.{% endif %}{% endfor %}</p>
75 <p> 76 <p>
76 <b>{% trans "Description" %}:</b> 77 <b>{% trans "Description" %}:</b>
77 - {{subject.description|linebreaks}} 78 + {{subject.description|safe}}
78 </p> 79 </p>
79 <div class="row"> 80 <div class="row">
80 <div class="col-xs-6 col-md-6"> 81 <div class="col-xs-6 col-md-6">
courses/templates/subject_category/index.html
@@ -58,7 +58,7 @@ @@ -58,7 +58,7 @@
58 </div> 58 </div>
59 <div class="panel-body"> 59 <div class="panel-body">
60 <p> 60 <p>
61 - {{subject.description|linebreaks}} 61 + {{subject.description| safe }}
62 </p> 62 </p>
63 </div> 63 </div>
64 </div> 64 </div>
courses/templates/topic/index.html
@@ -77,7 +77,7 @@ @@ -77,7 +77,7 @@
77 </div> 77 </div>
78 <div class="panel-body"> 78 <div class="panel-body">
79 <p> 79 <p>
80 - {{topic.description|linebreaks}} 80 + {{topic.description|safe}}
81 </p> 81 </p>
82 </div> 82 </div>
83 </div> 83 </div>
courses/views.py
@@ -15,7 +15,8 @@ from rolepermissions.verifications import has_object_permission @@ -15,7 +15,8 @@ from rolepermissions.verifications import has_object_permission
15 from django.http import HttpResponseRedirect, JsonResponse 15 from django.http import HttpResponseRedirect, JsonResponse
16 from .forms import CourseForm, UpdateCourseForm, CategoryCourseForm, SubjectForm,TopicForm,ActivityForm 16 from .forms import CourseForm, UpdateCourseForm, CategoryCourseForm, SubjectForm,TopicForm,ActivityForm
17 from .models import Course, Subject, CourseCategory,Topic, SubjectCategory,Activity, CategorySubject 17 from .models import Course, Subject, CourseCategory,Topic, SubjectCategory,Activity, CategorySubject
18 -from core.mixins import NotificationMixin 18 +from core.decorators import log_decorator
  19 +from core.mixins import LogMixin, NotificationMixin
19 from users.models import User 20 from users.models import User
20 from files.forms import FileForm 21 from files.forms import FileForm
21 from files.models import TopicFile 22 from files.models import TopicFile
@@ -123,8 +124,8 @@ class AllCoursesView(LoginRequiredMixin, NotificationMixin, generic.ListView): @@ -123,8 +124,8 @@ class AllCoursesView(LoginRequiredMixin, NotificationMixin, generic.ListView):
123 list_courses = None 124 list_courses = None
124 categorys_courses = None 125 categorys_courses = None
125 list_courses = Course.objects.all().order_by('name') 126 list_courses = Course.objects.all().order_by('name')
126 - categorys_courses = CourseCategory.objects.all().distinct().order_by('name')  
127 - 127 + #categorys_courses = CourseCategory.objects.all().distinct().order_by('name')
  128 + categorys_courses = CourseCategory.objects.all()
128 paginator = Paginator(list_courses, self.paginate_by) 129 paginator = Paginator(list_courses, self.paginate_by)
129 page = self.request.GET.get('page') 130 page = self.request.GET.get('page')
130 131
@@ -141,7 +142,11 @@ class AllCoursesView(LoginRequiredMixin, NotificationMixin, generic.ListView): @@ -141,7 +142,11 @@ class AllCoursesView(LoginRequiredMixin, NotificationMixin, generic.ListView):
141 142
142 return context 143 return context
143 144
144 -class CreateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edit.CreateView): 145 +class CreateCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.edit.CreateView):
  146 + log_component = "course"
  147 + log_resource = "course"
  148 + log_action = "create"
  149 + log_context = {}
145 150
146 allowed_roles = ['professor', 'system_admin'] 151 allowed_roles = ['professor', 'system_admin']
147 login_url = reverse_lazy("core:home") 152 login_url = reverse_lazy("core:home")
@@ -153,6 +158,15 @@ class CreateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,gener @@ -153,6 +158,15 @@ class CreateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,gener
153 def form_valid(self, form): 158 def form_valid(self, form):
154 self.object = form.save() 159 self.object = form.save()
155 self.object.professors.add(self.request.user) 160 self.object.professors.add(self.request.user)
  161 +
  162 + self.log_context['course_id'] = self.object.id
  163 + self.log_context['course_name'] = self.object.name
  164 + self.log_context['course_slug'] = self.object.slug
  165 + self.log_context['course_category_id'] = self.object.category.id
  166 + self.log_context['course_category_name'] = self.object.category.name
  167 +
  168 + super(CreateCourseView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  169 +
156 return super(CreateCourseView, self).form_valid(form) 170 return super(CreateCourseView, self).form_valid(form)
157 171
158 def get_context_data(self, **kwargs): 172 def get_context_data(self, **kwargs):
@@ -160,13 +174,17 @@ class CreateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,gener @@ -160,13 +174,17 @@ class CreateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,gener
160 if has_role(self.request.user,'system_admin'): 174 if has_role(self.request.user,'system_admin'):
161 courses = Course.objects.all() 175 courses = Course.objects.all()
162 elif has_role(self.request.user,'professor'): 176 elif has_role(self.request.user,'professor'):
163 - courses = self.request.user.courses.all() 177 + courses = self.request.user.courses_student.all()
164 context['courses'] = courses 178 context['courses'] = courses
165 context['title'] = _("Create Course") 179 context['title'] = _("Create Course")
166 context['now'] = date.today() 180 context['now'] = date.today()
167 return context 181 return context
168 182
169 -class ReplicateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edit.CreateView): 183 +class ReplicateCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin,generic.edit.CreateView):
  184 + log_component = "courses"
  185 + log_action = "replicate"
  186 + log_resource = "course"
  187 + log_context = {}
170 188
171 allowed_roles = ['professor', 'system_admin'] 189 allowed_roles = ['professor', 'system_admin']
172 login_url = reverse_lazy("core:home") 190 login_url = reverse_lazy("core:home")
@@ -188,6 +206,15 @@ class ReplicateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,ge @@ -188,6 +206,15 @@ class ReplicateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,ge
188 elif has_role(self.request.user,'professor'): 206 elif has_role(self.request.user,'professor'):
189 courses = self.request.user.courses_professors.all() 207 courses = self.request.user.courses_professors.all()
190 categorys_courses = CourseCategory.objects.all() 208 categorys_courses = CourseCategory.objects.all()
  209 +
  210 + self.log_context['course_id'] = course.id
  211 + self.log_context['course_name'] = course.name
  212 + self.log_context['course_slug'] = course.slug
  213 + self.log_context['course_category_id'] = course.category.id
  214 + self.log_context['course_category_name'] = course.category.name
  215 +
  216 + super(ReplicateCourseView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  217 +
191 context['courses'] = courses 218 context['courses'] = courses
192 context['course'] = course 219 context['course'] = course
193 context['categorys_courses'] = categorys_courses 220 context['categorys_courses'] = categorys_courses
@@ -198,7 +225,11 @@ class ReplicateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,ge @@ -198,7 +225,11 @@ class ReplicateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,ge
198 def get_success_url(self): 225 def get_success_url(self):
199 return reverse_lazy('course:view', kwargs={'slug' : self.object.slug}) 226 return reverse_lazy('course:view', kwargs={'slug' : self.object.slug})
200 227
201 -class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): 228 +class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.UpdateView):
  229 + log_component = "courses"
  230 + log_action = "update"
  231 + log_resource = "course"
  232 + log_context = {}
202 233
203 allowed_roles = ['professor', 'system_admin'] 234 allowed_roles = ['professor', 'system_admin']
204 login_url = reverse_lazy("core:home") 235 login_url = reverse_lazy("core:home")
@@ -213,6 +244,19 @@ class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): @@ -213,6 +244,19 @@ class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
213 return self.handle_no_permission() 244 return self.handle_no_permission()
214 return super(UpdateCourseView, self).dispatch(*args, **kwargs) 245 return super(UpdateCourseView, self).dispatch(*args, **kwargs)
215 246
  247 + def form_valid(self, form):
  248 + self.object = form.save()
  249 +
  250 + self.log_context['course_id'] = self.object.id
  251 + self.log_context['course_name'] = self.object.name
  252 + self.log_context['course_slug'] = self.object.slug
  253 + self.log_context['course_category_id'] = self.object.category.id
  254 + self.log_context['course_category_name'] = self.object.category.name
  255 +
  256 + super(UpdateCourseView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  257 +
  258 + return super(UpdateCourseView, self).form_valid(form)
  259 +
216 def get_context_data(self, **kwargs): 260 def get_context_data(self, **kwargs):
217 context = super(UpdateCourseView, self).get_context_data(**kwargs) 261 context = super(UpdateCourseView, self).get_context_data(**kwargs)
218 course = get_object_or_404(Course, slug = self.kwargs.get('slug')) 262 course = get_object_or_404(Course, slug = self.kwargs.get('slug'))
@@ -229,7 +273,11 @@ class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): @@ -229,7 +273,11 @@ class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
229 def get_success_url(self): 273 def get_success_url(self):
230 return reverse_lazy('course:view', kwargs={'slug' : self.object.slug}) 274 return reverse_lazy('course:view', kwargs={'slug' : self.object.slug})
231 275
232 -class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): 276 +class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.DeleteView):
  277 + log_component = "courses"
  278 + log_action = "delete"
  279 + log_resource = "course"
  280 + log_context = {}
233 281
234 allowed_roles = ['professor', 'system_admin'] 282 allowed_roles = ['professor', 'system_admin']
235 login_url = reverse_lazy("core:home") 283 login_url = reverse_lazy("core:home")
@@ -242,6 +290,15 @@ class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): @@ -242,6 +290,15 @@ class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView):
242 course = get_object_or_404(Course, slug = self.kwargs.get('slug')) 290 course = get_object_or_404(Course, slug = self.kwargs.get('slug'))
243 if(not has_object_permission('delete_course', self.request.user, course)): 291 if(not has_object_permission('delete_course', self.request.user, course)):
244 return self.handle_no_permission() 292 return self.handle_no_permission()
  293 +
  294 + self.log_context['course_id'] = course.id
  295 + self.log_context['course_name'] = course.name
  296 + self.log_context['course_slug'] = course.slug
  297 + self.log_context['course_category_id'] = course.category.id
  298 + self.log_context['course_category_name'] = course.category.name
  299 +
  300 + super(DeleteCourseView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  301 +
245 return super(DeleteCourseView, self).dispatch(*args, **kwargs) 302 return super(DeleteCourseView, self).dispatch(*args, **kwargs)
246 303
247 def get_context_data(self, **kwargs): 304 def get_context_data(self, **kwargs):
@@ -258,7 +315,11 @@ class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): @@ -258,7 +315,11 @@ class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView):
258 return context 315 return context
259 316
260 317
261 -class CourseView(NotificationMixin, generic.DetailView): 318 +class CourseView(LogMixin, NotificationMixin, generic.DetailView):
  319 + log_component = "courses"
  320 + log_action = "viewed"
  321 + log_resource = "course"
  322 + log_context = {}
262 323
263 login_url = reverse_lazy("core:home") 324 login_url = reverse_lazy("core:home")
264 redirect_field_name = 'next' 325 redirect_field_name = 'next'
@@ -272,6 +333,14 @@ class CourseView(NotificationMixin, generic.DetailView): @@ -272,6 +333,14 @@ class CourseView(NotificationMixin, generic.DetailView):
272 context = super(CourseView, self).get_context_data(**kwargs) 333 context = super(CourseView, self).get_context_data(**kwargs)
273 course = get_object_or_404(Course, slug = self.kwargs.get('slug')) 334 course = get_object_or_404(Course, slug = self.kwargs.get('slug'))
274 335
  336 + self.log_context['course_id'] = course.id
  337 + self.log_context['course_name'] = course.name
  338 + self.log_context['course_slug'] = course.slug
  339 + self.log_context['course_category_id'] = course.category.id
  340 + self.log_context['course_category_name'] = course.category.name
  341 +
  342 + super(CourseView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  343 +
275 category_sub = self.kwargs.get('category', None) 344 category_sub = self.kwargs.get('category', None)
276 345
277 if has_role(self.request.user,'system_admin'): 346 if has_role(self.request.user,'system_admin'):
@@ -329,12 +398,23 @@ class DeleteView(LoginRequiredMixin, HasRoleMixin, NotificationMixin, generic.De @@ -329,12 +398,23 @@ class DeleteView(LoginRequiredMixin, HasRoleMixin, NotificationMixin, generic.De
329 return self.response_class(request=self.request, template=self.get_template_names(), context=context, using=self.template_engine) 398 return self.response_class(request=self.request, template=self.get_template_names(), context=context, using=self.template_engine)
330 399
331 @login_required 400 @login_required
  401 +@log_decorator("course", "subscribe", "course")
332 def subscribe_course(request, slug): 402 def subscribe_course(request, slug):
333 course = get_object_or_404(Course, slug = slug) 403 course = get_object_or_404(Course, slug = slug)
334 404
335 course.students.add(request.user) 405 course.students.add(request.user)
336 406
337 if request.user in course.students.all(): 407 if request.user in course.students.all():
  408 +
  409 + log_context = {}
  410 + log_context['course_id'] = course.id
  411 + log_context['course_name'] = course.name
  412 + log_context['course_slug'] = course.slug
  413 + log_context['course_category_id'] = course.category.id
  414 + log_context['course_category_name'] = course.category.name
  415 +
  416 + request.log_context = log_context
  417 +
338 return JsonResponse({"status": "ok", "message": _("Successfully subscribed to the course!")}) 418 return JsonResponse({"status": "ok", "message": _("Successfully subscribed to the course!")})
339 else: 419 else:
340 return JsonResponse({"status": "erro", "message": _("An error has occured. Could not subscribe to this course, try again later")}) 420 return JsonResponse({"status": "erro", "message": _("An error has occured. Could not subscribe to this course, try again later")})
@@ -436,7 +516,11 @@ class DeleteCatView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): @@ -436,7 +516,11 @@ class DeleteCatView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView):
436 messages.success(self.request, _('Category deleted successfully!')) 516 messages.success(self.request, _('Category deleted successfully!'))
437 return reverse_lazy('course:manage_cat') 517 return reverse_lazy('course:manage_cat')
438 518
439 -class SubjectsView(LoginRequiredMixin, generic.ListView): 519 +class SubjectsView(LoginRequiredMixin, LogMixin, generic.ListView):
  520 + log_component = "course"
  521 + log_resource = "subject"
  522 + log_action = "viewed"
  523 + log_context = {}
440 524
441 login_url = reverse_lazy("core:home") 525 login_url = reverse_lazy("core:home")
442 redirect_field_name = 'next' 526 redirect_field_name = 'next'
@@ -450,6 +534,17 @@ class SubjectsView(LoginRequiredMixin, generic.ListView): @@ -450,6 +534,17 @@ class SubjectsView(LoginRequiredMixin, generic.ListView):
450 if(not has_object_permission('view_subject', self.request.user, subject)): 534 if(not has_object_permission('view_subject', self.request.user, subject)):
451 return self.handle_no_permission() 535 return self.handle_no_permission()
452 536
  537 + self.log_context['subject_id'] = subject.id
  538 + self.log_context['subject_name'] = subject.name
  539 + self.log_context['subject_slug'] = subject.slug
  540 + self.log_context['course_id'] = subject.course.id
  541 + self.log_context['course_name'] = subject.course.name
  542 + self.log_context['course_slug'] = subject.course.slug
  543 + self.log_context['course_category_id'] = subject.course.category.id
  544 + self.log_context['course_category_name'] = subject.course.category.name
  545 +
  546 + super(SubjectsView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  547 +
453 return super(SubjectsView, self).dispatch(*args, **kwargs) 548 return super(SubjectsView, self).dispatch(*args, **kwargs)
454 549
455 def get_queryset(self): 550 def get_queryset(self):
@@ -527,6 +622,8 @@ class TopicsView(LoginRequiredMixin, generic.ListView): @@ -527,6 +622,8 @@ class TopicsView(LoginRequiredMixin, generic.ListView):
527 context['students_activit'] = students_activit 622 context['students_activit'] = students_activit
528 context['materials'] = materials 623 context['materials'] = materials
529 context['form'] = ActivityForm 624 context['form'] = ActivityForm
  625 +
  626 +
530 627
531 return context 628 return context
532 629
@@ -594,7 +691,11 @@ class UpdateTopicView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): @@ -594,7 +691,11 @@ class UpdateTopicView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
594 context['subjects'] = topic.subject.course.subjects.all() 691 context['subjects'] = topic.subject.course.subjects.all()
595 return context 692 return context
596 693
597 -class CreateSubjectView(LoginRequiredMixin, HasRoleMixin, NotificationMixin, generic.edit.CreateView): 694 +class CreateSubjectView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.edit.CreateView):
  695 + log_component = "course"
  696 + log_resource = "subject"
  697 + log_action = "create"
  698 + log_context = {}
598 699
599 allowed_roles = ['professor', 'system_admin'] 700 allowed_roles = ['professor', 'system_admin']
600 login_url = reverse_lazy("core:home") 701 login_url = reverse_lazy("core:home")
@@ -626,6 +727,17 @@ class CreateSubjectView(LoginRequiredMixin, HasRoleMixin, NotificationMixin, gen @@ -626,6 +727,17 @@ class CreateSubjectView(LoginRequiredMixin, HasRoleMixin, NotificationMixin, gen
626 resource_slug = self.object.slug, actor=self.request.user, users= self.object.course.students.all(), 727 resource_slug = self.object.slug, actor=self.request.user, users= self.object.course.students.all(),
627 resource_link = reverse('course:view_subject', args=[self.object.slug])) 728 resource_link = reverse('course:view_subject', args=[self.object.slug]))
628 729
  730 + self.log_context['subject_id'] = self.object.id
  731 + self.log_context['subject_name'] = self.object.name
  732 + self.log_context['subject_slug'] = self.object.slug
  733 + self.log_context['course_id'] = course.id
  734 + self.log_context['course_name'] = course.name
  735 + self.log_context['course_slug'] = course.slug
  736 + self.log_context['course_category_id'] = course.category.id
  737 + self.log_context['course_category_name'] = course.category.name
  738 +
  739 + super(CreateSubjectView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  740 +
629 return super(CreateSubjectView, self).form_valid(form) 741 return super(CreateSubjectView, self).form_valid(form)
630 742
631 743
files/static/js/file.js
1 function get_modal_file(url, id, div_content){ 1 function get_modal_file(url, id, div_content){
2 2
3 $.get(url, function (data) { 3 $.get(url, function (data) {
4 - $(div_content).empty(); 4 + $(div_content).detach();
5 $(div_content).append(data); 5 $(div_content).append(data);
6 $(id).modal('show'); 6 $(id).modal('show');
7 }); 7 });
files/templates/files/create_file.html
@@ -47,7 +47,7 @@ @@ -47,7 +47,7 @@
47 <span id="helpBlock" class="help-block">{{ field.help_text }}</span> 47 <span id="helpBlock" class="help-block">{{ field.help_text }}</span>
48 {% endif %} 48 {% endif %}
49 </div> 49 </div>
50 - 50 +
51 {% if field.errors %} 51 {% if field.errors %}
52 <div class="alert alert-danger alert-dismissible clearfix" role="alert"> 52 <div class="alert alert-danger alert-dismissible clearfix" role="alert">
53 <button type="button" class="close" data-dismiss="alert" aria-label="Close"> 53 <button type="button" class="close" data-dismiss="alert" aria-label="Close">
@@ -71,7 +71,7 @@ @@ -71,7 +71,7 @@
71 71
72 <div class="form-group"> 72 <div class="form-group">
73 <div class="col-md-12"> 73 <div class="col-md-12">
74 - <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans "Close" %}</button> 74 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
75 <button class="btn btn-raised btn-primary" type="submit">{% trans 'Submit' %}</button> 75 <button class="btn btn-raised btn-primary" type="submit">{% trans 'Submit' %}</button>
76 </div> 76 </div>
77 </div> 77 </div>
@@ -85,7 +85,7 @@ @@ -85,7 +85,7 @@
85 </div> 85 </div>
86 86
87 {% block script_file %} 87 {% block script_file %}
88 - 88 +
89 {# // <script src="{% static 'js/file.js' %}"></script> #} 89 {# // <script src="{% static 'js/file.js' %}"></script> #}
90 <script type="text/javascript"> 90 <script type="text/javascript">
91 $("#form-file").submit(function(event) { 91 $("#form-file").submit(function(event) {
files/templates/files/delete_file.html
@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
31 </div> 31 </div>
32 <div class="form-group"> 32 <div class="form-group">
33 <div class="col-md-12"> 33 <div class="col-md-12">
34 - <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans "Close" %}</button> 34 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
35 <button class="btn btn-raised btn-primary" type="submit">{% trans 'Delete' %}</button> 35 <button class="btn btn-raised btn-primary" type="submit">{% trans 'Delete' %}</button>
36 </div> 36 </div>
37 </div> 37 </div>
@@ -45,7 +45,7 @@ @@ -45,7 +45,7 @@
45 </div> 45 </div>
46 46
47 {% block script_file %} 47 {% block script_file %}
48 - 48 +
49 {# // <script src="{% static 'js/file.js' %}"></script> #} 49 {# // <script src="{% static 'js/file.js' %}"></script> #}
50 <script type="text/javascript"> 50 <script type="text/javascript">
51 $("#form-delete-file").submit(function(event) { 51 $("#form-delete-file").submit(function(event) {
files/templates/files/update_file.html
@@ -52,7 +52,7 @@ @@ -52,7 +52,7 @@
52 <span id="helpBlock" class="help-block">{{ field.help_text }}</span> 52 <span id="helpBlock" class="help-block">{{ field.help_text }}</span>
53 {% endif %} 53 {% endif %}
54 </div> 54 </div>
55 - 55 +
56 {% if field.errors %} 56 {% if field.errors %}
57 <div class="alert alert-danger alert-dismissible clearfix" role="alert"> 57 <div class="alert alert-danger alert-dismissible clearfix" role="alert">
58 <button type="button" class="close" data-dismiss="alert" aria-label="Close"> 58 <button type="button" class="close" data-dismiss="alert" aria-label="Close">
@@ -76,7 +76,7 @@ @@ -76,7 +76,7 @@
76 76
77 <div class="form-group"> 77 <div class="form-group">
78 <div class="col-md-12"> 78 <div class="col-md-12">
79 - <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans "Close" %}</button> 79 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
80 <button class="btn btn-raised btn-primary" type="submit">{% trans 'Submit' %}</button> 80 <button class="btn btn-raised btn-primary" type="submit">{% trans 'Submit' %}</button>
81 </div> 81 </div>
82 </div> 82 </div>
@@ -90,7 +90,7 @@ @@ -90,7 +90,7 @@
90 </div> 90 </div>
91 91
92 {% block script_file %} 92 {% block script_file %}
93 - 93 +
94 {# // <script src="{% static 'js/file.js' %}"></script> #} 94 {# // <script src="{% static 'js/file.js' %}"></script> #}
95 <script type="text/javascript"> 95 <script type="text/javascript">
96 $("#form-update-file").submit(function(event) { 96 $("#form-update-file").submit(function(event) {
forum/templates/forum/forum_view.html
@@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
17 {% else %} 17 {% else %}
18 <li class="active">{{ forum.name }}</li> 18 <li class="active">{{ forum.name }}</li>
19 {% endif %} 19 {% endif %}
20 - 20 +
21 </ol> 21 </ol>
22 {% endblock %} 22 {% endblock %}
23 23
@@ -33,7 +33,7 @@ @@ -33,7 +33,7 @@
33 </ul> 33 </ul>
34 </div> 34 </div>
35 </div> 35 </div>
36 - 36 +
37 {% if request.user|has_role:'system_admin' or request.user|has_role:'professor' and request.user in forum.topic.subject.professors.all %} 37 {% if request.user|has_role:'system_admin' or request.user|has_role:'professor' and request.user in forum.topic.subject.professors.all %}
38 <div class="panel panel-primary navigation"> 38 <div class="panel panel-primary navigation">
39 <div class="panel-heading"> 39 <div class="panel-heading">
@@ -121,7 +121,7 @@ @@ -121,7 +121,7 @@
121 </section> 121 </section>
122 </div> 122 </div>
123 <div class="modal-footer"> 123 <div class="modal-footer">
124 - <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans 'Close' %}</button> 124 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans 'Close' %}</button>
125 <button type="button" onclick="$('#forum_create').submit();" class="btn btn-primary btn-raised">{% trans 'Update' %}</button> 125 <button type="button" onclick="$('#forum_create').submit();" class="btn btn-primary btn-raised">{% trans 'Update' %}</button>
126 </div> 126 </div>
127 </div> 127 </div>
links/static/js/links.js
1 function get_modal_link(url, id,div_content){ 1 function get_modal_link(url, id,div_content){
2 $.get(url, function (data) { 2 $.get(url, function (data) {
3 - $(div_content).empty(); 3 + $(div_content).detach();
4 $(div_content).append(data); 4 $(div_content).append(data);
5 $(id).modal('show'); 5 $(id).modal('show');
6 }); 6 });
links/static/links.js
@@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
1 -function get_modal_link(url, id,div_content){  
2 - $.get(url, function (data) {  
3 - $(div_content).empty();  
4 - $(div_content).append(data);  
5 - $(id).modal('show');  
6 - });  
7 -  
8 -}  
links/templates/links/create_link.html
1 {% load widget_tweaks i18n %} 1 {% load widget_tweaks i18n %}
2 -  
3 <!--MODAL CREATE LINK--> 2 <!--MODAL CREATE LINK-->
4 <div class="modal fade" id="createLinksModal" tabindex="-1" role="dialog" aria-labelledby="createLink"> 3 <div class="modal fade" id="createLinksModal" tabindex="-1" role="dialog" aria-labelledby="createLink">
5 <div class="modal-dialog" role="document"> 4 <div class="modal-dialog" role="document">
@@ -33,7 +32,7 @@ @@ -33,7 +32,7 @@
33 </div> 32 </div>
34 {% endfor %} 33 {% endfor %}
35 <div class="form-group"> 34 <div class="form-group">
36 - <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans "Cancel" %}</button> 35 + <button type="button" class="btn btn-raised btn-default " data-dismiss="modal">{% trans "Cancel" %}</button>
37 <button class="btn btn-raised btn-primary" type="submit">{% trans 'Submit' %}</button> 36 <button class="btn btn-raised btn-primary" type="submit">{% trans 'Submit' %}</button>
38 </div> 37 </div>
39 <!-- .end Card --> 38 <!-- .end Card -->
links/templates/links/delete_link.html
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 </div> 21 </div>
22 <div class="form-group"> 22 <div class="form-group">
23 <div class="col-md-12"> 23 <div class="col-md-12">
24 - <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans "Close" %}</button> 24 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
25 <button class="btn btn-raised btn-primary" type="submit">{% trans 'Delete' %}</button> 25 <button class="btn btn-raised btn-primary" type="submit">{% trans 'Delete' %}</button>
26 </div> 26 </div>
27 </div> 27 </div>
links/templates/links/update_link.html
@@ -36,7 +36,7 @@ @@ -36,7 +36,7 @@
36 {% endif %} 36 {% endif %}
37 {% endfor %} 37 {% endfor %}
38 <div class="form-group"> 38 <div class="form-group">
39 - <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans "Cancel" %}</button> 39 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Cancel" %}</button>
40 <button class="btn btn-raised btn-primary" type="submit">{% trans 'Submit' %}</button> 40 <button class="btn btn-raised btn-primary" type="submit">{% trans 'Submit' %}</button>
41 </div> 41 </div>
42 <!-- .end Card --> 42 <!-- .end Card -->
links/templates/links/view_link.html
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 <div class="card-block"> 14 <div class="card-block">
15 <b class="card-title">{{link.name}}</b><p></p> 15 <b class="card-title">{{link.name}}</b><p></p>
16 <p class="card-text"> </p><p>{{link.link_description}}</p> 16 <p class="card-text"> </p><p>{{link.link_description}}</p>
17 - <a href="{{ link.link_url }}" class="btn btn-primary">{% trans 'Read more' %}</a> 17 + <a href="{{ link.link_url }}" class="btn btn-raised btn-primary">{% trans 'Read more' %}</a>
18 </div> 18 </div>
19 </article> 19 </article>
20 <!-- .end Card --> 20 <!-- .end Card -->
poll/templates/poll/create.html
@@ -151,7 +151,7 @@ @@ -151,7 +151,7 @@
151 <div class="modal-footer"> 151 <div class="modal-footer">
152 152
153 <!-- Don't remove that!!! --> 153 <!-- Don't remove that!!! -->
154 - <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans "Close" %}</button> 154 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
155 {% block button_save %} 155 {% block button_save %}
156 <!-- Put curtom buttons here!!! --> 156 <!-- Put curtom buttons here!!! -->
157 <button type="submite" id="button" form="form" class="btn btn-primary btn-raised">{% trans "Create" %}</button> 157 <button type="submite" id="button" form="form" class="btn btn-primary btn-raised">{% trans "Create" %}</button>
requirements.txt
  1 +beautifulsoup4==4.5.1
1 click==6.6 2 click==6.6
2 decorator==4.0.10 3 decorator==4.0.10
3 deps==0.1.0 4 deps==0.1.0
@@ -10,18 +11,22 @@ django-floppyforms==1.7.0 @@ -10,18 +11,22 @@ django-floppyforms==1.7.0
10 django-modalview==0.1.5 11 django-modalview==0.1.5
11 django-role-permissions==1.2.1 12 django-role-permissions==1.2.1
12 django-s3direct==0.4.2 13 django-s3direct==0.4.2
  14 +django-summernote==0.8.6
13 django-widget-tweaks==1.4.1 15 django-widget-tweaks==1.4.1
  16 +django-wysiwyg==0.8.0
14 djangorestframework==3.4.6 17 djangorestframework==3.4.6
15 gunicorn==19.6.0 18 gunicorn==19.6.0
  19 +itsdangerous==0.24
16 Jinja2==2.8 20 Jinja2==2.8
  21 +lxml==3.6.4
17 MarkupSafe==0.23 22 MarkupSafe==0.23
18 Pillow==3.3.1 23 Pillow==3.3.1
19 psycopg2==2.6.2 24 psycopg2==2.6.2
20 pycpfcnpj==1.0.2 25 pycpfcnpj==1.0.2
  26 +requests==2.11.1
21 six==1.10.0 27 six==1.10.0
  28 +slugify==0.0.1
22 validators==0.11.0 29 validators==0.11.0
  30 +virtualenv==15.0.3
23 Werkzeug==0.11.11 31 Werkzeug==0.11.11
24 whitenoise==3.2.2 32 whitenoise==3.2.2
25 -beautifulsoup4==4.5.1  
26 -lxml==3.6.4  
27 -requests==2.11.1  
users/templates/users/create.html
@@ -38,7 +38,7 @@ @@ -38,7 +38,7 @@
38 {% else %} 38 {% else %}
39 <label for="{{ field.auto_id }}">{{ field.label }}</label> 39 <label for="{{ field.auto_id }}">{{ field.label }}</label>
40 {% endif %} 40 {% endif %}
41 - <input type="text" class="form-control input-sm date-picker" name="{{field.name}}" min="{{now|date:'d-m-Y'}}"> 41 + <input type="text" class="form-control input-sm date-picker" name="{{field.name}}" min="{{now|date:'SHORT_DATE_FORMAT'}}">
42 42
43 {% elif field.auto_id == 'id_image' %} 43 {% elif field.auto_id == 'id_image' %}
44 {% if field.field.required %} 44 {% if field.field.required %}
users/templates/users/profile.html
@@ -45,9 +45,11 @@ @@ -45,9 +45,11 @@
45 <div class="row"> 45 <div class="row">
46 <div class="col-md-4"> 46 <div class="col-md-4">
47 {% if user.image %} 47 {% if user.image %}
48 - <div style="background-image: url('{{ user.image.url }}'); background-size: 100% 100%; background-repeat: no-repeat; margin-left: 8em;" alt="photoUser" class="img-circle img-responsive img-list-user"></div> 48 + <div style="width: 200px; overflow:hidden; margin-left: 8em;">
  49 + <img src="{{ user.image.url }}" class="img-circle img-responsive img-list-user" >
  50 + </div>
49 {% else %} 51 {% else %}
50 - {% if usser.gender == 'M' %} 52 + {% if user.gender == 'M' %}
51 <img src="{% static 'img/male_avatar.png' %}" alt="Avatar" class="img-circle img-responsive img-list-user" style="margin-left: 8em;"> 53 <img src="{% static 'img/male_avatar.png' %}" alt="Avatar" class="img-circle img-responsive img-list-user" style="margin-left: 8em;">
52 {% else %} 54 {% else %}
53 <img src="{% static 'img/female_avatar.png' %}" alt="Avatar" class="img-circle img-responsive img-list-user" style="margin-left: 8em;"> 55 <img src="{% static 'img/female_avatar.png' %}" alt="Avatar" class="img-circle img-responsive img-list-user" style="margin-left: 8em;">