Commit 0c7d3f7bc4998010995cb8d03e16187555195167

Authored by fbormann
2 parents f83e8bdf 3894ffb6

Merge branch 'master' of https://github.com/amadeusproject/amadeuslms

app/templates/home.html
@@ -64,7 +64,7 @@ @@ -64,7 +64,7 @@
64 {% block sidebar %} 64 {% block sidebar %}
65 <div class="panel panel-primary"> 65 <div class="panel panel-primary">
66 <div class="panel-heading"> 66 <div class="panel-heading">
67 - <img src="{{ user.image.url }}" id="img" class="img-rounded"> 67 + <img src="{{ user.image_url }}" id="img" class="img-rounded">
68 <p></p> 68 <p></p>
69 <div class="row"> 69 <div class="row">
70 <div class="col-xs-3 col-md-3"> 70 <div class="col-xs-3 col-md-3">
@@ -92,7 +92,7 @@ @@ -92,7 +92,7 @@
92 {% if user|has_role:'system_admin' %} 92 {% if user|has_role:'system_admin' %}
93 <li> <a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li> 93 <li> <a href="{% url 'users:manage' %}">{% trans 'Manage Users' %}</a></li>
94 {% endif %} 94 {% endif %}
95 - {% if user|has_role:'system_admin, professor' %} 95 + {% if user|has_role:'system_admin' or user|has_role:'professor' %}
96 <li> 96 <li>
97 <a href="#courses_list" data-toggle="collapse">{% trans 'Manage Courses' %}</a> 97 <a href="#courses_list" data-toggle="collapse">{% trans 'Manage Courses' %}</a>
98 98
app/templates/home_teacher_student_content.html
1 -{% load i18n %} 1 +{% load static i18n %}
2 2
3 {% for notification in objects %} 3 {% for notification in objects %}
4 <li {% if not notification.read %}class="not_read"{% endif %}> 4 <li {% if not notification.read %}class="not_read"{% endif %}>
5 <div class="avatar"> 5 <div class="avatar">
6 - <img src="{{ notification.user.image.url }}"> 6 + <img src="{{ notification.user.image_url }}">
7 </div> 7 </div>
8 <div class="bubble-container"> 8 <div class="bubble-container">
9 <div class="bubble"> 9 <div class="bubble">
core/static/img/no_image.jpg 0 → 100644

2.99 KB

courses/forms.py
1 from django import forms 1 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 Category, Course, Subject, Topic 3 from .models import Category, Course, Subject, Topic
  4 +import datetime
4 5
5 class CategoryForm(forms.ModelForm): 6 class CategoryForm(forms.ModelForm):
6 7
@@ -16,6 +17,32 @@ class CategoryForm(forms.ModelForm): @@ -16,6 +17,32 @@ class CategoryForm(forms.ModelForm):
16 17
17 18
18 class CourseForm(forms.ModelForm): 19 class CourseForm(forms.ModelForm):
  20 + def clean_end_register_date(self):
  21 + init_register_date = self.data['init_register_date']
  22 + end_register_date = self.data['end_register_date']
  23 +
  24 + if init_register_date and end_register_date and end_register_date < init_register_date:
  25 + raise forms.ValidationError(_('The end date may not be before the start date.'))
  26 + return end_register_date
  27 +
  28 + def clean_init_date(self):
  29 + # print(dir(self))
  30 + print (self.data)
  31 + print (self.cleaned_data)
  32 + end_register_date = self.data['end_register_date']
  33 + init_date = self.data['init_date']
  34 +
  35 + if end_register_date and init_date and init_date <= end_register_date:
  36 + raise forms.ValidationError(_('The course start date must be after the end of registration.'))
  37 + return init_date
  38 +
  39 + def clean_end_date(self):
  40 + init_date = self.data['init_date']
  41 + end_date = self.data['end_date']
  42 +
  43 + if init_date and end_date and end_date < init_date:
  44 + raise forms.ValidationError(_('The end date may not be before the start date.'))
  45 + return end_date
