Commit e36918f284c6051bd9be3ef7a14a2f82089ca7c1

Authored by Jailson Dias
2 parents d99b5261 786f5747

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

amadeus/static/css/.sass-cache/a7f87b90919294b62ab4f8079e31dcda8f485534/green.sassc
No preview for this file type
amadeus/static/css/base/amadeus.css
... ... @@ -448,6 +448,7 @@ a:focus {
448 448 padding-bottom: 200px;
449 449 }
450 450 .panel-info{
  451 + margin-top: 10px;
451 452 }
452 453 .panel-default{
453 454 }
... ... @@ -1228,6 +1229,27 @@ div.dataTables_wrapper div.dataTables_paginate {
1228 1229 margin-right: 30px;
1229 1230 }
1230 1231  
  1232 +.form-field-report{
  1233 + color: #000000 !important;
  1234 +}
  1235 +
  1236 +.resource-tag-formset{
  1237 + width: 100%;
  1238 + display: inline-block;
  1239 + padding: 15px;
  1240 +}
  1241 +
  1242 +
  1243 +.report-resource-form{
  1244 + width: 30%;
  1245 + float: left;
  1246 +}
  1247 +
  1248 +#resources_accordion .panel-heading{
  1249 + background-color: #c4c4c4 !important;
  1250 +
  1251 +}
  1252 +
