Commit 85fd085c0bf9cf21e1fab108a5e358e459d70b9c
Exists in
master
and in
3 other branches
Merge branch 'refactoring' of https://github.com/amadeusproject/amadeuslms into refactoring
Showing
20 changed files
with
363 additions
and
224 deletions
Show diff stats
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
amadeus/static/css/base/amadeus.css
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 "" |
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 "" |
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 "" |
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 | ... | ... |
... | ... | @@ -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 "" |
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 "" |
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 "" |
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 "" |
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 "" |
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 "" |
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() | ... | ... |