19 46
20 class Meta: 47 class Meta:
21 model = Course 48 model = Course
@@ -47,6 +74,8 @@ class CourseForm(forms.ModelForm): @@ -47,6 +74,8 @@ class CourseForm(forms.ModelForm):
47 } 74 }
48 widgets = { 75 widgets = {
49 'categoy': forms.Select(), 76 'categoy': forms.Select(),
  77 + 'objectivies': forms.Textarea(attrs={'cols': 80, 'rows': 5}),
  78 + 'content': forms.Textarea(attrs={'cols': 80, 'rows': 5}),
50 } 79 }
51 80
52 class SubjectForm(forms.ModelForm): 81 class SubjectForm(forms.ModelForm):
courses/migrations/0013_auto_20160916_0001.py 0 → 100644
@@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-09-16 03:01
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations, models
  6 +import django.utils.timezone
  7 +
  8 +
  9 +class Migration(migrations.Migration):
  10 +
  11 + dependencies = [
  12 + ('courses', '0012_course_students'),
  13 + ]
  14 +
  15 + operations = [
  16 + migrations.AddField(
  17 + model_name='subject',
  18 + name='end_date',
  19 + field=models.DateField(default=django.utils.timezone.now, verbose_name='End of Subject Date'),
  20 + preserve_default=False,
  21 + ),
  22 + migrations.AddField(
  23 + model_name='subject',
  24 + name='init_date',
  25 + field=models.DateField(default=django.utils.timezone.now, verbose_name='Begin of Subject Date'),
  26 + preserve_default=False,
  27 + ),
  28 + ]
courses/models.py
@@ -48,6 +48,8 @@ class Subject(models.Model): @@ -48,6 +48,8 @@ class Subject(models.Model):
48 slug = AutoSlugField(_("Slug"),populate_from='name',unique=True) 48 slug = AutoSlugField(_("Slug"),populate_from='name',unique=True)
49 description = models.TextField(_('Description'), blank = True) 49 description = models.TextField(_('Description'), blank = True)
50 visible = models.BooleanField(_('Visible'), default = False) 50 visible = models.BooleanField(_('Visible'), default = False)
  51 + init_date = models.DateField(_('Begin of Subject Date'))
  52 + end_date = models.DateField(_('End of Subject Date'))
51 create_date = models.DateTimeField(_('Creation Date'), auto_now_add = True) 53 create_date = models.DateTimeField(_('Creation Date'), auto_now_add = True)
52 update_date = models.DateTimeField(_('Date of last update'), auto_now=True) 54 update_date = models.DateTimeField(_('Date of last update'), auto_now=True)
53 course = models.ForeignKey(Course, verbose_name = _('Course'), related_name="subjects") 55 course = models.ForeignKey(Course, verbose_name = _('Course'), related_name="subjects")
courses/templates/course/create.html
1 -{% extends 'app/base.html' %} 1 +{% extends 'course/view.html' %}
2 2
3 {% load static i18n %} 3 {% load static i18n %}
4 {% load widget_tweaks %} 4 {% load widget_tweaks %}
@@ -10,45 +10,56 @@ @@ -10,45 +10,56 @@
10 </ol> 10 </ol>
11 {% endblock %} 11 {% endblock %}
12 12
13 -{% block sidebar %}  
14 - <div class="list-group">  
15 - <a href="{% url 'course:manage' %}" class="list-group-item">  
16 - {% trans 'Courses' %}  
17 - </a>  
18 - </div>  
19 -{% endblock %}  
20 -  
21 {% block content %} 13 {% block content %}
22 - <div class="alert alert-info alert-dismissible" role="alert">  
23 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
24 - <span aria-hidden="true">&times;</span>  
25 - </button>  
26 - <p>{% trans 'All fields are required' %}</p>  
27 - </div>  
28 14
29 - <form method="post" action="" enctype="multipart/form-data">  
30 - {% csrf_token %}  
31 - {% for field in form %}  
32 - <div class="form-group{% if form.has_error %} has-error {% endif %}">  
33 - <label for="{{ field.auto_id }}">{{ field.label }}</label>  
34 - {% render_field field class='form-control input-sm' %}  
35 - <span id="helpBlock" class="help-block">{{ field.help_text }}</span>  
36 - {% if field.errors.length > 0 %}  
37 - <div class="alert alert-danger alert-dismissible" role="alert">  
38 - <button type="button" class="close" data-dismiss="alert" aria-label="Close">  
39 - <span aria-hidden="true">&times;</span>  
40 - </button>  
41 - <ul>  
42 - {% for error in field.errors %}  
43 - <li>{{ error }}</li>  
44 - {% endfor %}  
45 - </ul>  
46 - </div>  
47 - </div>  
48 - {% endif %}  
49 - </div>  
50 - {% endfor %}  
51 - <input type="submit" value="{% trans 'Save' %}" class="btn btn-sm btn-success" />  
52 - </form>  
53 - <br clear="all" /> 15 +</br>
  16 +<div class="card card-content">
  17 + <div class="card-body">
  18 + <form method="post" action="" enctype="multipart/form-data">
  19 + {% csrf_token %}
  20 + {% for field in form %}
  21 + <div class="form-group {% if form.has_error %} has-error {% endif %} is-fileinput">
  22 + <label for="{{ field.auto_id }}">{{ field.label }}</label>
  23 + {% if field.auto_id == 'id_init_register_date' or field.auto_id == 'id_end_register_date' or field.auto_id == 'id_init_date' or field.auto_id == 'id_end_date'%}
  24 + {% render_field field class='form-control' type='date' %}
  25 + {% elif field.auto_id == 'id_image' %}
  26 + {% render_field field class='form-control' %}
  27 + <div class="input-group">
  28 + <input type="text" readonly="" class="form-control" placeholder="Choose your photo..."/>
  29 + <span class="input-group-btn input-group-sm">
  30 + <button type="button" class="btn btn-fab btn-fab-mini">
  31 + <i class="material-icons">attach_file</i>
  32 + </button>
  33 + </span>
  34 + </div>
  35 + {% else %}
  36 + {% render_field field class='form-control' %}
  37 + {% endif %}
  38 + <span class="help-block">{{ field.help_text }}</span>
  39 + {% if field.errors %}
  40 + <div class="row">
  41 + </br>
  42 + <div class="alert alert-danger alert-dismissible" role="alert">
  43 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  44 + <span aria-hidden="true">&times;</span>
  45 + </button>
  46 + <ul>
  47 + {% for error in field.errors %}
  48 + <li>{{ error }}</li>
  49 + {% endfor %}
  50 + </ul>
  51 + </div>
  52 + </div>
  53 + {% endif %}
  54 + </div>
  55 + {% endfor %}
  56 + <div class="row text-center">
  57 + <input type="submit" value="{% trans 'Create' %}" class="btn btn-primary" />
  58 + </div>
  59 + </form>
  60 + </div>
  61 +</div>
  62 +</br>
  63 +</br>
  64 +</br>