1231 1253 .delete-row{
1232 1254 float: right;
1233 1255 background-color: gray;
... ... @@ -1277,7 +1299,7 @@ div.dataTables_wrapper div.dataTables_paginate {
1277 1299 /* End Reports */
1278 1300  
1279 1301 /* Chat */
1280   -.participants-group {
  1302 +.participants-group, .talks-group {
1281 1303 margin-left: 40px;
1282 1304 }
1283 1305  
... ... @@ -1407,4 +1429,13 @@ div.dataTables_wrapper div.dataTables_paginate {
1407 1429 border-width: 1px;
1408 1430 border-style: solid;
1409 1431 }
  1432 +
  1433 +.talking-header {
  1434 + line-height: 0.5 !important;
  1435 + margin-top: 0px;
  1436 +}
  1437 +
  1438 +.talk-last_msg {
  1439 + font-size: 14px;
  1440 +}
1410 1441 /* End Chat */
1411 1442 \ No newline at end of file
... ...
amadeus/static/css/themes/green.css
... ... @@ -501,6 +501,9 @@ a.add-row {
501 501 background-color: #FFFFFF;
502 502 border-color: #888888; }
503 503  
  504 +.talk-last_msg {
  505 + color: #888; }
  506 +
504 507 @media(max-width: 768px) {
505 508 .navbar .navbar-nav .dropdown .dropdown-menu li > a {
506 509 color: #333333 !important; }
... ...
amadeus/static/css/themes/green.css.map
1 1 {
2 2 "version": 3,
3   -"mappings": "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",
  3 +"mappings": "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",
4 4 "sources": ["green.sass"],
5 5 "names": [],
6 6 "file": "green.css"
... ...
amadeus/static/css/themes/green.sass
... ... @@ -673,6 +673,9 @@ a.add-row
673 673 background-color: $white
674 674 border-color: #888888
675 675  
  676 +.talk-last_msg
  677 + color: #888
  678 +
676 679 @media(max-width: 768px)
677 680 .navbar .navbar-nav .dropdown .dropdown-menu li > a
678 681 color: #333333 !important
... ...
amadeus/static/js/chat.js
1   -function getModalInfo(btn, space) {
  1 +function getModalInfo(btn, space, space_type) {
2 2 var url = btn.data('url');
3 3  
4 4 $.ajax({
5 5 method: 'get',
6 6 url: url,
7   - data: {'space': space},
  7 + data: {'space': space, 'space_type': space_type},
8 8 success: function (response) {
9 9 $("#chat-modal-info").html(response);
10 10  
... ... @@ -13,4 +13,51 @@ function getModalInfo(btn, space) {
13 13 $.material.init();
14 14 }
15 15 });
  16 +}
  17 +
  18 +function getForm(field) {
  19 + var url = field.find('h4').data('url');
  20 +
  21 + $.ajax({
  22 + url: url,
  23 + success: function (data) {
  24 + $('#chat-modal-form').html(data);
  25 +
  26 + setChatFormSubmit();
  27 +
  28 + $('#chat-modal-form').modal('show');
  29 + }
  30 + });
  31 +}
  32 +
  33 +function setChatFormSubmit() {
  34 + var frm = $('#chat-form');
  35 +
  36 + frm.submit(function () {
  37 + var formData = new FormData($(this)[0]);
  38 +
  39 + $.ajax({
  40 + type: frm.attr('method'),
  41 + url: frm.attr('action'),
  42 + data: formData,
  43 + dataType: "json",
  44 + async: false,
  45 + success: function (data) {
  46 + $('.messages-container').append(data.view);
  47 +
  48 + $('#chat-modal-form').modal('hide');
  49 +
  50 + alertify.success(data.message);
  51 + },
  52 + error: function(data) {
  53 + $("#chat-modal-form").html(data.responseText);
  54 + setChatFormSubmit();
  55 + },
  56 + cache: false,
  57 + contentType: false,
  58 + processData: false
  59 + });
  60 +
  61 + return false;
  62 + });
16 63 }
17 64 \ No newline at end of file
... ...
chat/forms.py 0 → 100644
... ... @@ -0,0 +1,44 @@
  1 +# coding=utf-8
  2 +from django import forms
  3 +from django.utils.translation import ugettext_lazy as _
  4 +from django.utils.html import strip_tags
  5 +from django.db.models import Q
  6 +
  7 +from resubmit.widgets import ResubmitFileWidget
  8 +
  9 +from .models import TalkMessages
  10 +
  11 +class Validation(forms.ModelForm):
  12 + MAX_UPLOAD_SIZE = 5*1024*1024
  13 +
  14 + def clean_text(self):
  15 + text = self.cleaned_data.get('text', '')
  16 + cleaned_text = strip_tags(text)
  17 +
  18 + if cleaned_text == '':
  19 + self._errors['text'] = [_('This field is required.')]
  20 +
  21 + return ValueError
  22 +
  23 + return text
  24 +
  25 + def clean_image(self):
  26 + image = self.cleaned_data.get('image', False)
  27 +
  28 + if image:
  29 + if hasattr(image, '_size'):
  30 + if image._size > self.MAX_UPLOAD_SIZE:
  31 + self._errors['image'] = [_("The image is too large. It should have less than 5MB.")]
  32 +
  33 + return ValueError
  34 +
  35 + return image
  36 +
  37 +class ChatMessageForm(Validation):
  38 + class Meta:
  39 + model = TalkMessages
  40 + fields = ['text', 'image']
  41 + widgets = {
  42 + 'text': forms.Textarea,
  43 + 'image': ResubmitFileWidget(attrs={'accept':'image/*'}),
  44 + }
0 45 \ No newline at end of file
... ...
chat/models.py
... ... @@ -36,13 +36,13 @@ class CategoryTalk(Conversation):
36 36 space = models.ForeignKey(Category, verbose_name = ('Category'), related_name = 'talk_category', null = True)
37 37  
38 38 class SubjectTalk(Conversation):
39   - space = models.ForeignKey(Subject, verbose_name = _('Subject'), related_name = 'talk_subject')
  39 + space = models.ForeignKey(Subject, verbose_name = _('Subject'), related_name = 'talk_subject', null = True)
40 40  
41 41 class TalkMessages(models.Model):
42 42 text = models.TextField(_('Comment'), blank = True)
43   - image = models.ImageField(verbose_name = _('Image'), null=True, blank = True, upload_to = upload_filename, validators = [validate_img_extension])
44   - talk = models.ForeignKey(Conversation, verbose_name = _('Conversation'), related_name = 'message_talk')
45   - user = models.ForeignKey(User, verbose_name = _('User'), related_name = 'message_user')
  43 + image = models.ImageField(verbose_name = _('Image'), null = True, blank = True, upload_to = upload_filename, validators = [validate_img_extension])
  44 + talk = models.ForeignKey(Conversation, verbose_name = _('Conversation'), related_name = 'message_talk', null = True)
  45 + user = models.ForeignKey(User, verbose_name = _('User'), related_name = 'message_user', null = True)
46 46 create_date = models.DateTimeField(_('Create Date'), auto_now_add = True)
47 47  
48 48 class ChatVisualizations(models.Model):
... ...
chat/templates/chat/_form.html 0 → 100644
... ... @@ -0,0 +1,113 @@
  1 +{% load static i18n %}
  2 +{% load widget_tweaks %}
  3 +
  4 +<div class="modal-dialog" role="document">
  5 + <div class="modal-content">
  6 + <div class="modal-body">
  7 + <form id="chat-form" method="post" action="{{ form_url }}" enctype="multipart/form-data">
  8 + {% csrf_token %}
  9 +
  10 + <div class="form-group{% if form.has_error %} has-error {% endif %}">
  11 + <label for="{{ form.text.auto_id }}">{{ form.text.label }} <span>*</span></label>
  12 + {% render_field form.text class='form-control text_simple_wysiwyg' %}
  13 +
  14 + <span id="helpBlock" class="help-block">{{ form.text.help_text }}</span>
  15 +
  16 + {% if form.text.errors %}
  17 + <div class="alert alert-danger alert-dismissible" role="alert">
  18 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  19 + <span aria-hidden="true">&times;</span>
  20 + </button>
  21 + <ul>
  22 + {% for error in form.text.errors %}
  23 + <li>{{ error }}</li>
  24 + {% endfor %}
  25 + </ul>
  26 + </div>
  27 + {% endif %}
  28 + </div>
  29 +
  30 + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">
  31 + {% render_field form.image %}
  32 +
  33 + <div class="filedrag">
  34 + {% trans 'Click or drop the file here' %}<br />
  35 +
  36 + <small>{% trans 'The file could not exceed 5MB.' %}</small>
  37 + </div>
  38 +
  39 + <span id="helpBlock" class="help-block">{{ form.image.help_text }}</span>
  40 +
  41 + {% if form.image.errors %}
  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 form.image.errors %}
  48 + <li>{{ error }}</li>
  49 + {% endfor %}
  50 + </ul>
  51 + </div>
  52 + {% endif %}
  53 + </div>
  54 + </form>
  55 + </div>
  56 + <div class="modal-footer">
  57 + <div class="col-md-12">
  58 + <button type="submit" id="button" form="chat-form" class="btn btn-success btn-raised post-button pull-left">{% trans "Save" %}</button>
  59 + <button type="button" class="btn btn-raised btn-default pull-right" data-dismiss="modal">{% trans "Cancel" %}</button>
  60 + </div>
  61 + </div>
  62 + </div>
  63 +</div>
  64 +
  65 +<script type="text/javascript">
  66 + $(function () {
  67 + $('.text_simple_wysiwyg').summernote({
  68 + dialogsInBody: true,
  69 + height: 150,
  70 + toolbar: [
  71 + // [groupName, [list of button]]
  72 + ['style', ['bold', 'italic']],
  73 + ['insert', ['link']]
  74 + ]
  75 + });
  76 +
  77 + $.material.init();
  78 +
  79 + if (window.File && window.FileList && window.FileReader) {
  80 + Init();
  81 + }
  82 + });
  83 +
  84 + // initialize
  85 + function Init() {
  86 + var small = $("#id_image"),
  87 + filedrag = $(".filedrag"),
  88 + common = $(".common-file-input");
  89 +
  90 + // file select
  91 + small.on("change", FileSelectHandler);
  92 +
  93 + // is XHR2 available?
  94 + var xhr = new XMLHttpRequest();
  95 + if (xhr.upload) {
  96 + // file drop
  97 + filedrag.on("drop", FileSelectHandler);
  98 + filedrag.attr('style', 'display:block');
  99 + common.attr('style', 'display:none');
  100 + }
  101 + }
  102 +
  103 + // file selection
  104 + function FileSelectHandler(e) {
  105 + var files = e.target.files || e.dataTransfer.files,
  106 + parent = $(e.target.offsetParent);
  107 +
  108 + // process all File objects
  109 + for (var i = 0, f; f = files[i]; i++) {
  110 + parent.find('.filedrag').html(f.name);
  111 + }
  112 + }
  113 +</script>
... ...
chat/templates/chat/_message.html 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +<div class="col-md-12">
  2 + <p>{{ talk_msg.user }}</p>
  3 + {% autoescape off %}
  4 + {{ talk_msg.text }}
  5 + {% endautoescape %}
  6 +</div>
0 7 \ No newline at end of file
... ...
chat/templates/chat/_profile.html
... ... @@ -17,7 +17,7 @@
17 17 <a class="status {{ status }}" title="{{ status|status_text }}"></a>
18 18 <b>{{ participant }}</b>
19 19 </h4>
20   - <a href="#" onclick="getModalInfo($(this), '{{ space }}'); return false;" data-url='{% url "chat:talk" participant.email %}' class="btn btn-raised btn-success btn-block">{% trans 'Send Message' %}</a>
  20 + <a href="#" onclick="getModalInfo($(this), '{{ space }}', '{{ space_type }}'); return false;" data-url='{% url "chat:talk" participant.email %}' class="btn btn-raised btn-success btn-block">{% trans 'Send Message' %}</a>
21 21 </div>
22 22 <div class="col-md-8">
23 23 <div class="form-group">
... ...
chat/templates/chat/_view.html 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +{% load i18n chat_tags %}
  2 +
  3 +{% chat_user request.user chat as talking_to %}
  4 +
  5 +{% is_online talking_to as status %}
  6 +
  7 +<div class="col-md-12 participant panel">
  8 + <div class="col-md-1 user-img">
  9 + <img src="{{ talking_to.image_url }}" class="img-responsive" />
  10 + </div>
  11 + <div class="col-md-6 user-info">
  12 + <h4 class='talking-header'><a class="status {{ status }}" data-toggle="tooltip" title="{{ status|status_text }}"></a> {{ talking_to }}</h4>
  13 + <p class="talk-last_msg">{% trans 'Last message in' %} {{ chat|last_message }}</p>
  14 + </div>
  15 + <div class="col-md-4 buttons pull-right text-center">
  16 + <a href="#" onclick="getModalInfo($(this), '{{ space }}', '{{ space_type }}'); return false;" data-url='{% url "chat:talk" talking_to.email %}' class="btn btn-raised btn-success pull-right">{% trans 'Access Talk' %}</a>
  17 + </div>
  18 +</div>
... ...
chat/templates/chat/_view_participant.html
... ... @@ -10,7 +10,7 @@
10 10 <h4><a class="status {{ status }}" data-toggle="tooltip" title="{{ status|status_text }}"></a> {{ participant }}</h4>
11 11 </div>
12 12 <div class="col-md-4 buttons pull-right text-center">
13   - <a href="#" onclick="getModalInfo($(this), '{{ space }}'); return false;" data-url='{% url "chat:profile" participant.email %}' class="btn btn-raised btn-default">{% trans 'See Profile' %}</a>
14   - <a href="#" onclick="getModalInfo($(this), '{{ space }}'); return false;" data-url='{% url "chat:talk" participant.email %}' class="btn btn-raised btn-success">{% trans 'Send Message' %}</a>
  13 + <a href="#" onclick="getModalInfo($(this), '{{ space }}', '{{ space_type }}'); return false;" data-url='{% url "chat:profile" participant.email %}' class="btn btn-raised btn-default">{% trans 'See Profile' %}</a>
  14 + <a href="#" onclick="getModalInfo($(this), '{{ space }}', '{{ space_type }}'); return false;" data-url='{% url "chat:talk" participant.email %}' class="btn btn-raised btn-success">{% trans 'Send Message' %}</a>
15 15 </div>
16 16 </div>
... ...
chat/templates/chat/list.html
... ... @@ -49,9 +49,11 @@
49 49 <div class="panel panel-info panel-body">
50 50 <h2 class="my-subjects-title"><b>{% trans 'Conversations' %}</b></h2>
51 51  
52   - {% for chat in conversations %}
53   - {% include 'chat/_view.html' %}
54   - {% endfor %}
  52 + <div class="talks-group">
  53 + {% for chat in conversations %}
  54 + {% include 'chat/_view.html' with space="0" space_type='general' %}
  55 + {% endfor %}
  56 + </div>
55 57 </div>
56 58 {% else %}
57 59 <div class="text-center no-subjects">
... ... @@ -63,5 +65,9 @@
63 65 </div>
64 66 </div>
65 67  
66   - <div class="modal fade" id="post-modal-form" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  68 + <div class="modal fade" id="chat-modal-info" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  69 +
  70 + <div class="modal fade" id="chat-modal-form" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  71 +
  72 + <script type="text/javascript" src="{% static 'js/chat.js' %}"></script>
67 73 {% endblock %}
68 74 \ No newline at end of file
... ...
chat/templates/chat/list_participants.html
... ... @@ -53,7 +53,7 @@
53 53  
54 54 <div class="participants-group">
55 55 {% for participant in participants %}
56   - {% include 'chat/_view_participant.html' with space="0" %}
  56 + {% include 'chat/_view_participant.html' with space="0" space_type='general' %}
57 57 {% endfor %}
58 58 </div>
59 59  
... ... @@ -71,5 +71,7 @@
71 71  
72 72 <div class="modal fade" id="chat-modal-info" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
73 73  
  74 + <div class="modal fade" id="chat-modal-form" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"></div>
  75 +
74 76 <script type="text/javascript" src="{% static 'js/chat.js' %}"></script>
75 77 {% endblock %}
76 78 \ No newline at end of file
... ...
chat/templates/chat/talk.html
... ... @@ -39,6 +39,9 @@
39 39 </div>
40 40 <div class="row-fluid">
41 41 <div class="messages-container">
  42 + {% for talk_msg in messages %}
  43 + {% include 'chat/_message.html' %}
  44 + {% endfor %}
42 45 </div>
43 46 </div>
44 47 </div>
... ... @@ -49,9 +52,9 @@
49 52 <img src="{{ request.user.image_url }}" class="img-responsive" />
50 53 </div>
51 54 </div>
52   - <div class="col-lg-11 col-md-11 col-sm-11 col-xs-11 message-field" onclick="comment($(this))">
53   - <div>
54   - <h4 data-url="">{% trans 'Type a new message to ' %}{{ participant }} <i class="fa fa-camera pull-right"></i></h4>
  55 + <div class="col-lg-11 col-md-11 col-sm-11 col-xs-11 message-field">
  56 + <div onclick="getForm($(this));">
  57 + <h4 data-url="{% url 'chat:create' participant.email talk_id space space_type %}">{% trans 'Type a new message to ' %}{{ participant }} <i class="fa fa-camera pull-right"></i></h4>
55 58 </div>
56 59 </div>
57 60 </div>
... ...
chat/templatetags/chat_tags.py
... ... @@ -7,6 +7,8 @@ from django.contrib.sessions.models import Session
7 7  
8 8 from log.models import Log
9 9  
  10 +from chat.models import TalkMessages
  11 +
10 12 register = template.Library()
11 13  
12 14 @register.assignment_tag(name = 'is_online')
... ... @@ -34,4 +36,17 @@ def status_text(status):
34 36 elif status == "away":
35 37 return _('Away')
36 38 else:
37   - return _("Offline")
38 39 \ No newline at end of file
  40 + return _("Offline")
  41 +
  42 +@register.assignment_tag(name = 'chat_user')
  43 +def chat_user(user, chat):
  44 + if chat.user_one == user:
  45 + return chat.user_two
  46 +
  47 + return chat.user_one
  48 +
  49 +@register.filter(name = 'last_message')
  50 +def last_message(chat):
  51 + last_message = TalkMessages.objects.filter(talk = chat).order_by('-create_date')[0]
  52 +
  53 + return last_message.create_date
39 54 \ No newline at end of file
... ...
chat/urls.py
... ... @@ -4,6 +4,8 @@ from . import views
4 4 urlpatterns = [
5 5 url(r'^$', views.GeneralIndex.as_view(), name='manage_general'),
6 6 url(r'^participants/$', views.GeneralParticipants.as_view(), name='participants_general'),
  7 + url(r'^render_message/([\w_-]+)/$', views.render_message, name='render_message'),
7 8 url(r'^talk/(?P<email>[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/$', views.GetTalk.as_view(), name = 'talk'),
  9 + url(r'^send_message/(?P<email>[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/(?P<talk_id>[\w_-]+)/(?P<space>[\w_-]+)/(?P<space_type>[\w_-]+)/$', views.SendMessage.as_view(), name = 'create'),
8 10 url(r'^participant/profile/(?P<email>[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})/$', views.ParticipantProfile.as_view(), name = 'profile'),
9 11 ]
10 12 \ No newline at end of file
... ...
chat/views.py
... ... @@ -10,9 +10,12 @@ from django.utils.translation import ugettext_lazy as _
10 10 from django.contrib.auth.mixins import LoginRequiredMixin
11 11 from django.db.models import Q
12 12  
  13 +from categories.models import Category
  14 +from subjects.models import Subject
13 15 from users.models import User
14 16  
15   -from .models import Conversation, TalkMessages, ChatVisualizations
  17 +from .models import Conversation, GeneralTalk, CategoryTalk, SubjectTalk, TalkMessages, ChatVisualizations
  18 +from .forms import ChatMessageForm
16 19  
17 20 class GeneralIndex(LoginRequiredMixin, generic.ListView):
18 21 login_url = reverse_lazy("users:login")
... ... @@ -75,6 +78,24 @@ class GeneralParticipants(LoginRequiredMixin, generic.ListView):
75 78  
76 79 return context
77 80  
  81 +class ParticipantProfile(LoginRequiredMixin, generic.DetailView):
  82 + login_url = reverse_lazy("users:login")
  83 + redirect_field_name = 'next'
  84 +
  85 + model = User
  86 + slug_field = 'email'
  87 + slug_url_kwarg = 'email'
  88 + context_object_name = 'participant'
  89 + template_name = 'chat/_profile.html'
  90 +
  91 + def get_context_data(self, **kwargs):
  92 + context = super(ParticipantProfile, self).get_context_data(**kwargs)
  93 +
  94 + context['space'] = self.request.GET.get('space', '0')
  95 + context['space_type'] = self.request.GET.get('space_type', 'general')
  96 +
  97 + return context
  98 +
78 99 class GetTalk(LoginRequiredMixin, generic.ListView):
79 100 login_url = reverse_lazy("users:login")
80 101 redirect_field_name = 'next'
... ... @@ -82,6 +103,7 @@ class GetTalk(LoginRequiredMixin, generic.ListView):
82 103 context_object_name = 'messages'
83 104 template_name = 'chat/talk.html'
84 105 paginate_by = 20
  106 + talk_id = "-1"
85 107  
86 108 def get_queryset(self):
87 109 user = self.request.user
... ... @@ -93,6 +115,7 @@ class GetTalk(LoginRequiredMixin, generic.ListView):
93 115  
94 116 if talks.count() > 0:
95 117 talk = talks[0]
  118 + self.talk_id = talk.id
96 119  
97 120 messages = TalkMessages.objects.filter(talk = talk).order_by('-create_date')
98 121  
... ... @@ -104,22 +127,93 @@ class GetTalk(LoginRequiredMixin, generic.ListView):
104 127 user_email = self.kwargs.get('email', '')
105 128  
106 129 context['participant'] = get_object_or_404(User, email = user_email)
  130 + context['talk_id'] = self.talk_id
  131 + context['space'] = self.request.GET.get('space', '0')
  132 + context['space_type'] = self.request.GET.get('space_type', 'general')
107 133  
108 134 return context
109 135  
110   -class ParticipantProfile(LoginRequiredMixin, generic.DetailView):
  136 +class SendMessage(LoginRequiredMixin, generic.edit.CreateView):
111 137 login_url = reverse_lazy("users:login")
112 138 redirect_field_name = 'next'
113 139  
114   - model = User
115   - slug_field = 'email'
116   - slug_url_kwarg = 'email'
117   - context_object_name = 'participant'
118   - template_name = 'chat/_profile.html'
  140 + form_class = ChatMessageForm
  141 + template_name = "chat/_form.html"
  142 +
  143 + def form_invalid(self, form):
  144 + context = super(SendMessage, self).form_invalid(form)
  145 + context.status_code = 400
  146 +
  147 + return context
  148 +
  149 + def form_valid(self, form):
  150 + self.object = form.save(commit = False)
  151 +
  152 + self.object.user = self.request.user
  153 +
  154 + talk_id = self.kwargs.get('talk_id', '-1')
  155 + user = get_object_or_404(User, email = self.kwargs.get('email', ''))
  156 + space_type = self.kwargs.get('space_type', 'general')
  157 + space = self.kwargs.get('space', 0)
  158 +
  159 + if talk_id == "-1":
  160 + if space_type == 'general':
  161 + talk = GeneralTalk.objects.create(user_one = self.request.user, user_two = user, space = 0)
  162 + elif space_type == 'category':
  163 + cat = get_object_or_404(Category, id = space)
  164 + talk = CategoryTalk.objects.create(user_one = self.request.user, user_two = user, space = cat)
  165 + else:
  166 + sub = get_object_or_404(Subject, id = space)
  167 + talk = SubjectTalk.objects.create(user_one = self.request.user, user_two = user, space = sub)
  168 + else:
  169 + talk = get_object_or_404(Conversation, id = talk_id)
  170 +
  171 + self.object.talk = talk
  172 +
  173 + self.object.save()
  174 +
  175 + #entries = []
  176 +
  177 + #paths = [reverse("mural:manage_general")]
  178 +
  179 + #notification = {
  180 + # "type": "mural",
  181 + # "subtype": "post",
  182 + # "paths": paths,
  183 + # "user_icon": self.object.user.image_url,
  184 + # "simple_notify": _("%s has made a post in General")%(str(self.object.user)),
  185 + # "complete": render_to_string("mural/_view.html", {"post": self.object}, self.request),
  186 + # "container": ".post",
  187 + # "accordion": False,
  188 + # "post_type": "general"
  189 + #}
  190 +
  191 + #notification = json.dumps(notification)
  192 +
  193 + #Group("user-%s" % user.id).send({'text': notification})
  194 +
  195 + ChatVisualizations.objects.create(viewed = False, message = self.object, user = user)
  196 +
  197 + return super(SendMessage, self).form_valid(form)
119 198  
120 199 def get_context_data(self, **kwargs):
121   - context = super(ParticipantProfile, self).get_context_data(**kwargs)
  200 + context = super(SendMessage, self).get_context_data(**kwargs)
122 201  
123   - context['space'] = self.request.GET.get('space', '0')
  202 + context['form_url'] = reverse_lazy('chat:create', args = (), kwargs = {'email': self.kwargs.get('email', ''), 'talk_id': self.kwargs.get('talk_id', None), 'space': self.kwargs.get('space', '0'), 'space_type': self.kwargs.get('space_type', 'general')})
124 203  
125   - return context
126 204 \ No newline at end of file
  205 + return context
  206 +
  207 + def get_success_url(self):
  208 + return reverse_lazy('chat:render_message', args = (self.object.id, ))
  209 +
  210 +def render_message(request, talk_msg):
  211 + msg = get_object_or_404(TalkMessages, id = talk_msg)
  212 +
  213 + context = {}
  214 + context['talk_msg'] = msg
  215 +
  216 + message = _('Message sent successfully!')
  217 +
  218 + html = render_to_string("chat/_message.html", context, request)
  219 +
  220 + return JsonResponse({'message': message, 'view': html, 'new_id': msg.id})
127 221 \ No newline at end of file
... ...
reports/forms.py
... ... @@ -11,34 +11,34 @@ class BaseResourceAndTagFormset(BaseFormSet):
11 11 Adds validation to check that no two links have the same anchor or URL
12 12 and that all links have both an anchor and URL.
13 13 """
14   - print("here 2")
15 14 print(self.errors)
16 15 if any(self.errors):
17 16 return
18 17  
19 18 for form in self.forms:
20   - print(form)
  19 + pass
21 20  
22 21 class ResourceAndTagForm(forms.Form):
23 22  
24 23 resource = forms.ChoiceField(label=_("Kind Of Resource"), required=True)
25   - tag = forms.ChoiceField(label=_('Tag'), required=True)
  24 + tag = forms.ChoiceField(label=_('Tag'))
26 25  
27 26 def __init__(self, *args, **kwargs):
28 27 super(ResourceAndTagForm, self).__init__(*args, **kwargs)
29 28 if kwargs.get('initial'):
30 29 initial = kwargs['initial']
31   - self.fields['resource'].choices = [(classes.__name__, classes.__name__) for classes in initial['class_name']]
  30 + self.fields['resource'].choices = [(classes.__name__.lower(), classes.__name__.lower()) for classes in initial['class_name']]
32 31 self.fields['tag'].choices = [(tag.id, tag.name) for tag in initial['tag']]
  32 +
33 33  
34 34  
35 35 class CreateInteractionReportForm(forms.Form):
36   - topic = forms.ChoiceField( label= _("Topics to select data from"))
37   - init_date = forms.DateField()
38   - end_date = forms.DateField()
  36 + topic = forms.ChoiceField( label= _("Topics"), required=True)
  37 + init_date = forms.DateField(required=True, label= _("Initial Date"))
  38 + end_date = forms.DateField(required=True, label= _("Final Date"))
39 39  
40   - from_mural = forms.BooleanField(required=False)
41   - from_messages = forms.BooleanField(required=False)
  40 + from_mural = forms.BooleanField(required=False, label=_("From Mural"))
  41 + from_messages = forms.BooleanField(required=False, label=_("Messages"))
42 42  
43 43 class Meta:
44 44 fields = ('topic', 'init_date', 'end_date', 'from_mural' , 'from_messages')
... ...
reports/locale/pt_BR/LC_MESSAGES/django.po
... ... @@ -8,7 +8,7 @@ msgid &quot;&quot;
8 8 msgstr ""
9 9 "Project-Id-Version: PACKAGE VERSION\n"
10 10 "Report-Msgid-Bugs-To: \n"
11   -"POT-Creation-Date: 2017-03-09 17:01-0300\n"
  11 +"POT-Creation-Date: 2017-03-16 19:05-0300\n"
12 12 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 13 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14 14 "Language-Team: LANGUAGE <LL@li.org>\n"
... ... @@ -17,70 +17,220 @@ msgstr &quot;&quot;
17 17 "Content-Type: text/plain; charset=UTF-8\n"
18 18 "Content-Transfer-Encoding: 8bit\n"
19 19 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
20   -#: reports/forms.py:8
21   -msgid "Topics to select data from"
22   -msgstr ""
23 20  
24   -#: reports/forms.py:25
  21 +#: forms.py:23
  22 +msgid "Kind Of Resource"
  23 +msgstr "Tipo de recurso"
  24 +
  25 +#: forms.py:24
  26 +msgid "Tag"
  27 +msgstr "Tag"
  28 +
  29 +#: forms.py:36
  30 +#, fuzzy
  31 +#| msgid "Topic"
  32 +msgid "Topics"
  33 +msgstr "Tópico"
  34 +
  35 +#: forms.py:37 templates/reports/view.html:58
  36 +msgid "Initial Date"
  37 +msgstr "Data inicial"
  38 +
  39 +#: forms.py:38
  40 +#, fuzzy
  41 +#| msgid "Initial Date"
  42 +msgid "Final Date"
  43 +msgstr "Data inicial"
  44 +
  45 +#: forms.py:40
  46 +msgid "From Mural"
  47 +msgstr "Mural da disciplina"
  48 +
  49 +#: forms.py:41
  50 +msgid "Messages"
  51 +msgstr "Mensagens"
  52 +
  53 +#: forms.py:52
25 54 msgid "All"
26   -msgstr ""
  55 +msgstr "Todos"
  56 +
  57 +#: forms.py:61
  58 +msgid "The initial date can't be after the end one."
  59 +msgstr "A data inicial não pode ser depois da final"
  60 +
  61 +#: forms.py:66
  62 +msgid "This date should be right or after "
  63 +msgstr "Esta data deve ser igual ou após"
  64 +
  65 +#: forms.py:72
  66 +msgid "This date should be right or before "
  67 +msgstr "Esta data deve ser igual ou anterior à"
27 68  
28   -#: reports/templates/reports/create.html:21
29   -#: reports/templates/reports/report.html.py:20
30   -#: reports/templates/reports/view.html:33
  69 +#: templates/reports/_form.html:4
  70 +msgid "General Parameters"
  71 +msgstr "Escolha o Tópico e o Período"
  72 +
  73 +#: templates/reports/_form.html:27
  74 +msgid "Choose the Data Source (is possible to pick more than one)"
  75 +msgstr "Escolha a fonte de dados (é possível escolher mais de uma)"
  76 +
  77 +#: templates/reports/_form.html:60
  78 +msgid "Interaction with resources"
  79 +msgstr "Interação com recursos"
  80 +
  81 +#: templates/reports/_form.html:92
  82 +msgid "Search"
  83 +msgstr "Buscar"
  84 +
  85 +#: templates/reports/create.html:27 templates/reports/view.html:33
31 86 msgid "Analytics"
32 87 msgstr ""
33 88  
34   -#: reports/templates/reports/create.html:31
35   -#: reports/templates/reports/report.html.py:30
36   -#: reports/templates/reports/view.html:43
  89 +#: templates/reports/create.html:37 templates/reports/view.html:43
37 90 msgid "Interaction Data"
38   -msgstr ""
  91 +msgstr "Dados de Interação"
39 92  
40   -#: reports/templates/reports/create.html:34
41   -#: reports/templates/reports/report.html.py:33
42   -#: reports/templates/reports/view.html:46
  93 +#: templates/reports/create.html:40 templates/reports/view.html:46
43 94 msgid "Report Card"
44   -msgstr ""
  95 +msgstr "Boletim do Tópico"
45 96  
46   -#: reports/templates/reports/create.html:37
47   -#: reports/templates/reports/report.html.py:36
48   -#: reports/templates/reports/view.html:49
  97 +#: templates/reports/create.html:43 templates/reports/view.html:49
49 98 msgid "Participation"
50   -msgstr ""
  99 +msgstr "Participações"
  100 +
  101 +#: templates/reports/create.html:55
  102 +msgid "add data source"
  103 +msgstr "Adicionar nova fonte de dados"
51 104  
52   -#: reports/templates/reports/view.html:56
  105 +#: templates/reports/create.html:56
  106 +msgid "remove data source"
  107 +msgstr "Remover esta fonte"
  108 +
  109 +#: templates/reports/view.html:56
53 110 msgid "Subject"
54   -msgstr ""
  111 +msgstr "Assunto"
55 112  
56   -#: reports/templates/reports/view.html:57
  113 +#: templates/reports/view.html:57
57 114 msgid "Topic"
  115 +msgstr "Tópico"
  116 +
  117 +#: templates/reports/view.html:59
  118 +msgid "End Date"
  119 +msgstr "Data final"
  120 +
  121 +#: templates/reports/view.html:60
  122 +msgid "new search"
  123 +msgstr "Nova Busca"
  124 +
  125 +#: templates/reports/view.html:66
  126 +msgid "register(s)"
  127 +msgstr "registro(s)"
  128 +
  129 +#: templates/reports/view.html:68
  130 +msgid "Interactions Data"
  131 +msgstr "Dados de interação"
  132 +
  133 +#: views.py:67
  134 +msgid "Report created successfully"
  135 +msgstr "Report criado com sucesso!"
  136 +
  137 +#: views.py:168
  138 +msgid "Number of help posts created by the user."
  139 +msgstr "Número de postagens de dúvidas criadas no mural da disciplina."
  140 +
  141 +#: views.py:174
  142 +msgid "Amount of comments on help posts created by the student."
58 143 msgstr ""
  144 +"Número de comentários criados para as próprias postagens de dúvidas no mural "
  145 +"da disciplina."
59 146  
60   -#: reports/templates/reports/view.html:58
61   -msgid "Initial Date"
  147 +#: views.py:179
  148 +msgid "Amount of comments made by the student on teachers help posts."
62 149 msgstr ""
  150 +"Número de comentários às postagens de dúvidas no mural da disciplina criadas "
  151 +"pelo professor."
63 152  
64   -#: reports/templates/reports/view.html:59
65   -msgid "End Date"
  153 +#: views.py:183
  154 +msgid "Amount of comments made by the student on other students help posts."
66 155 msgstr ""
  156 +"Número de comentários às postagens de dúvidas no mural da disciplina criadas "
  157 +"por outros estudantes."
67 158  
68   -#: reports/templates/reports/view.html:60
69   -msgid "new search"
  159 +#: views.py:194
  160 +msgid "Number of help posts created by the user that the teacher commented on."
70 161 msgstr ""
  162 +"Número de comentários às postagens de dúvidas no mural da disciplina criadas "
  163 +"por outros estudantes"
71 164  
72   -#: reports/templates/reports/view.html:66
73   -msgid "register(s)"
  165 +#: views.py:202
  166 +msgid "Number of help posts created by the user others students commented on."
74 167 msgstr ""
  168 +" Número de postagens de dúvidas criadas no mural da disciplina que foram "
  169 +"comentadas por outros estudantes."
  170 +
  171 +#: views.py:205
  172 +msgid "Number of student visualizations on the mural of the subject."
  173 +msgstr "Número de visualizações do mural da disciplina."
75 174  
76   -#: reports/templates/reports/view.html:68
77   -msgid "Variable Descriptions"
  175 +#: views.py:217
  176 +msgid "Number of access to mural between 6 a.m to 12a.m. ."
78 177 msgstr ""
  178 +"Número de acessos ao ambiente virtual da disciplina no horário de 06h às 12h."
79 179  
80   -#: reports/templates/reports/view.html:72
81   -msgid "Interactions Data"
  180 +#: views.py:221
  181 +msgid "Number of access to mural between 0 p.m to 6p.m. ."
82 182 msgstr ""
  183 +"Número de acessos ao ambiente virtual da disciplina no horário de 12h às 18h."
83 184  
84   -#: reports/views.py:47
85   -msgid "Report created successfully"
  185 +#: views.py:224
  186 +msgid "Number of access to mural between 6 p.m to 12p.m. ."
86 187 msgstr ""
  188 +"Número de acessos ao ambiente virtual da disciplina no horário de 18h às 24h."
  189 +
  190 +#: views.py:228
  191 +msgid "Number of access to mural between 0 a.m to 6a.m. ."
  192 +msgstr ""
  193 +"Número de acessos ao ambiente virtual da disciplina no horário de 24h às 06h."
  194 +
  195 +#: views.py:236 views.py:239
  196 +msgid "Number of access to the subject on "
  197 +msgstr "Número de acesso ao subject no "
  198 +
  199 +#: views.py:242
  200 +msgid "Number of distinct days the user access the subject. "
  201 +msgstr "Número de dias distintos que acessou o ambiente virtual da disciplina."
  202 +
  203 +#: views.py:243
  204 +msgid "Class"
  205 +msgstr "Classe"
  206 +
  207 +#: views.py:244
  208 +msgid "Performance"
  209 +msgstr "Desempenho"
  210 +
  211 +#~ msgid "Topics to select data from"
  212 +#~ msgstr "Tópico do qual os dados serão retirados"
  213 +
  214 +#~ msgid "Data Source"
  215 +#~ msgstr "Escolha a origem dos dados (É possível selecionar mais de uma)"
  216 +
  217 +#~ msgid "sunday"
  218 +#~ msgstr "domingo"
  219 +
  220 +#~ msgid "monday"
  221 +#~ msgstr "segunda-feira"
  222 +
  223 +#~ msgid "tuesday"
  224 +#~ msgstr "terça-feira"
  225 +
  226 +#~ msgid "wednesday"
  227 +#~ msgstr "quarta-feira"
  228 +
  229 +#~ msgid "thursday"
  230 +#~ msgstr "quinta-feira"
  231 +
  232 +#~ msgid "friday"
  233 +#~ msgstr "sexta-feira"
  234 +
  235 +#~ msgid "saturday"
  236 +#~ msgstr "sábado"
... ...
reports/templates/reports/_form.html
... ... @@ -19,17 +19,22 @@
19 19  
20 20  
21 21 {% if field.auto_id == 'id_init_date' or field.auto_id == 'id_end_date' %}
22   - <label> {{field.label}} </label>
23   - {% render_field field class='form-control date-picker' %}
  22 + <label class="form-field-report"> {{field.label}} </label>
  23 + {% render_field field class='form-control date-picker' %}
  24 +
24 25  
25 26  
26 27 {% elif field.auto_id == 'id_from_mural' %}
27   - <h5 class="one"> <span>{% trans "Data Source" %}</span></h5>
28   - <label> {{field.label}} </label>
29   - {% render_field field class='form-control' %}
  28 + <h5 class="one"> <span>{% trans "Choose the Data Source (is possible to pick more than one)" %}</span></h5>
  29 + <div class="report-check-fields">
  30 +
  31 + <label class="form-field-report"> {{field.label}}
  32 + {% render_field field class='form-control ' %}
  33 + </label>
  34 + </div>
30 35 {% else %}
31   - <label> {{field.label}} </label>
32   - {% render_field field class='form-control' %}
  36 + <label class="form-field-report"> {{field.label}} </label>
  37 + {% render_field field class='form-control ' %}
33 38 {% endif %}
34 39  
35 40 {% if field.errors %}
... ... @@ -57,7 +62,7 @@
57 62 <div class="col-md-12">
58 63 <a data-parent="#resources_accordion" data-toggle="collapse" href="#resources">
59 64 <h4 class="panel-title">
60   - <button class="btn btn-default btn-xs text-center cat-selector"><i class="fa fa-angle-right fa-2x" aria-hidden="true"></i></button><label for="resources">{% trans "Interaction with resources" %}</label>
  65 + <button class="btn btn-default btn-xs text-center cat-selector"><i class="fa fa-angle-right fa-2x" aria-hidden="true"></i></button><label class="form-field-report" for="resources">{% trans "Interaction with resources" %}</label>
61 66 </h4>
62 67 </a>
63 68 </div>
... ... @@ -77,8 +82,11 @@
77 82 {% endif %}
78 83 <div class="resource-tag-formset">
79 84 {% for field in resource_tag_form %}
80   - <label>{{field.label}}</label>
81   - {% render_field field class="form-control" %}
  85 + <div class="report-resource-form">
  86 + <label class="form-field-report">{{field.label}}</label>
  87 + {% render_field field class="form-control " %}
  88 +
  89 + </div>
82 90  
83 91  
84 92 {% endfor %}
... ... @@ -89,7 +97,7 @@
89 97 </div>
90 98  
91 99 <div class="row text-center">
92   - <input type="submit" value="Search" class="btn btn-success btn-raised" />
  100 + <input type="submit" value="{% trans "Search" %}" class="btn btn-success btn-raised" />
93 101 </div>
94 102 </form>
95 103  
... ...
reports/templates/reports/create.html
... ... @@ -52,18 +52,19 @@
52 52  
53 53  
54 54 $('.resource-tag-formset').formset({
55   - addText: 'add data source',
56   - deleteText: 'remove data source',
  55 + addText: "{% trans "add data source" %}",
  56 + deleteText: "{% trans "remove data source" %}",
57 57 added: function(object){
58   - $.get("{% url 'subjects:reports:get_resource_and_tags' %}?subject_id={{subject.id}}", function(data){
59   - fields = object.children("select");
  58 + var form_topic = $("select#id_topic :selected").filter(":selected").val(); //get user selected topic option
  59 +
  60 + $.get("{% url 'subjects:reports:get_resource_and_tags' %}?subject_id={{subject.id}}"+"&topic_choice="+form_topic, function(data){
  61 + fields = object.find("select"); //get any select below, which are the two fields of the form
60 62  
61 63 for(var j = 0; j < data.resources.length; j++){
62 64 fields[0].options[fields[0].options.length] = new Option(data.resources[j].name,data.resources[j].id);
63 65  
64 66 }
65 67 //Set initial tag options
66   - var form_topic = $("select#id_topic :selected").filter(":selected").val(); //get user selected topic option
67 68 $.get("{% url 'subjects:reports:get_tags' %}?resource_class_name="+fields[0].value+"&subject_id={{subject.id}}"+"&topic_choice="+form_topic, function(data){
68 69 fields[1].options.length = 0;
69 70 for(var j = 0; j < data.tags.length; j++){
... ... @@ -86,5 +87,9 @@
86 87 });
87 88 },
88 89 });
  90 +
  91 + $('.resource-tag-formset').remove(); //I remove the element so there is no empty form with no data, I can't override this behavior on the previous function call
  92 +
  93 + $('#id_form-TOTAL_FORMS')[0].value = 0;
89 94 </script>
90 95 {% endblock content %}
91 96 \ No newline at end of file
... ...
reports/views.py
... ... @@ -16,7 +16,7 @@ from subjects.models import Subject, Tag
16 16 from .forms import CreateInteractionReportForm, ResourceAndTagForm, BaseResourceAndTagFormset
17 17 from log.models import Log
18 18 from topics.models import Resource, Topic
19   -
  19 +from collections import OrderedDict
20 20 from django.forms import formset_factory
21 21  
22 22 class ReportView(LoginRequiredMixin, generic.FormView):
... ... @@ -58,7 +58,7 @@ class ReportView(LoginRequiredMixin, generic.FormView):
58 58  
59 59 #set formset
60 60 resourceTagFormSet = formset_factory(ResourceAndTagForm, formset=BaseResourceAndTagFormset)
61   - resourceTagFormSet = resourceTagFormSet(initial=[{'class_name': classes, 'tag':tags}])
  61 + resourceTagFormSet = resourceTagFormSet()
62 62 context['resource_tag_formset'] = resourceTagFormSet
63 63 return context
64 64  
... ... @@ -130,9 +130,13 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
130 130 context['init_date'] = params_data['init_date']
131 131 context['end_date'] = params_data['end_date']
132 132 context['subject'] = subject
  133 +
  134 + resources = params_data.getlist('resource')
  135 + tags = params_data.getlist('tag')
133 136 if params_data['from_mural']:
  137 + #I used getlist method so it can get more than one tag and one resource class_name
134 138 context['data'], context['header'] = self.get_mural_data(subject, params_data['init_date'], params_data['end_date'],
135   - params_data.getlist('resource'), params_data.getlist('tag'))
  139 + resources, tags )
136 140 return context
137 141  
138 142 def get_mural_data(self, subject, init_date, end_date, resources_id, tags_id):
... ... @@ -148,45 +152,46 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
148 152  
149 153 header = ['User']
150 154  
  155 + #For each student in the subject
151 156 for student in students:
152 157 data[student] = []
153 158  
154 159 data[student].append(student.social_name)
155 160  
156   - interactions = {}
  161 + interactions = OrderedDict()
157 162 #interactions['username'] = student.social_name
158 163  
159 164 help_posts_made_by_user = SubjectPost.objects.filter(action="help",space__id=subject.id, user=student,
160 165 create_date__range=(init_date, end_date))
161 166  
162 167 #number of help posts created by the student
163   - interactions['number of help posts created by the user'] = help_posts_made_by_user.count()
  168 + interactions[_('Number of help posts created by the user.')] = help_posts_made_by_user.count()
164 169  
165 170 help_posts = SubjectPost.objects.filter(action="help", create_date__range=(init_date, end_date),
166 171 space__id=subject.id)
167 172  
168 173 #comments count on help posts created by the student
169   - interactions['amount of comments on help posts created by the student'] = Comment.objects.filter(post__in = help_posts.filter(user=student),
  174 + interactions[_('Amount of comments on help posts created by the student.')] = Comment.objects.filter(post__in = help_posts.filter(user=student),
170 175 create_date__range=(init_date, end_date)).count()
171 176  
172 177  
173 178 #count the amount of comments made by the student on posts made by one of the professors
174   - interactions['amount of comments made by the student on teachers help posts'] = Comment.objects.filter(post__in = help_posts.filter(user__in= subject.professor.all()), create_date__range=(init_date, end_date),
  179 + interactions[_('Amount of comments made by the student on teachers help posts.')] = Comment.objects.filter(post__in = help_posts.filter(user__in= subject.professor.all()), create_date__range=(init_date, end_date),
175 180 user=student).count()
176 181  
177 182 #comments made by the user on other users posts
178   - interactions['amount of comments made by the student on other students help posts'] = Comment.objects.filter(post__in = help_posts.exclude(user=student),
  183 + interactions[_('Amount of comments made by the student on other students help posts.')] = Comment.objects.filter(post__in = help_posts.exclude(user=student),
179 184 create_date__range=(init_date, end_date),
180 185 user= student).count()
181 186  
182 187  
183   -
  188 +
184 189 comments_by_teacher = Comment.objects.filter(user__in=subject.professor.all())
185 190 help_posts_ids = []
186 191 for comment in comments_by_teacher:
187 192 help_posts_ids.append(comment.post.id)
188 193 #number of help posts created by the user that the teacher commented on
189   - interactions['Number of help posts created by the user that the teacher commented on'] = help_posts.filter(user=student, id__in = help_posts_ids).count()
  194 + interactions[_('Number of help posts created by the user that the teacher commented on.')] = help_posts.filter(user=student, id__in = help_posts_ids).count()
190 195  
191 196  
192 197 comments_by_others = Comment.objects.filter(user__in=subject.students.exclude(id = student.id))
... ... @@ -194,31 +199,33 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
194 199 for comment in comments_by_teacher:
195 200 help_posts_ids.append(comment.post.id)
196 201 #number of help posts created by the user others students commented on
197   - interactions['number of help posts created by the user others students commented on'] = help_posts.filter(user=student, id__in = help_posts_ids).count()
  202 + interactions[_('Number of help posts created by the user others students commented on.')] = help_posts.filter(user=student, id__in = help_posts_ids).count()
198 203  
199 204 #Number of student visualizations on the mural of the subject
200   - interactions['Number of student visualizations on the mural of the subject'] = MuralVisualizations.objects.filter(post__in = SubjectPost.objects.filter(space__id=subject.id),
  205 + interactions[_('Number of student visualizations on the mural of the subject.')] = MuralVisualizations.objects.filter(post__in = SubjectPost.objects.filter(space__id=subject.id),
201 206 user = student).count()
202 207  
203 208  
204 209 #VAR08 through VAR_019 of documenttation:
205   - print(resources_id)
206   - resources_data = self.get_resources_and_tags_data(resources_id, tags_id, student, subject)
  210 + if len(resources_id) > 0:
  211 + resources_data = self.get_resources_and_tags_data(resources_id, tags_id, student, subject)
  212 + for key, value in resources_data.items():
  213 + interactions[key] = value
  214 +
207 215  
208   - interactions = {**interactions, **resources_data}
209 216 #VAR20 - number of access to mural between 6 a.m to 12a.m.
210   - interactions[' number of access to mural between 6 a.m to 12a.m.'] = Log.objects.filter(action="access", resource="subject",
  217 + interactions[_('Number of access to mural between 6 a.m to 12a.m. .')] = Log.objects.filter(action="access", resource="subject",
211 218 user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (5, 11)).count()
212 219  
213 220 #VAR21 - number of access to mural between 0 p.m to 6p.m.
214   - interactions['number of access to mural between 0 p.m to 6p.m.'] = Log.objects.filter(action="access", resource="subject",
  221 + interactions[_('Number of access to mural between 0 p.m to 6p.m. .')] = Log.objects.filter(action="access", resource="subject",
215 222 user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (11, 17)).count()
216 223 #VAR22
217   - interactions['number of access to mural between 6 p.m to 12p.m.'] = Log.objects.filter(action="access", resource="subject",
  224 + interactions[_('Number of access to mural between 6 p.m to 12p.m. .')] = Log.objects.filter(action="access", resource="subject",
218 225 user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (17, 23)).count()
219 226  
220 227 #VAR23
221   - interactions['number of access to mural between 0 a.m to 6a.m.'] = Log.objects.filter(action="access", resource="subject",
  228 + interactions[_('Number of access to mural between 0 a.m to 6a.m. .')] = Log.objects.filter(action="access", resource="subject",
222 229 user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (23, 5)).count()
223 230  
224 231 #VAR24 through 30
... ... @@ -226,14 +233,15 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
226 233 day_names = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"]
227 234 distinct_days = 0
228 235 for day_num in day_numbers:
229   - interactions['number of access to the subject on '+ day_names[day_num]] = Log.objects.filter(action="access", resource="subject",
  236 + interactions[_('Number of access to the subject on ')+ day_names[day_num]] = Log.objects.filter(action="access", resource="subject",
230 237 user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__week_day = day_num).count()
231 238 #to save the distinct days the user has accessed
232   - if interactions['number of access to the subject on '+ day_names[day_num]] > 0:
  239 + if interactions[_('Number of access to the subject on ')+ day_names[day_num]] > 0:
233 240 distinct_days += 1
234 241  
235   - interactions['number of distinct days the user access the subject'] = distinct_days
236   -
  242 + interactions[_('Number of distinct days the user access the subject. ')] = distinct_days
  243 + interactions[_("Class")] = ""
  244 + interactions[_("Performance")] = ""
237 245 for value in interactions.values():
238 246 data[student].append(value)
239 247  
... ... @@ -246,34 +254,52 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
246 254 data = {}
247 255  
248 256 for i in range(len(resources)):
249   - print(data)
250   - print(resources)
251   - print(resources[i])
252   - print(tags[i])
253 257 data[str(resources[i]) + " with tag " + Tag.objects.get(id=int(tags[i])).name] = Log.objects.filter(action="view", resource=resources[i].lower(),
254 258 user_id = student.id, context__contains = {'subject_id': subject.id}).count()
255 259  
256 260 return data
257 261  
258 262  
259   -
  263 +"""
  264 +Get all possible resource subclasses available for that topic selected
  265 +"""
260 266 def get_resources(request):
261 267  
262 268 #get all possible resources
263 269 classes = Resource.__subclasses__()
264 270  
265 271 data = {}
  272 + subject = Subject.objects.get(id=request.GET['subject_id'])
266 273  
267   -
268   - data['resources']= [ {'id':class_name.__name__, 'name':class_name.__name__} for class_name in classes]
  274 + topic_choice = request.GET["topic_choice"]
  275 + if topic_choice.lower() == "all" or topic_choice.lower() == "todos":
  276 + topics = subject.topic_subject.all()
  277 + else:
  278 + topics = [Topic.objects.get(id=int(topic_choice))]
  279 +
  280 + resources_class_names = []
  281 + for topic in topics:
  282 + resource_set = Resource.objects.filter(topic = topic)
  283 + for resource in resource_set:
  284 + resources_class_names.append(resource._my_subclass)
  285 +
  286 + #remove duplicates
  287 + resources = set(resources_class_names)
  288 +
  289 + data['resources']= [ {'id':resource_type, 'name':resource_type} for resource_type in resources]
269 290 return JsonResponse(data)
270 291  
271 292  
  293 +
  294 +"""
  295 +This function returns all the tags associated
  296 +with a resource that is of the type of of the resource_class_name provided.
  297 +"""
272 298 def get_tags(request):
273 299 resource_type = request.GET['resource_class_name']
274 300 subject = Subject.objects.get(id=request.GET['subject_id'])
275 301 topic_choice = request.GET["topic_choice"]
276   - if topic_choice.lower() == "all":
  302 + if topic_choice.lower() == "all" or topic_choice.lower() == "todos":
277 303 topics = subject.topic_subject.all()
278 304 else:
279 305 topics = [Topic.objects.get(id=int(topic_choice))]
... ...