diff --git a/amadeus/settings.py b/amadeus/settings.py
index 438c378..e733a04 100644
--- a/amadeus/settings.py
+++ b/amadeus/settings.py
@@ -46,6 +46,7 @@ INSTALLED_APPS = [
'rest_framework',
'django_bootstrap_breadcrumbs',
's3direct',
+ 'django_summernote',
'users',
'core',
@@ -225,7 +226,59 @@ S3DIRECT_DESTINATIONS = {
# FILE UPLOAD
MAX_UPLOAD_SIZE = 10485760
+SUMMERNOTE_CONFIG = {
+ # Using SummernoteWidget - iframe mode
+ 'iframe': True, # or set False to use SummernoteInplaceWidget - no iframe mode
+
+ # Using Summernote Air-mode
+ 'airMode': False,
+
+ # Use native HTML tags (``, ``, ...) instead of style attributes
+ # (Firefox, Chrome only)
+ 'styleWithTags': True,
+
+ # Set text direction : 'left to right' is default.
+ 'direction': 'ltr',
+
+ # Change editor size
+ 'width': '100%',
+ 'height': '480',
+
+ # Use proper language setting automatically (default)
+ 'lang': None,
+
+ # Or, set editor language/locale forcely
+ 'lang_matches': {
+ 'pt': 'pt-BR',
+ },
+
+ # Customize toolbar buttons
+ 'toolbar': [
+ ['style', ['style']],
+ ['font', ['bold', 'italic', 'underline', 'superscript', 'subscript',
+ 'strikethrough', 'clear']],
+ ['fontname', ['fontname']],
+ ['fontsize', ['fontsize']],
+ ['color', ['color']],
+ ['para', ['ul', 'ol', 'paragraph']],
+ ['height', ['height']],
+ ['table', ['table']],
+ ['insert', ['link', 'picture', 'video', 'hr']],
+ ['view', ['fullscreen', 'codeview']],
+ ['help', ['help']],
+ ],
+
+ # Need authentication while uploading attachments.
+ 'attachment_require_authentication': True,
+
+ # Set `upload_to` function for attachments.
+ #'attachment_upload_to': my_custom_upload_to_func(),
+
+
+
+}
+
try:
from .local_settings import *
except ImportError:
- pass
+ pass
\ No newline at end of file
diff --git a/amadeus/urls.py b/amadeus/urls.py
index 52845ec..2f3745e 100644
--- a/amadeus/urls.py
+++ b/amadeus/urls.py
@@ -28,6 +28,7 @@ urlpatterns = [
#S3Direct
url(r'^s3direct/', include('s3direct.urls')),
+ url(r'^summernote/', include('django_summernote.urls')),
]
urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
diff --git a/core/mixins.py b/core/mixins.py
index 6c82977..57214e9 100644
--- a/core/mixins.py
+++ b/core/mixins.py
@@ -34,9 +34,6 @@ class LogMixin(object):
else:
action_resource = action_resource[0]
- print(context)
- print(json.dumps(context))
-
log = Log()
log.user = actor
log.context = json.dumps(context)
diff --git a/courses/forms.py b/courses/forms.py
index 4f32ac2..ae3a796 100644
--- a/courses/forms.py
+++ b/courses/forms.py
@@ -2,7 +2,7 @@ from django import forms
from django.utils.translation import ugettext_lazy as _
from .models import CourseCategory, Course, Subject, Topic, ActivityFile, Activity, FileMaterial, LinkMaterial
from s3direct.widgets import S3DirectWidget
-
+from django_summernote.widgets import SummernoteWidget
class CategoryCourseForm(forms.ModelForm):
@@ -79,8 +79,8 @@ class CourseForm(forms.ModelForm):
widgets = {
'categoy': forms.Select(),
- 'objectivies': forms.Textarea(attrs={'cols': 80, 'rows': 5}),
- 'content': forms.Textarea(attrs={'cols': 80, 'rows': 5}),
+ 'objectivies': SummernoteWidget(attrs={'cols': 80, 'rows': 5}),
+ 'content': SummernoteWidget(attrs={'cols': 80, 'rows': 5}),
}
class UpdateCourseForm(CourseForm):
@@ -120,8 +120,8 @@ class UpdateCourseForm(CourseForm):
}
widgets = {
'categoy': forms.Select(),
- 'objectivies': forms.Textarea(attrs={'cols': 80, 'rows': 5}),
- 'content': forms.Textarea(attrs={'cols': 80, 'rows': 5}),
+ 'objectivies': SummernoteWidget(attrs={'cols': 80, 'rows': 5}),
+ 'content': SummernoteWidget(attrs={'cols': 80, 'rows': 5}),
}
class SubjectForm(forms.ModelForm):
@@ -143,6 +143,9 @@ class SubjectForm(forms.ModelForm):
'end_date': _('End date of the subject'),
'visible': _('Is the subject visible?'),
}
+ widgets = {
+ 'description':SummernoteWidget(),
+ }
class TopicForm(forms.ModelForm):
@@ -157,6 +160,9 @@ class TopicForm(forms.ModelForm):
'name': _("Topic's name"),
'description': _("Topic's description"),
}
+ widgets = {
+ 'description':SummernoteWidget(),
+ }
class ActivityFileForm(forms.ModelForm):
name = forms.CharField(
diff --git a/courses/static/js/topic_editation_presentation.js b/courses/static/js/topic_editation_presentation.js
index 171aa34..73bf889 100644
--- a/courses/static/js/topic_editation_presentation.js
+++ b/courses/static/js/topic_editation_presentation.js
@@ -5,7 +5,8 @@ function show_editation(id_topic){
$(".presentation_"+ id_topic).css('display','none');
$(".editation_"+ id_topic).css('display','block');
};
- function show_presentation(id_topic){
+
+function show_presentation(id_topic){
$(".editation_"+ id_topic).css('display','none');
$(".presentation_"+ id_topic).css('display','block');
};
diff --git a/courses/templates/course/course_card.html b/courses/templates/course/course_card.html
index 59ce272..2f39e0e 100644
--- a/courses/templates/course/course_card.html
+++ b/courses/templates/course/course_card.html
@@ -38,7 +38,7 @@
{% trans 'Description' %}:
- {{course.content}}
+ {{course.content | safe }}
diff --git a/courses/templates/course/view.html b/courses/templates/course/view.html
index 879c426..4917e99 100644
--- a/courses/templates/course/view.html
+++ b/courses/templates/course/view.html
@@ -98,7 +98,7 @@
{% trans 'Description' %}:
- {{ course.objectivies }}
+ {{ course.objectivies |safe }}
@@ -174,7 +174,7 @@
{% trans "Description" %}:
- {{subject.description}}
+ {{subject.description | safe}}
diff --git a/courses/templates/subject/form_view_student.html b/courses/templates/subject/form_view_student.html
index 0451308..0c9ee20 100644
--- a/courses/templates/subject/form_view_student.html
+++ b/courses/templates/subject/form_view_student.html
@@ -27,7 +27,7 @@
- {{topic.description|linebreaks}}
+ {{topic.description|safe}}
diff --git a/courses/templates/subject/form_view_teacher.html b/courses/templates/subject/form_view_teacher.html
index 04367bc..73021df 100644
--- a/courses/templates/subject/form_view_teacher.html
+++ b/courses/templates/subject/form_view_teacher.html
@@ -39,7 +39,7 @@
- {{topic.description|linebreaks}}
+ {{topic.description|safe}}
diff --git a/courses/templates/subject/index.html b/courses/templates/subject/index.html
index 62b31a2..6f3dd47 100644
--- a/courses/templates/subject/index.html
+++ b/courses/templates/subject/index.html
@@ -75,7 +75,7 @@
{{professor}}{% if forloop.last %}.{% endif %}{% endfor %}
{% trans "Description" %}:
- {{subject.description|linebreaks}}
+ {{subject.description|safe}}
diff --git a/courses/templates/subject_category/index.html b/courses/templates/subject_category/index.html
index 091f223..3c94d96 100644
--- a/courses/templates/subject_category/index.html
+++ b/courses/templates/subject_category/index.html
@@ -58,7 +58,7 @@
- {{subject.description|linebreaks}}
+ {{subject.description| safe }}
diff --git a/courses/templates/topic/index.html b/courses/templates/topic/index.html
index 3c9659c..d97cf21 100644
--- a/courses/templates/topic/index.html
+++ b/courses/templates/topic/index.html
@@ -77,7 +77,7 @@
- {{topic.description|linebreaks}}
+ {{topic.description|safe}}
diff --git a/courses/views.py b/courses/views.py
index 42a4349..b571bf5 100644
--- a/courses/views.py
+++ b/courses/views.py
@@ -284,21 +284,12 @@ class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.Delet
redirect_field_name = 'next'
model = Course
template_name = 'course/delete.html'
- success_url = reverse_lazy('course:manage')
def dispatch(self, *args, **kwargs):
course = get_object_or_404(Course, slug = self.kwargs.get('slug'))
if(not has_object_permission('delete_course', self.request.user, course)):
return self.handle_no_permission()
- self.log_context['course_id'] = course.id
- self.log_context['course_name'] = course.name
- self.log_context['course_slug'] = course.slug
- self.log_context['course_category_id'] = course.category.id
- self.log_context['course_category_name'] = course.category.name
-
- super(DeleteCourseView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
-
return super(DeleteCourseView, self).dispatch(*args, **kwargs)
def get_context_data(self, **kwargs):
@@ -314,6 +305,17 @@ class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.Delet
return context
+ def get_success_url(self):
+ self.log_context['course_id'] = self.object.id
+ self.log_context['course_name'] = self.object.name
+ self.log_context['course_slug'] = self.object.slug
+ self.log_context['course_category_id'] = self.object.category.id
+ self.log_context['course_category_name'] = self.object.category.name
+
+ super(DeleteCourseView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
+
+ return reverse_lazy('course:manage')
+
class CourseView(LogMixin, NotificationMixin, generic.DetailView):
log_component = "courses"
@@ -586,7 +588,11 @@ class UploadMaterialView(LoginRequiredMixin, generic.edit.CreateView):
return self.success_url
-class TopicsView(LoginRequiredMixin, generic.ListView):
+class TopicsView(LoginRequiredMixin, LogMixin, generic.ListView):
+ log_component = "course"
+ log_resource = "topic"
+ log_action = "viewed"
+ log_context = {}
login_url = reverse_lazy("core:home")
redirect_field_name = 'next'
@@ -600,6 +606,20 @@ class TopicsView(LoginRequiredMixin, generic.ListView):
if(not has_object_permission('view_topic', self.request.user, topic)):
return self.handle_no_permission()
+ self.log_context['topic_id'] = topic.id
+ self.log_context['topic_name'] = topic.name
+ self.log_context['topic_slug'] = topic.slug
+ self.log_context['subject_id'] = topic.subject.id
+ self.log_context['subject_name'] = topic.subject.name
+ self.log_context['subject_slug'] = topic.subject.slug
+ self.log_context['course_id'] = topic.subject.course.id
+ self.log_context['course_name'] = topic.subject.course.name
+ self.log_context['course_slug'] = topic.subject.course.slug
+ self.log_context['course_category_id'] = topic.subject.course.category.id
+ self.log_context['course_category_name'] = topic.subject.course.category.name
+
+ super(TopicsView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
+
return super(TopicsView, self).dispatch(*args, **kwargs)
def get_queryset(self):
@@ -626,7 +646,11 @@ class TopicsView(LoginRequiredMixin, generic.ListView):
return context
-class CreateTopicView(LoginRequiredMixin, HasRoleMixin, NotificationMixin, generic.edit.CreateView):
+class CreateTopicView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.edit.CreateView):
+ log_component = "course"
+ log_resource = "topic"
+ log_action = "create"
+ log_context = {}
allowed_roles = ['professor', 'system_admin']
login_url = reverse_lazy("core:home")
@@ -656,10 +680,28 @@ class CreateTopicView(LoginRequiredMixin, HasRoleMixin, NotificationMixin, gener
super(CreateTopicView, self).createNotification("Topic "+ self.object.name + " was created",
resource_name=self.object.name, resource_link= reverse('course:view_topic',args=[self.object.slug]),
actor=self.request.user, users = self.object.subject.course.students.all() )
+
+ self.log_context['topic_id'] = self.object.id
+ self.log_context['topic_name'] = self.object.name
+ self.log_context['topic_slug'] = self.object.slug
+ self.log_context['subject_id'] = self.object.subject.id
+ self.log_context['subject_name'] = self.object.subject.name
+ self.log_context['subject_slug'] = self.object.subject.slug
+ self.log_context['course_id'] = self.object.subject.course.id
+ self.log_context['course_name'] = self.object.subject.course.name
+ self.log_context['course_slug'] = self.object.subject.course.slug
+ self.log_context['course_category_id'] = self.object.subject.course.category.id
+ self.log_context['course_category_name'] = self.object.subject.course.category.name
+
+ super(CreateTopicView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
return super(CreateTopicView, self).form_valid(form)
-class UpdateTopicView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
+class UpdateTopicView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.UpdateView):
+ log_component = "course"
+ log_resource = "topic"
+ log_action = "create"
+ log_context = {}
allowed_roles = ['professor','system_admin']
login_url = reverse_lazy("core:home")
@@ -689,6 +731,25 @@ class UpdateTopicView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
context['subjects'] = topic.subject.course.subjects.all()
return context
+ def form_valid(self, form):
+ self.object = form.save()
+
+ self.log_context['topic_id'] = self.object.id
+ self.log_context['topic_name'] = self.object.name
+ self.log_context['topic_slug'] = self.object.slug
+ self.log_context['subject_id'] = self.object.subject.id
+ self.log_context['subject_name'] = self.object.subject.name
+ self.log_context['subject_slug'] = self.object.subject.slug
+ self.log_context['course_id'] = self.object.subject.course.id
+ self.log_context['course_name'] = self.object.subject.course.name
+ self.log_context['course_slug'] = self.object.subject.course.slug
+ self.log_context['course_category_id'] = self.object.subject.course.category.id
+ self.log_context['course_category_name'] = self.object.subject.course.category.name
+
+ super(UpdateTopicView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
+
+ return super(UpdateTopicView, self).form_valid(form)
+
class CreateSubjectView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.edit.CreateView):
log_component = "course"
log_resource = "subject"
@@ -739,7 +800,11 @@ class CreateSubjectView(LoginRequiredMixin, HasRoleMixin, LogMixin, Notification
return super(CreateSubjectView, self).form_valid(form)
-class UpdateSubjectView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
+class UpdateSubjectView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.UpdateView):
+ log_component = "course"
+ log_resource = "subject"
+ log_action = "update"
+ log_context = {}
allowed_roles = ['professor', 'system_admin']
login_url = reverse_lazy("core:home")
@@ -753,6 +818,22 @@ class UpdateSubjectView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
return self.handle_no_permission()
return super(UpdateSubjectView, self).dispatch(*args, **kwargs)
+ def form_valid(self, form):
+ self.object = form.save()
+
+ self.log_context['subject_id'] = self.object.id
+ self.log_context['subject_name'] = self.object.name
+ self.log_context['subject_slug'] = self.object.slug
+ self.log_context['course_id'] = self.object.course.id
+ self.log_context['course_name'] = self.object.course.name
+ self.log_context['course_slug'] = self.object.course.slug
+ self.log_context['course_category_id'] = self.object.course.category.id
+ self.log_context['course_category_name'] = self.object.course.category.name
+
+ super(UpdateSubjectView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
+
+ return super(UpdateSubjectView, self).form_valid(form)
+
def get_object(self, queryset=None):
context = get_object_or_404(Subject, slug = self.kwargs.get('slug'))
return context
@@ -769,7 +850,11 @@ class UpdateSubjectView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
context['subjects'] = self.object.course.subjects.all()
return context
-class DeleteSubjectView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView):
+class DeleteSubjectView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.DeleteView):
+ log_component = "course"
+ log_resource = "subject"
+ log_action = "delete"
+ log_context = {}
allowed_roles = ['professor', 'system_admin']
login_url = reverse_lazy("core:home")
@@ -783,7 +868,6 @@ class DeleteSubjectView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView):
return self.handle_no_permission()
return super(DeleteSubjectView, self).dispatch(*args, **kwargs)
-
def get_context_data(self, **kwargs):
context = super(DeleteSubjectView, self).get_context_data(**kwargs)
context['course'] = self.object.course
@@ -794,9 +878,21 @@ class DeleteSubjectView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView):
return context
def get_success_url(self):
+ self.log_context['subject_id'] = self.object.id
+ self.log_context['subject_name'] = self.object.name
+ self.log_context['subject_slug'] = self.object.slug
+ self.log_context['course_id'] = self.object.course.id
+ self.log_context['course_name'] = self.object.course.name
+ self.log_context['course_slug'] = self.object.course.slug
+ self.log_context['course_category_id'] = self.object.course.category.id
+ self.log_context['course_category_name'] = self.object.course.category.name
+
+ super(DeleteSubjectView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
+
return reverse_lazy('course:view', kwargs={'slug' : self.object.course.slug})
@login_required
+@log_decorator("course", "subscribe", "subject")
def subscribe_subject(request, slug):
subject = get_object_or_404(Subject, slug = slug)
@@ -804,6 +900,18 @@ def subscribe_subject(request, slug):
subject.students.add(request.user)
if request.user in subject.students.all():
+ log_context = {}
+ log_context['subject_id'] = subject.id
+ log_context['subject_name'] = subject.name
+ log_context['subject_slug'] = subject.slug
+ log_context['course_id'] = subject.course.id
+ log_context['course_name'] = subject.course.name
+ log_context['course_slug'] = subject.course.slug
+ log_context['course_category_id'] = subject.course.category.id
+ log_context['course_category_name'] = subject.course.category.name
+
+ request.log_context = log_context
+
return JsonResponse({"status": "ok", "message": _("Successfully subscribed to the subject!")})
else:
return JsonResponse({"status": "erro", "message": _("An error has occured. Could not subscribe to this subject, try again later")})
diff --git a/files/static/js/file.js b/files/static/js/file.js
index 15d150b..ecb8f2d 100644
--- a/files/static/js/file.js
+++ b/files/static/js/file.js
@@ -1,7 +1,7 @@
function get_modal_file(url, id, div_content){
$.get(url, function (data) {
- $(div_content).empty();
+ $(div_content).detach();
$(div_content).append(data);
$(id).modal('show');
});
diff --git a/forum/static/js/forum.js b/forum/static/js/forum.js
index 622f8cb..43d958d 100644
--- a/forum/static/js/forum.js
+++ b/forum/static/js/forum.js
@@ -74,6 +74,8 @@ function setForumCreateFormSubmit(topic) {
success: function (data) {
$(".topic_" + topic).find('.foruns_list').append(" "+data.name+"");
+ alertify.success(data.message);
+
$("#createForum").modal('hide');
},
error: function(data) {
@@ -221,6 +223,8 @@ function delete_post(url, post) {
},
url: url,
success: function(data) {
+ alertify.success(data);
+
$("#post_"+post).remove();
}
});
diff --git a/forum/templates/forum/forum_form.html b/forum/templates/forum/forum_form.html
index e11791f..0c3945e 100644
--- a/forum/templates/forum/forum_form.html
+++ b/forum/templates/forum/forum_form.html
@@ -15,21 +15,21 @@
{% render_field field %}
{{ field.help_text }}
- {% if field.errors %}
-
-
-
-
-
- {% for error in field.errors %}
- - {{ error }}
- {% endfor %}
-
-
+ {% endif %}
+ {% if field.errors %}
+
+
+
+
+
+ {% for error in field.errors %}
+ - {{ error }}
+ {% endfor %}
+
- {% endif %}
+
{% endif %}
{% endfor %}
diff --git a/forum/templates/post/post_render.html b/forum/templates/post/post_render.html
index cf677ca..d6e21e7 100644
--- a/forum/templates/post/post_render.html
+++ b/forum/templates/post/post_render.html
@@ -8,7 +8,7 @@
{% trans 'reply' %}
- {% if request.user|has_role:'system_admin' or request.user|has_role:'professor' and request.user == post.user %}
+ {% if request.user|has_role:'system_admin' or request.user == post.user %}
{% csrf_token %}