54 {% endblock %} 65 {% endblock %}
courses/templates/course/view.html
@@ -94,10 +94,10 @@ @@ -94,10 +94,10 @@
94 </p> 94 </p>
95 <div class="row"> 95 <div class="row">
96 <div class="col-xs-6 col-md-6"> 96 <div class="col-xs-6 col-md-6">
97 - {# <p><b>{% trans "Begining" %}: </b>{{subject.init_date}}</p>#} 97 + <p><b>{% trans "Begining" %}: </b>{{subject.init_date}}</p>
98 </div> 98 </div>
99 <div class="col-xs-6 col-md-6"> 99 <div class="col-xs-6 col-md-6">
100 - {# <p><b>End: </b>23/08/2019</p>#} 100 + <p><b>{% trans "End" %}: </b>{{subject.end_date}}</p>
101 </div> 101 </div>
102 </div> 102 </div>
103 </div> 103 </div>
courses/urls.py
@@ -4,7 +4,7 @@ from . import views @@ -4,7 +4,7 @@ from . import views
4 4
5 urlpatterns = [ 5 urlpatterns = [
6 url(r'^$', views.IndexView.as_view(), name='manage'), 6 url(r'^$', views.IndexView.as_view(), name='manage'),
7 - url(r'^create/$', views.CreateView.as_view(), name='create'), 7 + url(r'^create/$', views.CreateCourseView.as_view(), name='create'),
8 url(r'^edit/(?P<slug>[\w_-]+)/$', views.UpdateView.as_view(), name='update'), 8 url(r'^edit/(?P<slug>[\w_-]+)/$', views.UpdateView.as_view(), name='update'),
9 url(r'^(?P<slug>[\w_-]+)/$', views.CourseView.as_view(), name='view'), 9 url(r'^(?P<slug>[\w_-]+)/$', views.CourseView.as_view(), name='view'),
10 url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteView.as_view(), name='delete'), 10 url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteView.as_view(), name='delete'),
courses/views.py
@@ -32,7 +32,7 @@ class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView): @@ -32,7 +32,7 @@ class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView):
32 32
33 return context 33 return context
34 34
35 -class CreateView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edit.CreateView): 35 +class CreateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edit.CreateView):
36 36
37 allowed_roles = ['professor', 'system_admin'] 37 allowed_roles = ['professor', 'system_admin']
38 login_url = reverse_lazy("core:home") 38 login_url = reverse_lazy("core:home")
@@ -41,17 +41,9 @@ class CreateView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edi @@ -41,17 +41,9 @@ class CreateView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edi
41 form_class = CourseForm 41 form_class = CourseForm
42 success_url = reverse_lazy('course:manage') 42 success_url = reverse_lazy('course:manage')
43 def form_valid(self, form): 43 def form_valid(self, form):
44 - self.object = form.save(commit = False)  
45 - self.object.slug = slugify(self.object.name)  
46 - print('Fooooiiii!!')  
47 - self.object.save()  
48 -  
49 - return super(CreateView, self).form_valid(form)  
50 -  
51 - def render_to_response(self, context, **response_kwargs):  
52 - messages.success(self.request, _('Course created successfully!'))  
53 -  
54 - return self.response_class(request=self.request, template=self.get_template_names(), context=context, using=self.template_engine) 44 + self.object = form.save()
  45 + self.object.professors.add(self.request.user)
  46 + return super(CreateCourseView, self).form_valid(form)
