Commit 85fd085c0bf9cf21e1fab108a5e358e459d70b9c

Authored by Jailson Dias
2 parents c168e75f 2eb21435

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

amadeus/context_processors.py
... ... @@ -3,6 +3,7 @@ from datetime import datetime
3 3 from themes.models import Themes
4 4 from notifications.models import Notification
5 5 from mural.models import MuralVisualizations
  6 +from chat.models import ChatVisualizations
6 7  
7 8 def theme(request):
8 9 context = {}
... ... @@ -35,4 +36,16 @@ def mural_notifies(request):
35 36  
36 37 context['mural_notifications_count'] = notifications
37 38  
  39 + return context
  40 +
  41 +def chat_notifies(request):
  42 + context = {}
  43 +
  44 + notifications = 0
  45 +
  46 + if request.user.is_authenticated:
  47 + notifications = ChatVisualizations.objects.filter(viewed = False, user = request.user).count()
  48 +
  49 + context['chat_notifications_count'] = notifications
  50 +
38 51 return context
39 52 \ No newline at end of file
... ...
amadeus/settings.py
... ... @@ -118,6 +118,7 @@ TEMPLATES = [
118 118 'amadeus.context_processors.theme',
119 119 'amadeus.context_processors.notifies',
120 120 'amadeus.context_processors.mural_notifies',
  121 + 'amadeus.context_processors.chat_notifies',
121 122 ],
122 123 },
123 124 },
... ...
amadeus/static/css/base/amadeus.css
... ... @@ -1468,6 +1468,7 @@ div.dataTables_wrapper div.dataTables_paginate {
1468 1468 #msg_editable {
1469 1469 width: 100%;
1470 1470 z-index: 1;
  1471 + min-height: 20px;
1471 1472 }
1472 1473  
1473 1474 .action-button {
... ...
amadeus/static/js/socket.js
... ... @@ -239,6 +239,46 @@ function messageReceived(content) {
239 239  
240 240 $(this).hide();
241 241 });
  242 + } else {
  243 + var talk_line = $("#talk-" + content.container),
  244 + talk_notifies = talk_line.find('.chat_notify'),
  245 + actual_count = talk_notifies.text(),
  246 + actual_date = talk_line.find(".talk-last_msg");
  247 +
  248 + actual_count = parseInt(actual_count, 10) + 1;
  249 +
  250 + talk_notifies.text(actual_count);
  251 +
  252 + actual_date.html(content.last_date);
  253 +
  254 + $('.chat_badge').each(function () {
  255 + var actual = $(this).text();
  256 +
  257 + if (actual != "+99") {
  258 + actual = parseInt(actual, 10) + 1;
  259 +
  260 + if (actual > 99) {
  261 + actual = "+99";
  262 + }
  263 +
  264 + $(this).text(actual);
  265 + }
  266 +
  267 + $(this).show();
  268 + });
  269 +
  270 + $('.chat-tabs').find('li').each(function () {
  271 + var identity = $(this).data('chat');
  272 +
  273 + if (identity == content.subtype) {
  274 + var span = $(this).find('span'),
  275 + actual = span.text();
  276 +
  277 + actual = parseInt(actual, 10) + 1;
  278 +
  279 + span.text(actual);
  280 + }
  281 + });
242 282 }
243 283  
244 284 if (("Notification" in window)) {
... ...
amadeus/templates/base.html
... ... @@ -209,6 +209,7 @@
209 209 <li class="item {{ chat_menu_active }} action_icon" data-toggle="tooltip" data-placement="right" title="{% trans "Messages" %}">
210 210 <a href="{% url 'chat:manage_general' %}">
211 211 <i class="fa fa-envelope-o" aria-hidden="true"></i>
  212 + <span class="badge notify_badge chat_badge" {% if chat_notifications_count == 0 %} style="display:none" {% endif %}>{% if chat_notifications_count > 99 %} +99 {% else %} {{ chat_notifications_count }} {% endif %}</span>
212 213 </a>
213 214 </li>
214 215 <li class="item {{ pendencies_menu_active }} action_icon" data-toggle="tooltip" data-placement="right" title="{% trans "Pendencies" %}">
... ... @@ -263,6 +264,7 @@
263 264 <li class="item {{ chat_menu_active }} action_icon" data-toggle="tooltip" data-placement="top" title="{% trans "Messages" %}">
264 265 <a href="{% url 'chat:manage_general' %}">
265 266 <i class="fa fa-envelope-o" aria-hidden="true"></i>
  267 + <span class="badge notify_badge chat_badge" {% if chat_notifications_count == 0 %} style="display:none" {% endif %}>{% if chat_notifications_count > 99 %} +99 {% else %} {{ chat_notifications_count }} {% endif %}</span>
266 268 </a>
267 269 </li>
268 270 <li class="item {{ pendencies_menu_active }} action_icon" data-toggle="tooltip" data-placement="top" title="{% trans "Pendencies" %}">
... ...
categories/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-21 23:06-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"
... ... @@ -18,146 +18,144 @@ msgstr &quot;&quot;
18 18 "Content-Transfer-Encoding: 8bit\n"
19 19 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
20 20  
21   -#: categories/forms.py:23
  21 +#: .\forms.py:23
22 22 msgid "There is another category with this name, try another one."
23   -msgstr ""
  23 +msgstr "Existe outra categoria com este nome, tente outro nome."
24 24  
25   -#: categories/models.py:9
  25 +#: .\models.py:9
26 26 msgid "Name"
27 27 msgstr "Nome"
28 28  
29   -#: categories/models.py:10
  29 +#: .\models.py:10
30 30 msgid "Slug"
31 31 msgstr "Slug"
32 32  
33   -#: categories/models.py:11
  33 +#: .\models.py:11
34 34 msgid "description"
35 35 msgstr "Descrição"
36 36  
37   -#: categories/models.py:12
  37 +#: .\models.py:12
38 38 msgid "visible"
39 39 msgstr "Visível"
40 40  
41   -#: categories/models.py:14
  41 +#: .\models.py:14
42 42 msgid "Creation Date"
43 43 msgstr "Data de criação"
44 44  
45   -#: categories/models.py:15
  45 +#: .\models.py:15
46 46 msgid "Modified Date"
47 47 msgstr "Data de modificação"
48 48  
49   -#: categories/models.py:19
  49 +#: .\models.py:19
50 50 msgid "Category"
51 51 msgstr "Categoria"
52 52  
53   -#: categories/models.py:20 categories/views.py:49
  53 +#: .\models.py:20 .\views.py:49
54 54 msgid "Categories"
55 55 msgstr "Categorias"
56 56  
57   -#: categories/templates/categories/_form.html:21
58   -msgid "Atribute coordinators role to users"
59   -msgstr "Atribuir perfil de coordenadores a usuários"
  57 +#: .\templates\categories\_form.html:14
  58 +msgid "Coordinators"
  59 +msgstr "Coordenadores"
  60 +
  61 +#: .\templates\categories\_form.html:21
  62 +msgid "Atribute coordinator role to users"
  63 +msgstr "Atribua perfil de coordenador aos usuários"
60 64  
61   -#: categories/templates/categories/_form.html:62
  65 +#: .\templates\categories\_form.html:67
62 66 msgid "Save"
63 67 msgstr "Salvar"
64 68  
65   -#: categories/templates/categories/_form.html:68
66   -#: categories/templates/categories/_form.html:69
67   -msgid "try an username"
68   -msgstr "Tente um nome de usuário"
  69 +#: .\templates\categories\_form.html:73 .\templates\categories\_form.html:74
  70 +msgid "search for an username"
  71 +msgstr "pesquise por um nome de usuário"
69 72  
70   -#: categories/templates/categories/category_card.html:18
71   -#: categories/templates/categories/list.html:69
72   -#: categories/templates/categories/list.html:114
  73 +#: .\templates\categories\category_card.html:18
  74 +#: .\templates\categories\list.html:69 .\templates\categories\list.html:114
73 75 msgid "Replicate"
74 76 msgstr "Replicar"
75 77  
76   -#: categories/templates/categories/category_card.html:19
77   -#: categories/templates/categories/home_admin_content.html:6
78   -#: categories/templates/categories/list.html:73
79   -#: categories/templates/categories/list.html:116
  78 +#: .\templates\categories\category_card.html:19
  79 +#: .\templates\categories\home_admin_content.html:6
  80 +#: .\templates\categories\list.html:73 .\templates\categories\list.html:116
80 81 msgid "Edit"
81 82 msgstr "Editar"
82 83  
83   -#: categories/templates/categories/category_card.html:20
84   -#: categories/templates/categories/list.html:74
85   -#: categories/templates/categories/list.html:117
  84 +#: .\templates\categories\category_card.html:20
  85 +#: .\templates\categories\list.html:74 .\templates\categories\list.html:117
86 86 msgid "Remove"
87 87 msgstr "Remover"
88 88  
89   -#: categories/templates/categories/category_card.html:26
  89 +#: .\templates\categories\category_card.html:26
90 90 msgid "Are you sure you want to subscribe to this course?"
91 91 msgstr "Tem certeza que você deseja se inscrever neste curso?"
92 92  
93   -#: categories/templates/categories/category_card.html:27
  93 +#: .\templates\categories\category_card.html:27
94 94 msgid "Subscribe"
95 95 msgstr "Inscrever-se"
96 96  
97   -#: categories/templates/categories/delete.html:12
  97 +#: .\templates\categories\delete.html:12
98 98 msgid "Are you sure you want to delete the category"
99 99 msgstr "Voce tem certeza que seja deletar esta categoria"
100 100  
101   -#: categories/templates/categories/delete.html:12
  101 +#: .\templates\categories\delete.html:12
102 102 msgid "All its data will be lost and can't be recovered"
103 103 msgstr "Todos os seus dados seråo perdido e não podem ser recuperados"
104 104  
105   -#: categories/templates/categories/delete.html:18
  105 +#: .\templates\categories\delete.html:18
106 106 msgid "Close"
107 107 msgstr "Cancelar"
108 108  
109   -#: categories/templates/categories/delete.html:19
  109 +#: .\templates\categories\delete.html:19
110 110 msgid "Delete"
111 111 msgstr "Deletar"
112 112  
113   -#: categories/templates/categories/home.html:26
  113 +#: .\templates\categories\home.html:26
114 114 msgid "categories"
115 115 msgstr "Categorias"
116 116  
117   -#: categories/templates/categories/list.html:31 categories/views.py:106
  117 +#: .\templates\categories\list.html:31 .\views.py:106
118 118 msgid "Create Category"
119 119 msgstr "Criar Categoria"
120 120  
121   -#: categories/templates/categories/list.html:39
  121 +#: .\templates\categories\list.html:39
122 122 msgid "My subjects"
123 123 msgstr "Meus assuntos"
124 124  
125   -#: categories/templates/categories/list.html:40
  125 +#: .\templates\categories\list.html:40
126 126 msgid "all subjects"
127 127 msgstr "Todos os assuntos"
128 128  
129   -#: categories/templates/categories/list.html:86
130   -#: categories/templates/categories/list.html:129
  129 +#: .\templates\categories\list.html:86 .\templates\categories\list.html:129
131 130 msgid "Coordinator(s) "
132 131 msgstr "Coordenador(es)"
133 132  
134   -#: categories/templates/categories/list.html:90
135   -#: categories/templates/categories/list.html:133
  133 +#: .\templates\categories\list.html:90 .\templates\categories\list.html:133
136 134 msgid "It doesn't possess coordinators"
137 135 msgstr "Não possui coordenadores"
138 136  
139   -#: categories/templates/categories/notifications_timeline.html:14
  137 +#: .\templates\categories\notifications_timeline.html:14
140 138 msgid "at"
141 139 msgstr "em"
142 140  
143   -#: categories/templates/categories/notifications_timeline.html:15
  141 +#: .\templates\categories\notifications_timeline.html:15
144 142 msgid "ago"
145 143 msgstr "atras"
146 144  
147   -#: categories/templates/categories/update.html:8
  145 +#: .\templates\categories\update.html:8
148 146 msgid "Update: "
149 147 msgstr "Editar: "
150 148  
151   -#: categories/views.py:104
  149 +#: .\views.py:104
152 150 msgid "Replicate Category"
153 151 msgstr "Replicar Categoria"
154 152  
155   -#: categories/views.py:131
  153 +#: .\views.py:131
156 154 #, python-format
157 155 msgid "Category \"%s\" register successfully!"
158 156 msgstr "Categoria \"%s\" foi registrada com sucesso!"
159 157  
160   -#: categories/views.py:167
  158 +#: .\views.py:167
161 159 msgid ""
162 160 "The category cannot be removed, it contains one or more virtual enviroments "
163 161 "attach."
... ... @@ -165,19 +163,16 @@ msgstr &quot;&quot;
165 163 "A categoria não pode ser removida, ela contém um ou mais ambientes virtuais "
166 164 "vinculados."
167 165  
168   -#: categories/views.py:180
  166 +#: .\views.py:180
169 167 #, python-format
170 168 msgid "Category \"%s\" removed successfully!"
171 169 msgstr "Categoria \"%s\" removida com sucesso!"
172 170  
173   -#: categories/views.py:208
  171 +#: .\views.py:208
174 172 #, python-format
175 173 msgid "Category \"%s\" updated successfully!"
176 174 msgstr "Categoria \"%s\" atualizada com sucesso!"
177 175  
178   -#: categories/views.py:224
  176 +#: .\views.py:224
179 177 msgid "Update Category"
180 178 msgstr "Atualizar Categoria"
181   -
182   -#~ msgid "coordinators"
183   -#~ msgstr "Coordenadores"
... ...
categories/templates/categories/_form.html
... ... @@ -11,14 +11,14 @@
11 11 <div class="col-md-12">
12 12 <a data-parent="#coordinators_accordion" data-toggle="collapse" href="#coords">
13 13 <h4 class="panel-title">
14   - <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="{{ field.auto_id }}">{{ field.label }}</label>
  14 + <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="{{ field.auto_id }}">{% trans 'Coordinators' %}</label>
15 15 </h4>
16 16 </a>
17 17 </div>
18 18 </div>
19 19 </div>
20 20 <div id="coords" class="panel-collapse collapse">
21   - <p><em>{% trans 'Atribute coordinators role to users' %}:</em></p>
  21 + <p><em>{% trans 'Atribute coordinator role to users' %}:</em></p>
22 22 {% render_field field class='form-control' %}
23 23 </div>
24 24 </div>
... ... @@ -70,8 +70,8 @@
70 70  
71 71 <script type="text/javascript">
72 72 $('#id_coordinators').multiSelect({
73   - selectableHeader: "<input type='text' class='form-control search-input category-search-users' autocomplete='off' placeholder='{% trans "try an username" %} '>",
74   - selectionHeader: "<input type='text' class='form-control search-input category-search-users' autocomplete='off' placeholder='{% trans "try an username" %} '>",
  73 + selectableHeader: "<input type='text' class='form-control search-input category-search-users' autocomplete='off' placeholder='{% trans "search for an username" %} '>",
  74 + selectionHeader: "<input type='text' class='form-control search-input category-search-users' autocomplete='off' placeholder='{% trans "search for an username" %} '>",
75 75 afterInit: function(ms){
76 76 var that = this,
77 77 $selectableSearch = that.$selectableUl.prev(),
... ...
chat/templates/chat/_view.html
... ... @@ -4,12 +4,12 @@
4 4  
5 5 {% is_online talking_to as status %}
6 6  
7   -<div class="col-md-12 participant panel">
  7 +<div id="talk-chat-{{ talking_to.id }}" class="col-md-12 participant panel">
8 8 <div class="col-md-1 user-img">
9 9 <img src="{{ talking_to.image_url }}" class="img-responsive" />
10 10 </div>
11 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>
  12 + <h4 class='talking-header'><a class="status {{ status }}" data-toggle="tooltip" title="{{ status|status_text }}"></a> {{ talking_to }} (<span class="chat_notify">{{ chat|notifies:request.user }}</span>)</h4>
13 13 <p class="talk-last_msg">{% trans 'Last message in' %} {{ chat|last_message }}</p>
14 14 </div>
15 15 <div class="col-md-4 buttons pull-right text-center">
... ...
chat/templates/chat/list.html
... ... @@ -13,10 +13,10 @@
13 13  
14 14 {% block content %}
15 15 <div id="core-subjects-options-div">
16   - <ul class="core-subjects-options mural-tabs">
  16 + <ul class="core-subjects-options chat-tabs">
17 17 <a href="{% url 'chat:manage_general' %}"><li data-chat="general" class="active">{% trans "General" %} (<span>{{ totals.general }}</span>)</li></a>
18   - <a href=""><li data-chat="categories">{% trans "Per Category" %} (<span>{{ totals.category }}</span>)</li></a>
19   - <a href=""><li data-chat="subjects">{% trans "Per Subject" %} (<span>{{ totals.subject }}</span>)</li></a>
  18 + <a href=""><li data-chat="category">{% trans "Per Category" %} (<span>{{ totals.category }}</span>)</li></a>
  19 + <a href=""><li data-chat="subject">{% trans "Per Subject" %} (<span>{{ totals.subject }}</span>)</li></a>
20 20 </ul>
21 21 </div>
22 22  
... ...
chat/templatetags/chat_tags.py
... ... @@ -7,7 +7,7 @@ from django.contrib.sessions.models import Session
7 7  
8 8 from log.models import Log
9 9  
10   -from chat.models import TalkMessages
  10 +from chat.models import TalkMessages, ChatVisualizations
11 11  
12 12 register = template.Library()
13 13  
... ... @@ -49,4 +49,10 @@ def chat_user(user, chat):
49 49 def last_message(chat):
50 50 last_message = TalkMessages.objects.filter(talk = chat).order_by('-create_date')[0]
51 51  
52   - return last_message.create_date
53 52 \ No newline at end of file
  53 + return last_message.create_date
  54 +
  55 +@register.filter(name = 'notifies')
  56 +def notifies(chat, user):
  57 + total = ChatVisualizations.objects.filter(message__talk = chat, user = user).count()
  58 +
  59 + return total
54 60 \ No newline at end of file
... ...
chat/views.py
... ... @@ -7,6 +7,7 @@ from django.http import JsonResponse
7 7 from django.template.loader import render_to_string
8 8 from django.core.urlresolvers import reverse, reverse_lazy
9 9 import textwrap
  10 +from django.utils import formats
10 11 from django.utils.html import strip_tags
11 12 from django.utils.translation import ugettext_lazy as _
12 13 from django.contrib.auth.mixins import LoginRequiredMixin
... ... @@ -193,7 +194,8 @@ class SendMessage(LoginRequiredMixin, generic.edit.CreateView):
193 194 "notify_title": str(self.object.user),
194 195 "simple_notify": simple_notify,
195 196 "complete": render_to_string("chat/_message.html", {"talk_msg": self.object}, self.request),
196   - "container": "chat-" + str(self.object.user.id)
  197 + "container": "chat-" + str(self.object.user.id),
  198 + "last_date": _("Last message in %s")%(formats.date_format(self.object.create_date, "SHORT_DATETIME_FORMAT"))
197 199 }
198 200  
199 201 notification = json.dumps(notification)
... ...
file_link/views.py
... ... @@ -21,7 +21,7 @@ from .models import FileLink
21 21 class DownloadFile(LoginRequiredMixin, LogMixin, generic.DetailView):
22 22 log_component = 'resources'
23 23 log_action = 'view'
24   - log_resource = 'file_link'
  24 + log_resource = 'filelink'
25 25 log_context = {}
26 26  
27 27 login_url = reverse_lazy("users:login")
... ... @@ -63,9 +63,9 @@ class DownloadFile(LoginRequiredMixin, LogMixin, generic.DetailView):
63 63 self.log_context['topic_id'] = file_link.topic.id
64 64 self.log_context['topic_name'] = file_link.topic.name
65 65 self.log_context['topic_slug'] = file_link.topic.slug
66   - self.log_context['file_link_id'] = file_link.id
67   - self.log_context['file_link_name'] = file_link.name
68   - self.log_context['file_link_slug'] = file_link.slug
  66 + self.log_context['filelink_id'] = file_link.id
  67 + self.log_context['filelink_name'] = file_link.name
  68 + self.log_context['filelink_slug'] = file_link.slug
69 69  
70 70 super(DownloadFile, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
71 71  
... ... @@ -74,7 +74,7 @@ class DownloadFile(LoginRequiredMixin, LogMixin, generic.DetailView):
74 74 class CreateView(LoginRequiredMixin, LogMixin, generic.edit.CreateView):
75 75 log_component = 'resources'
76 76 log_action = 'create'
77   - log_resource = 'file_link'
  77 + log_resource = 'filelink'
78 78 log_context = {}
79 79  
80 80 login_url = reverse_lazy("users:login")
... ... @@ -163,9 +163,9 @@ class CreateView(LoginRequiredMixin, LogMixin, generic.edit.CreateView):
163 163 self.log_context['topic_id'] = self.object.topic.id
164 164 self.log_context['topic_name'] = self.object.topic.name
165 165 self.log_context['topic_slug'] = self.object.topic.slug
166   - self.log_context['file_link_id'] = self.object.id
167   - self.log_context['file_link_name'] = self.object.name
168   - self.log_context['file_link_slug'] = self.object.slug
  166 + self.log_context['filelink_id'] = self.object.id
  167 + self.log_context['filelink_name'] = self.object.name
  168 + self.log_context['filelink_slug'] = self.object.slug
169 169  
170 170 super(CreateView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
171 171  
... ... @@ -192,7 +192,7 @@ class CreateView(LoginRequiredMixin, LogMixin, generic.edit.CreateView):
192 192 class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView):
193 193 log_component = 'resources'
194 194 log_action = 'update'
195   - log_resource = 'file_link'
  195 + log_resource = 'filelink'
196 196 log_context = {}
197 197  
198 198 login_url = reverse_lazy("users:login")
... ... @@ -277,9 +277,9 @@ class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView):
277 277 self.log_context['topic_id'] = self.object.topic.id
278 278 self.log_context['topic_name'] = self.object.topic.name
279 279 self.log_context['topic_slug'] = self.object.topic.slug
280   - self.log_context['file_link_id'] = self.object.id
281   - self.log_context['file_link_name'] = self.object.name
282   - self.log_context['file_link_slug'] = self.object.slug
  280 + self.log_context['filelink_id'] = self.object.id
  281 + self.log_context['filelink_name'] = self.object.name
  282 + self.log_context['filelink_slug'] = self.object.slug
283 283  
284 284 super(UpdateView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
285 285  
... ... @@ -306,7 +306,7 @@ class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView):
306 306 class DeleteView(LoginRequiredMixin, LogMixin, generic.DeleteView):
307 307 log_component = 'resources'
308 308 log_action = 'delete'
309   - log_resource = 'file_link'
  309 + log_resource = 'filelink'
310 310 log_context = {}
311 311  
312 312 login_url = reverse_lazy("users:login")
... ... @@ -337,9 +337,9 @@ class DeleteView(LoginRequiredMixin, LogMixin, generic.DeleteView):
337 337 self.log_context['topic_id'] = self.object.topic.id
338 338 self.log_context['topic_name'] = self.object.topic.name
339 339 self.log_context['topic_slug'] = self.object.topic.slug
340   - self.log_context['file_link_id'] = self.object.id
341   - self.log_context['file_link_name'] = self.object.name
342   - self.log_context['file_link_slug'] = self.object.slug
  340 + self.log_context['filelink_id'] = self.object.id
  341 + self.log_context['filelink_name'] = self.object.name
  342 + self.log_context['filelink_slug'] = self.object.slug
343 343  
344 344 super(DeleteView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
345 345  
... ...
pdf_file/views.py
... ... @@ -23,7 +23,7 @@ class ViewPDFFile(LoginRequiredMixin, LogMixin, generic.TemplateView):
23 23 template_name='pdf_file/view.html'
24 24 log_component = 'resources'
25 25 log_action = 'view'
26   - log_resource = 'pdf_file'
  26 + log_resource = 'pdffile'
27 27 log_context = {}
28 28 def dispatch(self, request, *args, **kwargs):
29 29 slug = self.kwargs.get('slug', '')
... ... @@ -52,9 +52,9 @@ class ViewPDFFile(LoginRequiredMixin, LogMixin, generic.TemplateView):
52 52 self.log_context['topic_id'] = pdf_file.topic.id
53 53 self.log_context['topic_name'] = pdf_file.topic.name
54 54 self.log_context['topic_slug'] = pdf_file.topic.slug
55   - self.log_context['pdf_id'] = pdf_file.id
56   - self.log_context['pdf_name'] = pdf_file.name
57   - self.log_context['pdf_slug'] = pdf_file.slug
  55 + self.log_context['pdffile_id'] = pdf_file.id
  56 + self.log_context['pdffile_name'] = pdf_file.name
  57 + self.log_context['pdffile_slug'] = pdf_file.slug
58 58  
59 59 super(ViewPDFFile, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
60 60  
... ... @@ -87,6 +87,7 @@ class PDFFileCreateView(LoginRequiredMixin, LogMixin , generic.CreateView):
87 87 login_url = reverse_lazy("users:login")
88 88 redirect_field_name = 'next'
89 89  
  90 + log_resource = 'pdffile'
90 91  
91 92 def dispatch(self, request, *args, **kwargs):
92 93 slug = self.kwargs.get('slug', '')
... ... @@ -168,9 +169,9 @@ class PDFFileCreateView(LoginRequiredMixin, LogMixin , generic.CreateView):
168 169 self.log_context['topic_id'] = self.object.topic.id
169 170 self.log_context['topic_name'] = self.object.topic.name
170 171 self.log_context['topic_slug'] = self.object.topic.slug
171   - self.log_context['pdf_file_id'] = self.object.id
172   - self.log_context['pdf_file_name'] = self.object.name
173   - self.log_context['pdf_file_slug'] = self.object.slug
  172 + self.log_context['pdffile_id'] = self.object.id
  173 + self.log_context['pdffile_name'] = self.object.name
  174 + self.log_context['pdffile_slug'] = self.object.slug
174 175  
175 176 super(PDFFileCreateView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
176 177  
... ... @@ -198,7 +199,7 @@ class PDFFileCreateView(LoginRequiredMixin, LogMixin , generic.CreateView):
198 199 class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView):
199 200 log_component = 'resources'
200 201 log_action = 'update'
201   - log_resource = 'pdf_file'
  202 + log_resource = 'pdffile'
202 203 log_context = {}
203 204  
204 205 login_url = reverse_lazy("users:login")
... ... @@ -283,9 +284,9 @@ class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView):
283 284 self.log_context['topic_id'] = self.object.topic.id
284 285 self.log_context['topic_name'] = self.object.topic.name
285 286 self.log_context['topic_slug'] = self.object.topic.slug
286   - self.log_context['pdf_file_id'] = self.object.id
287   - self.log_context['pdf_file_name'] = self.object.name
288   - self.log_context['pdf_file_slug'] = self.object.slug
  287 + self.log_context['pdffile_id'] = self.object.id
  288 + self.log_context['pdffile_name'] = self.object.name
  289 + self.log_context['pdffile_slug'] = self.object.slug
289 290  
290 291 super(UpdateView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
291 292  
... ... @@ -343,9 +344,9 @@ class DeleteView(LoginRequiredMixin, LogMixin, generic.DeleteView):
343 344 self.log_context['topic_id'] = self.object.topic.id
344 345 self.log_context['topic_name'] = self.object.topic.name
345 346 self.log_context['topic_slug'] = self.object.topic.slug
346   - self.log_context['pdf_file_id'] = self.object.id
347   - self.log_context['pdf_file_name'] = self.object.name
348   - self.log_context['pdf_file_slug'] = self.object.slug
  347 + self.log_context['pdffile_id'] = self.object.id
  348 + self.log_context['pdffile_name'] = self.object.name
  349 + self.log_context['pdffile_slug'] = self.object.slug
349 350  
350 351 super(DeleteView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
351 352  
... ...
reports/migrations/0002_reportxls.py 0 → 100644
... ... @@ -0,0 +1,30 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10.4 on 2017-03-21 00:55
  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 + dependencies = [
  13 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
  14 + ('reports', '0001_initial'),
  15 + ]
  16 +
  17 + operations = [
  18 + migrations.CreateModel(
  19 + name='ReportXLS',
  20 + fields=[
  21 + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
  22 + ('xls_data', models.TextField()),
  23 + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
  24 + ],
  25 + options={
  26 + 'verbose_name': 'ReportCSV',
  27 + 'verbose_name_plural': 'ReportCSVs',
  28 + },
  29 + ),
  30 + ]
... ...
reports/models.py
... ... @@ -12,4 +12,17 @@ class ReportCSV(models.Model):
12 12  
13 13 def __str__(self):
14 14 pass
  15 +
  16 +
  17 +class ReportXLS(models.Model):
  18 +
  19 + user = models.ForeignKey(User)
  20 + xls_data = models.TextField()
  21 +
  22 + class Meta:
  23 + verbose_name = "ReportCSV"
  24 + verbose_name_plural = "ReportCSVs"
  25 +
  26 + def __str__(self):
  27 + pass
15 28  
16 29 \ No newline at end of file
... ...
reports/templates/reports/view.html
... ... @@ -65,7 +65,7 @@
65 65 <ul id="report-info">
66 66 <li> {{data.values|length}} {% trans "register(s)" %} </li>
67 67 <li>
68   - <a href="{% url 'subjects:reports:download_report' %}?{{csv_data}}"><i class="fa fa-download" aria-hidden="true"></i> {% trans "Interactions Data" %}</a>
  68 + <a href="{% url 'subjects:reports:download_report_csv' %}"><i class="fa fa-download" aria-hidden="true"></i> {% trans "Interactions Data" %}</a>
69 69  
70 70  
71 71 </li>
... ...
reports/urls.py
... ... @@ -7,5 +7,5 @@ urlpatterns = [
7 7 url(r'^view/interactions/$', views.ViewReportView.as_view(), name='view_report'),
8 8 url(r'^get/resources/$', views.get_resources, name='get_resource_and_tags'),
9 9 url(r'^get/tags/$', views.get_tags, name='get_tags'),
10   - url(r'^post/download_report/$', views.download_report, name="download_report"),
  10 + url(r'^post/download_report/$', views.download_report_csv, name="download_report_csv"),
11 11 ]
12 12 \ No newline at end of file
... ...
reports/views.py
... ... @@ -11,14 +11,14 @@ import django.views.generic as generic
11 11 from mural.models import SubjectPost, Comment, MuralVisualizations
12 12 from django.db.models import Q
13 13 from django.contrib.auth.mixins import LoginRequiredMixin
14   -from datetime import datetime, date
  14 +from datetime import datetime, date, timedelta
15 15 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   -from .models import ReportCSV
  21 +from .models import ReportCSV, ReportXLS
22 22 import pandas as pd
23 23  
24 24 class ReportView(LoginRequiredMixin, generic.FormView):
... ... @@ -143,32 +143,47 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
143 143  
144 144 #this is to save the csv for further download
145 145 df = pd.DataFrame.from_dict(context['data'], orient='index')
146   -
147 146 df.columns = context['header']
148 147 #so it does not exist more than one report CSV available for that user to download
149 148 if ReportCSV.objects.filter(user= self.request.user).count() > 0:
150 149 report = ReportCSV.objects.get(user=self.request.user)
151 150 report.delete()
152 151  
153   -
  152 +
154 153 report = ReportCSV(user= self.request.user, csv_data = df.to_csv())
155 154 report.save()
156 155  
  156 + #for excel files
  157 + """ if ReportXLS.objects.filter(user= self.request.user).count() > 0:
  158 + report = ReportXLS.objects.get(user=self.request.user)
  159 + report.delete()
  160 +
  161 + df.drop(df.columns[[0]], axis=1, inplace=True)
  162 + writer = pd.ExcelWriter('pandas_simple.xlsx')
  163 + report = ReportXLS(user= self.request.user, xls_data = df.to_excel(writer))
  164 + report.save()"""
  165 +
  166 +
157 167 return context
158 168  
159 169 def get_mural_data(self, subject, init_date, end_date, resources_id, tags_id):
160 170 data = {}
161 171 students = subject.students.all()
162   - formats = ["%d/%m/%Y", "%m/%d/%Y"] #so it accepts english and portuguese date formats
  172 + formats = ["%d/%m/%Y", "%m/%d/%Y", "%Y-%m-%d"] #so it accepts english and portuguese date formats
163 173 for fmt in formats:
164 174 try:
165   - init_date = datetime.strptime(init_date, fmt)
166   - end_date = datetime.strptime(end_date, fmt)
  175 + init_date = datetime.strptime(init_date, fmt).date()
  176 + end_date = datetime.strptime(end_date, fmt).date()
  177 +
167 178 except ValueError:
168 179 pass
169 180  
170 181 header = ['User']
171   -
  182 +
  183 + #I use this so the system can gather data up to end_date 11h59 p.m.
  184 + end_date = end_date + timedelta(days=1)
  185 +
  186 +
172 187 #For each student in the subject
173 188 for student in students:
174 189 data[student] = []
... ... @@ -226,7 +241,7 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
226 241  
227 242 #VAR08 through VAR_019 of documenttation:
228 243 if len(resources_id) > 0:
229   - resources_data = self.get_resources_and_tags_data(resources_id, tags_id, student, subject)
  244 + resources_data = self.get_resources_and_tags_data(resources_id, tags_id, student, subject, init_date, end_date)
230 245 for key, value in resources_data.items():
231 246 interactions[key] = value
232 247  
... ... @@ -268,12 +283,26 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
268 283 header.append(key)
269 284 return data, header
270 285  
271   - def get_resources_and_tags_data(self, resources, tags, student, subject):
272   - data = {}
  286 + def get_resources_and_tags_data(self, resources_types, tags, student, subject, init_date, end_date):
  287 + data = OrderedDict()
273 288  
274   - for i in range(len(resources)):
275   - data[str(resources[i]) + " with tag " + Tag.objects.get(id=int(tags[i])).name] = Log.objects.filter(action="view", resource=resources[i].lower(),
276   - user_id = student.id, context__contains = {'subject_id': subject.id}).count()
  289 + for i in range(len(resources_types)):
  290 +
  291 + resources = Resource.objects.select_related(resources_types[i].lower()).filter(tags__in = tags, topic__in=subject.topic_subject.all())
  292 + distinct_resources = 0
  293 + total_count = 0
  294 + for resource in resources:
  295 + count = Log.objects.filter(action="view", resource=resources_types[i].lower(),
  296 + user_id = student.id, context__contains = {'subject_id': subject.id,
  297 + resources_types[i].lower()+'_id': resource.id}, datetime__range=(init_date, end_date)).count()
  298 + if count > 0:
  299 + distinct_resources += 1
  300 + total_count += count
  301 +
  302 + data[str(resources_types[i]) + " with tag " + Tag.objects.get(id=int(tags[i])).name] = total_count
  303 + data["distintic " + str(resources_types[i]) + " with tag " + Tag.objects.get(id=int(tags[i])).name] = distinct_resources
  304 + """data["distinct" + str(resources[i]) + " with tag " + Tag.objects.get(id=int(tags[i])).name] = Log.objects.filter(action="view", resource=resources[i].lower(),
  305 + user_id = student.id, context__contains = {'subject_id': subject.id}).distinct().count()"""
277 306  
278 307 return data
279 308  
... ... @@ -317,27 +346,32 @@ def get_tags(request):
317 346 resource_type = request.GET['resource_class_name']
318 347 subject = Subject.objects.get(id=request.GET['subject_id'])
319 348 topic_choice = request.GET["topic_choice"]
  349 +
  350 + #Have to fix this to accept translated options
320 351 if topic_choice.lower() == "all" or topic_choice.lower() == "todos":
321 352 topics = subject.topic_subject.all()
322 353 else:
323 354 topics = [Topic.objects.get(id=int(topic_choice))]
324 355 data = {}
325   - tags = []
  356 + tags = set()
326 357 for topic in topics:
327 358 resource_set = Resource.objects.select_related(resource_type.lower()).filter(topic = topic)
328 359  
329 360 for resource in resource_set:
330 361 if resource._my_subclass == resource_type.lower():
331 362 for tag in resource.tags.all():
332   - tags.append(tag)
333   -
  363 + if tag.name != "":
  364 + tags.add(tag)
  365 +
334 366  
335   -
  367 + #adding empty tag for the purpose of giving the user this option for adicional behavior
  368 + tags = list(tags)
  369 + tags.append(Tag(name=""))
336 370 data['tags'] = [ {'id':tag.id, 'name':tag.name} for tag in tags]
337 371 return JsonResponse(data)
338 372  
339 373  
340   -def download_report(request):
  374 +def download_report_csv(request):
341 375 report = ReportCSV.objects.get(user=request.user)
342 376  
343 377 response = HttpResponse(report.csv_data,content_type='text/csv')
... ...
users/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-21 22:47-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"
... ... @@ -18,69 +18,69 @@ msgstr &quot;&quot;
18 18 "Content-Transfer-Encoding: 8bit\n"
19 19 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
20 20  
21   -#: users/forms.py:25 users/forms.py:30 users/forms.py:189
  21 +#: .\forms.py:25 .\forms.py:30 .\forms.py:189
22 22 msgid "You must insert an email address"
23 23 msgstr "Você deve inserir um endereço de email"
24 24  
25   -#: users/forms.py:40
  25 +#: .\forms.py:40
26 26 msgid "The image is too large. It should have less than 2MB."
27 27 msgstr "A imagem é muito grande. Ela deve conter menos de 2MB."
28 28  
29   -#: users/forms.py:51
  29 +#: .\forms.py:51
30 30 msgid "The confirmation password is incorrect."
31 31 msgstr "A confirmação de senha está incorreta."
32 32  
33   -#: users/forms.py:58 users/forms.py:114 users/templates/users/login.html:52
  33 +#: .\forms.py:58 .\forms.py:114 .\templates\users\login.html:52
34 34 msgid "Password"
35 35 msgstr "Senha"
36 36  
37   -#: users/forms.py:59 users/forms.py:115 users/forms.py:146 users/forms.py:202
  37 +#: .\forms.py:59 .\forms.py:115 .\forms.py:146 .\forms.py:202
38 38 msgid "Confirm Password"
39 39 msgstr "Confirmação de Senha"
40 40  
41   -#: users/forms.py:76 users/forms.py:180 users/templates/users/list.html:56
42   -#: users/templates/users/login.html:47 users/templates/users/search.html:47
  41 +#: .\forms.py:76 .\forms.py:180 .\templates\users\list.html:56
  42 +#: .\templates\users\login.html:47 .\templates\users\search.html:47
43 43 msgid "Email"
44 44 msgstr "Email"
45 45  
46   -#: users/forms.py:77 users/models.py:27 users/templates/users/list.html:55
47   -#: users/templates/users/search.html:46
  46 +#: .\forms.py:77 .\models.py:27 .\templates\users\list.html:55
  47 +#: .\templates\users\search.html:46
48 48 msgid "Name"
49 49 msgstr "Nome"
50 50  
51   -#: users/forms.py:78 users/models.py:28
  51 +#: .\forms.py:78 .\models.py:28
52 52 msgid "Last Name"
53 53 msgstr "Sobrenome"
54 54  
55   -#: users/forms.py:79 users/models.py:29
  55 +#: .\forms.py:79 .\models.py:29
56 56 msgid "Social Name"
57 57 msgstr "Nome Social"
58 58  
59   -#: users/forms.py:145 users/forms.py:201
  59 +#: .\forms.py:145 .\forms.py:201
60 60 msgid "New Password"
61 61 msgstr "Nova Senha"
62 62  
63   -#: users/forms.py:152
  63 +#: .\forms.py:152
64 64 msgid "The value inputed does not match with your actual password."
65 65 msgstr "O valor inserido não corresponde à sua senha atual."
66 66  
67   -#: users/forms.py:173
  67 +#: .\forms.py:173
68 68 msgid "Actual Password"
69 69 msgstr "Senha Atual"
70 70  
71   -#: users/forms.py:194
  71 +#: .\forms.py:194
72 72 msgid "You must insert a valid email address"
73 73 msgstr "Você deve inserir um endereço de email válido"
74 74  
75   -#: users/models.py:16
  75 +#: .\models.py:16
76 76 msgid "File not supported."
77 77 msgstr "Arquivo não suportado."
78 78  
79   -#: users/models.py:20
  79 +#: .\models.py:20
80 80 msgid "Mail"
81 81 msgstr "Email"
82 82  
83   -#: users/models.py:23
  83 +#: .\models.py:23
84 84 msgid ""
85 85 "Type a valid email. This fields should only contain letters, numbers and the "
86 86 "characteres: @/./+/-/_ ."
... ... @@ -88,111 +88,109 @@ msgstr &quot;&quot;
88 88 "Digite um email válido. Esse campo deve conter apenas letras, números e os "
89 89 "caracteres: @/./+/-/_ ."
90 90  
91   -#: users/models.py:26
  91 +#: .\models.py:26
92 92 msgid "Your email address that will be used to access the platform"
93 93 msgstr "Seu endereço de email que será usado para acessar a plataforma"
94 94  
95   -#: users/models.py:30 users/templates/users/list.html:57
96   -#: users/templates/users/profile.html:60 users/templates/users/search.html:48
  95 +#: .\models.py:30 .\templates\users\list.html:57
  96 +#: .\templates\users\profile.html:60 .\templates\users\search.html:48
97 97 msgid "Description"
98 98 msgstr "Descrição"
99 99  
100   -#: users/models.py:31
  100 +#: .\models.py:31
101 101 msgid "Photo"
102 102 msgstr "Foto"
103 103  
104   -#: users/models.py:32
  104 +#: .\models.py:32
105 105 msgid "Create Date"
106 106 msgstr "Data de Criação"
107 107  
108   -#: users/models.py:33
  108 +#: .\models.py:33
109 109 msgid "Last Update"
110 110 msgstr "Última Atualização"
111 111  
112   -#: users/models.py:34
  112 +#: .\models.py:34
113 113 msgid "Show email?"
114 114 msgstr "Mostrar email?"
115 115  
116   -#: users/models.py:34
  116 +#: .\models.py:34
117 117 msgid "Allow everyone to see my address"
118 118 msgstr "Permitir que todos vejam meu endereço de email"
119 119  
120   -#: users/models.py:34
  120 +#: .\models.py:34
121 121 msgid "Only classmates can see my address"
122 122 msgstr "Apenas meus colegas de disciplina podem ver meu endereço de email"
123 123  
124   -#: users/models.py:34
  124 +#: .\models.py:34
125 125 msgid "Nobody can see my address"
126 126 msgstr "Ninguém pode ver meu endereço de email"
127 127  
128   -#: users/models.py:35
  128 +#: .\models.py:35
129 129 msgid "Administrator"
130 130 msgstr "Administrador"
131 131  
132   -#: users/models.py:36
  132 +#: .\models.py:36
133 133 msgid "Active"
134 134 msgstr "Ativo"
135 135  
136   -#: users/models.py:44
  136 +#: .\models.py:44
137 137 msgid "User"
138 138 msgstr "Usuário"
139 139  
140   -#: users/models.py:45
  140 +#: .\models.py:45
141 141 msgid "Users"
142 142 msgstr "Usuários"
143 143  
144   -#: users/models.py:63
  144 +#: .\models.py:63
145 145 msgid "Yes"
146 146 msgstr "Sim"
147 147  
148   -#: users/models.py:65
  148 +#: .\models.py:65
149 149 msgid "Is not an admin"
150 150 msgstr "Não é administrador"
151 151  
152   -#: users/templates/users/_form.html:16 users/templates/users/register.html:52
  152 +#: .\templates\users\_form.html:16 .\templates\users\register.html:52
153 153 msgid "Choose your photo..."
154 154 msgstr "Escolha sua foto..."
155 155  
156   -#: users/templates/users/_form.html:61
  156 +#: .\templates\users\_form.html:62
157 157 msgid "Save"
158 158 msgstr "Salvar"
159 159  
160   -#: users/templates/users/_form.html:64 users/templates/users/delete.html:27
161   -#: users/templates/users/delete_account.html:27
  160 +#: .\templates\users\_form.html:65 .\templates\users\delete.html:27
  161 +#: .\templates\users\delete_account.html:27
162 162 msgid "Cancel"
163 163 msgstr "Cancelar"
164 164  
165   -#: users/templates/users/delete.html:9
  165 +#: .\templates\users\delete.html:9
166 166 msgid "Delete User"
167 167 msgstr "Deletar Usuário"
168 168  
169   -#: users/templates/users/delete.html:19
  169 +#: .\templates\users\delete.html:19
170 170 msgid "Are you sure you want delete the user"
171 171 msgstr "Tem certeza que deseja deletar o usuário"
172 172  
173   -#: users/templates/users/delete.html:20
174   -#: users/templates/users/delete_account.html:20
  173 +#: .\templates\users\delete.html:20 .\templates\users\delete_account.html:20
175 174 msgid "All data will be lost and havent how recover it."
176 175 msgstr "Toda informação será perdida e não poderá ser recuperada"
177 176  
178   -#: users/templates/users/delete.html:24
179   -#: users/templates/users/delete_account.html:24
  177 +#: .\templates\users\delete.html:24 .\templates\users\delete_account.html:24
180 178 msgid "Remove"
181 179 msgstr "Deletar"
182 180  
183   -#: users/templates/users/delete_account.html:9
  181 +#: .\templates\users\delete_account.html:9
184 182 msgid "Remove Account"
185 183 msgstr "Remover Conta"
186 184  
187   -#: users/templates/users/delete_account.html:19
  185 +#: .\templates\users\delete_account.html:19
188 186 msgid "Are you sure you want delete your account?"
189 187 msgstr "Tem certeza que deseja deletar sua conta?"
190 188  
191   -#: users/templates/users/forgot_password.html:39 users/views.py:380
  189 +#: .\templates\users\forgot_password.html:39 .\views.py:380
192 190 msgid "Forgot Password"
193 191 msgstr "Esqueceu Senha"
194 192  
195   -#: users/templates/users/forgot_password.html:40
  193 +#: .\templates\users\forgot_password.html:40
196 194 msgid ""
197 195 "Enter your email below (the one used to access the platform) to recover your "
198 196 "password"
... ... @@ -200,132 +198,131 @@ msgstr &quot;&quot;
200 198 "Digite seu endereço de email abaixo (o utilizado para acessar a plataforma) "
201 199 "para recuperar sua senha"
202 200  
203   -#: users/templates/users/forgot_password.html:72
  201 +#: .\templates\users\forgot_password.html:72
204 202 msgid "Recover"
205 203 msgstr "Recuperar"
206 204  
207   -#: users/templates/users/forgot_password.html:75
208   -#: users/templates/users/new_password.html:80
209   -#: users/templates/users/register.html:91
  205 +#: .\templates\users\forgot_password.html:75
  206 +#: .\templates\users\new_password.html:80 .\templates\users\register.html:91
210 207 msgid "Back"
211 208 msgstr "Voltar"
212 209  
213   -#: users/templates/users/list.html:30 users/templates/users/search.html:21
  210 +#: .\templates\users\list.html:30 .\templates\users\search.html:21
214 211 msgid "Search..."
215 212 msgstr "Pesquisar..."
216 213  
217   -#: users/templates/users/list.html:41 users/templates/users/search.html:32
  214 +#: .\templates\users\list.html:41 .\templates\users\search.html:32
218 215 msgid "Create User"
219 216 msgstr "Criar Usuário"
220 217  
221   -#: users/templates/users/list.html:59 users/templates/users/profile.html:63
222   -#: users/templates/users/search.html:50
  218 +#: .\templates\users\list.html:59 .\templates\users\profile.html:63
  219 +#: .\templates\users\search.html:50
223 220 msgid "Not Informed"
224 221 msgstr "Não Informado"
225 222  
226   -#: users/templates/users/list.html:65 users/templates/users/search.html:56
  223 +#: .\templates\users\list.html:65 .\templates\users\search.html:56
227 224 msgid "Edit"
228 225 msgstr "Editar"
229 226  
230   -#: users/templates/users/list.html:66 users/templates/users/search.html:57
  227 +#: .\templates\users\list.html:66 .\templates\users\search.html:57
231 228 msgid "Delete"
232 229 msgstr "Deletar"
233 230  
234   -#: users/templates/users/list.html:76 users/templates/users/search.html:67
  231 +#: .\templates\users\list.html:76 .\templates\users\search.html:67
235 232 msgid "No users found"
236 233 msgstr "Nenhum usuário encontrado"
237 234  
238   -#: users/templates/users/login.html:39
  235 +#: .\templates\users\login.html:39
239 236 msgid "Sign in with your account to continue"
240 237 msgstr "Entre com a sua conta para continuar"
241 238  
242   -#: users/templates/users/login.html:63 users/templates/users/login.html:70
  239 +#: .\templates\users\login.html:63 .\templates\users\login.html:70
243 240 msgid "Log in"
244 241 msgstr "Entrar"
245 242  
246   -#: users/templates/users/login.html:66 users/views.py:354
  243 +#: .\templates\users\login.html:66 .\views.py:354
247 244 msgid "Sign Up"
248 245 msgstr "Cadastrar"
249 246  
250   -#: users/templates/users/login.html:81 users/templates/users/login.html:117
  247 +#: .\templates\users\login.html:81 .\templates\users\login.html:117
251 248 msgid "Forgot your password?"
252 249 msgstr "Esqueceu sua senha?"
253 250  
254   -#: users/templates/users/new_password.html:39
  251 +#: .\templates\users\new_password.html:39
255 252 msgid "Set new password"
256 253 msgstr "Digite a nova senha"
257 254  
258   -#: users/templates/users/new_password.html:77
  255 +#: .\templates\users\new_password.html:77
259 256 msgid "Reset"
260 257 msgstr "Restaurar"
261 258  
262   -#: users/templates/users/profile.html:40
  259 +#: .\templates\users\profile.html:40
263 260 msgid "System Admin"
264 261 msgstr "Administrador do sistema"
265 262  
266   -#: users/templates/users/profile.html:44
  263 +#: .\templates\users\profile.html:44
267 264 msgid "Coordinator in"
268 265 msgstr "Coordenador em"
269 266  
270   -#: users/templates/users/profile.html:48
  267 +#: .\templates\users\profile.html:48
271 268 msgid "Professor in"
272 269 msgstr "Professor em"
273 270  
274   -#: users/templates/users/profile.html:52
  271 +#: .\templates\users\profile.html:52
275 272 msgid "Student in"
276 273 msgstr "Estudante em"
277 274  
278   -#: users/templates/users/register.html:39
  275 +#: .\templates\users\register.html:39
279 276 msgid "User Register"
280 277 msgstr "Cadastro de Usuário"
281 278  
282   -#: users/templates/users/register.html:88
  279 +#: .\templates\users\register.html:88
283 280 msgid "Register"
284 281 msgstr "Cadastrar"
285 282  
286   -#: users/templatetags/profile_verifies.py:16
  283 +#: .\templatetags\profile_verifies.py:16
287 284 msgid "Is not a coordinator"
288 285 msgstr "Não é coordenador"
289 286  
290   -#: users/templatetags/profile_verifies.py:25
  287 +#: .\templatetags\profile_verifies.py:25
291 288 msgid "Is not a professor"
292 289 msgstr "Não é professor"
293 290  
294   -#: users/templatetags/profile_verifies.py:34
  291 +#: .\templatetags\profile_verifies.py:34
295 292 msgid "Is not a student"
296 293 msgstr "Não é estudante"
297 294  
298   -#: users/views.py:55
  295 +#: .\views.py:55
299 296 msgid "Manage Users"
300 297 msgstr "Gerenciar Usuários"
301 298  
302   -#: users/views.py:85
  299 +#: .\views.py:85
303 300 msgid "Search Users"
304 301 msgstr "Pesquisar Usuário"
305 302  
306   -#: users/views.py:108
  303 +#: .\views.py:108
307 304 #, python-format
308   -msgid "User %s created successfully"
309   -msgstr "Usuário %s criado com sucesso"
  305 +msgid "User \"%s\" created successfully"
  306 +msgstr "Usuário \"%s\" criado com sucesso"
310 307  
311   -#: users/views.py:122
  308 +#: .\views.py:122
312 309 msgid "Add User"
313 310 msgstr "Cadastrar Usuário"
314 311  
315   -#: users/views.py:156
  312 +#: .\views.py:156
316 313 #, python-format
317   -msgid "User %s updated successfully"
318   -msgstr "Usuário %s atualizado com sucesso"
  314 +msgid "User \"%s\" updated successfully"
  315 +msgstr "Usuário \"%s\" atualizado com sucesso"
319 316  
320   -#: users/views.py:170
  317 +#: .\views.py:170
321 318 msgid "Update User"
322 319 msgstr "Atualizar Usuário"
323 320  
324   -#: users/views.py:225
  321 +#: .\views.py:225
325 322 msgid "User removed successfully!"
326 323 msgstr "Usuário removido com sucesso!"
327 324  
328   -#: users/views.py:226
  325 +#: .\views.py:226
329 326 msgid ""
330 327 "Could not remove the account. The user is attach to one or more functions "
331 328 "(administrator, coordinator, professor ou student) in the system."
... ... @@ -333,39 +330,39 @@ msgstr &quot;&quot;
333 330 "Não é possível deletar a conta. O usuário está vinculado com uma ou mais "
334 331 "funções (administrador, coordenador, professor ou estudante) no sistema."
335 332  
336   -#: users/views.py:249
  333 +#: .\views.py:249
337 334 msgid "Delete Account"
338 335 msgstr "Remover Conta"
339 336  
340   -#: users/views.py:292
  337 +#: .\views.py:292
341 338 msgid "Password changed successfully!"
342 339 msgstr "Senha alterada com sucesso!"
343 340  
344   -#: users/views.py:298
  341 +#: .\views.py:298
345 342 msgid "Change Password"
346 343 msgstr "Alterar Senha"
347 344  
348   -#: users/views.py:316
  345 +#: .\views.py:316
349 346 msgid "Profile"
350 347 msgstr "Perfil"
351 348  
352   -#: users/views.py:335
  349 +#: .\views.py:335
353 350 msgid "Update Profile"
354 351 msgstr "Atualizar Perfil"
355 352  
356   -#: users/views.py:341
  353 +#: .\views.py:341
357 354 msgid "Profile edited successfully!"
358 355 msgstr "Perfil editado com sucesso!"
359 356  
360   -#: users/views.py:361
  357 +#: .\views.py:361
361 358 msgid "User successfully registered!"
362 359 msgstr "Usuário cadastrado com sucesso!"
363 360  
364   -#: users/views.py:399
  361 +#: .\views.py:399
365 362 msgid "Recover Password"
366 363 msgstr "Recuperar Senha"
367 364  
368   -#: users/views.py:435
  365 +#: .\views.py:435
369 366 msgid ""
370 367 "Soon you'll receive an email with instructions to set your new password. If "
371 368 "you don't receive it in 24 hours, please check your spam box."
... ... @@ -373,34 +370,38 @@ msgstr &quot;&quot;
373 370 "Em breve você receberá um email com instruções para cadastrar sua nova "
374 371 "senha. Se você não recebê-lo em 24 hhoras, por favor olhe sua caixa de spam."
375 372  
376   -#: users/views.py:438
  373 +#: .\views.py:438
377 374 msgid "No user is associated with this email address"
378 375 msgstr "Nenhum usuário associado com esse endereço de email."
379 376  
380   -#: users/views.py:451
  377 +#: .\views.py:451
381 378 msgid "Reset Password"
382 379 msgstr "Recuperar Senha"
383 380  
384   -#: users/views.py:473
  381 +#: .\views.py:473
385 382 msgid "Password reset successfully."
386 383 msgstr "Senha alterada com sucesso!"
387 384  
388   -#: users/views.py:477
  385 +#: .\views.py:477
389 386 msgid "We were not able to reset your password."
390 387 msgstr "Não foi possível restaurar sua senha"
391 388  
392   -#: users/views.py:480
  389 +#: .\views.py:480
393 390 msgid "The reset password link is no longer valid."
394 391 msgstr "O link para restaurar senha não está mais válido."
395 392  
396   -#: users/views.py:486
  393 +#: .\views.py:486
397 394 msgid "Log In"
398 395 msgstr "Entrar"
399 396  
400   -#: users/views.py:507
  397 +#: .\views.py:507
401 398 msgid "System under maintenance. Try again later"
402 399 msgstr "Sistema em manutenção. Tente novamente mais tarde"
403 400  
404   -#: users/views.py:509
  401 +#: .\views.py:509
405 402 msgid "E-mail or password are incorrect."
406 403 msgstr "Email ou senha incorretos."
  404 +
  405 +#, fuzzy
  406 +#~ msgid "User {name} created successfully"
  407 +#~ msgstr "Usuário {name} criado com sucesso"
... ...
users/views.py
... ... @@ -105,7 +105,7 @@ class CreateView(braces_mixins.LoginRequiredMixin, braces_mixins.StaffuserRequir
105 105 def form_valid(self, form):
106 106 self.object = form.save()
107 107  
108   - msg = _("User %s created successfully" % self.object.get_short_name())
  108 + msg = _('User "%s" created successfully')%(self.object.get_short_name() )
109 109  
110 110 self.log_context['user_id'] = self.object.id
111 111 self.log_context['user_name'] = self.object.get_short_name()
... ... @@ -153,7 +153,7 @@ class UpdateView(braces_mixins.LoginRequiredMixin, braces_mixins.StaffuserRequir
153 153  
154 154 self.object.save()
155 155  
156   - msg = _("User %s updated successfully" % self.object.get_short_name())
  156 + msg = _('User "%s" updated successfully')%(self.object.get_short_name())
157 157  
158 158 self.log_context['user_id'] = self.object.id
159 159 self.log_context['user_name'] = self.object.get_short_name()
... ...