Commit 22b71966d2d9b9096da3fd33cc84c9d13d5a3873

Authored by Felipe Henrique de Almeida Bormann
1 parent 1b22fd60

removed matheuslins code, which is represented as the exercise app and checked i…

…f nothing else was affected when removing it
amadeus/settings.py
@@ -60,7 +60,6 @@ INSTALLED_APPS = [ @@ -60,7 +60,6 @@ INSTALLED_APPS = [
60 'poll', 60 'poll',
61 'links', 61 'links',
62 'files', 62 'files',
63 - 'exercise',  
64 63
65 ] 64 ]
66 65
amadeus/urls.py
@@ -23,7 +23,6 @@ urlpatterns = [ @@ -23,7 +23,6 @@ urlpatterns = [
23 url(r'^home/', include('app.urls', namespace = 'app')), 23 url(r'^home/', include('app.urls', namespace = 'app')),
24 url(r'^courses/', include('courses.urls', namespace = 'course')), 24 url(r'^courses/', include('courses.urls', namespace = 'course')),
25 url(r'^users/', include('users.urls', namespace = 'users')), 25 url(r'^users/', include('users.urls', namespace = 'users')),
26 - url(r'^exercise/', include('exercise.urls', namespace = 'exercise')),  
27 url(r'^admin/', admin.site.urls), 26 url(r'^admin/', admin.site.urls),
28 url(r'^', include('core.urls', namespace = 'core')), 27 url(r'^', include('core.urls', namespace = 'core')),
29 #API 28 #API
courses/templates/subject/form_view_student.html
1 -{% load static i18n list_topic_foruns permission_tags widget_tweaks professor_access list_topic_exercises %} 1 +{% load static i18n list_topic_foruns permission_tags widget_tweaks professor_access %}
2 {% professor_subject topic.subject user as professor_links %} 2 {% professor_subject topic.subject user as professor_links %}
3 3
4 {% block javascript %} 4 {% block javascript %}
courses/templates/topic/update.html
1 -{% load static i18n list_topic_foruns permission_tags widget_tweaks professor_access list_topic_exercises course_value_field %} 1 +{% load static i18n list_topic_foruns permission_tags widget_tweaks professor_access course_value_field %}
2 2
3 <form class="" id="form_topic_update_{{topic.slug}}" method="post" action=""> 3 <form class="" id="form_topic_update_{{topic.slug}}" method="post" action="">
4 {% csrf_token %} 4 {% csrf_token %}
@@ -84,7 +84,6 @@ @@ -84,7 +84,6 @@
84 <ul class="dropdown-menu" aria-labelledby="dLabel"> 84 <ul class="dropdown-menu" aria-labelledby="dLabel">
85 <li><a href="javascript:createForum('{% url 'course:forum:create' %}', '{{ topic.id }}')">{% trans 'Create Forum' %}</a></li> 85 <li><a href="javascript:createForum('{% url 'course:forum:create' %}', '{{ topic.id }}')">{% trans 'Create Forum' %}</a></li>
86 <li><a href="javascript:modal.get('{% url 'course:poll:create_poll' topic.slug%}','#poll','#requisicoes_ajax');">{% trans 'Create Poll' %}</a></li> 86 <li><a href="javascript:modal.get('{% url 'course:poll:create_poll' topic.slug%}','#poll','#requisicoes_ajax');">{% trans 'Create Poll' %}</a></li>
87 - <li><a href="javascript:modal.get('{% url 'course:exercise:create_exercise' topic.slug %}', '#createExercisesModal','#requisicoes_ajax')">{% trans 'Delivery Material' %}</a></li>  
88 <li><a href="{% url 'course:exam:create_exam' topic.slug %}">{% trans 'Create exam' %}</a></li> 87 <li><a href="{% url 'course:exam:create_exam' topic.slug %}">{% trans 'Create exam' %}</a></li>
89 </ul> 88 </ul>
90 </div> 89 </div>
courses/templates/topic/view.html
1 -{% load static i18n list_topic_foruns permission_tags widget_tweaks professor_access list_topic_exercises %} 1 +{% load static i18n list_topic_foruns permission_tags widget_tweaks professor_access %}
2 <!-- Block with Log info --> 2 <!-- Block with Log info -->
3 <input type="hidden" class="log_id" value="{{ topic_log_id }}" /> 3 <input type="hidden" class="log_id" value="{{ topic_log_id }}" />
4 <input type="hidden" class="log_url" value="{% url 'course:topic_log' topic.id %}" /> 4 <input type="hidden" class="log_url" value="{% url 'course:topic_log' topic.id %}" />
@@ -51,7 +51,7 @@ @@ -51,7 +51,7 @@
51 <ul class="dropdown-menu" aria-labelledby="dLabel"> 51 <ul class="dropdown-menu" aria-labelledby="dLabel">
52 <li><a href="javascript:createForum('{% url 'course:forum:create' %}', '{{ topic.id }}')">{% trans 'Create Forum' %}</a></li> 52 <li><a href="javascript:createForum('{% url 'course:forum:create' %}', '{{ topic.id }}')">{% trans 'Create Forum' %}</a></li>
53 <li><a href="javascript:modal.get('{% url 'course:poll:create_poll' topic.slug%}','#poll','#requisicoes_ajax');">{% trans 'Create Poll' %}</a></li> 53 <li><a href="javascript:modal.get('{% url 'course:poll:create_poll' topic.slug%}','#poll','#requisicoes_ajax');">{% trans 'Create Poll' %}</a></li>
54 - <li><a href="javascript:modal.get('{% url 'course:exercise:create_exercise' topic.slug %}', '#createExercisesModal','#requisicoes_ajax')">{% trans 'Delivery Material' %}</a></li> 54 +
55 <li><a href="{% url 'course:exam:create_exam' topic.slug %}">{% trans 'Create exam' %}</a></li> 55 <li><a href="{% url 'course:exam:create_exam' topic.slug %}">{% trans 'Create exam' %}</a></li>
56 </ul> 56 </ul>
57 </div> 57 </div>
@@ -61,7 +61,7 @@ @@ -61,7 +61,7 @@
61 <ul> 61 <ul>
62 {% list_topic_poll request topic %} 62 {% list_topic_poll request topic %}
63 {% list_topic_foruns request topic %} 63 {% list_topic_foruns request topic %}
64 - {% list_topic_exercise request topic %} 64 +
65 </ul> 65 </ul>
66 </div> 66 </div>
67 {% endif %} 67 {% endif %}
courses/urls.py
@@ -33,7 +33,6 @@ urlpatterns = [ @@ -33,7 +33,6 @@ urlpatterns = [
33 url(r'^upload-material/$', views.UploadMaterialView.as_view(), name='upload_material'), 33 url(r'^upload-material/$', views.UploadMaterialView.as_view(), name='upload_material'),
34 url(r'^subjects/file-material-view/(?P<slug>[\w_-]+)/$', views.FileMaterialView.as_view(), name='file_material_view'), 34 url(r'^subjects/file-material-view/(?P<slug>[\w_-]+)/$', views.FileMaterialView.as_view(), name='file_material_view'),
35 url(r'^links/',include('links.urls',namespace = 'links')), 35 url(r'^links/',include('links.urls',namespace = 'links')),
36 - url(r'^exercise/', include('exercise.urls', namespace='exercise')),  
37 url(r'^topic/(?P<topic>[\w_-]+)/$', views.topic_log, name='topic_log'), 36 url(r'^topic/(?P<topic>[\w_-]+)/$', views.topic_log, name='topic_log'),
38 url(r'^(?P<slug>[\w_-]+)/', include([ 37 url(r'^(?P<slug>[\w_-]+)/', include([
39 url(r'^$', views.CourseView.as_view(), name='view'), 38 url(r'^$', views.CourseView.as_view(), name='view'),
courses/views.py
@@ -16,7 +16,7 @@ from django.shortcuts import get_object_or_404 @@ -16,7 +16,7 @@ from django.shortcuts import get_object_or_404
16 from django.urls import reverse 16 from django.urls import reverse
17 from django.utils.translation import ugettext_lazy as _ 17 from django.utils.translation import ugettext_lazy as _
18 from django.views import generic 18 from django.views import generic
19 -from exercise.models import Exercise 19 +
20 from files.forms import FileForm 20 from files.forms import FileForm
21 from files.models import TopicFile 21 from files.models import TopicFile
22 from functools import reduce 22 from functools import reduce
@@ -623,7 +623,6 @@ class SubjectsView(AccessMixin, LogMixin, generic.ListView): @@ -623,7 +623,6 @@ class SubjectsView(AccessMixin, LogMixin, generic.ListView):
623 context['course'] = subject.course 623 context['course'] = subject.course
624 context['subject'] = subject 624 context['subject'] = subject
625 context['topics'] = Topic.objects.filter(subject = subject) 625 context['topics'] = Topic.objects.filter(subject = subject)
626 - context['exercise'] = Exercise.objects.filter(topic__subject=subject)  
627 context['title'] = subject.name 626 context['title'] = subject.name
628 if has_role(self.request.user,'professor') or has_role(self.request.user,'system_admin'): 627 if has_role(self.request.user,'professor') or has_role(self.request.user,'system_admin'):
629 context['files'] = TopicFile.objects.filter(professor__name = self.request.user.name) 628 context['files'] = TopicFile.objects.filter(professor__name = self.request.user.name)
exercise/__init__.py
exercise/admin.py
@@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
1 -from django.contrib import admin  
2 -from .models import Exercise  
3 -  
4 -class ExerciseAdmin(admin.ModelAdmin):  
5 - list_display = ['name_exercise']  
6 - search_fields = ['name_exercise']  
7 -  
8 -admin.site.register(Exercise, ExerciseAdmin)  
exercise/apps.py
@@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
1 -from django.apps import AppConfig  
2 -  
3 -  
4 -class ExerciseConfig(AppConfig):  
5 - name = 'exercise'  
exercise/forms.py
@@ -1,32 +0,0 @@ @@ -1,32 +0,0 @@
1 -from .models import Exercise  
2 -from django import forms  
3 -from django.core.exceptions import ValidationError, FieldError  
4 -from django.utils.translation import ugettext_lazy as _  
5 -import requests  
6 -  
7 -  
8 -class ExerciseForm(forms.ModelForm):  
9 -  
10 - def __init__(self, *args, **kwargs):  
11 - super(ExerciseForm, self).__init__(*args, **kwargs)  
12 - self.fields["allowed"].required = False  
13 - self.fields["allowed"].initial = False  
14 -  
15 - # def clean_allowed(self):  
16 - # if('allowed' in self.data):  
17 - # allowed = self.data['allowed']  
18 - # raise forms.ValidationError(_('It is required one these fields.'))  
19 - # return True  
20 -  
21 - class Meta:  
22 - model = Exercise  
23 - fields = ['name_exercise', 'description',  
24 - 'end_date', 'file', 'allowed']  
25 -  
26 -  
27 -class UpdateExerciseForm(forms.ModelForm):  
28 -  
29 - class Meta:  
30 - model = Exercise  
31 - fields = ['name_exercise', 'description',  
32 - 'end_date', 'file']  
exercise/locale/pt_BR/LC_MESSAGES/django.po
@@ -1,125 +0,0 @@ @@ -1,125 +0,0 @@
1 -# SOME DESCRIPTIVE TITLE.  
2 -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER  
3 -# This file is distributed under the same license as the PACKAGE package.  
4 -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.  
5 -#  
6 -#, fuzzy  
7 -msgid ""  
8 -msgstr ""  
9 -"Project-Id-Version: PACKAGE VERSION\n"  
10 -"Report-Msgid-Bugs-To: \n"  
11 -"POT-Creation-Date: 2016-11-24 00:05-0300\n"  
12 -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"  
13 -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"  
14 -"Language-Team: LANGUAGE <LL@li.org>\n"  
15 -"Language: \n"  
16 -"MIME-Version: 1.0\n"  
17 -"Content-Type: text/plain; charset=UTF-8\n"  
18 -"Content-Transfer-Encoding: 8bit\n"  
19 -"Plural-Forms: nplurals=2; plural=(n > 1);\n"  
20 -  
21 -#: .\models.py:24  
22 -msgid "Name"  
23 -msgstr "Nome"  
24 -  
25 -#: .\models.py:25 .\templates\exercise\card_topic_exercises.html:11  
26 -msgid "Description"  
27 -msgstr "Descrição"  
28 -  
29 -#: .\models.py:26 .\templates\exercise\card_topic_exercises.html:22  
30 -msgid "Delivery Date"  
31 -msgstr "Data de entrega"  
32 -  
33 -#: .\models.py:28  
34 -msgid "Topic"  
35 -msgstr "Tópico"  
36 -  
37 -#: .\models.py:29  
38 -msgid "Professors"  
39 -msgstr "Professores"  
40 -  
41 -#: .\models.py:30  
42 -msgid "Students"  
43 -msgstr "Estudantes"  
44 -  
45 -#: .\models.py:32  
46 -msgid "Type file"  
47 -msgstr "Tipo de arquivo"  
48 -  
49 -#: .\models.py:33  
50 -msgid "Allowed delivery after end date?"  
51 -msgstr "Permitido entregar após a data de término?"  
52 -  
53 -#: .\templates\exercise\card_list_user.html:23  
54 -#: .\templates\exercise\card_topic_exercises.html:26  
55 -msgid "Grade"  
56 -msgstr "Nota"  
57 -  
58 -#: .\templates\exercise\card_list_user.html:30  
59 -msgid "Give a grade"  
60 -msgstr "Dar a nota"  
61 -  
62 -#: .\templates\exercise\card_list_user.html:37  
63 -msgid "Delivery"  
64 -msgstr "Entregar"  
65 -  
66 -#: .\templates\exercise\card_list_user.html:45  
67 -msgid "Create"  
68 -msgstr "Criar"  
69 -  
70 -#: .\templates\exercise\card_list_user.html:52  
71 -msgid "Create a specific exercise"  
72 -msgstr "Criar um exercício específico"  
73 -  
74 -#: .\templates\exercise\card_topic_exercises.html:15  
75 -msgid "Don't have description"  
76 -msgstr "Não possui descrição"  
77 -  
78 -#: .\templates\exercise\card_topic_exercises.html:34  
79 -msgid "Not yet"  
80 -msgstr "Ainda não"  
81 -  
82 -#: .\templates\exercise\card_topic_exercises.html:41  
83 -msgid "File"  
84 -msgstr "Arquivo"  
85 -  
86 -#: .\templates\exercise\card_topic_exercises.html:45  
87 -msgid "Exercise not yet"  
88 -msgstr "Sem exercícios por enquanto"  
89 -  
90 -#: .\templates\exercise\card_topic_exercises.html:49  
91 -msgid "Teacher waiting corretion"  
92 -msgstr "Aguardando correção do professor"  
93 -  
94 -#: .\templates\exercise\create_exercise.html:8  
95 -msgid "Create a New Material"  
96 -msgstr "Criar um novo Material"  
97 -  
98 -#: .\templates\exercise\create_exercise.html:36  
99 -msgid "Choose your file..."  
100 -msgstr "Escolha seu arquivo..."  
101 -  
102 -#: .\templates\exercise\create_exercise.html:66  
103 -msgid "The file size shouldnt exceed 10MB"  
104 -msgstr "O tamanho do arquivo não pode exceder 10MB"  
105 -  
106 -#: .\templates\exercise\create_exercise.html:72  
107 -#: .\templates\exercise\delete_exercise.html:24  
108 -msgid "Close"  
109 -msgstr "Fechar"  
110 -  
111 -#: .\templates\exercise\create_exercise.html:73  
112 -msgid "Submit"  
113 -msgstr "Enviar"  
114 -  
115 -#: .\templates\exercise\delete_exercise.html:12  
116 -msgid "Delete Exercise"  
117 -msgstr "Apagar exercício"  
118 -  
119 -#: .\templates\exercise\delete_exercise.html:20  
120 -msgid "Are you sure to delete the exercise "  
121 -msgstr "Você tem certeza que quer deletar o exercício "  
122 -  
123 -#: .\templates\exercise\delete_exercise.html:25  
124 -msgid "Delete"  
125 -msgstr "Apagar"  
exercise/migrations/0001_initial.py
@@ -1,32 +0,0 @@ @@ -1,32 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -# Generated by Django 1.10 on 2016-11-24 15:17  
3 -from __future__ import unicode_literals  
4 -  
5 -from decimal import Decimal  
6 -from django.db import migrations, models  
7 -import django.db.models.deletion  
8 -  
9 -  
10 -class Migration(migrations.Migration):  
11 -  
12 - initial = True  
13 -  
14 - dependencies = [  
15 - ('core', '0001_initial'),  
16 - ]  
17 -  
18 - operations = [  
19 - migrations.CreateModel(  
20 - name='Exercise',  
21 - fields=[  
22 - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),  
23 - ('name_exercise', models.CharField(max_length=100, verbose_name='Name')),  
24 - ('description', models.TextField(blank=True, verbose_name='Description')),  
25 - ('end_date', models.DateField(verbose_name='Delivery Date')),  
26 - ('grade', models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=20, null=True)),  
27 - ('file', models.FileField(upload_to='uploads/%Y/%m/%d')),  
28 - ('allowed', models.BooleanField(default=False, verbose_name='Allowed delivery after end date?')),  
29 - ('file_type', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='exercise_type', to='core.MimeType', verbose_name='Type file')),  
30 - ],  
31 - ),  
32 - ]  
exercise/migrations/0002_auto_20161124_1217.py
@@ -1,36 +0,0 @@ @@ -1,36 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -# Generated by Django 1.10 on 2016-11-24 15:17  
3 -from __future__ import unicode_literals  
4 -  
5 -from django.conf import settings  
6 -from django.db import migrations, models  
7 -import django.db.models.deletion  
8 -  
9 -  
10 -class Migration(migrations.Migration):  
11 -  
12 - initial = True  
13 -  
14 - dependencies = [  
15 - ('exercise', '0001_initial'),  
16 - migrations.swappable_dependency(settings.AUTH_USER_MODEL),  
17 - ('courses', '0002_auto_20161124_1217'),  
18 - ]  
19 -  
20 - operations = [  
21 - migrations.AddField(  
22 - model_name='exercise',  
23 - name='professors',  
24 - field=models.ManyToManyField(blank=True, related_name='professors_exercise', to=settings.AUTH_USER_MODEL, verbose_name='Professors'),  
25 - ),  
26 - migrations.AddField(  
27 - model_name='exercise',  
28 - name='students',  
29 - field=models.ManyToManyField(blank=True, related_name='subject_exercise', to=settings.AUTH_USER_MODEL, verbose_name='Students'),  
30 - ),  
31 - migrations.AddField(  
32 - model_name='exercise',  
33 - name='topic',  
34 - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exercise_topic', to='courses.Topic', verbose_name='Topic'),  
35 - ),  
36 - ]  
exercise/migrations/__init__.py
exercise/models.py
@@ -1,36 +0,0 @@ @@ -1,36 +0,0 @@
1 -from courses.models import Topic  
2 -from decimal import Decimal  
3 -from django.db import models  
4 -from django.utils.translation import ugettext_lazy as _  
5 -from users.models import User  
6 -from core.models import MimeType  
7 -  
8 -"""  
9 - Function to return the path where the file should be saved  
10 -"""  
11 -  
12 -  
13 -def file_path(instance, filename):  
14 - return '/'.join([instance.topic.subject.course.slug, instance.topic.subject.slug, instance.topic.slug, filename])  
15 -  
16 -  
17 -"""  
18 -It represents the Exercises inside topic.  
19 -"""  
20 -  
21 -  
22 -class Exercise(models.Model):  
23 -  
24 - name_exercise = models.CharField(_('Name'), max_length=100)  
25 - description = models.TextField(_('Description'), blank=True)  
26 - end_date = models.DateField(_('Delivery Date'))  
27 - grade = models.DecimalField(max_digits=20, decimal_places=2, default=Decimal('0.00'), null=True)  
28 - topic = models.ForeignKey(Topic, verbose_name=_('Topic'), related_name='exercise_topic')  
29 - professors = models.ManyToManyField(User, verbose_name=_('Professors'), related_name='professors_exercise', blank=True)  
30 - students = models.ManyToManyField(User, verbose_name=_('Students'), related_name='subject_exercise', blank = True)  
31 - file = models.FileField(upload_to='uploads/%Y/%m/%d')  
32 - file_type = models.ForeignKey(MimeType, verbose_name=_('Type file'), related_name='exercise_type',null=True)  
33 - allowed = models.BooleanField(_('Allowed delivery after end date?'), default=False)  
34 -  
35 - def __str__(self):  
36 - return self.name_exercise  
exercise/static/js/exercise.js
@@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
1 -function get_modal_exercise(url, id,div_content){  
2 - $.get(url, function (data) {  
3 - $(div_content).detach();  
4 - $(div_content).append(data);  
5 - $(id).modal('show');  
6 - });  
7 -}  
exercise/templates/exercise/card_list_user.html
@@ -1,64 +0,0 @@ @@ -1,64 +0,0 @@
1 -{% load static i18n list_topic_foruns permission_tags widget_tweaks professor_access list_topic_exercises %}  
2 -  
3 -<div class="col-md-12 col-sm-12 col-lg-12">  
4 - <div class="panel-group accordion ui-accordion ui-widget ui-helper-reset ui-sortable" role="tablist" aria-multiselectable="false">  
5 - <div class="group"><div class="panel panel-default">  
6 - <div class="panel-heading topic ui-sortable-handle" role="tab">  
7 - <div class="row">  
8 - <div class="col-md-1 moreAccordion" data-toggle="collapse" data-parent="#accordion-{{user.id}}" href=".collapseTopic-{{user.id}}" aria-expanded="false" aria-controls="collapseTopic-{{user.id}}">  
9 - <button class="btn btn-default btn-sm caret-square"><i class="fa fa-caret-square-o-down fa-2x" aria-hidden="true"></i></button>  
10 - </div>  
11 - <div class="col-xs-9 col-md-9 titleTopic">  
12 - <a href="" role="button">  
13 - <h4>{{user|capfirst}}</h4>  
14 - </a>  
15 - </div>  
16 - </div>  
17 - </div>  
18 - <div class="panel-collapse collapseTopic-{{user.id}} collapse in" role="tabpanel" aria-labelledby="heading_{{user.id}}" aria-expanded="true" aria-hidden="false">  
19 - <div class="panel-body">  
20 - <div class="row">  
21 - <div class="col-md-4">  
22 - <div class="resource_inline">  
23 - <h4>{% trans 'Grade' %}</h4>  
24 - </div>  
25 - <div class="resource_inline">  
26 - {# dropdown de create exercício #}  
27 - <div class="dropdown">  
28 - <a href="#" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-plus-circle fa-lg" aria-hidden="true"></i></a>  
29 - <ul class="dropdown-menu" aria-labelledby="dLabel">  
30 - <li><a href="javascript:modal.get('{% url 'course:exercise:create_exercise' topic.slug %}', '#createExercisesModal','#requisicoes_ajax')">{% trans 'Give a grade' %}</a></li>  
31 - </ul>  
32 - </div>  
33 - </div>  
34 - </div>  
35 - <div class="col-md-4">  
36 - <div class="resource_inline">  
37 - <h4>{% trans 'Delivery' %}</h4>  
38 - </div>  
39 - {% for exercise in exercises %}  
40 - <li><a href="{{exercise.file.url}}" target="_blank">{{exercise.name_exercise}}</a></li>  
41 - {% endfor %}  
42 - </div>  
43 - <div class="col-md-4">  
44 - <div class="resource_inline">  
45 - <h4>{% trans 'Create' %}</h4>  
46 - </div>  
47 - <div class="resource_inline">  
48 - {# dropdown de create exercício #}  
49 - <div class="dropdown">  
50 - <a href="#" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-plus-circle fa-lg" aria-hidden="true"></i></a>  
51 - <ul class="dropdown-menu" aria-labelledby="dLabel">  
52 - <li><a href="javascript:modal.get('{% url 'course:exercise:create_exercise' topic.slug %}', '#createExercisesModal','#requisicoes_ajax')">{% trans 'Create a specific exercise' %}</a></li>  
53 - </ul>  
54 - </div>  
55 - </div>  
56 - {% include "exercise/create_exercise.html" %}  
57 - </div>  
58 - </div>  
59 - </div>  
60 - </div>  
61 - </div>  
62 - </div>  
63 -</div>  
64 -</div>  
65 \ No newline at end of file 0 \ No newline at end of file
exercise/templates/exercise/card_topic_exercises.html
@@ -1,59 +0,0 @@ @@ -1,59 +0,0 @@
1 -{% load static widget_tweaks i18n %}  
2 -  
3 -<div class="col-lg-4 col-xs-4 col-sm-4">  
4 - <div class="panel panel-default">  
5 - <div class="panel-body">  
6 - <form class="form-horizontal">  
7 - <fieldset>  
8 - <center><legend>{{exercise.name_exercise}}</legend></center>  
9 - <div class="container-fluid">  
10 - <div class="form-group">  
11 - <label class="col-md-2 col-xs-2 col-sm-2 control-label">{% trans 'Description' %}: </label><br>  
12 - {% if exercise.description%}  
13 - {{exercise.description}}  
14 - {% else %}  
15 - {% trans "Don't have description" %}  
16 - {% endif %}  
17 - </div>  
18 - <div class="form-group">  
19 -  
20 - </div>  
21 - <div class="form-group">  
22 - <label class="col-md-2 col-xs-2 col-sm-2 control-label">{% trans 'Delivery Date' %}: </label><br>{{exercise.end_date}}  
23 -  
24 - </div>  
25 - <div class="form-group">  
26 - <label for="nota" class="col-md-2 control-label">{% trans 'Grade' %}:  
27 - {% if exercise.grade %}  
28 - <div class="col-md-4">  
29 - <p id="nota" class="form-control">  
30 - {{exercise.grade}}  
31 - </p>  
32 - </div>  
33 - {% else %}  
34 - {% trans 'Not yet' %}  
35 - {% endif %}  
36 - </label>  
37 - </div>  
38 - {% if exercise.file %}  
39 - <div class="form-group">  
40 - <label for="DelExc" class="col-md-4 control-label"> <i class="fa fa-file-archive-o fa-3x" aria-hidden="true">  
41 - <a href="{{exercise.file.url}}" target="_blank">{% trans 'File' %}</a>  
42 - </i>  
43 - </div>  
44 - {% else %}  
45 - <p>{% trans 'Exercise not yet' %}</p>  
46 - {% endif %}  
47 - {% if not exercise.grade %}  
48 - <div class="form-group">  
49 - <label class="col-md-6 control-label"><i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i>{% trans 'Teacher waiting corretion' %}  
50 - </div>  
51 - {% endif %}  
52 - </div>  
53 -  
54 - </fieldset>  
55 - </form>  
56 -  
57 - </div>  
58 - </div>  
59 -</div>  
60 \ No newline at end of file 0 \ No newline at end of file
exercise/templates/exercise/create_exercise.html
@@ -1,113 +0,0 @@ @@ -1,113 +0,0 @@
1 -{% load widget_tweaks i18n static %}  
2 -<!--MODAL CREATE EXERCISE-->  
3 -<div class="modal fade" id="createExercisesModal" tabindex="-1" role="dialog" aria-labelledby="createExercise">  
4 - <div class="modal-dialog" role="document">  
5 - <div class="modal-content">  
6 - <div class="modal-header">  
7 - <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>  
8 - <h4 class="modal-title" id="createExercise">{% trans 'Create a New Material' %}</h4>  
9 - </div>  
10 - <div class="modal-body">  
11 - <!-- Card -->  
12 - <form class="form-horizontal" method="post" id="form-exercise" enctype="multipart/form-data">  
13 - {% csrf_token %}  
14 - {% if messages %}  
15 - {% for message in messages %}  
16 - <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">  
17 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
18 - <span aria-hidden="true">&times;</span>  
19 - </button>  
20 - <p>{{ message }}</p>  
21 - </div>  
22 - {% endfor %}  
23 - {% endif %}  
24 - <fieldset>  
25 - {% for field in form %}  
26 - <div class="form-group is-empy{% if form.has_error %} has-error {% endif %} is-fileinput">  
27 - <div class="col-md-12">  
28 - {% if field.field.required %}  
29 - <label for="{{ field.auto_id }}" class="control-label">{{ field.label }}<span>*</span></label>  
30 - {% else %}  
31 - <label for="{{ field.auto_id }}" class=" control-label">{{ field.label }}</label>  
32 - {% endif %}  
33 - {% if field.auto_id == 'id_file' %}  
34 - {% render_field field class='form-control input-sm' %}  
35 - <div class="input-group">  
36 - <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your file...' %}">  
37 - <span class="input-group-btn input-group-sm">  
38 - <button type="button" class="btn btn-fab btn-fab-mini">  
39 - <i class="material-icons">attach_file</i>  
40 - </button>  
41 - </span>  
42 - </div>  
43 - {% else %}  
44 - {% render_field field class='form-control input-sm' %}  
45 - <span id="helpBlock" class="help-block">{{ field.help_text }}</span>  
46 - {% endif %}  
47 - </div>  
48 -  
49 - {% if field.errors %}  
50 - <div class="alert alert-danger alert-dismissible clearfix" role="alert">  
51 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
52 - <span aria-hidden="true">&times;</span>  
53 - </button>  
54 - <ul>  
55 - {% for error in field.errors %}  
56 - <li>{{ error }}</li>  
57 - {% endfor %}  
58 - </ul>  
59 - </div>  
60 - {% endif %}  
61 - </div>  
62 - {% endfor %}  
63 -  
64 - <div class="form-group">  
65 - <div class="col-md-12 text-center">  
66 - <p><b>{% trans 'The file size shouldnt exceed 10MB' %}</b></p>  
67 - </div>  
68 - </div>  
69 -  
70 - <div class="form-group">  
71 - <div class="col-md-12">  
72 - <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>  
73 - <button class="btn btn-raised btn-primary" type="submit">{% trans 'Submit' %}</button>  
74 - </div>  
75 - </div>  
76 - </fieldset>  
77 - </form>  
78 - <!-- .end Card -->  
79 - </div>  
80 - </div>  
81 - </div>  
82 -</div>  
83 -<!-- EndModal -->  
84 -<script type="text/javascript">  
85 - $("#form-exercise").submit(function(event) {  
86 - $("#createExercisesModal").modal("hide");  
87 - var data = new FormData($('#form-exercise').get(0));  
88 - $.ajax({  
89 - url: "{% url 'course:exercise:create_exercise' topic.slug %}",  
90 - type: $("#form-exercise").attr('method'),  
91 - data: data,  
92 - cache: false,  
93 - processData: false,  
94 - contentType: false,  
95 - success: function(data) {  
96 - $('#createExercisesModal').modal('hide');  
97 - $('#list-topic{{ topic.id }}-exercises').append(data);  
98 - $('#list-topic{{ topic.id }}-exercises-edit').append(data);  
99 - alertify.success('Exercise successfully created!')  
100 - setTimeout(function () { location.reload(1); }, 1000);  
101 - },  
102 - error: function(data){  
103 - $('#requisicoes_ajax').empty();  
104 - $('#requisicoes_ajax').append(data.responseText);  
105 - $('#createExercisesModal').modal('show');  
106 - alertify.alert('Invalid exercise, insert a valid one!');  
107 - $('div.modal-backdrop.fade.in').remove();  
108 -  
109 - }  
110 - });  
111 - event.preventDefault();  
112 - });  
113 -</script>  
exercise/templates/exercise/delete_exercise.html
@@ -1,66 +0,0 @@ @@ -1,66 +0,0 @@
1 -{% load static widget_tweaks i18n %}  
2 -  
3 -<!-- MODAL DELETE LINK -->  
4 -<exercise rel="stylesheet" type="text/css" href="{% static 'css/exercise.css' %}">  
5 -  
6 -<div class="erro-update">  
7 - <div class="modal fade" id="exerciseDeleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteExerciseLabel" style="z-index: 10">  
8 - <div class="modal-dialog" role="document">  
9 - <div class="modal-content">  
10 - <div class="modal-header">  
11 - <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>  
12 - <h4 class="modal-title" id="deleteExerciseLabel">{% trans 'Delete Exercise' %}</h4>  
13 - </div>  
14 - <div class="modal-body">  
15 - <!-- Card -->  
16 - <form class="form-horizontal" method="post" id="form-delete-exercise" enctype="multipart/form-data">  
17 - {% csrf_token %}  
18 - <fieldset>  
19 - <div class="col-md-12">  
20 - {% trans "Are you sure to delete the exercise " %} <strong>"{{ exercise.name }}"</strong> </a> of {{ exercise.topic.name }}?  
21 - </div>  
22 - <div class="form-group">  
23 - <div class="col-md-12">  
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>  
26 - </div>  
27 - </div>  
28 - </fieldset>  
29 - </form>  
30 - <!-- .end Card -->  
31 - </div>  
32 - </div>  
33 - </div>  
34 - </div>  
35 -</div>  
36 - <script src="{% static 'js/exercise.js' %}"></script>  
37 - <script type="text/javascript">  
38 - $("#form-delete-exercise").submit(function(event) {  
39 - var data = new FormData($('#form-delete-exercise').get(0));  
40 - $('#exerciseDeleteModal').modal('hide');  
41 - $.ajax({  
42 - url: "{% url 'course:exercises:delete_exercise' exercise.slug %}",  
43 - type: $("#form-delete-exercise").attr('method'),  
44 - data: data,  
45 - cache: false,  
46 - processData: false,  
47 - contentType: false,  
48 - success: function(data) {  
49 - $('#requisicoes_ajax').empty();  
50 - $('#exercise_{{ exercise.slug }}').remove();  
51 - $('#exercise_edit_icon_{{ exercise.slug }}').remove();  
52 - $('#exercise_edit_{{ exercise.slug }}').remove();  
53 - alertify.alert('Exercise successfully deleted!')  
54 - },  
55 - error: function(data){  
56 - $("div.modal-backdrop.fade.in").remove();  
57 - $('#requisicoes_ajax').empty();  
58 - $('#requisicoes_ajax').append(data.responseText);  
59 - $('#exerciseDeleteModal').modal('show');  
60 - alertify.alert('Error when trying to delete.');  
61 - }  
62 - });  
63 - event.preventDefault();  
64 - });  
65 - </script>  
66 -<!-- EndModal -->  
exercise/templates/exercise/exercise_edit.html
@@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
1 -{% load static i18n list_topic_foruns permission_tags %}  
2 -<div id="exercise-topic{{ topic.id }}-exercises-edit">  
3 - {% for exercise in exercises %}  
4 - <li class="icon_edit_remove" id = "exercise_edit_icon_{{ exercise.slug }}"> <a href="javascript:modal.get('{% url 'course:exercise:update_exercise' exercise.slug %}', '#exercisesModalEdit', '#requisicoes_ajax')"><i class="fa fa-pencil fa-lg" aria-hidden="true"></i></a> <a href="javascript:modal.get('', '#exerciseDeleteModal', '#requisicoes_ajax')"><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a></li>  
5 - <li id = "exercise_edit_{{ exercise.slug }}"><i class="fa fa-file" aria-hidden="true"></i> <a href="javascript:modal.get('', '#viewExerciseModal','#requisicoes_ajax')">{{exercise.name_exercise}}</a></li>  
6 - {% endfor %}  
7 -</div>  
exercise/templates/exercise/exercise_list.html
@@ -1,6 +0,0 @@ @@ -1,6 +0,0 @@
1 -{% load static i18n list_topic_foruns permission_tags %}  
2 -<div id="list-topic{{ topic.id }}-exercises">  
3 -{% for exercise in exercises %}  
4 - <li id="exercise_{{ exercise.slug }}"><i class="fa fa-file" aria-hidden="true"></i> <a href="{{exercise.file.url}}">{{exercise.name_exercise}}</a></li>  
5 -{% endfor %}  
6 -</div>  
exercise/templates/exercise/render_exercise.html
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -<li id="exercise_{{ exercise.slug }}"><i class="material-icons">{{ exercise.file_type.icon }}</i> <a href="{{ exercise.file_url.url }}" target="_blank">{{ exercise.name }}</a></li>  
2 \ No newline at end of file 0 \ No newline at end of file
exercise/templates/exercise/update_exercise.html
@@ -1,120 +0,0 @@ @@ -1,120 +0,0 @@
1 -{% load static widget_tweaks i18n %}  
2 -  
3 -<!-- MODAL CREATE FILE -->  
4 -<link rel="stylesheet" type="text/css" href="{% static 'css/file.css' %}">  
5 -  
6 -<div class="erro-update">  
7 - <div class="modal fade" id="exercisesModalEdit" tabindex="-1" role="dialog" aria-labelledby="updateFileLabel" style="z-index: 10">  
8 - <div class="modal-dialog" role="document">  
9 - <div class="modal-content">  
10 - <div class="modal-header">  
11 - <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>  
12 - <h4 class="modal-title" id="updateFileLabel">{% trans 'Edit Material' %}</h4>  
13 - </div>  
14 - <div class="modal-body">  
15 - <!-- Card -->  
16 - <form class="form-horizontal" method="post" id="form-update-exercise" enctype="multipart/form-data">  
17 - {% csrf_token %}  
18 - {% if messages %}  
19 - {% for message in messages %}  
20 - <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">  
21 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
22 - <span aria-hidden="true">&times;</span>  
23 - </button>  
24 - <p>{{ message }}</p>  
25 - </div>  
26 - {% endfor %}  
27 - {% endif %}  
28 - <fieldset>  
29 - {% for field in form %}  
30 - <div class="form-group is-empy{% if form.has_error %} has-error {% endif %} is-fileinput">  
31 - <div class="col-md-12">  
32 - {% if field.field.required %}  
33 - <label for="{{ field.auto_id }}" class="control-label">{{ field.label }}<span>*</span></label>  
34 - {% else %}  
35 - <label for="{{ field.auto_id }}" class=" control-label">{{ field.label }}</label>  
36 - {% endif %}  
37 - {% if field.auto_id == 'id_file' %}  
38 - <input class="form-control input-sm" id="id_file_url" name="file_url" type="file">  
39 - <div class="input-group">  
40 - <input type="text" readonly="" class="form-control" placeholder="{% trans 'Choose your file...' %}">  
41 - <span class="input-group-btn input-group-sm">  
42 - <button type="button" class="btn btn-fab btn-fab-mini">  
43 - <i class="material-icons">attach_file</i>  
44 - </button>  
45 - </span>  
46 - </div>  
47 - <div class="crearfix">  
48 - <a href="{{ file.file_url.url }}" target="_blank">{% trans "See current file" %}</a>  
49 - </div>  
50 - {% else %}  
51 - {% render_field field class='form-control input-sm' %}  
52 - <span id="helpBlock" class="help-block">{{ field.help_text }}</span>  
53 - {% endif %}  
54 - </div>  
55 -  
56 - {% if field.errors %}  
57 - <div class="alert alert-danger alert-dismissible clearfix" role="alert">  
58 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
59 - <span aria-hidden="true">&times;</span>  
60 - </button>  
61 - <ul>  
62 - {% for error in field.errors %}  
63 - <li>{{ error }}</li>  
64 - {% endfor %}  
65 - </ul>  
66 - </div>  
67 - {% endif %}  
68 - </div>  
69 - {% endfor %}  
70 -  
71 - <div class="form-group">  
72 - <div class="col-md-12 text-center">  
73 - <p><b>{% trans 'The file size shouldnt exceed 10MB' %}</b></p>  
74 - </div>  
75 - </div>  
76 -  
77 - <div class="form-group">  
78 - <div class="col-md-12">  
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>  
81 - </div>  
82 - </div>  
83 - </fieldset>  
84 - </form>  
85 - <!-- .end Card -->  
86 - </div>  
87 - </div>  
88 - </div>  
89 - </div>  
90 -</div>  
91 -  
92 -{% block script_file %}  
93 -  
94 - {# // <script src="{% static 'js/file.js' %}"></script> #}  
95 - <script type="text/javascript">  
96 - $("#form-update-exercise").submit(function(event) {  
97 - var data = new FormData($('#form-update-exercise').get(0));  
98 - $.ajax({  
99 - url: "{% url 'course:exercise:update_exercise' exercise.slug %}",  
100 - type: $("#form-update-exercise").attr('method'),  
101 - data: data,  
102 - cache: false,  
103 - processData: false,  
104 - contentType: false,  
105 - success: function(data) {  
106 - $('#Carrinho').modal('hide');  
107 - $('#file_edit_{{ exercise.slug }}').replaceWith(data);  
108 - $('#file_{{ exercise.slug }}').replaceWith(data);  
109 - },  
110 - error: function(data){  
111 - $('.erro-update').html(data.responseText);  
112 - $('.modal-backdrop').remove();  
113 - $('#Carrinho').modal();  
114 - }  
115 - });  
116 - event.preventDefault();  
117 - });  
118 - </script>  
119 -{% endblock script_file %}  
120 -<!-- EndModal -->  
121 \ No newline at end of file 0 \ No newline at end of file
exercise/templatetags/__init__.py
exercise/templatetags/list_topic_exercises.py
@@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
1 -from django import template  
2 -from exercise.models import Exercise  
3 -  
4 -register = template.Library()  
5 -  
6 -  
7 -@register.inclusion_tag('exercise/exercise_list.html')  
8 -def list_topic_exercise(request, topic):  
9 - context = {  
10 - 'request': request,  
11 - }  
12 - context['exercises'] = Exercise.objects.filter(topic=topic)  
13 -  
14 - return context  
15 -  
16 -  
17 -@register.inclusion_tag('exercise/exercise_edit.html')  
18 -def list_topic_exercise_edit(request, topic):  
19 - context = {  
20 - 'request': request,  
21 - }  
22 - context['exercises'] = Exercise.objects.filter(topic=topic)  
23 - context['topic'] = topic  
24 -  
25 - return context  
exercise/tests.py
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 -from django.test import TestCase  
2 -  
3 -# Create your tests here.  
exercise/urls.py
@@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
1 -from django.conf.urls import url  
2 -from . import views  
3 -  
4 -urlpatterns = [  
5 - url(r'^create_exercise/(?P<slug>[\w_-]+)/$', views.CreateExercise.as_view(), name='create_exercise'),  
6 - url(r'^delete_exercise/(?P<slug>[\w_-]+)/$', views.DeleteExercise.as_view(), name='delete_exercise'),  
7 - url(r'^update_exercise/(?P<slug>[\w_-]+)/$', views.UpdateExercise.as_view(), name='update_exercise'),  
8 - url(r'^render-exercise/(?P<id>[0-9]+)/$', views.render_exercise, name='render_exercise'),  
9 -]  
exercise/views.py
@@ -1,253 +0,0 @@ @@ -1,253 +0,0 @@
1 -from .forms import ExerciseForm, UpdateExerciseForm  
2 -from .models import Exercise  
3 -from core.decorators import log_decorator  
4 -from core.mixins import LogMixin, NotificationMixin  
5 -from core.models import Log, MimeType  
6 -from courses.models import Topic  
7 -from datetime import datetime  
8 -from django.conf import settings  
9 -from django.contrib import messages  
10 -from django.contrib.auth.mixins import LoginRequiredMixin  
11 -from django.core.urlresolvers import reverse_lazy  
12 -from django.shortcuts import render, get_object_or_404, redirect  
13 -from django.urls import reverse  
14 -from django.views import generic  
15 -from files.utils import mime_type_to_material_icons  
16 -from rolepermissions.mixins import HasRoleMixin  
17 -from rolepermissions.verifications import has_role  
18 -from users.models import User  
19 -  
20 -  
21 -class CreateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, NotificationMixin, generic.CreateView):  
22 - log_component = 'exercise'  
23 - log_resource = 'exercise'  
24 - log_action = 'create'  
25 - log_component = {}  
26 -  
27 - allowed_roles = ['professor', 'student']  
28 - login_url = reverse_lazy("core:home")  
29 - redirect_field_name = 'next'  
30 - model = Exercise  
31 - template_name = 'exercise/create_exercise.html'  
32 - form_class = ExerciseForm  
33 - success_url = reverse_lazy('course:exercise:render_exercise')  
34 -  
35 - log_component = "subject"  
36 - log_resource = "exercise"  
37 - log_action = "create"  
38 - log_context = {}  
39 -  
40 - def form_invalid(self, form, **kwargs):  
41 - context = super(CreateExercise, self).form_invalid(form)  
42 - context.status_code = 400  
43 -  
44 - return context  
45 -  
46 - def form_valid(self, form):  
47 - self.object = form.save(commit = False)  
48 - topic = get_object_or_404(Topic, slug = self.kwargs.get('slug'))  
49 - self.object.topic = topic  
50 -  
51 - # Set MimeType  
52 - exercise = self.request.FILES['file']  
53 - try:  
54 - if exercise:  
55 - exercise_type = exercise.content_type  
56 -  
57 - # Check if exist a mimetype in database  
58 - try:  
59 - self.object.file_type = MimeType.objects.get(typ = exercise_type)  
60 - # Create if not  
61 - except:  
62 - mtype = MimeType.objects.create(  
63 - typ = exercise_type,  
64 - icon = mime_type_to_material_icons[exercise_type]  
65 - )  
66 - mtype.save()  
67 - self.object.file_type = mtype  
68 - except:  
69 - print('Exercise not uploaded')  
70 -  
71 - self.object.save()  
72 - self.object.professors = topic.subject.professors.all()  
73 - self.object.students = topic.subject.students.all()  
74 - self.object.save()  
75 - #CREATE LOG  
76 - self.log_context['topic_id'] = topic.id  
77 - self.log_context['topic_name'] = topic.name  
78 - self.log_context['topic_slug'] = topic.slug  
79 - self.log_context['subject_id'] = topic.subject.id  
80 - self.log_context['subject_name'] = topic.subject.name  
81 - self.log_context['subject_slug'] = topic.subject.slug  
82 -  
83 - super(CreateExercise, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)  
84 -  
85 -  
86 -  
87 - #CREATE NOTIFICATION  
88 - super(CreateExercise, self).createNotification(message="uploaded a Exercise "+ self.object.name_exercise, actor=self.request.user,  
89 - resource_name=self.object.name_exercise, resource_link= reverse('course:view_topic', args=[self.object.topic.slug]),  
90 - users=self.object.topic.subject.students.all())  
91 -  
92 - self.log_context['exercise_id'] = self.object.id  
93 - self.log_context['exercise_name'] = self.object.name_exercise  
94 - self.log_context['topic_id'] = self.object.topic.id  
95 - self.log_context['topic_name'] = self.object.topic.name  
96 - self.log_context['topic_slug'] = self.object.topic.slug  
97 - self.log_context['subject_id'] = self.object.topic.subject.id  
98 - self.log_context['subject_name'] = self.object.topic.subject.name  
99 - self.log_context['subject_slug'] = self.object.topic.subject.slug  
100 - self.log_context['course_id'] = self.object.topic.subject.course.id  
101 - self.log_context['course_name'] = self.object.topic.subject.course.name  
102 - self.log_context['course_slug'] = self.object.topic.subject.course.slug  
103 - self.log_context['course_category_id'] = self.object.topic.subject.course.category.id  
104 - self.log_context['course_category_name'] = self.object.topic.subject.course.category.name  
105 -  
106 - super(CreateExercise, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)  
107 -  
108 - return self.get_success_url()  
109 -  
110 - def get_context_data(self, **kwargs):  
111 - context = super(CreateExercise, self).get_context_data(**kwargs)  
112 - topic = get_object_or_404(Topic, slug=self.kwargs.get('slug'))  
113 - context['topic'] = topic  
114 - context['subject'] = topic.subject  
115 - context['subjects'] = topic.subject.course.subjects.all()  
116 - context['form'] = self.form_class  
117 -  
118 - try:  
119 - context['latest_exercise'] = Exercise.objects.latest('id')  
120 - except:  
121 - pass  
122 - return context  
123 -  
124 - def get_success_url(self):  
125 - self.success_url = redirect('course:exercise:render_exercise', id = self.object.id)  
126 -  
127 - return self.success_url  
128 -  
129 -  
130 -def render_exercise(request, id):  
131 - template_name = 'exercise/render_exercise.html'  
132 - exercise = get_object_or_404(Exercise, id = id)  
133 -  
134 - context = {  
135 - 'exercise': exercise  
136 - }  
137 -  
138 - log_context = {}  
139 - log_context['exercise_id'] = exercise.id  
140 - log_context['exercise_name'] = exercise.name_exercise  
141 - log_context['topic_id'] = exercise.topic.id  
142 - log_context['topic_name'] = exercise.topic.name  
143 - log_context['topic_slug'] = exercise.topic.slug  
144 - log_context['subject_id'] = exercise.topic.subject.id  
145 - log_context['subject_name'] = exercise.topic.subject.name  
146 - log_context['subject_slug'] = exercise.topic.subject.slug  
147 - log_context['course_id'] = exercise.topic.subject.course.id  
148 - log_context['course_name'] = exercise.topic.subject.course.name  
149 - log_context['course_slug'] = exercise.topic.subject.course.slug  
150 - log_context['course_category_id'] = exercise.topic.subject.course.category.id  
151 - log_context['course_category_name'] = exercise.topic.subject.course.category.name  
152 -  
153 - request.log_context = log_context  
154 -  
155 - return render(request, template_name, context)  
156 -  
157 -  
158 -class UpdateExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.UpdateView):  
159 - log_component = 'exercise'  
160 - log_resource = 'exercise'  
161 - log_action = 'update'  
162 - log_context = {}  
163 -  
164 - allowed_roles = ['student']  
165 - login_url = reverse_lazy("core:home")  
166 - redirect_field_name = 'next'  
167 - model = Exercise  
168 - template_name = 'exercise/update_exercise.html'  
169 - form_class = UpdateExerciseForm  
170 - context_object_name = 'exercise'  
171 - success_url = reverse_lazy('course:exercise:render_exercise')  
172 -  
173 - def form_invalid(self, form, **kwargs):  
174 - context = super(UpdateExercise, self).form_invalid(form)  
175 - context.status_code = 400  
176 -  
177 - return context  
178 -  
179 -  
180 - def form_valid(self, form):  
181 - self.object = form.save()  
182 -  
183 - self.log_context['exercise_id'] = self.object.id  
184 - self.log_context['exercise_name'] = self.object.name  
185 - self.log_context['topic_id'] = self.object.topic.id  
186 - self.log_context['topic_name'] = self.object.topic.name  
187 - self.log_context['topic_slug'] = self.object.topic.slug  
188 - self.log_context['subject_id'] = self.object.topic.subject.id  
189 - self.log_context['subject_name'] = self.object.topic.subject.name  
190 - self.log_context['subject_slug'] = self.object.topic.subject.slug  
191 - self.log_context['course_id'] = self.object.topic.subject.course.id  
192 - self.log_context['course_name'] = self.object.topic.subject.course.name  
193 - self.log_context['course_slug'] = self.object.topic.subject.course.slug  
194 - self.log_context['course_category_id'] = self.object.topic.subject.course.category.id  
195 - self.log_context['course_category_name'] = self.object.topic.subject.course.category.name  
196 -  
197 - super(UpdateExercise, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)  
198 -  
199 - return super(UpdateExercise, self).form_valid(form)  
200 -  
201 - def get_object(self, queryset=None):  
202 - return get_object_or_404(Exercise, slug = self.kwargs.get('slug'))  
203 -  
204 - def get_success_url(self):  
205 - self.success_url = reverse_lazy('course:exercise:render_exercise', args = (self.object.id, ))  
206 -  
207 - return self.success_url  
208 -  
209 -  
210 -class DeleteExercise(LoginRequiredMixin, HasRoleMixin, LogMixin, generic.DeleteView):  
211 - log_component = 'exercise'  
212 - log_resource = 'exercise'  
213 - log_action = 'delete'  
214 - log_context = {}  
215 -  
216 - allowed_roles = ['student']  
217 - login_url = reverse_lazy("core:home")  
218 - redirect_field_name = 'next'  
219 - model = Exercise  
220 - template_name = 'exercise/delete_exercise.html'  
221 -  
222 - def dispatch(self, *args, **kwargs):  
223 - exercise = get_object_or_404(Exercise, slug = self.kwargs.get('slug'))  
224 - if(not (exercise.topic.owner == self.request.user) and not(has_role(self.request.user, 'system_admin')) ):  
225 - return self.handle_no_permission()  
226 - return super(DeleteExercise, self).dispatch(*args, **kwargs)  
227 -  
228 - def get_context_data(self, **kwargs):  
229 - context = super(DeleteExercise, self).get_context_data(**kwargs)  
230 - context['course'] = self.object.topic.subject.course  
231 - context['subject'] = self.object.topic.subject  
232 - context['exercise'] = self.object  
233 - context["topic"] = self.object.topic  
234 - return context  
235 -  
236 - def get_success_url(self):  
237 - self.log_context['exercise_id'] = self.object.id  
238 - self.log_context['exercise_name'] = self.object.name  
239 - self.log_context['topic_id'] = self.object.topic.id  
240 - self.log_context['topic_name'] = self.object.topic.name  
241 - self.log_context['topic_slug'] = self.object.topic.slug  
242 - self.log_context['subject_id'] = self.object.topic.subject.id  
243 - self.log_context['subject_name'] = self.object.topic.subject.name  
244 - self.log_context['subject_slug'] = self.object.topic.subject.slug  
245 - self.log_context['course_id'] = self.object.topic.subject.course.id  
246 - self.log_context['course_name'] = self.object.topic.subject.course.name  
247 - self.log_context['course_slug'] = self.object.topic.subject.course.slug  
248 - self.log_context['course_category_id'] = self.object.topic.subject.course.category.id  
249 - self.log_context['course_category_name'] = self.object.topic.subject.course.category.name  
250 -  
251 - super(DeleteExercise, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)  
252 -  
253 - return reverse_lazy('course:view_topic', kwargs={'slug' : self.object.topic.slug})  
254 \ No newline at end of file 0 \ No newline at end of file