55 47
56 class UpdateView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): 48 class UpdateView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView):
57 49
@@ -87,7 +79,7 @@ class CourseView(LoginRequiredMixin, NotificationMixin, generic.DetailView): @@ -87,7 +79,7 @@ class CourseView(LoginRequiredMixin, NotificationMixin, generic.DetailView):
87 context = super(CourseView, self).get_context_data(**kwargs) 79 context = super(CourseView, self).get_context_data(**kwargs)
88 course = get_object_or_404(Course, slug = self.kwargs.get('slug')) 80 course = get_object_or_404(Course, slug = self.kwargs.get('slug'))
89 if has_role(self.request.user,'system_admin'): 81 if has_role(self.request.user,'system_admin'):
90 - subjects = Subject.objects.all() 82 + subjects = course.subjects.all()
91 elif has_role(self.request.user,'professor'): 83 elif has_role(self.request.user,'professor'):
92 subjects = course.subjects.filter(professors__in=[self.request.user]) 84 subjects = course.subjects.filter(professors__in=[self.request.user])
93 elif has_role(self.request.user, 'student'): 85 elif has_role(self.request.user, 'student'):
users/admin.py
1 from django.contrib import admin 1 from django.contrib import admin
2 from .models import User 2 from .models import User
3 -from .forms import ProfileForm 3 +from .forms import UserForm
4 4
5 class UserAdmin(admin.ModelAdmin): 5 class UserAdmin(admin.ModelAdmin):
6 list_display = ['username', 'name', 'email', 'is_staff', 'is_active'] 6 list_display = ['username', 'name', 'email', 'is_staff', 'is_active']
7 search_fields = ['username', 'name', 'email'] 7 search_fields = ['username', 'name', 'email']
8 - form = ProfileForm 8 + form = UserForm
9 9
10 admin.site.register(User, UserAdmin) 10 admin.site.register(User, UserAdmin)
11 \ No newline at end of file 11 \ No newline at end of file
users/forms.py
1 # coding=utf-8 1 # coding=utf-8
2 - 2 +import os
  3 +from django.conf import settings
3 from django import forms 4 from django import forms
4 from django.utils.translation import ugettext_lazy as _ 5 from django.utils.translation import ugettext_lazy as _
  6 +from rolepermissions.shortcuts import assign_role
5 from .models import User 7 from .models import User
6 8
7 9
@@ -25,10 +27,32 @@ class ProfileForm(forms.ModelForm): @@ -25,10 +27,32 @@ class ProfileForm(forms.ModelForm):
25 } 27 }
26 28
27 class UserForm(forms.ModelForm): 29 class UserForm(forms.ModelForm):
  30 + def save(self, commit=True):
  31 + super(UserForm, self).save(commit=False)
  32 +
  33 + #if not self.instance.image:
  34 + # self.instance.image = os.path.join(os.path.dirname(settings.BASE_DIR), 'uploads', 'no_image.jpg')
  35 +
  36 + self.instance.set_password(self.cleaned_data['password'])
  37 + self.instance.save()
  38 +
  39 + if self.instance.is_staff:
  40 + assign_role(self.instance, 'system_admin')
  41 + elif self.instance.type_profile == 2:
  42 + assign_role(self.instance, 'student')
  43 + elif self.instance.type_profile == 1:
  44 + assign_role(self.instance, 'professor')
  45 +
  46 + self.instance.save()
  47 +
  48 + return self.instance
