Commit 3fe44fc09c899c27c80f10f7c07a9003f106ca3b
1 parent
a4d0a0ff
Exists in
master
and in
5 other branches
conflix
Showing
20 changed files
with
484 additions
and
69 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) |
core/mixins.py
@@ -34,9 +34,6 @@ class LogMixin(object): | @@ -34,9 +34,6 @@ class LogMixin(object): | ||
34 | else: | 34 | else: |
35 | action_resource = action_resource[0] | 35 | action_resource = action_resource[0] |
36 | 36 | ||
37 | - print(context) | ||
38 | - print(json.dumps(context)) | ||
39 | - | ||
40 | log = Log() | 37 | log = Log() |
41 | log.user = actor | 38 | log.user = actor |
42 | log.context = json.dumps(context) | 39 | log.context = json.dumps(context) |
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 | ||
@@ -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/course/course_card.html
courses/templates/course/view.html
@@ -98,7 +98,7 @@ | @@ -98,7 +98,7 @@ | ||
98 | <p> | 98 | <p> |
99 | <b>{% trans 'Description' %}:</b> | 99 | <b>{% trans 'Description' %}:</b> |
100 | <i> | 100 | <i> |
101 | - {{ course.objectivies }} | 101 | + {{ course.objectivies |safe }} |
102 | </i> | 102 | </i> |
103 | </p> | 103 | </p> |
104 | 104 | ||
@@ -174,7 +174,7 @@ | @@ -174,7 +174,7 @@ | ||
174 | <p> | 174 | <p> |
175 | <b>{% trans "Description" %}: </b> | 175 | <b>{% trans "Description" %}: </b> |
176 | <i> | 176 | <i> |
177 | - {{subject.description}} | 177 | + {{subject.description | safe}} |
178 | </i> | 178 | </i> |
179 | </p> | 179 | </p> |
180 | <div class="row"> | 180 | <div class="row"> |
courses/templates/subject/form_view_student.html
courses/templates/subject/form_view_teacher.html
courses/templates/subject/index.html
@@ -75,7 +75,7 @@ | @@ -75,7 +75,7 @@ | ||
75 | {{professor}}{% if forloop.last %}.{% endif %}{% endfor %}</p> | 75 | {{professor}}{% if forloop.last %}.{% endif %}{% endfor %}</p> |
76 | <p> | 76 | <p> |
77 | <b>{% trans "Description" %}:</b> | 77 | <b>{% trans "Description" %}:</b> |
78 | - {{subject.description|linebreaks}} | 78 | + {{subject.description|safe}} |
79 | </p> | 79 | </p> |
80 | <div class="row"> | 80 | <div class="row"> |
81 | <div class="col-xs-6 col-md-6"> | 81 | <div class="col-xs-6 col-md-6"> |
courses/templates/subject_category/index.html
courses/templates/topic/index.html
courses/views.py
@@ -284,21 +284,12 @@ class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.Delet | @@ -284,21 +284,12 @@ class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.Delet | ||
284 | redirect_field_name = 'next' | 284 | redirect_field_name = 'next' |
285 | model = Course | 285 | model = Course |
286 | template_name = 'course/delete.html' | 286 | template_name = 'course/delete.html' |
287 | - success_url = reverse_lazy('course:manage') | ||
288 | 287 | ||
289 | def dispatch(self, *args, **kwargs): | 288 | def dispatch(self, *args, **kwargs): |
290 | course = get_object_or_404(Course, slug = self.kwargs.get('slug')) | 289 | course = get_object_or_404(Course, slug = self.kwargs.get('slug')) |
291 | if(not has_object_permission('delete_course', self.request.user, course)): | 290 | if(not has_object_permission('delete_course', self.request.user, course)): |
292 | return self.handle_no_permission() | 291 | return self.handle_no_permission() |
293 | 292 | ||
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 | - | ||
302 | return super(DeleteCourseView, self).dispatch(*args, **kwargs) | 293 | return super(DeleteCourseView, self).dispatch(*args, **kwargs) |
303 | 294 | ||
304 | def get_context_data(self, **kwargs): | 295 | def get_context_data(self, **kwargs): |
@@ -314,6 +305,17 @@ class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.Delet | @@ -314,6 +305,17 @@ class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.Delet | ||
314 | 305 | ||
315 | return context | 306 | return context |
316 | 307 | ||
308 | + def get_success_url(self): | ||
309 | + self.log_context['course_id'] = self.object.id | ||
310 | + self.log_context['course_name'] = self.object.name | ||
311 | + self.log_context['course_slug'] = self.object.slug | ||
312 | + self.log_context['course_category_id'] = self.object.category.id | ||
313 | + self.log_context['course_category_name'] = self.object.category.name | ||
314 | + | ||
315 | + super(DeleteCourseView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
316 | + | ||
317 | + return reverse_lazy('course:manage') | ||
318 | + | ||
317 | 319 | ||
318 | class CourseView(LogMixin, NotificationMixin, generic.DetailView): | 320 | class CourseView(LogMixin, NotificationMixin, generic.DetailView): |
319 | log_component = "courses" | 321 | log_component = "courses" |
@@ -586,7 +588,11 @@ class UploadMaterialView(LoginRequiredMixin, generic.edit.CreateView): | @@ -586,7 +588,11 @@ class UploadMaterialView(LoginRequiredMixin, generic.edit.CreateView): | ||
586 | 588 | ||
587 | return self.success_url | 589 | return self.success_url |
588 | 590 | ||
589 | -class TopicsView(LoginRequiredMixin, generic.ListView): | 591 | +class TopicsView(LoginRequiredMixin, LogMixin, generic.ListView): |
592 | + log_component = "course" | ||
593 | + log_resource = "topic" | ||
594 | + log_action = "viewed" | ||
595 | + log_context = {} | ||
590 | 596 | ||
591 | login_url = reverse_lazy("core:home") | 597 | login_url = reverse_lazy("core:home") |
592 | redirect_field_name = 'next' | 598 | redirect_field_name = 'next' |
@@ -600,6 +606,20 @@ class TopicsView(LoginRequiredMixin, generic.ListView): | @@ -600,6 +606,20 @@ class TopicsView(LoginRequiredMixin, generic.ListView): | ||
600 | if(not has_object_permission('view_topic', self.request.user, topic)): | 606 | if(not has_object_permission('view_topic', self.request.user, topic)): |
601 | return self.handle_no_permission() | 607 | return self.handle_no_permission() |
602 | 608 | ||
609 | + self.log_context['topic_id'] = topic.id | ||
610 | + self.log_context['topic_name'] = topic.name | ||
611 | + self.log_context['topic_slug'] = topic.slug | ||
612 | + self.log_context['subject_id'] = topic.subject.id | ||
613 | + self.log_context['subject_name'] = topic.subject.name | ||
614 | + self.log_context['subject_slug'] = topic.subject.slug | ||
615 | + self.log_context['course_id'] = topic.subject.course.id | ||
616 | + self.log_context['course_name'] = topic.subject.course.name | ||
617 | + self.log_context['course_slug'] = topic.subject.course.slug | ||
618 | + self.log_context['course_category_id'] = topic.subject.course.category.id | ||
619 | + self.log_context['course_category_name'] = topic.subject.course.category.name | ||
620 | + | ||
621 | + super(TopicsView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
622 | + | ||
603 | return super(TopicsView, self).dispatch(*args, **kwargs) | 623 | return super(TopicsView, self).dispatch(*args, **kwargs) |
604 | 624 | ||
605 | def get_queryset(self): | 625 | def get_queryset(self): |
@@ -626,7 +646,11 @@ class TopicsView(LoginRequiredMixin, generic.ListView): | @@ -626,7 +646,11 @@ class TopicsView(LoginRequiredMixin, generic.ListView): | ||
626 | return context | 646 | return context |
627 | 647 | ||
628 | 648 | ||
629 | -class CreateTopicView(LoginRequiredMixin, HasRoleMixin, NotificationMixin, generic.edit.CreateView): | 649 | +class CreateTopicView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.edit.CreateView): |
650 | + log_component = "course" | ||
651 | + log_resource = "topic" | ||
652 | + log_action = "create" | ||
653 | + log_context = {} | ||
630 | 654 | ||
631 | allowed_roles = ['professor', 'system_admin'] | 655 | allowed_roles = ['professor', 'system_admin'] |
632 | login_url = reverse_lazy("core:home") | 656 | login_url = reverse_lazy("core:home") |
@@ -656,10 +680,28 @@ class CreateTopicView(LoginRequiredMixin, HasRoleMixin, NotificationMixin, gener | @@ -656,10 +680,28 @@ class CreateTopicView(LoginRequiredMixin, HasRoleMixin, NotificationMixin, gener | ||
656 | super(CreateTopicView, self).createNotification("Topic "+ self.object.name + " was created", | 680 | super(CreateTopicView, self).createNotification("Topic "+ self.object.name + " was created", |
657 | resource_name=self.object.name, resource_link= reverse('course:view_topic',args=[self.object.slug]), | 681 | resource_name=self.object.name, resource_link= reverse('course:view_topic',args=[self.object.slug]), |
658 | actor=self.request.user, users = self.object.subject.course.students.all() ) | 682 | actor=self.request.user, users = self.object.subject.course.students.all() ) |
683 | + | ||
684 | + self.log_context['topic_id'] = self.object.id | ||
685 | + self.log_context['topic_name'] = self.object.name | ||
686 | + self.log_context['topic_slug'] = self.object.slug | ||
687 | + self.log_context['subject_id'] = self.object.subject.id | ||
688 | + self.log_context['subject_name'] = self.object.subject.name | ||
689 | + self.log_context['subject_slug'] = self.object.subject.slug | ||
690 | + self.log_context['course_id'] = self.object.subject.course.id | ||
691 | + self.log_context['course_name'] = self.object.subject.course.name | ||
692 | + self.log_context['course_slug'] = self.object.subject.course.slug | ||
693 | + self.log_context['course_category_id'] = self.object.subject.course.category.id | ||
694 | + self.log_context['course_category_name'] = self.object.subject.course.category.name | ||
695 | + | ||
696 | + super(CreateTopicView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
659 | 697 | ||
660 | return super(CreateTopicView, self).form_valid(form) | 698 | return super(CreateTopicView, self).form_valid(form) |
661 | 699 | ||
662 | -class UpdateTopicView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | 700 | +class UpdateTopicView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.UpdateView): |
701 | + log_component = "course" | ||
702 | + log_resource = "topic" | ||
703 | + log_action = "create" | ||
704 | + log_context = {} | ||
663 | 705 | ||
664 | allowed_roles = ['professor','system_admin'] | 706 | allowed_roles = ['professor','system_admin'] |
665 | login_url = reverse_lazy("core:home") | 707 | login_url = reverse_lazy("core:home") |
@@ -689,6 +731,25 @@ class UpdateTopicView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | @@ -689,6 +731,25 @@ class UpdateTopicView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | ||
689 | context['subjects'] = topic.subject.course.subjects.all() | 731 | context['subjects'] = topic.subject.course.subjects.all() |
690 | return context | 732 | return context |
691 | 733 | ||
734 | + def form_valid(self, form): | ||
735 | + self.object = form.save() | ||
736 | + | ||
737 | + self.log_context['topic_id'] = self.object.id | ||
738 | + self.log_context['topic_name'] = self.object.name | ||
739 | + self.log_context['topic_slug'] = self.object.slug | ||
740 | + self.log_context['subject_id'] = self.object.subject.id | ||
741 | + self.log_context['subject_name'] = self.object.subject.name | ||
742 | + self.log_context['subject_slug'] = self.object.subject.slug | ||
743 | + self.log_context['course_id'] = self.object.subject.course.id | ||
744 | + self.log_context['course_name'] = self.object.subject.course.name | ||
745 | + self.log_context['course_slug'] = self.object.subject.course.slug | ||
746 | + self.log_context['course_category_id'] = self.object.subject.course.category.id | ||
747 | + self.log_context['course_category_name'] = self.object.subject.course.category.name | ||
748 | + | ||
749 | + super(UpdateTopicView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
750 | + | ||
751 | + return super(UpdateTopicView, self).form_valid(form) | ||
752 | + | ||
692 | class CreateSubjectView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.edit.CreateView): | 753 | class CreateSubjectView(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.edit.CreateView): |
693 | log_component = "course" | 754 | log_component = "course" |
694 | log_resource = "subject" | 755 | log_resource = "subject" |
@@ -739,7 +800,11 @@ class CreateSubjectView(LoginRequiredMixin, HasRoleMixin, LogMixin, Notification | @@ -739,7 +800,11 @@ class CreateSubjectView(LoginRequiredMixin, HasRoleMixin, LogMixin, Notification | ||
739 | return super(CreateSubjectView, self).form_valid(form) | 800 | return super(CreateSubjectView, self).form_valid(form) |
740 | 801 | ||
741 | 802 | ||
742 | -class UpdateSubjectView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | 803 | +class UpdateSubjectView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.UpdateView): |
804 | + log_component = "course" | ||
805 | + log_resource = "subject" | ||
806 | + log_action = "update" | ||
807 | + log_context = {} | ||
743 | 808 | ||
744 | allowed_roles = ['professor', 'system_admin'] | 809 | allowed_roles = ['professor', 'system_admin'] |
745 | login_url = reverse_lazy("core:home") | 810 | login_url = reverse_lazy("core:home") |
@@ -753,6 +818,22 @@ class UpdateSubjectView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | @@ -753,6 +818,22 @@ class UpdateSubjectView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | ||
753 | return self.handle_no_permission() | 818 | return self.handle_no_permission() |
754 | return super(UpdateSubjectView, self).dispatch(*args, **kwargs) | 819 | return super(UpdateSubjectView, self).dispatch(*args, **kwargs) |
755 | 820 | ||
821 | + def form_valid(self, form): | ||
822 | + self.object = form.save() | ||
823 | + | ||
824 | + self.log_context['subject_id'] = self.object.id | ||
825 | + self.log_context['subject_name'] = self.object.name | ||
826 | + self.log_context['subject_slug'] = self.object.slug | ||
827 | + self.log_context['course_id'] = self.object.course.id | ||
828 | + self.log_context['course_name'] = self.object.course.name | ||
829 | + self.log_context['course_slug'] = self.object.course.slug | ||
830 | + self.log_context['course_category_id'] = self.object.course.category.id | ||
831 | + self.log_context['course_category_name'] = self.object.course.category.name | ||
832 | + | ||
833 | + super(UpdateSubjectView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
834 | + | ||
835 | + return super(UpdateSubjectView, self).form_valid(form) | ||
836 | + | ||
756 | def get_object(self, queryset=None): | 837 | def get_object(self, queryset=None): |
757 | context = get_object_or_404(Subject, slug = self.kwargs.get('slug')) | 838 | context = get_object_or_404(Subject, slug = self.kwargs.get('slug')) |
758 | return context | 839 | return context |
@@ -769,7 +850,11 @@ class UpdateSubjectView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | @@ -769,7 +850,11 @@ class UpdateSubjectView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | ||
769 | context['subjects'] = self.object.course.subjects.all() | 850 | context['subjects'] = self.object.course.subjects.all() |
770 | return context | 851 | return context |
771 | 852 | ||
772 | -class DeleteSubjectView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | 853 | +class DeleteSubjectView(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.DeleteView): |
854 | + log_component = "course" | ||
855 | + log_resource = "subject" | ||
856 | + log_action = "delete" | ||
857 | + log_context = {} | ||
773 | 858 | ||
774 | allowed_roles = ['professor', 'system_admin'] | 859 | allowed_roles = ['professor', 'system_admin'] |
775 | login_url = reverse_lazy("core:home") | 860 | login_url = reverse_lazy("core:home") |
@@ -783,7 +868,6 @@ class DeleteSubjectView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | @@ -783,7 +868,6 @@ class DeleteSubjectView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | ||
783 | return self.handle_no_permission() | 868 | return self.handle_no_permission() |
784 | return super(DeleteSubjectView, self).dispatch(*args, **kwargs) | 869 | return super(DeleteSubjectView, self).dispatch(*args, **kwargs) |
785 | 870 | ||
786 | - | ||
787 | def get_context_data(self, **kwargs): | 871 | def get_context_data(self, **kwargs): |
788 | context = super(DeleteSubjectView, self).get_context_data(**kwargs) | 872 | context = super(DeleteSubjectView, self).get_context_data(**kwargs) |
789 | context['course'] = self.object.course | 873 | context['course'] = self.object.course |
@@ -794,9 +878,21 @@ class DeleteSubjectView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | @@ -794,9 +878,21 @@ class DeleteSubjectView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | ||
794 | return context | 878 | return context |
795 | 879 | ||
796 | def get_success_url(self): | 880 | def get_success_url(self): |
881 | + self.log_context['subject_id'] = self.object.id | ||
882 | + self.log_context['subject_name'] = self.object.name | ||
883 | + self.log_context['subject_slug'] = self.object.slug | ||
884 | + self.log_context['course_id'] = self.object.course.id | ||
885 | + self.log_context['course_name'] = self.object.course.name | ||
886 | + self.log_context['course_slug'] = self.object.course.slug | ||
887 | + self.log_context['course_category_id'] = self.object.course.category.id | ||
888 | + self.log_context['course_category_name'] = self.object.course.category.name | ||
889 | + | ||
890 | + super(DeleteSubjectView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
891 | + | ||
797 | return reverse_lazy('course:view', kwargs={'slug' : self.object.course.slug}) | 892 | return reverse_lazy('course:view', kwargs={'slug' : self.object.course.slug}) |
798 | 893 | ||
799 | @login_required | 894 | @login_required |
895 | +@log_decorator("course", "subscribe", "subject") | ||
800 | def subscribe_subject(request, slug): | 896 | def subscribe_subject(request, slug): |
801 | subject = get_object_or_404(Subject, slug = slug) | 897 | subject = get_object_or_404(Subject, slug = slug) |
802 | 898 | ||
@@ -804,6 +900,18 @@ def subscribe_subject(request, slug): | @@ -804,6 +900,18 @@ def subscribe_subject(request, slug): | ||
804 | subject.students.add(request.user) | 900 | subject.students.add(request.user) |
805 | 901 | ||
806 | if request.user in subject.students.all(): | 902 | if request.user in subject.students.all(): |
903 | + log_context = {} | ||
904 | + log_context['subject_id'] = subject.id | ||
905 | + log_context['subject_name'] = subject.name | ||
906 | + log_context['subject_slug'] = subject.slug | ||
907 | + log_context['course_id'] = subject.course.id | ||
908 | + log_context['course_name'] = subject.course.name | ||
909 | + log_context['course_slug'] = subject.course.slug | ||
910 | + log_context['course_category_id'] = subject.course.category.id | ||
911 | + log_context['course_category_name'] = subject.course.category.name | ||
912 | + | ||
913 | + request.log_context = log_context | ||
914 | + | ||
807 | return JsonResponse({"status": "ok", "message": _("Successfully subscribed to the subject!")}) | 915 | return JsonResponse({"status": "ok", "message": _("Successfully subscribed to the subject!")}) |
808 | else: | 916 | else: |
809 | return JsonResponse({"status": "erro", "message": _("An error has occured. Could not subscribe to this subject, try again later")}) | 917 | return JsonResponse({"status": "erro", "message": _("An error has occured. Could not subscribe to this subject, try again later")}) |
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 | }); |
forum/static/js/forum.js
@@ -74,6 +74,8 @@ function setForumCreateFormSubmit(topic) { | @@ -74,6 +74,8 @@ function setForumCreateFormSubmit(topic) { | ||
74 | success: function (data) { | 74 | success: function (data) { |
75 | $(".topic_" + topic).find('.foruns_list').append("<li><i class='fa fa-commenting' aria-hidden='true'></i> <a id='forum_"+data.forum_id+"' href='"+data.url+"'> "+data.name+"</a></li>"); | 75 | $(".topic_" + topic).find('.foruns_list').append("<li><i class='fa fa-commenting' aria-hidden='true'></i> <a id='forum_"+data.forum_id+"' href='"+data.url+"'> "+data.name+"</a></li>"); |
76 | 76 | ||
77 | + alertify.success(data.message); | ||
78 | + | ||
77 | $("#createForum").modal('hide'); | 79 | $("#createForum").modal('hide'); |
78 | }, | 80 | }, |
79 | error: function(data) { | 81 | error: function(data) { |
@@ -221,6 +223,8 @@ function delete_post(url, post) { | @@ -221,6 +223,8 @@ function delete_post(url, post) { | ||
221 | }, | 223 | }, |
222 | url: url, | 224 | url: url, |
223 | success: function(data) { | 225 | success: function(data) { |
226 | + alertify.success(data); | ||
227 | + | ||
224 | $("#post_"+post).remove(); | 228 | $("#post_"+post).remove(); |
225 | } | 229 | } |
226 | }); | 230 | }); |
forum/templates/forum/forum_form.html
@@ -15,21 +15,21 @@ | @@ -15,21 +15,21 @@ | ||
15 | <label for="{{ field.auto_id }}">{{ field.label }}</label> | 15 | <label for="{{ field.auto_id }}">{{ field.label }}</label> |
16 | {% render_field field %} | 16 | {% render_field field %} |
17 | <span class="help-block">{{ field.help_text }}</span> | 17 | <span class="help-block">{{ field.help_text }}</span> |
18 | - {% if field.errors %} | ||
19 | - <div class="row"> | ||
20 | - <br /> | ||
21 | - <div class="alert alert-danger alert-dismissible" role="alert"> | ||
22 | - <button type="button" class="close" data-dismiss="alert" aria-label="Close"> | ||
23 | - <span aria-hidden="true">×</span> | ||
24 | - </button> | ||
25 | - <ul> | ||
26 | - {% for error in field.errors %} | ||
27 | - <li>{{ error }}</li> | ||
28 | - {% endfor %} | ||
29 | - </ul> | ||
30 | - </div> | 18 | + {% endif %} |
19 | + {% if field.errors %} | ||
20 | + <div class="row"> | ||
21 | + <br /> | ||
22 | + <div class="alert alert-danger alert-dismissible" role="alert"> | ||
23 | + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> | ||
24 | + <span aria-hidden="true">×</span> | ||
25 | + </button> | ||
26 | + <ul> | ||
27 | + {% for error in field.errors %} | ||
28 | + <li>{{ error }}</li> | ||
29 | + {% endfor %} | ||
30 | + </ul> | ||
31 | </div> | 31 | </div> |
32 | - {% endif %} | 32 | + </div> |
33 | {% endif %} | 33 | {% endif %} |
34 | </div> | 34 | </div> |
35 | {% endfor %} | 35 | {% endfor %} |
forum/templates/post/post_render.html
@@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
8 | <a href="javascript:answer('{{ post.id }}', '{% url 'course:forum:reply_post' %}');"> | 8 | <a href="javascript:answer('{{ post.id }}', '{% url 'course:forum:reply_post' %}');"> |
9 | <i class="material-icons">{% trans 'reply' %}</i> | 9 | <i class="material-icons">{% trans 'reply' %}</i> |
10 | </a> | 10 | </a> |
11 | - {% if request.user|has_role:'system_admin' or request.user|has_role:'professor' and request.user == post.user %} | 11 | + {% if request.user|has_role:'system_admin' or request.user == post.user %} |
12 | {% csrf_token %} | 12 | {% csrf_token %} |
13 | <div class="btn-group icon-more-horiz"> | 13 | <div class="btn-group icon-more-horiz"> |
14 | <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | 14 | <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> |
forum/views.py
@@ -18,7 +18,7 @@ from core.models import Action, Resource | @@ -18,7 +18,7 @@ from core.models import Action, Resource | ||
18 | 18 | ||
19 | from .forms import ForumForm, PostForm, PostAnswerForm | 19 | from .forms import ForumForm, PostForm, PostAnswerForm |
20 | 20 | ||
21 | -from core.mixins import NotificationMixin | 21 | +from core.mixins import LogMixin, NotificationMixin |
22 | 22 | ||
23 | """ | 23 | """ |
24 | Forum Section | 24 | Forum Section |
@@ -44,7 +44,12 @@ class ForumIndex(LoginRequiredMixin, generic.ListView): | @@ -44,7 +44,12 @@ class ForumIndex(LoginRequiredMixin, generic.ListView): | ||
44 | 44 | ||
45 | return context | 45 | return context |
46 | 46 | ||
47 | -class CreateForumView(LoginRequiredMixin, HasRoleMixin, generic.edit.CreateView, NotificationMixin): | 47 | +class CreateForumView(LoginRequiredMixin, HasRoleMixin, generic.edit.CreateView, LogMixin, NotificationMixin): |
48 | + log_component = "forum" | ||
49 | + log_action = "create" | ||
50 | + log_resource = "forum" | ||
51 | + log_context = {} | ||
52 | + | ||
48 | allowed_roles = ['professor', 'system_admin'] | 53 | allowed_roles = ['professor', 'system_admin'] |
49 | 54 | ||
50 | login_url = reverse_lazy("core:home") | 55 | login_url = reverse_lazy("core:home") |
@@ -67,14 +72,36 @@ class CreateForumView(LoginRequiredMixin, HasRoleMixin, generic.edit.CreateView, | @@ -67,14 +72,36 @@ class CreateForumView(LoginRequiredMixin, HasRoleMixin, generic.edit.CreateView, | ||
67 | super(CreateForumView, self).createNotification("Forum "+ self.object.name + " was created", | 72 | super(CreateForumView, self).createNotification("Forum "+ self.object.name + " was created", |
68 | resource_name=self.object.name, resource_link= reverse('course:forum:view', args=[self.object.slug]), | 73 | resource_name=self.object.name, resource_link= reverse('course:forum:view', args=[self.object.slug]), |
69 | actor=self.request.user, users = self.object.topic.subject.students.all() ) | 74 | actor=self.request.user, users = self.object.topic.subject.students.all() ) |
75 | + | ||
76 | + self.log_context['forum_id'] = self.object.id | ||
77 | + self.log_context['forum_name'] = self.object.name | ||
78 | + self.log_context['topic_id'] = self.object.topic.id | ||
79 | + self.log_context['topic_name'] = self.object.topic.name | ||
80 | + self.log_context['topic_slug'] = self.object.topic.slug | ||
81 | + self.log_context['subject_id'] = self.object.topic.subject.id | ||
82 | + self.log_context['subject_name'] = self.object.topic.subject.name | ||
83 | + self.log_context['subject_slug'] = self.object.topic.subject.slug | ||
84 | + self.log_context['course_id'] = self.object.topic.subject.course.id | ||
85 | + self.log_context['course_name'] = self.object.topic.subject.course.name | ||
86 | + self.log_context['course_slug'] = self.object.topic.subject.course.slug | ||
87 | + self.log_context['course_category_id'] = self.object.topic.subject.course.category.id | ||
88 | + self.log_context['course_category_name'] = self.object.topic.subject.course.category.name | ||
89 | + | ||
90 | + super(CreateForumView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
91 | + | ||
70 | return self.success_url | 92 | return self.success_url |
71 | 93 | ||
72 | def render_forum(request, forum): | 94 | def render_forum(request, forum): |
73 | last_forum = get_object_or_404(Forum, id = forum) | 95 | last_forum = get_object_or_404(Forum, id = forum) |
74 | 96 | ||
75 | - return JsonResponse({'url': str(reverse_lazy('course:forum:view', args = (), kwargs = {'slug': last_forum.slug})), 'forum_id': str(forum), 'name': str(last_forum.name)}) | 97 | + return JsonResponse({'url': str(reverse_lazy('course:forum:view', args = (), kwargs = {'slug': last_forum.slug})), 'forum_id': str(forum), 'name': str(last_forum.name), 'message': _('Forum created successfully!')}) |
98 | + | ||
99 | +class UpdateForumView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView, LogMixin): | ||
100 | + log_component = "forum" | ||
101 | + log_action = "update" | ||
102 | + log_resource = "forum" | ||
103 | + log_context = {} | ||
76 | 104 | ||
77 | -class UpdateForumView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | ||
78 | allowed_roles = ['professor', 'system_admin'] | 105 | allowed_roles = ['professor', 'system_admin'] |
79 | 106 | ||
80 | login_url = reverse_lazy("core:home") | 107 | login_url = reverse_lazy("core:home") |
@@ -97,6 +124,22 @@ class UpdateForumView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | @@ -97,6 +124,22 @@ class UpdateForumView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): | ||
97 | 124 | ||
98 | def get_success_url(self): | 125 | def get_success_url(self): |
99 | self.success_url = reverse('course:forum:render_edit_forum', args = (self.object.id, )) | 126 | self.success_url = reverse('course:forum:render_edit_forum', args = (self.object.id, )) |
127 | + | ||
128 | + self.log_context['forum_id'] = self.object.id | ||
129 | + self.log_context['forum_name'] = self.object.name | ||
130 | + self.log_context['topic_id'] = self.object.topic.id | ||
131 | + self.log_context['topic_name'] = self.object.topic.name | ||
132 | + self.log_context['topic_slug'] = self.object.topic.slug | ||
133 | + self.log_context['subject_id'] = self.object.topic.subject.id | ||
134 | + self.log_context['subject_name'] = self.object.topic.subject.name | ||
135 | + self.log_context['subject_slug'] = self.object.topic.subject.slug | ||
136 | + self.log_context['course_id'] = self.object.topic.subject.course.id | ||
137 | + self.log_context['course_name'] = self.object.topic.subject.course.name | ||
138 | + self.log_context['course_slug'] = self.object.topic.subject.course.slug | ||
139 | + self.log_context['course_category_id'] = self.object.topic.subject.course.category.id | ||
140 | + self.log_context['course_category_name'] = self.object.topic.subject.course.category.name | ||
141 | + | ||
142 | + super(UpdateForumView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
100 | 143 | ||
101 | return self.success_url | 144 | return self.success_url |
102 | 145 | ||
@@ -108,7 +151,12 @@ def render_edit_forum(request, forum): | @@ -108,7 +151,12 @@ def render_edit_forum(request, forum): | ||
108 | 151 | ||
109 | return render(request, 'forum/render_forum.html', context) | 152 | return render(request, 'forum/render_forum.html', context) |
110 | 153 | ||
111 | -class ForumDeleteView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | 154 | +class ForumDeleteView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView, LogMixin): |
155 | + log_component = "forum" | ||
156 | + log_action = "delete" | ||
157 | + log_resource = "forum" | ||
158 | + log_context = {} | ||
159 | + | ||
112 | allowed_roles = ['professor', 'system_admin'] | 160 | allowed_roles = ['professor', 'system_admin'] |
113 | 161 | ||
114 | login_url = reverse_lazy("core:home") | 162 | login_url = reverse_lazy("core:home") |
@@ -116,7 +164,6 @@ class ForumDeleteView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | @@ -116,7 +164,6 @@ class ForumDeleteView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | ||
116 | 164 | ||
117 | model = Forum | 165 | model = Forum |
118 | pk_url_kwarg = 'pk' | 166 | pk_url_kwarg = 'pk' |
119 | - success_url = reverse_lazy('course:forum:deleted_forum') | ||
120 | 167 | ||
121 | def dispatch(self, *args, **kwargs): | 168 | def dispatch(self, *args, **kwargs): |
122 | forum = get_object_or_404(Forum, id = self.kwargs.get('pk')) | 169 | forum = get_object_or_404(Forum, id = self.kwargs.get('pk')) |
@@ -126,10 +173,34 @@ class ForumDeleteView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | @@ -126,10 +173,34 @@ class ForumDeleteView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): | ||
126 | 173 | ||
127 | return super(ForumDeleteView, self).dispatch(*args, **kwargs) | 174 | return super(ForumDeleteView, self).dispatch(*args, **kwargs) |
128 | 175 | ||
176 | + def get_success_url(self): | ||
177 | + self.log_context['forum_id'] = self.object.id | ||
178 | + self.log_context['forum_name'] = self.object.name | ||
179 | + self.log_context['topic_id'] = self.object.topic.id | ||
180 | + self.log_context['topic_name'] = self.object.topic.name | ||
181 | + self.log_context['topic_slug'] = self.object.topic.slug | ||
182 | + self.log_context['subject_id'] = self.object.topic.subject.id | ||
183 | + self.log_context['subject_name'] = self.object.topic.subject.name | ||
184 | + self.log_context['subject_slug'] = self.object.topic.subject.slug | ||
185 | + self.log_context['course_id'] = self.object.topic.subject.course.id | ||
186 | + self.log_context['course_name'] = self.object.topic.subject.course.name | ||
187 | + self.log_context['course_slug'] = self.object.topic.subject.course.slug | ||
188 | + self.log_context['course_category_id'] = self.object.topic.subject.course.category.id | ||
189 | + self.log_context['course_category_name'] = self.object.topic.subject.course.category.name | ||
190 | + | ||
191 | + super(ForumDeleteView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
192 | + | ||
193 | + return reverse_lazy('course:forum:deleted_forum') | ||
194 | + | ||
129 | def forum_deleted(request): | 195 | def forum_deleted(request): |
130 | return HttpResponse(_("Forum deleted successfully.")) | 196 | return HttpResponse(_("Forum deleted successfully.")) |
131 | 197 | ||
132 | -class ForumDetailView(LoginRequiredMixin, generic.DetailView): | 198 | +class ForumDetailView(LoginRequiredMixin, LogMixin, generic.DetailView): |
199 | + log_component = "forum" | ||
200 | + log_action = "viewed" | ||
201 | + log_resource = "forum" | ||
202 | + log_context = {} | ||
203 | + | ||
133 | login_url = reverse_lazy("core:home") | 204 | login_url = reverse_lazy("core:home") |
134 | redirect_field_name = 'next' | 205 | redirect_field_name = 'next' |
135 | 206 | ||
@@ -143,6 +214,22 @@ class ForumDetailView(LoginRequiredMixin, generic.DetailView): | @@ -143,6 +214,22 @@ class ForumDetailView(LoginRequiredMixin, generic.DetailView): | ||
143 | if(not has_object_permission('view_forum', self.request.user, forum)): | 214 | if(not has_object_permission('view_forum', self.request.user, forum)): |
144 | return self.handle_no_permission() | 215 | return self.handle_no_permission() |
145 | 216 | ||
217 | + self.log_context['forum_id'] = forum.id | ||
218 | + self.log_context['forum_name'] = forum.name | ||
219 | + self.log_context['topic_id'] = forum.topic.id | ||
220 | + self.log_context['topic_name'] = forum.topic.name | ||
221 | + self.log_context['topic_slug'] = forum.topic.slug | ||
222 | + self.log_context['subject_id'] = forum.topic.subject.id | ||
223 | + self.log_context['subject_name'] = forum.topic.subject.name | ||
224 | + self.log_context['subject_slug'] = forum.topic.subject.slug | ||
225 | + self.log_context['course_id'] = forum.topic.subject.course.id | ||
226 | + self.log_context['course_name'] = forum.topic.subject.course.name | ||
227 | + self.log_context['course_slug'] = forum.topic.subject.course.slug | ||
228 | + self.log_context['course_category_id'] = forum.topic.subject.course.category.id | ||
229 | + self.log_context['course_category_name'] = forum.topic.subject.course.category.name | ||
230 | + | ||
231 | + super(ForumDetailView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
232 | + | ||
146 | return super(ForumDetailView, self).dispatch(*args, **kwargs) | 233 | return super(ForumDetailView, self).dispatch(*args, **kwargs) |
147 | 234 | ||
148 | def get_context_data(self, **kwargs): | 235 | def get_context_data(self, **kwargs): |
@@ -195,7 +282,12 @@ def load_posts(request, forum_id): | @@ -195,7 +282,12 @@ def load_posts(request, forum_id): | ||
195 | 282 | ||
196 | return JsonResponse({'num_pages': paginator.num_pages, 'page': page_obj.number, 'btn_text': _('Load more posts'), 'html': html}) | 283 | return JsonResponse({'num_pages': paginator.num_pages, 'page': page_obj.number, 'btn_text': _('Load more posts'), 'html': html}) |
197 | 284 | ||
198 | -class CreatePostView(LoginRequiredMixin, generic.edit.CreateView, NotificationMixin): | 285 | +class CreatePostView(LoginRequiredMixin, generic.edit.CreateView, LogMixin, NotificationMixin): |
286 | + log_component = "forum" | ||
287 | + log_action = "create" | ||
288 | + log_resource = "post" | ||
289 | + log_context = {} | ||
290 | + | ||
199 | login_url = reverse_lazy("core:home") | 291 | login_url = reverse_lazy("core:home") |
200 | redirect_field_name = 'next' | 292 | redirect_field_name = 'next' |
201 | 293 | ||
@@ -211,6 +303,23 @@ class CreatePostView(LoginRequiredMixin, generic.edit.CreateView, NotificationMi | @@ -211,6 +303,23 @@ class CreatePostView(LoginRequiredMixin, generic.edit.CreateView, NotificationMi | ||
211 | resource_slug = self.object.forum.slug, actor=self.request.user, users= self.object.forum.topic.subject.students.all(), | 303 | resource_slug = self.object.forum.slug, actor=self.request.user, users= self.object.forum.topic.subject.students.all(), |
212 | resource_link = reverse('course:forum:view', args=[self.object.forum.slug])) | 304 | resource_link = reverse('course:forum:view', args=[self.object.forum.slug])) |
213 | 305 | ||
306 | + self.log_context['post_id'] = self.object.id | ||
307 | + self.log_context['forum_id'] = self.object.forum.id | ||
308 | + self.log_context['forum_name'] = self.object.forum.name | ||
309 | + self.log_context['topic_id'] = self.object.forum.topic.id | ||
310 | + self.log_context['topic_name'] = self.object.forum.topic.name | ||
311 | + self.log_context['topic_slug'] = self.object.forum.topic.slug | ||
312 | + self.log_context['subject_id'] = self.object.forum.topic.subject.id | ||
313 | + self.log_context['subject_name'] = self.object.forum.topic.subject.name | ||
314 | + self.log_context['subject_slug'] = self.object.forum.topic.subject.slug | ||
315 | + self.log_context['course_id'] = self.object.forum.topic.subject.course.id | ||
316 | + self.log_context['course_name'] = self.object.forum.topic.subject.course.name | ||
317 | + self.log_context['course_slug'] = self.object.forum.topic.subject.course.slug | ||
318 | + self.log_context['course_category_id'] = self.object.forum.topic.subject.course.category.id | ||
319 | + self.log_context['course_category_name'] = self.object.forum.topic.subject.course.category.name | ||
320 | + | ||
321 | + super(CreatePostView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
322 | + | ||
214 | return super(CreatePostView, self).form_valid(form) | 323 | return super(CreatePostView, self).form_valid(form) |
215 | 324 | ||
216 | def get_success_url(self): | 325 | def get_success_url(self): |
@@ -228,7 +337,12 @@ def render_post(request, post): | @@ -228,7 +337,12 @@ def render_post(request, post): | ||
228 | 337 | ||
229 | return JsonResponse({'new_id': last_post.id, 'html': html}) | 338 | return JsonResponse({'new_id': last_post.id, 'html': html}) |
230 | 339 | ||
231 | -class PostUpdateView(LoginRequiredMixin, generic.UpdateView): | 340 | +class PostUpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView): |
341 | + log_component = "forum" | ||
342 | + log_action = "update" | ||
343 | + log_resource = "post" | ||
344 | + log_context = {} | ||
345 | + | ||
232 | login_url = reverse_lazy("core:home") | 346 | login_url = reverse_lazy("core:home") |
233 | redirect_field_name = 'next' | 347 | redirect_field_name = 'next' |
234 | 348 | ||
@@ -236,18 +350,66 @@ class PostUpdateView(LoginRequiredMixin, generic.UpdateView): | @@ -236,18 +350,66 @@ class PostUpdateView(LoginRequiredMixin, generic.UpdateView): | ||
236 | model = Post | 350 | model = Post |
237 | template_name = "post/post_update_form.html" | 351 | template_name = "post/post_update_form.html" |
238 | 352 | ||
353 | + def form_valid(self, form): | ||
354 | + self.object = form.save() | ||
355 | + | ||
356 | + self.log_context['post_id'] = self.object.id | ||
357 | + self.log_context['forum_id'] = self.object.forum.id | ||
358 | + self.log_context['forum_name'] = self.object.forum.name | ||
359 | + self.log_context['topic_id'] = self.object.forum.topic.id | ||
360 | + self.log_context['topic_name'] = self.object.forum.topic.name | ||
361 | + self.log_context['topic_slug'] = self.object.forum.topic.slug | ||
362 | + self.log_context['subject_id'] = self.object.forum.topic.subject.id | ||
363 | + self.log_context['subject_name'] = self.object.forum.topic.subject.name | ||
364 | + self.log_context['subject_slug'] = self.object.forum.topic.subject.slug | ||
365 | + self.log_context['course_id'] = self.object.forum.topic.subject.course.id | ||
366 | + self.log_context['course_name'] = self.object.forum.topic.subject.course.name | ||
367 | + self.log_context['course_slug'] = self.object.forum.topic.subject.course.slug | ||
368 | + self.log_context['course_category_id'] = self.object.forum.topic.subject.course.category.id | ||
369 | + self.log_context['course_category_name'] = self.object.forum.topic.subject.course.category.name | ||
370 | + | ||
371 | + super(PostUpdateView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
372 | + | ||
373 | + return super(PostUpdateView, self).form_valid(form) | ||
374 | + | ||
239 | def get_success_url(self): | 375 | def get_success_url(self): |
240 | self.success_url = reverse('course:forum:render_post', args = (self.object.id, )) | 376 | self.success_url = reverse('course:forum:render_post', args = (self.object.id, )) |
241 | 377 | ||
242 | return self.success_url | 378 | return self.success_url |
243 | 379 | ||
244 | -class PostDeleteView(LoginRequiredMixin, generic.DeleteView): | 380 | +class PostDeleteView(LoginRequiredMixin, LogMixin, generic.DeleteView): |
381 | + log_component = "forum" | ||
382 | + log_action = "delete" | ||
383 | + log_resource = "post" | ||
384 | + log_context = {} | ||
385 | + | ||
245 | login_url = reverse_lazy("core:home") | 386 | login_url = reverse_lazy("core:home") |
246 | redirect_field_name = 'next' | 387 | redirect_field_name = 'next' |
247 | 388 | ||
248 | model = Post | 389 | model = Post |
249 | pk_url_kwarg = 'pk' | 390 | pk_url_kwarg = 'pk' |
250 | - success_url = reverse_lazy('course:forum:deleted_post') | 391 | + |
392 | + def get_success_url(self): | ||
393 | + self.success_url = reverse_lazy('course:forum:deleted_post') | ||
394 | + | ||
395 | + self.log_context['post_id'] = self.object.id | ||
396 | + self.log_context['forum_id'] = self.object.forum.id | ||
397 | + self.log_context['forum_name'] = self.object.forum.name | ||
398 | + self.log_context['topic_id'] = self.object.forum.topic.id | ||
399 | + self.log_context['topic_name'] = self.object.forum.topic.name | ||
400 | + self.log_context['topic_slug'] = self.object.forum.topic.slug | ||
401 | + self.log_context['subject_id'] = self.object.forum.topic.subject.id | ||
402 | + self.log_context['subject_name'] = self.object.forum.topic.subject.name | ||
403 | + self.log_context['subject_slug'] = self.object.forum.topic.subject.slug | ||
404 | + self.log_context['course_id'] = self.object.forum.topic.subject.course.id | ||
405 | + self.log_context['course_name'] = self.object.forum.topic.subject.course.name | ||
406 | + self.log_context['course_slug'] = self.object.forum.topic.subject.course.slug | ||
407 | + self.log_context['course_category_id'] = self.object.forum.topic.subject.course.category.id | ||
408 | + self.log_context['course_category_name'] = self.object.forum.topic.subject.course.category.name | ||
409 | + | ||
410 | + super(PostDeleteView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
411 | + | ||
412 | + return self.success_url | ||
251 | 413 | ||
252 | def post_deleted(request): | 414 | def post_deleted(request): |
253 | return HttpResponse(_("Post deleted successfully.")) | 415 | return HttpResponse(_("Post deleted successfully.")) |
@@ -308,7 +470,12 @@ class PostAnswerIndex(LoginRequiredMixin, generic.ListView): | @@ -308,7 +470,12 @@ class PostAnswerIndex(LoginRequiredMixin, generic.ListView): | ||
308 | 470 | ||
309 | return context | 471 | return context |
310 | 472 | ||
311 | -class CreatePostAnswerView(LoginRequiredMixin, generic.edit.CreateView): | 473 | +class CreatePostAnswerView(LoginRequiredMixin, LogMixin, generic.edit.CreateView): |
474 | + log_component = "forum" | ||
475 | + log_action = "create" | ||
476 | + log_resource = "post_answer" | ||
477 | + log_context = {} | ||
478 | + | ||
312 | login_url = reverse_lazy("core:home") | 479 | login_url = reverse_lazy("core:home") |
313 | redirect_field_name = 'next' | 480 | redirect_field_name = 'next' |
314 | 481 | ||
@@ -321,6 +488,25 @@ class CreatePostAnswerView(LoginRequiredMixin, generic.edit.CreateView): | @@ -321,6 +488,25 @@ class CreatePostAnswerView(LoginRequiredMixin, generic.edit.CreateView): | ||
321 | 488 | ||
322 | self.object.save() | 489 | self.object.save() |
323 | 490 | ||
491 | + self.log_context['post_answer_id'] = self.object.id | ||
492 | + self.log_context['post_id'] = self.object.post.id | ||
493 | + self.log_context['post_user_id'] = self.object.post.user.id | ||
494 | + self.log_context['post_user_name'] = self.object.post.user.name | ||
495 | + self.log_context['forum_id'] = self.object.post.forum.id | ||
496 | + self.log_context['forum_name'] = self.object.post.forum.name | ||
497 | + self.log_context['topic_id'] = self.object.post.forum.topic.id | ||
498 | + self.log_context['topic_name'] = self.object.post.forum.topic.name | ||
499 | + self.log_context['topic_slug'] = self.object.post.forum.topic.slug | ||
500 | + self.log_context['subject_id'] = self.object.post.forum.topic.subject.id | ||
501 | + self.log_context['subject_name'] = self.object.post.forum.topic.subject.name | ||
502 | + self.log_context['subject_slug'] = self.object.post.forum.topic.subject.slug | ||
503 | + self.log_context['course_id'] = self.object.post.forum.topic.subject.course.id | ||
504 | + self.log_context['course_name'] = self.object.post.forum.topic.subject.course.name | ||
505 | + self.log_context['course_slug'] = self.object.post.forum.topic.subject.course.slug | ||
506 | + self.log_context['course_category_id'] = self.object.post.forum.topic.subject.course.category.id | ||
507 | + self.log_context['course_category_name'] = self.object.post.forum.topic.subject.course.category.name | ||
508 | + | ||
509 | + super(CreatePostAnswerView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
324 | 510 | ||
325 | return super(CreatePostAnswerView, self).form_valid(form) | 511 | return super(CreatePostAnswerView, self).form_valid(form) |
326 | 512 | ||
@@ -339,7 +525,12 @@ def render_post_answer(request, answer): | @@ -339,7 +525,12 @@ def render_post_answer(request, answer): | ||
339 | 525 | ||
340 | return JsonResponse({'new_id': last_answer.id, 'html': html}) | 526 | return JsonResponse({'new_id': last_answer.id, 'html': html}) |
341 | 527 | ||
342 | -class PostAnswerUpdateView(LoginRequiredMixin, generic.UpdateView): | 528 | +class PostAnswerUpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView): |
529 | + log_component = "forum" | ||
530 | + log_action = "update" | ||
531 | + log_resource = "post_answer" | ||
532 | + log_context = {} | ||
533 | + | ||
343 | login_url = reverse_lazy("core:home") | 534 | login_url = reverse_lazy("core:home") |
344 | redirect_field_name = 'next' | 535 | redirect_field_name = 'next' |
345 | 536 | ||
@@ -350,16 +541,65 @@ class PostAnswerUpdateView(LoginRequiredMixin, generic.UpdateView): | @@ -350,16 +541,65 @@ class PostAnswerUpdateView(LoginRequiredMixin, generic.UpdateView): | ||
350 | 541 | ||
351 | def get_success_url(self): | 542 | def get_success_url(self): |
352 | self.success_url = reverse('course:forum:render_post_answer', args = (self.object.id, )) | 543 | self.success_url = reverse('course:forum:render_post_answer', args = (self.object.id, )) |
544 | + | ||
545 | + self.log_context['post_answer_id'] = self.object.id | ||
546 | + self.log_context['post_id'] = self.object.post.id | ||
547 | + self.log_context['post_user_id'] = self.object.post.user.id | ||
548 | + self.log_context['post_user_name'] = self.object.post.user.name | ||
549 | + self.log_context['forum_id'] = self.object.post.forum.id | ||
550 | + self.log_context['forum_name'] = self.object.post.forum.name | ||
551 | + self.log_context['topic_id'] = self.object.post.forum.topic.id | ||
552 | + self.log_context['topic_name'] = self.object.post.forum.topic.name | ||
553 | + self.log_context['topic_slug'] = self.object.post.forum.topic.slug | ||
554 | + self.log_context['subject_id'] = self.object.post.forum.topic.subject.id | ||
555 | + self.log_context['subject_name'] = self.object.post.forum.topic.subject.name | ||
556 | + self.log_context['subject_slug'] = self.object.post.forum.topic.subject.slug | ||
557 | + self.log_context['course_id'] = self.object.post.forum.topic.subject.course.id | ||
558 | + self.log_context['course_name'] = self.object.post.forum.topic.subject.course.name | ||
559 | + self.log_context['course_slug'] = self.object.post.forum.topic.subject.course.slug | ||
560 | + self.log_context['course_category_id'] = self.object.post.forum.topic.subject.course.category.id | ||
561 | + self.log_context['course_category_name'] = self.object.post.forum.topic.subject.course.category.name | ||
562 | + | ||
563 | + super(PostAnswerUpdateView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
353 | 564 | ||
354 | return self.success_url | 565 | return self.success_url |
355 | 566 | ||
356 | -class PostAnswerDeleteView(LoginRequiredMixin, generic.DeleteView): | 567 | +class PostAnswerDeleteView(LoginRequiredMixin, LogMixin, generic.DeleteView): |
568 | + log_component = "forum" | ||
569 | + log_action = "delete" | ||
570 | + log_resource = "post_answer" | ||
571 | + log_context = {} | ||
572 | + | ||
357 | login_url = reverse_lazy("core:home") | 573 | login_url = reverse_lazy("core:home") |
358 | redirect_field_name = 'next' | 574 | redirect_field_name = 'next' |
359 | 575 | ||
360 | model = PostAnswer | 576 | model = PostAnswer |
361 | - pk_url_kwarg = 'pk' | ||
362 | - success_url = reverse_lazy('course:forum:deleted_answer') | 577 | + pk_url_kwarg = 'pk' |
578 | + | ||
579 | + def get_success_url(self): | ||
580 | + self.success_url = reverse_lazy('course:forum:deleted_answer') | ||
581 | + | ||
582 | + self.log_context['post_answer_id'] = self.object.id | ||
583 | + self.log_context['post_id'] = self.object.post.id | ||
584 | + self.log_context['post_user_id'] = self.object.post.user.id | ||
585 | + self.log_context['post_user_name'] = self.object.post.user.name | ||
586 | + self.log_context['forum_id'] = self.object.post.forum.id | ||
587 | + self.log_context['forum_name'] = self.object.post.forum.name | ||
588 | + self.log_context['topic_id'] = self.object.post.forum.topic.id | ||
589 | + self.log_context['topic_name'] = self.object.post.forum.topic.name | ||
590 | + self.log_context['topic_slug'] = self.object.post.forum.topic.slug | ||
591 | + self.log_context['subject_id'] = self.object.post.forum.topic.subject.id | ||
592 | + self.log_context['subject_name'] = self.object.post.forum.topic.subject.name | ||
593 | + self.log_context['subject_slug'] = self.object.post.forum.topic.subject.slug | ||
594 | + self.log_context['course_id'] = self.object.post.forum.topic.subject.course.id | ||
595 | + self.log_context['course_name'] = self.object.post.forum.topic.subject.course.name | ||
596 | + self.log_context['course_slug'] = self.object.post.forum.topic.subject.course.slug | ||
597 | + self.log_context['course_category_id'] = self.object.post.forum.topic.subject.course.category.id | ||
598 | + self.log_context['course_category_name'] = self.object.post.forum.topic.subject.course.category.name | ||
599 | + | ||
600 | + super(PostAnswerDeleteView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context) | ||
601 | + | ||
602 | + return self.success_url | ||
363 | 603 | ||
364 | def answer_deleted(request): | 604 | def answer_deleted(request): |
365 | return HttpResponse(_("Post answer deleted successfully.")) | 605 | return HttpResponse(_("Post answer deleted successfully.")) |
366 | \ No newline at end of file | 606 | \ No newline at end of file |
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 | }); |
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 |