28 49
29 class Meta: 50 class Meta:
30 model = User 51 model = User
31 - fields = ['username', 'name', 'email', 'birth_date', 'city', 'state', 'gender', 'type_profile', 'cpf', 'phone', 'image', 'is_staff', 'is_active'] 52 + fields = ['username', 'name', 'email', 'password', 'birth_date', 'city', 'state', 'gender', 'type_profile', 'cpf', 'phone', 'image', 'is_staff', 'is_active']
  53 + widgets = {
  54 + 'password':forms.PasswordInput
  55 + }
32 56
33 class EditUserForm(forms.ModelForm): 57 class EditUserForm(forms.ModelForm):
34 58
users/migrations/0013_auto_20160915_2334.py 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10 on 2016-09-16 02:34
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations, models
  6 +
  7 +
  8 +class Migration(migrations.Migration):
  9 +
  10 + dependencies = [
  11 + ('users', '0012_auto_20160908_1625'),
  12 + ]
  13 +
  14 + operations = [
  15 + migrations.AlterField(
  16 + model_name='user',
  17 + name='image',
  18 + field=models.ImageField(blank=True, upload_to='users/', verbose_name='Image'),
  19 + ),
  20 + ]
users/models.py
@@ -4,6 +4,7 @@ from django.db import models @@ -4,6 +4,7 @@ from django.db import models
4 from django.core import validators 4 from django.core import validators
5 from django.utils.translation import ugettext_lazy as _ 5 from django.utils.translation import ugettext_lazy as _
6 from django.contrib.auth.models import AbstractBaseUser, UserManager, PermissionsMixin 6 from django.contrib.auth.models import AbstractBaseUser, UserManager, PermissionsMixin
  7 +from django.contrib.staticfiles.templatetags.staticfiles import static
7 8
8 class User(AbstractBaseUser, PermissionsMixin): 9 class User(AbstractBaseUser, PermissionsMixin):
9 10
@@ -19,7 +20,7 @@ class User(AbstractBaseUser, PermissionsMixin): @@ -19,7 +20,7 @@ class User(AbstractBaseUser, PermissionsMixin):
19 city = models.CharField(_('City'), max_length = 90, blank = True) 20 city = models.CharField(_('City'), max_length = 90, blank = True)
20 state = models.CharField(_('State'), max_length = 30, blank = True) 21 state = models.CharField(_('State'), max_length = 30, blank = True)
21 gender = models.CharField(_('Gender'), max_length = 1, choices = (('M', _('Male')), ('F', _('Female')))) 22 gender = models.CharField(_('Gender'), max_length = 1, choices = (('M', _('Male')), ('F', _('Female'))))
22 - image = models.ImageField(verbose_name = _('Image'), blank = True, upload_to = 'users/', default = 'no_image.jpg') 23 + image = models.ImageField(verbose_name = _('Image'), blank = True, upload_to = 'users/')
23 birth_date = models.DateField(_('Birth Date'), null = True, blank = True) 24 birth_date = models.DateField(_('Birth Date'), null = True, blank = True)
24 phone = models.CharField(_('Phone'), max_length = 30, blank = True) 25 phone = models.CharField(_('Phone'), max_length = 30, blank = True)
25 cpf = models.CharField(_('Cpf'), max_length = 15, blank = True) 26 cpf = models.CharField(_('Cpf'), max_length = 15, blank = True)
@@ -40,8 +41,15 @@ class User(AbstractBaseUser, PermissionsMixin): @@ -40,8 +41,15 @@ class User(AbstractBaseUser, PermissionsMixin):
40 def __str__(self): 41 def __str__(self):
41 return self.name or self.username 42 return self.name or self.username
42 43
43 - def det_full_name(self): 44 + def get_full_name(self):
44 return str(self) 45 return str(self)
45 46
46 def get_short_name(self): 47 def get_short_name(self):
47 - return str(self).split(" ")[0]  
48 \ No newline at end of file 48 \ No newline at end of file
  49 + return str(self).split(" ")[0]
  50 +
  51 + @property
  52 + def image_url(self):
  53 + if self.image and hasattr(self.image, 'url'):
  54 + return self.image.url
  55 + else:
  56 + return static('img/no_image.jpg')
49 \ No newline at end of file 57 \ No newline at end of file