Commit 17776dcf618219e0278b2331bd3ab9abed3de0eb

Authored by Felipe Bormann
2 parents 7433e08d 2c9d9435

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

amadeus/static/css/.sass-cache/a7f87b90919294b62ab4f8079e31dcda8f485534/green.sassc
No preview for this file type
amadeus/static/css/base/amadeus.css
... ... @@ -1612,7 +1612,7 @@ div.dataTables_wrapper div.dataTables_paginate {
1612 1612 font-size: 14px;
1613 1613 }
1614 1614  
1615   -.subject-related-panel .panel {
  1615 +.subject-related-panel .panel:not(.participant) {
1616 1616 margin-bottom: 0px;
1617 1617 }
1618 1618  
... ...
amadeus/static/css/base/amadeus_responsive.css
... ... @@ -7,11 +7,6 @@
7 7 height: 38px;
8 8 }
9 9  
10   - .mural .post_make .user-img img {
11   - max-width: 70px;
12   - max-height: 70px;
13   - }
14   -
15 10 .mural .post_make .post-field h4 {
16 11 line-height: 2.6em;
17 12 }
... ... @@ -35,11 +30,6 @@
35 30 height: 38px;
36 31 }
37 32  
38   - .mural .post_make .user-img img {
39   - max-width: 65px;
40   - max-height: 65px;
41   - }
42   -
43 33 .mural .post_make .post-field h4 {
44 34 line-height: 2.3em;
45 35 }
... ... @@ -134,11 +124,6 @@
134 124 height: 60px;
135 125 }
136 126  
137   - .mural .post_make .user-img img {
138   - max-width: 60px;
139   - max-height: 60px;
140   - }
141   -
142 127 .mural .post_make .post-field h4 {
143 128 line-height: 2em;
144 129 }
... ... @@ -228,11 +213,6 @@
228 213 height: 50px;
229 214 }
230 215  
231   - .mural .post_make .user-img img {
232   - max-width: 50px;
233   - max-height: 50px;
234   - }
235   -
236 216 .mural .post_make .post-field h4 {
237 217 line-height: 1.6em;
238 218 }
... ...
amadeus/static/css/themes/green.css
... ... @@ -396,9 +396,6 @@ a.add-row {
396 396 .mural .post_make {
397 397 background: #FFFFFF; }
398 398  
399   -.mural .post_make .user-img, .post .post-img, .post .post-comment .user-img div, .comment .comment-img div {
400   - background: #CCCCCC; }
401   -
402 399 .mural .post_make .post-field div {
403 400 border-color: #CCCCCC; }
404 401  
... ...
amadeus/static/css/themes/green.css.map
1 1 {
2 2 "version": 3,
3   -"mappings": "AAOA,gJAAgJ;EAC5I,gBAAgB,EAAE,KAAK;;AAG3B,mBAAmB;EACf,KAAK,EAXO,OAAO;;AAcvB,gGAA4F;EACxF,gBAAgB,EAfJ,OAAO;;AAkBvB,kGAA8F;EAC1F,YAAY,EAnBA,OAAO;;AAsBvB,iMAAiM;EAC7L,KAAK,EAAE,IAAI;EACX,gBAAgB,EAxBJ,OAAO;EAyBnB,YAAY,EAzBA,OAAO;;AA4BvB,+BAA+B;EAC3B,gBAAgB,EA7BJ,OAAO;EA8BnB,KAAK,EAAE,yBAAqB;;AAGhC,aAAa;EACT,gBAAgB,EAAE,kBAAkB;;AAGxC,YAAY;EACR,UAAU,EAtCE,OAAO;;AAyCvB,iBAAiB;EACb,UAAU,EAzCI,OAAO;;;AA+CzB,+CAA+C;EAC3C,UAAU,EAAE,OAAO;EACnB,KAAK,EAlDO,OAAO;;AAqDvB,qDAAqD;EACjD,KAAK,EAtDO,OAAO;;;AA2DvB,mBAAmB;EACf,gBAAgB,EA5DJ,OAAO;EA6DnB,KAAK,EAAE,KAAK;;AAGhB,qBAAqB;EACjB,KAAK,EAAE,KAAK;;AAGhB,qCAAqC;EACjC,gBAAgB,EApEF,OAAO;;AAuEzB,2BAA2B;EACvB,gBAAgB,EAxEF,OAAO;;;;AA+EzB,qBAAsB;EAClB,KAAK,EAAE,OAAO;;AAGlB,mBAAoB;EAChB,KAAK,EAAE,OAAO;;AAGlB,sBAAsB;EAClB,KAAK,EAAG,OAAO;;AAGnB,oBAAqB;EACjB,KAAK,EAAE,OAAO;;AAIlB,kBAAkB;EACd,KAAK,EAAE,OAAO;;AAIlB,gBAAgB;EACZ,gBAAgB,EAAE,kBAAkB;EACpC,KAAK,EAtGO,OAAO;;AAyGvB,gCAAgC;EAC5B,gBAAgB,EAAE,kBAAkB;;AAGxC,uDAAuD;EACnD,KAAK,EAAE,OAAO;;AAGlB,6DAA6D;EACzD,KAAK,EAjHD,OAAO;;AAoHf,+BAA+B;EAC3B,gBAAgB,EAAE,kBAAkB;;AAGxC,sDAAsD;EAClD,KAAK,EAAE,OAAO;;AAGlB,4DAA4D;EACxD,KAAK,EA7HD,OAAO;;AAgIf,cAAc;EACV,KAAK,EAAE,kBAAkB;;;AAK7B,aAAa;EACT,aAAa,EAAE,4BAA8B;;AAGjD,aAAa;EACT,UAAU,EAAE,4BAA8B;;;AAM9C,eAAe;EACX,gBAAgB,EAAE,kBAAkB;EACpC,KAAK,EAAE,KAAK;;;AAKhB,6BAA6B;EACzB,gBAAgB,EAAE,kBAAiB;;AAGvC,8FAA8F;EAC1F,KAAK,EAAE,kBAAkB;;AAG7B,iBAAiB;EACb,UAAU,EAAE,kBAAiB;EAC7B,UAAU,EAAE,iBAAiB;;;AAKjC,6BAA6B;EACzB,gBAAgB,EAAE,kBAAkB;;AAGxC,oHAAoH;EAChH,KAAK,EAAE,OAAO;;AAGlB,gIAAgI;EAC5H,KAAK,EAhLD,OAAO;;AAmLf,wFAAwF;EACpF,UAAU,EApLN,OAAO;;AAuLf,uCAAuC;EACnC,gBAAgB,EAAE,kBAAkB;EACpC,KAAK,EA1LO,OAAO;;AA6LvB,mBAAmB;EACf,UAAU,EAAE,OAAO;;AAGvB,kBAAkB;EACd,KAAK,EAAE,KAAK;;AAGhB,wBAAwB;EACpB,KAAK,EAAE,OAAO;;AAGlB,iCAAiC;EAC7B,KAAK,EAAE,kBAAkB;;AAG7B,gBAAgB;EACZ,gBAAgB,EAAE,OAAO;EACzB,KAAK,EA9MD,OAAO;;AAiNf,uBAAuB;EACnB,UAAU,EAnNE,OAAO;;AAsNvB,yBAA0B;EACtB,gBAAgB,EAtNZ,OAAO;EAuNX,mBAAmB,EAAE,OAAO;EAC5B,KAAK,EAAE,OAAO;;AAGlB,gCAAiC;EAC7B,KAAK,EAAE,OAAO;EACd,mBAAmB,EA/NL,OAAO;;AAkOzB,mBAAmB;EACf,gBAAgB,EAAE,OAAO;EACzB,KAAK,EAAE,KAAK;;AAGhB,4EAA4E;EACxE,UAAU,EAtON,OAAO;;;AA8Of,mBAAmB;EACf,UAAU,EAAE,kBAA2B;;AAG3C,qBAAqB;EACjB,KAAK,EAAE,KAAK;;AAGhB,mBAAmB;EACf,UAAU,EAzPI,OAAO;;AA4PzB,wBAAwB;EACpB,UAAU,EAAE,kBAA2B;;AAG3C,mCAAmC;EAC/B,UAAU,EAjQI,OAAO;;AAoQzB,WAAW;EACP,KAAK,EApQO,OAAO;;AAwQvB,cAAc;EACV,UAAU,EAzQE,OAAO;;AA4QvB,qBAAqB;EACjB,UAAU,EA7QE,OAAO;EA8QnB,KAAK,EAAE,OAAO;;AAGlB,2BAA2B;EACvB,UAAU,EAAE,kBAAkB;;AAGlC,2CAA2C;EACvC,UAAU,EAtRE,OAAO;;AAyRvB,iDAAiD;EAC7C,UAAU,EAAE,OAAO;;AAGvB,8DAA8D;EAC1D,KAAK,EAAE,OAAO;;AAGlB,oEAAoE;EAChE,KAAK,EApSO,OAAO;;AAuSvB,qDAAqD;EACjD,KAAK,EAxSO,OAAO;;AA2SvB,YAAY;EACR,UAAU,EA1SE,OAAO;;AA8SvB,gBAAgB;EACZ,gBAAgB,EAAE,KAAK;;AAG3B,+BAA+B;EAC3B,KAAK,EAAE,OAAO;;AAGlB,oBAAoB;EAChB,KAAK,EAAE,OAAO;;AAGlB,gBAAgB;EACZ,KAAK,EAAE,OAAO;;;AAGlB,YAAY;EACR,KAAK,EAAE,yBAAqB;;AAGhC,sCAAsC;EAClC,KAAK,EAlUD,OAAO;;AAqUf,UAAU;EACN,UAAU,EAAE,KAAK;;AAGrB,eAAe;EACX,UAAU,EA3UE,OAAO;;AA8UvB,cAAc;EACV,KAAK,EAAE,OAAO;;AAGlB,gCAAgC;EAC5B,KAAK,EAAE,KAAK;;AAGhB,kBAAkB;EACd,KAAK,EAAE,KAAK;;AAGhB,sCAAsC;EAClC,KAAK,EAAE,KAAK;;AAEhB,uBAAuB;EACnB,KAAK,EAAE,IAAI;;AAGf,qBAAqB;EACjB,KAAK,EAAE,kBAAiB;;AAG5B,iBAAiB;EACb,aAAa,EAAE,iBAAiB;;AAIpC,kBAAkB;EACd,KAAK,EA1WD,OAAO;EA2WX,UAAU,EA9WE,OAAO;;AAiXvB,oBAAoB;EAChB,KAAK,EAAE,KAAK;;AAGhB,oCAAoC;EAChC,gBAAgB,EArXF,OAAO;;AAwXzB,0BAA0B;EACtB,gBAAgB,EAzXF,OAAO;;AA6XzB,iBAAiB;EACb,aAAa,EAAE,iBAAiB;;AAGpC,kBAAkB;EACd,gBAAgB,EAAE,kBAAkB;EACpC,KAAK,EAAE,KAAK;;AAGhB,SAAS;EACL,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,eAAe;;AAG3B,OAAO;EACH,KAAK,EA1YD,OAAO;EA2YX,UAAU,EAAE,OAAO;;AAGvB,YAAY;EACR,KAAK,EAAE,OAAO;;AAGlB,0CAA0C;EACtC,UAAU,EAAE,eAAe;EAC3B,KAAK,EAAE,eAAe;;AAG1B,wCAAwC;EACpC,UAAU,EAAE,IAAI;;AAGpB,uBAAuB;EACnB,MAAM,EAAE,cAAc;EACtB,KAAK,EAAE,OAAO;;AAGlB,eAAe;EACX,KAAK,EAAE,OAAO;EACd,gBAAgB,EAAE,IAAI;EACtB,YAAY,EAAE,IAAI;;AAGtB,wCAAwC;EACpC,UAAU,EAAE,OAAO;EACnB,KAAK,EAxaD,OAAO;EAyaX,YAAY,EAAE,OAAO;;;AAMzB,qBAAqB;EACjB,MAAM,EAAE,iBAAiB;;AAG7B,gCAAgC;EAC5B,gBAAgB,EAAE,IAAI;;AAG1B,+CAA+C;EAC3C,kBAAkB,EAAE,mGAAqF;EACzG,UAAU,EAAE,mGAAqF;EACjG,gBAAgB,EAAE,IAAI;EACtB,KAAK,EAAE,mBAAe;;AAG1B,SAAS;EACL,kBAAkB,EAAE,mGAAqF;EACzG,UAAU,EAAE,mGAAqF;EACjG,gBAAgB,EAAE,OAAO;EACzB,KAAK,EAAE,yBAAqB;;;AAKhC,iCAAiC;EAC7B,gBAAgB,EAAE,IAAI;EACtB,MAAM,EAAE,cAAc;;AAG1B,0BAA0B;EACtB,gBAAgB,EAAE,IAAI;;AAG1B,gCAAgC;EAC5B,gBAAgB,EAAE,eAAe;;AAGrC,0CAA0C;EACtC,KAAK,EAAE,OAAO;;AAGlB,uCAAuC;EACnC,UAAU,EA1dE,OAAO;;AA6dvB,4CAA4C;EACxC,aAAa,EAAE,yBAAyB;;AAG5C,qCAAqC;EACjC,KAAK,EAAE,OAAO;;AAGlB,2CAA2C;EACvC,KAAK,EAAE,OAAO;;AAGlB,oDAAoD;EAChD,KAAK,EAAE,IAAI;;AAGf,gBAAgB;EACZ,KAAK,EAAE,OAAO;;AAGlB,uHAAuH;EACnH,gBAAgB,EAAE,kBAAkB;;AAKxC,qBAAqB;EACjB,KAAK,EAAE,OAAO;;AAIlB,iBAAiB;EACb,gBAAgB,EAAE,kBAAkB;EACpC,KAAK,EAAE,kBAAyB;;AAGpC,SAAS;EACL,YAAY,EAAE,OAAO;;AAGzB,qBAAqB;EACjB,gBAAgB,EArgBZ,OAAO;;AAwgBf,eAAe;EACX,KAAK,EAAE,OAAO;;AAGlB,yBAAyB;EACrB,gBAAgB,EAAE,OAAO;EACzB,KAAK,EA9gBD,OAAO;;AAihBf,qDAAqD;EACjD,gBAAgB,EAAE,kBAAkB;;AAGxC,QAAQ;EACJ,UAAU,EAAE,IAAI;EAChB,KAAK,EAAE,IAAI;;AAGf,iBAAiB;EACb,UAAU,EA3hBN,OAAO;;AA8hBf,0GAA0G;EACtG,UAAU,EAAE,OAAO;;AAGvB,iCAAiC;EAC7B,YAAY,EAAE,OAAO;;AAGzB,gCAAgC;EAC5B,KAAK,EAAE,OAAO;;AAGlB,sFAAsF;EAClF,KAAK,EAAE,OAAO;;AAGlB,sEAAsE;EAClE,KAAK,EAAE,OAAO;;AAGlB,6BAA6B;EACzB,KAAK,EAAE,OAAO;;AAGlB,WAAW;EACP,KAAK,EAAE,OAAO;;AAGlB,mBAAmB;EACf,gBAAgB,EAAE,OAAO;EACzB,UAAU,EAAE,OAAO;;AAGvB,sCAAsC;EAClC,YAAY,EAAE,OAAO;EACrB,UAAU,EAjkBN,OAAO;;AAokBf,gBAAgB;EACZ,UAAU,EAtkBE,OAAO;EAukBnB,gBAAgB,EAAE,OAAO;;AAG7B,mCAAmC;EAC/B,KAAK,EAAE,OAAO;;AAGlB,aAAa;EACT,KAAK,EAAE,OAAO;;AAGlB,UAAU;EACN,KAAK,EAAE,kBAAkB;;AAG7B,QAAQ;EACJ,KAAK,EAAE,kBAAkB;;AAG7B,0BAA0B;EACtB,UAAU,EA3lBE,OAAO;;AA8lBvB,gCAAgC;EAC5B,KAAK,EAAE,OAAO;;AAId,sCAAK;EACD,KAAK,EAAE,OAAO;;AAIlB,8BAAC;EACG,KAAK,EAAE,OAAO;;AAGtB,YAAY;EACR,UAAU,EA5mBN,OAAO;;AA8mBf,sBAAsB;EAClB,UAAU,EAAE,kBAAkB;;AAElC,gBAAgB;EACZ,UAAU,EAAE,IAAI;;AAGpB,gNAAgN;EAC5M,gBAAgB,EAAE,OAAO;;AAE7B,sCAAsC;EAClC,gBAAgB,EAAE,OAAO;;AAE7B,aAAa;EACT,gBAAgB,EAAE,IAAI;;AAE1B,0BAA0B;EACtB,KAAK,EAAE,OAAO;;AAElB,sDAAsD;EAClD,KAAK,EAAE,OAAO;;AAElB,8FAA8F;EAC1F,YAAY,EAAE,IAAI;EAClB,gBAAgB,EAvoBJ,OAAO;;AA0oBvB,mHAAmH;EAC/G,gBAAgB,EAAE,OAAO;;AAE7B,6GAA6G;EACzG,gBAAgB,EAAE,OAAO;;AAE7B,mBAAmB;EACf,gBAAgB,EAAE,OAAO;EACzB,gBAAgB,EAAE,OAAO;;AAE7B,eAAe;EACX,gBAAgB,EAAE,kBAAkB;;AAExC,yBAAyB;EACrB,gBAAgB,EAAE,OAAO;;AAE7B,4CAA4C;EACxC,gBAAgB,EA1pBZ,OAAO;EA2pBX,YAAY,EAAE,OAAO;;AAEzB,cAAc;EACV,KAAK,EAAE,IAAI;;AAEf,aAAa;EACT,gBAAgB,EAAE,OAAO;;AAE7B,yCAAyC;EACrC,KAAK,EAAE,IAAI;;AAEf,aAAa;EACT,KAAK,EAvqBD,OAAO;EAwqBX,gBAAgB,EAAE,OAAO;;AAE7B,0BAA0B;EACtB,UAAU,EAAE,IAAI;;AAEpB,iCAAiC;EAC7B,gBAAgB,EA9qBZ,OAAO;;AAgrBf,aAAa;EACT,UAAU,EAAE,oBAAoB;;AAEpC,eAAe;EACX,KAAK,EAAE,OAAO;;AAElB,kBAAkB;EACd,UAAU,EAAE,oBAAoB;;AAEpC,qCAAqC;EACjC,gBAAgB,EAAE,OAAO;;AAE7B,gBAAgB;EACZ,gBAAgB,EAAE,kBAAkB;;AAExC,6BAA6B;EACzB,UAAU,EAnsBE,OAAO;EAosBnB,KAAK,EAjsBD,OAAO;;AAmsBf,6EAA6E;EACzE,KAAK,EAAE,OAAO;;AAElB,WAAW;EACP,YAAY,EAAE,kBAAyB;;;EAGvC,mDAAmD;IAC/C,KAAK,EAAE,kBAAkB;;EAE7B,yDAAyD;IACrD,KAAK,EAAE,kBAAyB",
  3 +"mappings": "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",
4 4 "sources": ["green.sass"],
5 5 "names": [],
6 6 "file": "green.css"
... ...
amadeus/static/css/themes/green.sass
... ... @@ -544,10 +544,6 @@ a.add-row
544 544 background: $white
545 545  
546 546  
547   -.mural .post_make .user-img, .post .post-img, .post .post-comment .user-img div, .comment .comment-img div
548   - background: #CCCCCC
549   -
550   -
551 547 .mural .post_make .post-field div
552 548 border-color: #CCCCCC
553 549  
... ...
amadeus/templates/base.html
... ... @@ -145,7 +145,7 @@
145 145 </ul>
146 146 </li>
147 147 <li style="width:40px;">
148   - <a href="" id="contrast_button">
  148 + <a href="{% url 'themes:contrast' %}" id="contrast_button">
149 149 <i style="font-size:15px;right: 150%;" class="glyphicon glyphicon-adjust"></i>
150 150 </a>
151 151  
... ... @@ -209,11 +209,11 @@
209 209 $("#contrast_button" ).click(function() {
210 210 if (Cookies.get('contrast_check')) {
211 211 Cookies.remove('contrast_check')
212   - location.reload()
  212 + //location.reload()
213 213 }
214 214 else {
215 215 Cookies.set('contrast_check','contrast')
216   - location.reload()
  216 + //location.reload()
217 217 }
218 218  
219 219 });
... ...
file_link/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-04-15 00:13-0300\n"
  11 +"POT-Creation-Date: 2017-05-05 17:50-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,27 +18,27 @@ msgstr &quot;&quot;
18 18 "Content-Transfer-Encoding: 8bit\n"
19 19 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
20 20  
21   -#: file_link/forms.py:26
  21 +#: forms.py:26
22 22 msgid "Tags"
23 23 msgstr "Tags"
24 24  
25   -#: file_link/forms.py:32
  25 +#: forms.py:32
26 26 msgid "File name"
27 27 msgstr "Nome do arquivo"
28 28  
29   -#: file_link/forms.py:52
  29 +#: forms.py:52
30 30 msgid "This subject already has a file link with this name"
31 31 msgstr "Esse assunto já possui um Link para Arquivo com esse nome"
32 32  
33   -#: file_link/forms.py:64
  33 +#: forms.py:64
34 34 msgid "The file is too large. It should have less than 10MB."
35 35 msgstr "Esse arquivo é muito grande. Ele deve conter menos de 10MB."
36 36  
37   -#: file_link/forms.py:69
  37 +#: forms.py:69
38 38 msgid "This field is required."
39 39 msgstr "Esse campo é obrigatório."
40 40  
41   -#: file_link/models.py:23
  41 +#: models.py:23
42 42 msgid ""
43 43 "Please select a valid file. The uploaded file must have one of the following "
44 44 "extensions: .doc, .docx, .html, .jpg, .odp, .ods, .odt, .pdf, .png, .ppt, ."
... ... @@ -48,76 +48,146 @@ msgstr &quot;&quot;
48 48 "das seguintes extensões: .doc, .docx, .html, .jpg, .odp, .ods, .odt, .pdf, ."
49 49 "png, .ppt, .pptx, .xlx e .xlsx"
50 50  
51   -#: file_link/models.py:26
  51 +#: models.py:26
52 52 msgid "File"
53 53 msgstr "Arquivo"
54 54  
55   -#: file_link/models.py:29
  55 +#: models.py:29
56 56 msgid "File Link"
57 57 msgstr "Link para Arquivo"
58 58  
59   -#: file_link/models.py:30
  59 +#: models.py:30
60 60 msgid "File Links"
61 61 msgstr "Links para Arquivo"
62 62  
63   -#: file_link/models.py:49
  63 +#: models.py:49
64 64 msgid "Are you sure you want delete the file link"
65 65 msgstr "Você tem certeza que deseja remover o Link para Arquivo"
66 66  
67   -#: file_link/templates/file_links/_form.html:33
  67 +#: templates/file_links/_form.html:33
68 68 msgid "Choose your file..."
69 69 msgstr "Escolha seu arquivo..."
70 70  
71   -#: file_link/templates/file_links/_form.html:47
  71 +#: templates/file_links/_form.html:47
72 72 msgid "Click or drop the file here"
73 73 msgstr "Clique ou solte o arquivo aqui"
74 74  
75   -#: file_link/templates/file_links/_form.html:49
  75 +#: templates/file_links/_form.html:49
76 76 msgid "The file could not exceed 10MB."
77 77 msgstr "O arquivo não pode exceder 10MB."
78 78  
79   -#: file_link/templates/file_links/_form.html:69
  79 +#: templates/file_links/_form.html:69
80 80 msgid "Common resources settings"
81 81 msgstr "Configurações comuns à todos os recursos"
82 82  
83   -#: file_link/templates/file_links/_form.html:118
  83 +#: templates/file_links/_form.html:118
84 84 msgid "Pendencies Notifications"
85 85 msgstr "Notificações de Pendências"
86 86  
87   -#: file_link/templates/file_links/_form.html:134
  87 +#: templates/file_links/_form.html:134
88 88 msgid "Action not performed by the user"
89 89 msgstr "Ação não realizada pelo usuário"
90 90  
91   -#: file_link/templates/file_links/_form.html:160
  91 +#: templates/file_links/_form.html:160
92 92 msgid "Wished period"
93 93 msgstr "Período desejado"
94 94  
95   -#: file_link/templates/file_links/_form.html:256
  95 +#: templates/file_links/_form.html:256
96 96 msgid "Attribute students to file link"
97 97 msgstr "Atribuir estudantes ao Link para Arquivo"
98 98  
99   -#: file_link/templates/file_links/_form.html:276
  99 +#: templates/file_links/_form.html:276
100 100 msgid "Attribute groups to file link"
101 101 msgstr "Atribuir grupos de estudo ao Link para Arquivo"
102 102  
103   -#: file_link/templates/file_links/_form.html:322
  103 +#: templates/file_links/_form.html:322
104 104 msgid "Save"
105 105 msgstr "Salvar"
106 106  
107   -#: file_link/templates/file_links/create.html:20 file_link/views.py:177
  107 +#: templates/file_links/create.html:20 views.py:186
108 108 msgid "Create File Link"
109 109 msgstr "Criar Link para Arquivo"
110 110  
111   -#: file_link/templates/file_links/update.html:20
  111 +#: templates/file_links/relatorios.html:17
  112 +#: templates/file_links/relatorios.html:37
  113 +msgid "User"
  114 +msgstr "Usuário"
  115 +
  116 +#: templates/file_links/relatorios.html:17
  117 +#: templates/file_links/relatorios.html:37
  118 +msgid "Group"
  119 +msgstr "Grupo"
  120 +
  121 +#: templates/file_links/relatorios.html:17
  122 +msgid "Action"
  123 +msgstr "Ação"
  124 +
  125 +#: templates/file_links/relatorios.html:17
  126 +msgid "Date of Action"
  127 +msgstr "Data da ação"
  128 +
  129 +#: templates/file_links/relatorios.html:37
  130 +msgid "Send message"
  131 +msgstr "Enviar Mensagem"
  132 +
  133 +#: templates/file_links/relatorios.html:37
  134 +msgid "Action don't realized"
  135 +msgstr "Ação não realizada"
  136 +
  137 +#: templates/file_links/relatorios.html:151
  138 +#: templates/file_links/relatorios.html:171
  139 +msgid "Reports"
  140 +msgstr "Relatórios"
  141 +
  142 +#: templates/file_links/relatorios.html:178
  143 +msgid "Report of the resource "
  144 +msgstr "Relatórios do recurso "
  145 +
  146 +#: templates/file_links/relatorios.html:187
  147 +msgid "Select the period: "
  148 +msgstr "Selecione o período: "
  149 +
  150 +#: templates/file_links/relatorios.html:196
  151 +msgid "Search"
  152 +msgstr "Pesquisar"
  153 +
  154 +#: templates/file_links/relatorios.html:220
  155 +msgid "Filter: "
  156 +msgstr "Filtro: "
  157 +
  158 +#: templates/file_links/relatorios.html:244
  159 +#: templates/file_links/relatorios.html:329
  160 +msgid "record(s)"
  161 +msgstr "Relatório(s)"
  162 +
  163 +#: templates/file_links/send_message.html:38
  164 +#| msgid "Click or drop the file here"
  165 +msgid "Click or drop the picture here"
  166 +msgstr "Clique ou solte a imagem aqui"
  167 +
  168 +#: templates/file_links/send_message.html:40
  169 +#| msgid "The file could not exceed 10MB."
  170 +msgid "The picture could not exceed 5MB."
  171 +msgstr "A imagem não pode exceder 5MB."
  172 +
  173 +#: templates/file_links/send_message.html:62
  174 +msgid "Close"
  175 +msgstr "Fechar"
  176 +
  177 +#: templates/file_links/send_message.html:63
  178 +msgid "Send"
  179 +msgstr "Enviar"
  180 +
  181 +#: templates/file_links/update.html:20
112 182 msgid "Edit: "
113 183 msgstr "Editar: "
114 184  
115   -#: file_link/views.py:104 file_link/views.py:117 file_link/views.py:227
116   -#: file_link/views.py:229 file_link/views.py:245 file_link/views.py:247
  185 +#: views.py:113 views.py:126 views.py:236 views.py:238 views.py:254
  186 +#: views.py:256
117 187 msgid "Visualize"
118 188 msgstr "Visualizar"
119 189  
120   -#: file_link/views.py:188
  190 +#: views.py:197
121 191 #, python-format
122 192 msgid ""
123 193 "The File Link \"%s\" was added to the Topic \"%s\" of the virtual "
... ... @@ -126,16 +196,16 @@ msgstr &quot;&quot;
126 196 "O Link para Arquivo \"%s\" foi adicionado ao tópico \"%s\" do ambiente "
127 197 "virtual \"%s\" com sucesso!"
128 198  
129   -#: file_link/views.py:291
  199 +#: views.py:300
130 200 msgid "Update File Link"
131 201 msgstr "Atualizar Link para Arquivo"
132 202  
133   -#: file_link/views.py:302
  203 +#: views.py:311
134 204 #, python-format
135 205 msgid "The File Link \"%s\" was updated successfully!"
136 206 msgstr "O Link para Arquivo \"%s\" foi atualizado com sucesso!"
137 207  
138   -#: file_link/views.py:329
  208 +#: views.py:338
139 209 #, python-format
140 210 msgid ""
141 211 "The File Link \"%s\" was removed successfully from virtual environment \"%s"
... ... @@ -144,11 +214,43 @@ msgstr &quot;&quot;
144 214 "O Link para Arquivo \"%s\" foi removido do ambiente virtual \"%s\" com "
145 215 "sucesso!"
146 216  
  217 +#: views.py:397
  218 +#| msgid "File Links"
  219 +msgid "File Link Reports"
  220 +msgstr "Relatŕios de Link para Arquivo"
  221 +
  222 +#: views.py:416
  223 +msgid "Realized"
  224 +msgstr "Realizado"
  225 +
  226 +#: views.py:416
  227 +msgid "Unrealized"
  228 +msgstr "Não Realizado"
  229 +
  230 +#: views.py:416
  231 +msgid "Historic"
  232 +msgstr "Histórico"
  233 +
  234 +#: views.py:434 views.py:443
  235 +msgid "View"
  236 +msgstr "Visualizar"
  237 +
  238 +#: views.py:442
  239 +#, fuzzy
  240 +#| msgid "File Link"
  241 +msgid "File link"
  242 +msgstr "Link para Arquivo"
  243 +
  244 +#: views.py:447
  245 +msgid "Actions about resource"
  246 +msgstr "Ações sobre o recurso"
  247 +
  248 +#: views.py:448
  249 +msgid "Quantity"
  250 +msgstr "Quantidade"
  251 +
147 252 #~ msgid "File not supported."
148 253 #~ msgstr "Arquivo não suportado."
149 254  
150   -#~ msgid "Close"
151   -#~ msgstr "Fechar"
152   -
153 255 #~ msgid "Delete"
154 256 #~ msgstr "Remover"
... ...
file_link/templates/file_links/relatorios.html 0 → 100644
... ... @@ -0,0 +1,408 @@
  1 +{% extends "subjects/view.html" %}
  2 +
  3 +{% load static i18n pagination permissions_tags subject_counter %}
  4 +{% load django_bootstrap_breadcrumbs %}
  5 +
  6 +{% block javascript%}
  7 + {{ block.super }}
  8 + <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  9 + <script type="text/javascript">
  10 + var tabela_atual = true;
  11 +
  12 + var array_history = [];
  13 + {%for data_json in json_history.data %}
  14 + array_history.push(["{{data_json.0}}","{{data_json.1}}","{{view}}",{% if data_json.3 is not None %}new Date('{{data_json.3.isoformat}}'){% else%}null{% endif %}]);
  15 + {% endfor%}
  16 + var json_history = {"data":array_history};
  17 + var column_history = [{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":'{% trans "Action" %}'},{"date":'{% trans "Date of Action" %}'}];
  18 +
  19 + var search = [];
  20 + for (var i in json_history["data"]){
  21 + search.push([json_history["data"][i][0],json_history["data"][i][1],
  22 + json_history["data"][i][2],json_history["data"][i][3]]);
  23 + }
  24 +
  25 + var array_n_did = [];
  26 + var checkbox = {};
  27 + {%for data_json in json_n_did.data%}
  28 + var input = '<div class="checkbox">\
  29 + <label for="{{data_json.0}}_google_table">\
  30 + <input id="{{data_json.0}}_google_table" name="{{data_json.0}}_google_table" type="checkbox"><span class="checkbox-material"><span class="check"></span></span>\
  31 + </label>\
  32 + </div>'
  33 + checkbox["{{data_json.0}}_google_table"] = "{{data_json.4}}";
  34 + array_n_did.push([input,"{{data_json.1}}","{{data_json.2}}","{{data_json.3}}"]);
  35 + {% endfor%}
  36 + var json_n_did = {"data":array_n_did};
  37 + var column_n_did = [{"string":'<a href="javascript:void(0);" onclick="return openmodal();"> {% trans "Send message" %}</a>'},{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":"{% trans "Action don't realized" %}"}];
  38 + </script>
  39 +
  40 +
  41 + <script type="text/javascript">
  42 + google.charts.load('current', {'packages':['corechart',"table"]});
  43 + google.charts.setOnLoadCallback(drawChart);
  44 + google.charts.setOnLoadCallback(drawTable);
  45 +
  46 + function drawChart() {
  47 + var data = google.visualization.arrayToDataTable({{db_data|safe}});
  48 + var options = {
  49 + title: '{{title_chart}}',
  50 + // legend: {position: 'right', maxLines: 1},
  51 + bar: { groupWidth: '30%' },
  52 + chartArea:{width:"50%"},
  53 + titlePosition: 'out',
  54 + vAxis: {
  55 + title: '{{title_vAxis}}',
  56 + ticks: [0, .20, .40, .60, .80, 1],
  57 + viewWindow: {
  58 + min: 0,
  59 + max: 1
  60 + }
  61 + },
  62 + isStacked: "percent",
  63 + };
  64 +
  65 + function selectHandler() {
  66 + var selectedItem = chart.getSelection()[0];
  67 + if (selectedItem) {
  68 + var col = data.getColumnLabel(selectedItem.column);
  69 + if (col == "{{n_did_table}}"){
  70 + tabela_atual = false;
  71 + search = [];
  72 + for (var i in json_n_did["data"]){
  73 + search.push([json_n_did["data"][i][0],json_n_did["data"][i][1],
  74 + json_n_did["data"][i][2],json_n_did["data"][i][3]]);
  75 + }
  76 + searcher(col, tabela_atual,true);
  77 +
  78 + } else if (col == "{{did_table}}"){
  79 + tabela_atual = true;
  80 + search = [];
  81 + for (var i in json_history["data"]){
  82 + search.push([json_history["data"][i][0],json_history["data"][i][1],
  83 + json_history["data"][i][2],json_history["data"][i][3]]);
  84 + }
  85 + searcher(col, tabela_atual,true);
  86 + }
  87 + }
  88 + chart.setSelection([])
  89 + }
  90 +
  91 + var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
  92 + google.visualization.events.addListener(chart, 'select', selectHandler);
  93 + chart.draw(data, options);
  94 +
  95 + }
  96 +
  97 + var sortAscending = {0:false,1:false,2:false,3:false};
  98 + function drawTable(columns = column_history,rows = pagination(json_history["data"],1),isdate = true,columndate = 3) {
  99 + var data_table = new google.visualization.DataTable();
  100 + for (var i in columns){
  101 + for (var item in columns[i]){
  102 + data_table.addColumn(item,columns[i][item]);
  103 + }
  104 + }
  105 +
  106 + data_table.addRows(rows);
  107 + var formate_date = new google.visualization.DateFormat({pattern: 'dd/MM/yyyy HH:mm'});
  108 + if (isdate) formate_date.format(data_table, columndate);
  109 +
  110 + // var methods = [];
  111 + // for (var m in data_table) {
  112 + // if (typeof data_table[m] == "function") {
  113 + // methods.push(m);
  114 + // }
  115 + // }
  116 + // console.log(methods.join(","));
  117 + var options = {
  118 + sort: "event",
  119 + allowHtml: true,
  120 + cssClassNames : {
  121 + tableRow: 'text-center',
  122 + tableCell: 'text-center',
  123 + headerCell: 'text-center'
  124 + },
  125 + showRowNumber: true,
  126 + width: '100%',
  127 + height: '100%',
  128 + }
  129 + function ordenar(properties){
  130 + var columnIndex = properties['column'];
  131 + if (columnIndex > 0) {
  132 + options["sortColumn"] = columnIndex;
  133 + options["sortAscending"] = sortAscending[columnIndex];
  134 + data_table.sort({column:columnIndex,desc:sortAscending[columnIndex]});
  135 + sortAscending = {0:false,1:false,2:false,3:false};
  136 + sortAscending[columnIndex] = !sortAscending[columnIndex];
  137 + // console.log(sortAscending);
  138 + table.draw(data_table, options);
  139 + }
  140 + }
  141 +
  142 + var table = new google.visualization.Table(document.getElementById('table_div'));
  143 + google.visualization.events.addListener(table, 'sort', function(e) {ordenar(e)});
  144 + table.draw(data_table, options);
  145 + }
  146 + </script>
  147 +{% endblock%}
  148 +
  149 +{% block breadcrumbs %}
  150 + {{ block.super }}
  151 + {% trans 'Reports' as bread %}
  152 + {% breadcrumb bread filelink%}
  153 +{% endblock %}
  154 +
  155 +{% block content %}
  156 + {% if messages %}
  157 + {% for message in messages %}
  158 + <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">
  159 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  160 + <span aria-hidden="true">&times;</span>
  161 + </button>
  162 + <p>{{ message }}</p>
  163 + </div>
  164 + {% endfor %}
  165 + {% endif %}
  166 + <div class="panel panel-info topic-panel">
  167 + <div class="panel-heading">
  168 + <div class="row">
  169 + <div class="col-md-12 category-header">
  170 + <h4 class="panel-title" style="margin-top: 10px; margin-bottom: 8px">
  171 + <span>{{filelink}} / {% trans "Reports" %}</span>
  172 + </h4>
  173 + </div>
  174 + </div>
  175 + </div>
  176 + <div class="row">
  177 + <div class="col-md-12 text-center">
  178 + <h4 style="margin-top: 15px; margin-bottom: 10px" ><strong>{% trans "Report of the resource " %}{{filelink}}</strong></h4>
  179 + </div>
  180 + </div>
  181 + <div class="row">
  182 + <div class="col-md-12">
  183 +
  184 + <ul class="list-inline nav-justified">
  185 + <div id="general-parameters-div">
  186 + <div class="general-parameters-field">
  187 + <li class="text-right"><h4>{% trans "Select the period: " %}</h4></li>
  188 + </div>
  189 + <form id="period-form" action="" method="get">
  190 + <div class="general-parameters-field">
  191 + <li> <input class="form-control datetime-picker" name="init_date" type="text" required="" value="{% if LANGUAGE_CODE == 'pt-br' %}{{init_date|date:'d/m/Y H:i'}} {% else %} {{init_date|date:'m/d/Y H:i P'}} {% endif %}"></li>
  192 + </div>
  193 + <div class="general-parameters-field">
  194 + <li><input id="inputdate" class="form-control datetime-picker" name="end_date" type="text" required="" value="{% if LANGUAGE_CODE == 'pt-br' %}{{end_date|date:'d/m/Y H:i'}} {% else %} {{end_date|date:'m/d/Y H:i P'}} {% endif %}"></li>
  195 + </div>
  196 + <li><input type="submit" value="{% trans 'Search' %}" style="margin-left: 15px;" class="btn btn-success btn-raised"></li>
  197 + </form>
  198 + </div>
  199 + <ul>
  200 + </div>
  201 + </div>
  202 +
  203 + <div class="row">
  204 + <div class="col-md-10 col-md-offset-1">
  205 + <div id="chart_div" style="height: 500px; margin-top: -50px;"></div>
  206 + </div>
  207 + </div>
  208 +
  209 + <div class="row">
  210 + <div class="col-md-10 col-md-offset-1">
  211 + <div class="text-center">
  212 + <ul class="list-inline nav-justified">
  213 + <li>
  214 + <ul id="view-table" class="list-inline text-right">
  215 + <li><h3 id="title-table"></h3></li>
  216 + </ul>
  217 + </li>
  218 + <li>
  219 + <ul class="list-inline text-right">
  220 + <li><p>{% trans "Filter: " %}</p></li>
  221 + <li><input id="search-input" class="form-control" type="text" name="search" value=""></li>
  222 + </ul>
  223 + </li>
  224 + </ul>
  225 + </div>
  226 + <form id="google-chart-checkbox" action="" method="get">
  227 + <div id="table_div"></div>
  228 + </form>
  229 + <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12 text-center">
  230 + <ul class="pagination">
  231 +
  232 + </ul>
  233 + </div>
  234 + </div>
  235 + </div>
  236 + <div id="modal-message"></div>
  237 + <div class="row">
  238 + <br><br>
  239 + </div>
  240 + </div>
  241 +
  242 + <script type="text/javascript">
  243 +
  244 + $("#title-table").text(search.length + " {% trans 'record(s)' %}");
  245 + function putpagination(data = json_history["data"], load_histoty = true){
  246 + var len = Math.ceil(data.length / 20);
  247 + $(".pagination").empty();
  248 + $(".pagination").append('<li class="disabled"><span>«</span></li>');
  249 + $(".pagination").append('<li id="1" class="active">\
  250 + <a href="javascript:void(0);" onclick="return clickPagination(1, '+ load_histoty +');">1</a>\
  251 + </li>');
  252 + for (var i = 2; i <= len;i++){
  253 + $(".pagination").append('<li id="' + i + '">\
  254 + <a href="javascript:void(0);" onclick="return clickPagination(' + i +', ' + load_histoty + ');">' + i + '</a>\
  255 + </li>');
  256 + }
  257 + if (len > 1) $(".pagination").append('<li><a href="javascript:void(0);" onclick="return clickPagination(2, '+ load_histoty +');"><span>»</span></a></li>');
  258 + else $(".pagination").append('<li class="disabled"><span>»</span></li>');
  259 + };
  260 + putpagination();
  261 +
  262 + $('#period-form').submit(function(event) {
  263 + $('<input />').attr('type', 'hidden')
  264 + .attr('name', "language")
  265 + .attr('value', '{{ LANGUAGE_CODE }}')
  266 + .appendTo('#period-form');
  267 + });
  268 + function add(element,local, first = false){
  269 + if (first) $(local).prepend(element);
  270 + else $(local).append(element);
  271 + }
  272 + function text(element){
  273 + return $(element).text();
  274 + }
  275 + function length(element) {
  276 + return $(element).length;
  277 + }
  278 +
  279 + $("#search-input").on("keyup",function(){
  280 + search = [];
  281 + var text = $("#search-input").val();
  282 + searcher(text,tabela_atual);
  283 + });
  284 +
  285 + function searcher(text, load_histoty = false,apaga=false){
  286 + if(apaga){
  287 + $("#search-input").val("");
  288 + }
  289 + var data = [];
  290 + if (!load_histoty){
  291 + data = $.map(json_n_did["data"], function (obj) {
  292 + return $.extend(true, {}, obj);
  293 + });
  294 + } else {
  295 + data = $.map(json_history["data"], function (obj) {
  296 + return $.extend(true, {}, obj);
  297 + });
  298 + }
  299 + if (load_histoty){
  300 + for (var i in data){
  301 + data[i][3] = moment(data[i][3]).format("DD/MM/YYYY HH:mm");
  302 + }
  303 + }
  304 + if (load_histoty){
  305 + for (var i in data){
  306 + if (data[i][0].toLowerCase().includes(text.toLowerCase())
  307 + || data[i][1].toLowerCase().includes(text.toLowerCase())
  308 + || data[i][2].toLowerCase().includes(text.toLowerCase())
  309 + || data[i][3].toLowerCase().includes(text.toLowerCase())){
  310 + search.push(json_history["data"][i]);
  311 + }
  312 + }
  313 + }
  314 + else {
  315 + for (var i in data){
  316 + if (data[i][1].toLowerCase().includes(text.toLowerCase())
  317 + || data[i][2].toLowerCase().includes(text.toLowerCase())
  318 + || data[i][3].toLowerCase().includes(text.toLowerCase())){
  319 + search.push(json_n_did["data"][i]);
  320 + }
  321 + }
  322 + }
  323 + console.log(search);
  324 + if (!load_histoty){
  325 + drawTable(column_n_did,pagination(search,1),false);
  326 + } else {
  327 + drawTable(column_history,pagination(search,1),true,3);
  328 + }
  329 + $("#title-table").text(search.length + " {% trans 'record(s)' %}");
  330 + putpagination(search,load_histoty);
  331 + }
  332 +
  333 + function pagination(data,pag){
  334 + var len = data.length;
  335 + var first = (pag * 20 - 20 < len) ? pag * 20 - 20:len;
  336 + var end = (pag * 20 < len) ? pag * 20:len;
  337 + var search = data.slice(first,end);
  338 + return search;
  339 + }
  340 +
  341 + function clickPagination(pag, load_histoty = false){
  342 + $(".pagination > li").last().remove();
  343 + $(".pagination > li").first().remove();
  344 +
  345 + if (!load_histoty){
  346 + drawTable(column_n_did,pagination(search,pag),false);
  347 + } else {
  348 + drawTable(column_history,pagination(search,pag),true,3);
  349 + }
  350 +
  351 + if (pag < Math.ceil(search.length / 20))
  352 + $(".pagination").append('<li><a href="javascript:void(0);" onclick="return clickPagination(' + (pag + 1) + ', '+ load_histoty +');"><span>»</span></a></li>');
  353 + else $(".pagination").append('<li class="disabled"><span>»</span></li>');
  354 + if (pag > 1)
  355 + $(".pagination").prepend('<li><a href="javascript:void(0);" onclick="return clickPagination(' + (pag - 1) + ', '+ load_histoty +');"><span>«</span></a></li>');
  356 + else $(".pagination").prepend('<li class="disabled"><span>«</span></li>');
  357 + $(".active").removeClass("active");
  358 + $("#" + pag).addClass("active");
  359 + }
  360 +
  361 + function openmodal(){
  362 + $( "#modal-message" ).empty();
  363 + $.get( "{% url 'file_links:send_message' filelink.slug %}", function( data ) {
  364 + $( "#modal-message" ).append( data );
  365 + $("#send-message-modal").modal("show");
  366 + });
  367 + }
  368 +
  369 + function sendMessage(){
  370 + $("#send-message-modal").modal("hide");
  371 + var checked = $("#google-chart-checkbox").serializeArray();
  372 + var email = [];
  373 + for (var i in checked){
  374 + email.push(checkbox[checked[i]["name"]]);
  375 + }
  376 + $('<input />').attr('type', 'hidden')
  377 + .attr('name', "users[]")
  378 + .attr('value', email)
  379 + .appendTo('#text_chat_form');
  380 +
  381 + var formData = new FormData($('#text_chat_form').get(0));
  382 + $.ajax({
  383 + url: "{% url 'file_links:send_message' filelink.slug %}",
  384 + type: "POST",
  385 + data: formData,
  386 + cache: false,
  387 + processData: false,
  388 + contentType: false,
  389 + success: function(data) {
  390 + if (data["message"]){
  391 + console.log("success");
  392 + $("body").removeClass("modal-open");
  393 + $( "#modal-message" ).empty();
  394 + $(".modal-backdrop.fade.in").remove();
  395 + } else {
  396 + $( "#modal-message" ).empty();
  397 + $(".modal-backdrop.fade.in").remove();
  398 + $( "#modal-message" ).append( data );
  399 + $("#send-message-modal").modal("show");
  400 + }
  401 + },
  402 + error: function(data){
  403 + console.log("erro");
  404 + }
  405 + });
  406 + }
  407 + </script>
  408 +{% endblock %}
... ...
file_link/templates/file_links/send_message.html 0 → 100644
... ... @@ -0,0 +1,112 @@
  1 +
  2 + {% load widget_tweaks i18n %}
  3 + <!-- Modal (remember to change the ids!!!) -->
  4 +<div class="modal fade" id="send-message-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  5 + <div class="modal-dialog" role="document">
  6 + <div class="modal-content">
  7 + <!-- Modal Body -->
  8 + <div class="modal-body">
  9 + <form id="text_chat_form" action="" method="POST" enctype="multipart/form-data">
  10 + {% csrf_token %}
  11 + {% comment %}Area para o Texto{% endcomment %}
  12 + <div class="form-group{% if form.has_error %} has-error {% endif %}">
  13 + <label for="{{ form.comment.auto_id }}">{{ form.comment.label }}: <span>*</span></label>
  14 + {% render_field form.comment class='form-control text_simple_wysiwyg' %}
  15 +
  16 + <span id="helpBlock" class="help-block">{{ form.comment.help_text }}</span>
  17 +
  18 + {% if form.comment.errors %}
  19 + <div class="alert alert-danger alert-dismissible" role="alert">
  20 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  21 + <span aria-hidden="true">&times;</span>
  22 + </button>
  23 + <ul>
  24 + {% for error in form.comment.errors %}
  25 + <li>{{ error }}</li>
  26 + {% endfor %}
  27 + </ul>
  28 + </div>
  29 + {% endif %}
  30 + </div>
  31 + {% comment %}Area para anexar a imagem {% endcomment %}
  32 + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">
  33 + {% render_field form.image %}
  34 +
  35 + <div class="filedrag">
  36 + {% trans 'Click or drop the picture here' %}<br />
  37 +
  38 + <small>{% trans 'The picture could not exceed 5MB.' %}</small>
  39 + </div>
  40 +
  41 + {% if form.image.errors %}
  42 + <div class="alert alert-danger alert-dismissible" role="alert">
  43 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  44 + <span aria-hidden="true">&times;</span>
  45 + </button>
  46 + <ul>
  47 + {% for error in form.image.errors %}
  48 + <li>{{ error }}</li>
  49 + {% endfor %}
  50 + </ul>
  51 + </div>
  52 + {% endif %}
  53 +
  54 + </div>
  55 + </form>
  56 + </div>
  57 + <!-- Modal Footer -->
  58 + <div id="delete-category-footer"class="modal-footer">
  59 + <!-- Don't remove that!!! -->
  60 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
  61 + <a href="javascript:void(0)" onclick="return sendMessage()" form="text_chat_form" class="btn btn-success btn-raised erase-button">{% trans "Send" %}</a>
  62 + </div>
  63 + </div>
  64 + </div>
  65 +</div>
  66 +
  67 +<script type="text/javascript">
  68 +
  69 + $('.text_simple_wysiwyg').summernote({
  70 + dialogsInBody: true,
  71 + disableDragAndDrop: true,
  72 + height: 150,
  73 + toolbar: [
  74 + // [groupName, [list of button]]
  75 + ['style', ['bold', 'italic']],
  76 + ['insert', ['link']]
  77 + ]
  78 + });
  79 +
  80 + if (window.File && window.FileList && window.FileReader) {
  81 + Init();
  82 + }
  83 +
  84 + function Init() {
  85 + var small = $("#id_image"),
  86 + filedrag = $(".filedrag"),
  87 + common = $(".common-file-input");
  88 +
  89 + // file select
  90 + small.on("change", FileSelectHandler);
  91 +
  92 + // is XHR2 available?
  93 + var xhr = new XMLHttpRequest();
  94 + if (xhr.upload) {
  95 + // file drop
  96 + filedrag.on("drop", FileSelectHandler);
  97 + filedrag.attr('style', 'display:block');
  98 + common.attr('style', 'display:none');
  99 + }
  100 + }
  101 +
  102 + // file selection
  103 + function FileSelectHandler(e) {
  104 + var files = e.target.files || e.dataTransfer.files,
  105 + parent = $(e.target.offsetParent);
  106 +
  107 + // process all File objects
  108 + for (var i = 0, f; f = files[i]; i++) {
  109 + parent.find('.filedrag').html(f.name);
  110 + }
  111 + }
  112 +</script>
0 113 \ No newline at end of file
... ...
file_link/urls.py
... ... @@ -8,4 +8,6 @@ urlpatterns = [
8 8 url(r'^update/(?P<topic_slug>[\w_-]+)/(?P<slug>[\w_-]+)/$', views.UpdateView.as_view(), name = 'update'),
9 9 url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteView.as_view(), name = 'delete'),
10 10 url(r'^download/(?P<slug>[\w_-]+)/$', views.DownloadFile.as_view(), name = 'download'),
  11 + url(r'^chart/(?P<slug>[\w_-]+)/$', views.StatisticsView.as_view(), name = 'get_chart'),
  12 + url(r'^send-message/(?P<slug>[\w_-]+)/$', views.SendMessage.as_view(), name = 'send_message'),
11 13 ]
... ...
file_link/views.py
... ... @@ -18,6 +18,15 @@ from pendencies.forms import PendenciesForm
18 18 from .forms import FileLinkForm
19 19 from .models import FileLink
20 20  
  21 +
  22 +import datetime
  23 +from log.models import Log
  24 +from chat.models import Conversation, TalkMessages
  25 +from users.models import User
  26 +from subjects.models import Subject
  27 +
  28 +from webpage.forms import FormModalMessage
  29 +
21 30 class DownloadFile(LoginRequiredMixin, LogMixin, generic.DetailView):
22 31 log_component = 'resources'
23 32 log_action = 'view'
... ... @@ -343,4 +352,145 @@ class DeleteView(LoginRequiredMixin, LogMixin, generic.DeleteView):
343 352  
344 353 super(DeleteView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
345 354  
346   - return reverse_lazy('subjects:view', kwargs = {'slug': self.object.topic.subject.slug})
347 355 \ No newline at end of file
  356 + return reverse_lazy('subjects:view', kwargs = {'slug': self.object.topic.subject.slug})
  357 +
  358 +
  359 +class StatisticsView(LoginRequiredMixin, LogMixin, generic.DetailView):
  360 + log_component = 'resources'
  361 + log_action = 'view_statistics'
  362 + log_resource = 'filelink'
  363 + log_context = {}
  364 +
  365 + login_url = reverse_lazy("users:login")
  366 + redirect_field_name = 'next'
  367 + model = FileLink
  368 + template_name = 'file_links/relatorios.html'
  369 +
  370 + def dispatch(self, request, *args, **kwargs):
  371 + slug = self.kwargs.get('slug', '')
  372 + filelink = get_object_or_404(FileLink, slug = slug)
  373 +
  374 + if not has_subject_permissions(request.user, filelink.topic.subject):
  375 + return redirect(reverse_lazy('subjects:home'))
  376 +
  377 + return super(StatisticsView, self).dispatch(request, *args, **kwargs)
  378 +
  379 + def get_context_data(self, **kwargs):
  380 + context = super(StatisticsView, self).get_context_data(**kwargs)
  381 +
  382 + self.log_context['category_id'] = self.object.topic.subject.category.id
  383 + self.log_context['category_name'] = self.object.topic.subject.category.name
  384 + self.log_context['category_slug'] = self.object.topic.subject.category.slug
  385 + self.log_context['subject_id'] = self.object.topic.subject.id
  386 + self.log_context['subject_name'] = self.object.topic.subject.name
  387 + self.log_context['subject_slug'] = self.object.topic.subject.slug
  388 + self.log_context['topic_id'] = self.object.topic.id
  389 + self.log_context['topic_name'] = self.object.topic.name
  390 + self.log_context['topic_slug'] = self.object.topic.slug
  391 + self.log_context['filelink_id'] = self.object.id
  392 + self.log_context['filelink_name'] = self.object.name
  393 + self.log_context['filelink_slug'] = self.object.slug
  394 +
  395 + super(StatisticsView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  396 +
  397 +
  398 + context['title'] = _('File Link Reports')
  399 +
  400 + slug = self.kwargs.get('slug')
  401 + filelink = get_object_or_404(FileLink, slug = slug)
  402 + print (self.request.GET.get('init_date',''))
  403 + date_format = "%d/%m/%Y %H:%M" if self.request.GET.get('language','') == 'pt-br' else "%m/%d/%Y %I:%M %p"
  404 + if self.request.GET.get('language','') == "":
  405 + start_date = datetime.datetime.now() - datetime.timedelta(30)
  406 + end_date = datetime.datetime.now()
  407 + else :
  408 + start_date = datetime.datetime.strptime(self.request.GET.get('init_date',''),date_format)
  409 + end_date = datetime.datetime.strptime(self.request.GET.get('end_date',''),date_format)
  410 + context["init_date"] = start_date
  411 + context["end_date"] = end_date
  412 + alunos = filelink.students.all()
  413 + if filelink.all_students :
  414 + alunos = filelink.topic.subject.students.all()
  415 +
  416 + vis_ou = Log.objects.filter(context__contains={'filelink_id':filelink.id},resource="filelink",action="view",user_email__in=(aluno.email for aluno in alunos), datetime__range=(start_date,end_date + datetime.timedelta(minutes = 1)))
  417 + did,n_did,history = str(_("Realized")),str(_("Unrealized")),str(_("Historic"))
  418 + re = []
  419 + data_n_did,data_history = [],[]
  420 + json_n_did, json_history = {},{}
  421 +
  422 + from django.db.models import Count, Max
  423 + views_user = vis_ou.values("user_email").annotate(views=Count("user_email"))
  424 + date_last = vis_ou.values("user_email").annotate(last=Max("datetime"))
  425 +
  426 + for log_al in vis_ou.order_by("datetime"):
  427 + data_history.append([str(alunos.get(email=log_al.user_email)),
  428 + ", ".join([str(x) for x in filelink.topic.subject.group_subject.filter(participants__email=log_al.user_email)]),
  429 + log_al.action,log_al.datetime])
  430 + json_history["data"] = data_history
  431 +
  432 + not_view = alunos.exclude(email__in=[log.user_email for log in vis_ou.distinct("user_email")])
  433 + index = 0
  434 + for alun in not_view:
  435 + data_n_did.append([index,str(alun),", ".join([str(x) for x in filelink.topic.subject.group_subject.filter(participants__email=alun.email)]),str(_('View')), str(alun.email)])
  436 + index += 1
  437 + json_n_did["data"] = data_n_did
  438 +
  439 +
  440 + context["json_n_did"] = json_n_did
  441 + context["json_history"] = json_history
  442 + c_visualizou = vis_ou.distinct("user_email").count()
  443 + column_view = str(_('View'))
  444 + re.append([str(_('File link')),did,n_did])
  445 + re.append([column_view,c_visualizou, alunos.count() - c_visualizou])
  446 + context['topic'] = filelink.topic
  447 + context['subject'] = filelink.topic.subject
  448 + context['db_data'] = re
  449 + context['title_chart'] = _('Actions about resource')
  450 + context['title_vAxis'] = _('Quantity')
  451 + context['view'] = column_view
  452 + context["n_did_table"] = n_did
  453 + context["did_table"] = did
  454 + context["history_table"] = history
  455 + return context
  456 +
  457 +
  458 +
  459 +class SendMessage(LoginRequiredMixin, LogMixin, generic.edit.FormView):
  460 + log_component = 'resources'
  461 + log_action = 'send'
  462 + log_resource = 'filelink'
  463 + log_context = {}
  464 +
  465 + login_url = reverse_lazy("users:login")
  466 + redirect_field_name = 'next'
  467 +
  468 + template_name = 'file_links/send_message.html'
  469 + form_class = FormModalMessage
  470 +
  471 + def dispatch(self, request, *args, **kwargs):
  472 + slug = self.kwargs.get('slug', '')
  473 + filelink = get_object_or_404(FileLink, slug = slug)
  474 + self.filelink = filelink
  475 +
  476 + if not has_subject_permissions(request.user, filelink.topic.subject):
  477 + return redirect(reverse_lazy('subjects:home'))
  478 +
  479 + return super(SendMessage, self).dispatch(request, *args, **kwargs)
  480 +
  481 + def form_valid(self, form):
  482 + message = form.cleaned_data.get('comment')
  483 + image = form.cleaned_data.get("image")
  484 + users = (self.request.POST.get('users[]','')).split(",")
  485 + user = self.request.user
  486 + subject = self.filelink.topic.subject
  487 + for u in users:
  488 + to_user = User.objects.get(email=u)
  489 + talk, create = Conversation.objects.get_or_create(user_one=user,user_two=to_user)
  490 + created = TalkMessages.objects.create(text=message,talk=talk,user=user,subject=subject,image=image)
  491 + return JsonResponse({"message":"ok"})
  492 +
  493 + def get_context_data(self, **kwargs):
  494 + context = super(SendMessage,self).get_context_data()
  495 + context["filelink"] = get_object_or_404(FileLink, slug=self.kwargs.get('slug', ''))
  496 + return context
  497 +
... ...
links/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-02-09 18:40-0300\n"
  11 +"POT-Creation-Date: 2017-05-05 19:49-0300\n"
12 12 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 13 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14 14 "Language-Team: LANGUAGE <LL@li.org>\n"
... ... @@ -17,106 +17,197 @@ msgstr &quot;&quot;
17 17 "Content-Type: text/plain; charset=UTF-8\n"
18 18 "Content-Transfer-Encoding: 8bit\n"
19 19  
20   -#: links/forms.py:27
  20 +#: forms.py:27
21 21 msgid "Tags"
22 22 msgstr ""
23 23  
24   -#: links/forms.py:28
  24 +#: forms.py:28
25 25 msgid "Website URL"
26 26 msgstr ""
27 27  
28   -#: links/forms.py:34
  28 +#: forms.py:34
29 29 msgid "Link name"
30 30 msgstr ""
31 31  
32   -#: links/forms.py:35
  32 +#: forms.py:35
33 33 msgid "End View"
34 34 msgstr ""
35 35  
36   -#: links/forms.py:36
  36 +#: forms.py:36
37 37 msgid "End View Date"
38 38 msgstr ""
39 39  
40   -#: links/forms.py:64
  40 +#: forms.py:64
41 41 msgid "There is already a link with this name on this subject"
42 42 msgstr ""
43 43  
44   -#: links/models.py:11
  44 +#: models.py:13
45 45 msgid "Link_URL"
46 46 msgstr ""
47 47  
48   -#: links/models.py:31 links/templates/links/delete.html:9
  48 +#: models.py:33 templates/links/delete.html:12
49 49 msgid "Are you sure you want delete the Website link"
50 50 msgstr ""
51 51  
52   -#: links/templates/links/_form.html:112
  52 +#: templates/links/_form.html:112
53 53 msgid "Pendencies Notifications"
54 54 msgstr ""
55 55  
56   -#: links/templates/links/_form.html:130
  56 +#: templates/links/_form.html:130
57 57 msgid "Action not performed by the user"
58 58 msgstr ""
59 59  
60   -#: links/templates/links/_form.html:156
  60 +#: templates/links/_form.html:156
61 61 msgid "Wished period"
62 62 msgstr ""
63 63  
64   -#: links/templates/links/_form.html:252
  64 +#: templates/links/_form.html:252
65 65 msgid "Attribute students to file link"
66 66 msgstr ""
67 67  
68   -#: links/templates/links/_form.html:272
  68 +#: templates/links/_form.html:272
69 69 msgid "Attribute groups to file link"
70 70 msgstr ""
71 71  
72   -#: links/templates/links/_form.html:320
  72 +#: templates/links/_form.html:320
73 73 msgid "Save"
74 74 msgstr ""
75 75  
76   -#: links/templates/links/create.html:20
  76 +#: templates/links/create.html:20
77 77 msgid "Create Website Link"
78 78 msgstr ""
79 79  
80   -#: links/templates/links/delete.html:14
  80 +#: templates/links/delete.html:18 templates/links/send_message.html:62
81 81 msgid "Close"
82 82 msgstr ""
83 83  
84   -#: links/templates/links/delete.html:17
  84 +#: templates/links/delete.html:19
85 85 msgid "Delete"
86 86 msgstr ""
87 87  
88   -#: links/templates/links/update.html:20
  88 +#: templates/links/relatorios.html:17 templates/links/relatorios.html:37
  89 +msgid "User"
  90 +msgstr ""
  91 +
  92 +#: templates/links/relatorios.html:17 templates/links/relatorios.html:37
  93 +msgid "Group"
  94 +msgstr ""
  95 +
  96 +#: templates/links/relatorios.html:17
  97 +msgid "Action"
  98 +msgstr ""
  99 +
  100 +#: templates/links/relatorios.html:17
  101 +msgid "Date of Action"
  102 +msgstr ""
  103 +
  104 +#: templates/links/relatorios.html:37
  105 +msgid "Send message"
  106 +msgstr ""
  107 +
  108 +#: templates/links/relatorios.html:37
  109 +msgid "Action don't realized"
  110 +msgstr ""
  111 +
  112 +#: templates/links/relatorios.html:151 templates/links/relatorios.html:171
  113 +msgid "Reports"
  114 +msgstr ""
  115 +
  116 +#: templates/links/relatorios.html:178
  117 +msgid "Report of the resource "
  118 +msgstr ""
  119 +
  120 +#: templates/links/relatorios.html:187
  121 +msgid "Select the period: "
  122 +msgstr ""
  123 +
  124 +#: templates/links/relatorios.html:196
  125 +msgid "Search"
  126 +msgstr ""
  127 +
  128 +#: templates/links/relatorios.html:220
  129 +msgid "Filter: "
  130 +msgstr ""
  131 +
  132 +#: templates/links/relatorios.html:244 templates/links/relatorios.html:329
  133 +msgid "record(s)"
  134 +msgstr ""
  135 +
  136 +#: templates/links/send_message.html:38
  137 +msgid "Click or drop the picture here"
  138 +msgstr ""
  139 +
  140 +#: templates/links/send_message.html:40
  141 +msgid "The picture could not exceed 5MB."
  142 +msgstr ""
  143 +
  144 +#: templates/links/send_message.html:63
  145 +msgid "Send"
  146 +msgstr ""
  147 +
  148 +#: templates/links/update.html:20
89 149 msgid "Edit: "
90 150 msgstr ""
91 151  
92   -#: links/views.py:51 links/views.py:64 links/views.py:224 links/views.py:226
93   -#: links/views.py:242 links/views.py:244
  152 +#: views.py:59 views.py:72 views.py:256 views.py:258 views.py:274 views.py:276
94 153 msgid "Visualize"
95 154 msgstr ""
96 155  
97   -#: links/views.py:124
  156 +#: views.py:134
98 157 msgid "Create Webiste Link"
99 158 msgstr ""
100 159  
101   -#: links/views.py:135
  160 +#: views.py:145
102 161 #, python-format
103 162 msgid ""
104 163 "The Link \"%s\" was added to the Topic \"%s\" of the virtual environment "
105 164 "\"%s\" successfully!"
106 165 msgstr ""
107 166  
108   -#: links/views.py:163
  167 +#: views.py:173
109 168 #, python-format
110 169 msgid ""
111 170 "The Website Link \"%s\" was removed successfully from virtual environment "
112 171 "\"%s\"!"
113 172 msgstr ""
114 173  
115   -#: links/views.py:288
  174 +#: views.py:322
116 175 msgid "Update Website Link"
117 176 msgstr ""
118 177  
119   -#: links/views.py:299
  178 +#: views.py:333
120 179 #, python-format
121 180 msgid "The Website Link \"%s\" was updated successfully!"
122 181 msgstr ""
  182 +
  183 +#: views.py:377
  184 +msgid "Links Reports"
  185 +msgstr ""
  186 +
  187 +#: views.py:396
  188 +msgid "Realized"
  189 +msgstr ""
  190 +
  191 +#: views.py:396
  192 +msgid "Unrealized"
  193 +msgstr ""
  194 +
  195 +#: views.py:396
  196 +msgid "Historic"
  197 +msgstr ""
  198 +
  199 +#: views.py:414 views.py:423
  200 +msgid "View"
  201 +msgstr ""
  202 +
  203 +#: views.py:422
  204 +msgid "Links"
  205 +msgstr ""
  206 +
  207 +#: views.py:427
  208 +msgid "Actions about resource"
  209 +msgstr ""
  210 +
  211 +#: views.py:428
  212 +msgid "Quantity"
  213 +msgstr ""
... ...
links/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-04-15 00:13-0300\n"
  11 +"POT-Creation-Date: 2017-05-05 19:49-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,88 +18,147 @@ msgstr &quot;&quot;
18 18 "Content-Transfer-Encoding: 8bit\n"
19 19 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
20 20  
21   -#: links/forms.py:27
  21 +#: forms.py:27
22 22 msgid "Tags"
23 23 msgstr ""
24 24  
25   -#: links/forms.py:28
  25 +#: forms.py:28
26 26 msgid "Website URL"
27 27 msgstr "URL do site:"
28 28  
29   -#: links/forms.py:34
  29 +#: forms.py:34
30 30 msgid "Link name"
31 31 msgstr "Nome do Link"
32 32  
33   -#: links/forms.py:35
  33 +#: forms.py:35
34 34 msgid "End View"
35 35 msgstr ""
36 36  
37   -#: links/forms.py:36
  37 +#: forms.py:36
38 38 msgid "End View Date"
39 39 msgstr ""
40 40  
41   -#: links/forms.py:64
  41 +#: forms.py:64
42 42 msgid "There is already a link with this name on this subject"
43 43 msgstr "Ja existe um link com este nome neste Assunto"
44 44  
45   -#: links/models.py:11
  45 +#: models.py:13
46 46 msgid "Link_URL"
47 47 msgstr "URL do link"
48 48  
49   -#: links/models.py:31 links/templates/links/delete.html:12
  49 +#: models.py:33 templates/links/delete.html:12
50 50 msgid "Are you sure you want delete the Website link"
51 51 msgstr "Tem certeza que voce deseja remover esse Link para Website"
52 52  
53   -#: links/templates/links/_form.html:112
  53 +#: templates/links/_form.html:112
54 54 msgid "Pendencies Notifications"
55 55 msgstr ""
56 56  
57   -#: links/templates/links/_form.html:130
  57 +#: templates/links/_form.html:130
58 58 msgid "Action not performed by the user"
59 59 msgstr ""
60 60  
61   -#: links/templates/links/_form.html:156
  61 +#: templates/links/_form.html:156
62 62 msgid "Wished period"
63 63 msgstr ""
64 64  
65   -#: links/templates/links/_form.html:252
  65 +#: templates/links/_form.html:252
66 66 msgid "Attribute students to file link"
67 67 msgstr ""
68 68  
69   -#: links/templates/links/_form.html:272
  69 +#: templates/links/_form.html:272
70 70 msgid "Attribute groups to file link"
71 71 msgstr ""
72 72  
73   -#: links/templates/links/_form.html:320
  73 +#: templates/links/_form.html:320
74 74 msgid "Save"
75 75 msgstr "Salvar"
76 76  
77   -#: links/templates/links/create.html:20
  77 +#: templates/links/create.html:20
78 78 msgid "Create Website Link"
79 79 msgstr "Criar Link do Website"
80 80  
81   -#: links/templates/links/delete.html:18
  81 +#: templates/links/delete.html:18 templates/links/send_message.html:62
82 82 msgid "Close"
83 83 msgstr "Fechar"
84 84  
85   -#: links/templates/links/delete.html:19
  85 +#: templates/links/delete.html:19
86 86 msgid "Delete"
87 87 msgstr "Remover"
88 88  
89   -#: links/templates/links/update.html:20
  89 +#: templates/links/relatorios.html:17 templates/links/relatorios.html:37
  90 +msgid "User"
  91 +msgstr "Usuário"
  92 +
  93 +#: templates/links/relatorios.html:17 templates/links/relatorios.html:37
  94 +msgid "Group"
  95 +msgstr "Grupo"
  96 +
  97 +#: templates/links/relatorios.html:17
  98 +msgid "Action"
  99 +msgstr "Ação"
  100 +
  101 +#: templates/links/relatorios.html:17
  102 +msgid "Date of Action"
  103 +msgstr "Data da ação"
  104 +
  105 +#: templates/links/relatorios.html:37
  106 +msgid "Send message"
  107 +msgstr "Enviar Mensagem"
  108 +
  109 +#: templates/links/relatorios.html:37
  110 +msgid "Action don't realized"
  111 +msgstr "Ação não realizada"
  112 +
  113 +#: templates/links/relatorios.html:151 templates/links/relatorios.html:171
  114 +msgid "Reports"
  115 +msgstr "Relatórios"
  116 +
  117 +#: templates/links/relatorios.html:178
  118 +msgid "Report of the resource "
  119 +msgstr "Relatórios do recurso "
  120 +
  121 +#: templates/links/relatorios.html:187
  122 +msgid "Select the period: "
  123 +msgstr "Selecione o período: "
  124 +
  125 +#: templates/links/relatorios.html:196
  126 +msgid "Search"
  127 +msgstr "Pesquisar"
  128 +
  129 +#: templates/links/relatorios.html:220
  130 +msgid "Filter: "
  131 +msgstr "Filtro: "
  132 +
  133 +#: templates/links/relatorios.html:244 templates/links/relatorios.html:329
  134 +msgid "record(s)"
  135 +msgstr "Relatório(s)"
  136 +
  137 +#: templates/links/send_message.html:38
  138 +msgid "Click or drop the picture here"
  139 +msgstr "Clique ou solte a imagem aqui"
  140 +
  141 +#: templates/links/send_message.html:40
  142 +msgid "The picture could not exceed 5MB."
  143 +msgstr "A imagem não pode exceder 5MB."
  144 +
  145 +#: templates/links/send_message.html:63
  146 +msgid "Send"
  147 +msgstr "Enviar"
  148 +
  149 +#: templates/links/update.html:20
90 150 msgid "Edit: "
91 151 msgstr "Editar: "
92 152  
93   -#: links/views.py:51 links/views.py:64 links/views.py:234 links/views.py:236
94   -#: links/views.py:252 links/views.py:254
  153 +#: views.py:59 views.py:72 views.py:256 views.py:258 views.py:274 views.py:276
95 154 msgid "Visualize"
96 155 msgstr "Visualizar"
97 156  
98   -#: links/views.py:126
  157 +#: views.py:134
99 158 msgid "Create Webiste Link"
100 159 msgstr "Criar Link de Website"
101 160  
102   -#: links/views.py:137
  161 +#: views.py:145
103 162 #, python-format
104 163 msgid ""
105 164 "The Link \"%s\" was added to the Topic \"%s\" of the virtual environment "
... ... @@ -108,7 +167,7 @@ msgstr &quot;&quot;
108 167 "O link \"%s\" foi adicionado com sucesso ao Topico \"%s\" do ambiente "
109 168 "virtual \"%s\" "
110 169  
111   -#: links/views.py:165
  170 +#: views.py:173
112 171 #, python-format
113 172 msgid ""
114 173 "The Website Link \"%s\" was removed successfully from virtual environment "
... ... @@ -116,11 +175,45 @@ msgid &quot;&quot;
116 175 msgstr ""
117 176 "O Link do site \"%s\" foi removido com sucesso do ambiente virtual \"%s\" "
118 177  
119   -#: links/views.py:300
  178 +#: views.py:322
120 179 msgid "Update Website Link"
121 180 msgstr "Atualizar Link do website"
122 181  
123   -#: links/views.py:311
  182 +#: views.py:333
124 183 #, python-format
125 184 msgid "The Website Link \"%s\" was updated successfully!"
126 185 msgstr "O link do website \"%s\" foi atualizado com sucesso! "
  186 +
  187 +#: views.py:377
  188 +msgid "Links Reports"
  189 +msgstr "Relatórios de links"
  190 +
  191 +#: views.py:396
  192 +msgid "Realized"
  193 +msgstr "Realizado"
  194 +
  195 +#: views.py:396
  196 +msgid "Unrealized"
  197 +msgstr "Não Realizado"
  198 +
  199 +#: views.py:396
  200 +msgid "Historic"
  201 +msgstr "Histórico"
  202 +
  203 +#: views.py:414 views.py:423
  204 +msgid "View"
  205 +msgstr "Visualizar"
  206 +
  207 +#: views.py:422
  208 +#, fuzzy
  209 +#| msgid "Link_URL"
  210 +msgid "Links"
  211 +msgstr "Links"
  212 +
  213 +#: views.py:427
  214 +msgid "Actions about resource"
  215 +msgstr "Ações sobre o recurso"
  216 +
  217 +#: views.py:428
  218 +msgid "Quantity"
  219 +msgstr "Quantidade"
... ...
links/models.py
... ... @@ -6,6 +6,8 @@ import datetime
6 6 from topics.models import Topic, Resource
7 7 from users.models import User
8 8 from django.utils import timezone
  9 +from django.core.urlresolvers import reverse_lazy
  10 +
9 11 # Create your models here.
10 12 class Link(Resource):
11 13 link_url = models.URLField(verbose_name = _("Link_URL"))
... ... @@ -19,7 +21,7 @@ class Link(Resource):
19 21 return self.name
20 22  
21 23 def access_link(self):
22   - return self.link_url
  24 + return reverse_lazy('links:view', kwargs = {'slug': self.slug})
23 25  
24 26 def update_link(self):
25 27 return 'links:update'
... ...
links/templates/links/relatorios.html 0 → 100644
... ... @@ -0,0 +1,408 @@
  1 +{% extends "subjects/view.html" %}
  2 +
  3 +{% load static i18n pagination permissions_tags subject_counter %}
  4 +{% load django_bootstrap_breadcrumbs %}
  5 +
  6 +{% block javascript%}
  7 + {{ block.super }}
  8 + <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  9 + <script type="text/javascript">
  10 + var tabela_atual = true;
  11 +
  12 + var array_history = [];
  13 + {%for data_json in json_history.data %}
  14 + array_history.push(["{{data_json.0}}","{{data_json.1}}","{{view}}",{% if data_json.3 is not None %}new Date('{{data_json.3.isoformat}}'){% else%}null{% endif %}]);
  15 + {% endfor%}
  16 + var json_history = {"data":array_history};
  17 + var column_history = [{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":'{% trans "Action" %}'},{"date":'{% trans "Date of Action" %}'}];
  18 +
  19 + var search = [];
  20 + for (var i in json_history["data"]){
  21 + search.push([json_history["data"][i][0],json_history["data"][i][1],
  22 + json_history["data"][i][2],json_history["data"][i][3]]);
  23 + }
  24 +
  25 + var array_n_did = [];
  26 + var checkbox = {};
  27 + {%for data_json in json_n_did.data%}
  28 + var input = '<div class="checkbox">\
  29 + <label for="{{data_json.0}}_google_table">\
  30 + <input id="{{data_json.0}}_google_table" name="{{data_json.0}}_google_table" type="checkbox"><span class="checkbox-material"><span class="check"></span></span>\
  31 + </label>\
  32 + </div>'
  33 + checkbox["{{data_json.0}}_google_table"] = "{{data_json.4}}";
  34 + array_n_did.push([input,"{{data_json.1}}","{{data_json.2}}","{{data_json.3}}"]);
  35 + {% endfor%}
  36 + var json_n_did = {"data":array_n_did};
  37 + var column_n_did = [{"string":'<a href="javascript:void(0);" onclick="return openmodal();"> {% trans "Send message" %}</a>'},{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":"{% trans "Action don't realized" %}"}];
  38 + </script>
  39 +
  40 +
  41 + <script type="text/javascript">
  42 + google.charts.load('current', {'packages':['corechart',"table"]});
  43 + google.charts.setOnLoadCallback(drawChart);
  44 + google.charts.setOnLoadCallback(drawTable);
  45 +
  46 + function drawChart() {
  47 + var data = google.visualization.arrayToDataTable({{db_data|safe}});
  48 + var options = {
  49 + title: '{{title_chart}}',
  50 + // legend: {position: 'right', maxLines: 1},
  51 + bar: { groupWidth: '30%' },
  52 + chartArea:{width:"50%"},
  53 + titlePosition: 'out',
  54 + vAxis: {
  55 + title: '{{title_vAxis}}',
  56 + ticks: [0, .20, .40, .60, .80, 1],
  57 + viewWindow: {
  58 + min: 0,
  59 + max: 1
  60 + }
  61 + },
  62 + isStacked: "percent",
  63 + };
  64 +
  65 + function selectHandler() {
  66 + var selectedItem = chart.getSelection()[0];
  67 + if (selectedItem) {
  68 + var col = data.getColumnLabel(selectedItem.column);
  69 + if (col == "{{n_did_table}}"){
  70 + tabela_atual = false;
  71 + search = [];
  72 + for (var i in json_n_did["data"]){
  73 + search.push([json_n_did["data"][i][0],json_n_did["data"][i][1],
  74 + json_n_did["data"][i][2],json_n_did["data"][i][3]]);
  75 + }
  76 + searcher(col, tabela_atual,true);
  77 +
  78 + } else if (col == "{{did_table}}"){
  79 + tabela_atual = true;
  80 + search = [];
  81 + for (var i in json_history["data"]){
  82 + search.push([json_history["data"][i][0],json_history["data"][i][1],
  83 + json_history["data"][i][2],json_history["data"][i][3]]);
  84 + }
  85 + searcher(col, tabela_atual,true);
  86 + }
  87 + }
  88 + chart.setSelection([])
  89 + }
  90 +
  91 + var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
  92 + google.visualization.events.addListener(chart, 'select', selectHandler);
  93 + chart.draw(data, options);
  94 +
  95 + }
  96 +
  97 + var sortAscending = {0:false,1:false,2:false,3:false};
  98 + function drawTable(columns = column_history,rows = pagination(json_history["data"],1),isdate = true,columndate = 3) {
  99 + var data_table = new google.visualization.DataTable();
  100 + for (var i in columns){
  101 + for (var item in columns[i]){
  102 + data_table.addColumn(item,columns[i][item]);
  103 + }
  104 + }
  105 +
  106 + data_table.addRows(rows);
  107 + var formate_date = new google.visualization.DateFormat({pattern: 'dd/MM/yyyy HH:mm'});
  108 + if (isdate) formate_date.format(data_table, columndate);
  109 +
  110 + // var methods = [];
  111 + // for (var m in data_table) {
  112 + // if (typeof data_table[m] == "function") {
  113 + // methods.push(m);
  114 + // }
  115 + // }
  116 + // console.log(methods.join(","));
  117 + var options = {
  118 + sort: "event",
  119 + allowHtml: true,
  120 + cssClassNames : {
  121 + tableRow: 'text-center',
  122 + tableCell: 'text-center',
  123 + headerCell: 'text-center'
  124 + },
  125 + showRowNumber: true,
  126 + width: '100%',
  127 + height: '100%',
  128 + }
  129 + function ordenar(properties){
  130 + var columnIndex = properties['column'];
  131 + if (columnIndex > 0) {
  132 + options["sortColumn"] = columnIndex;
  133 + options["sortAscending"] = sortAscending[columnIndex];
  134 + data_table.sort({column:columnIndex,desc:sortAscending[columnIndex]});
  135 + sortAscending = {0:false,1:false,2:false,3:false};
  136 + sortAscending[columnIndex] = !sortAscending[columnIndex];
  137 + // console.log(sortAscending);
  138 + table.draw(data_table, options);
  139 + }
  140 + }
  141 +
  142 + var table = new google.visualization.Table(document.getElementById('table_div'));
  143 + google.visualization.events.addListener(table, 'sort', function(e) {ordenar(e)});
  144 + table.draw(data_table, options);
  145 + }
  146 + </script>
  147 +{% endblock%}
  148 +
  149 +{% block breadcrumbs %}
  150 + {{ block.super }}
  151 + {% trans 'Reports' as bread %}
  152 + {% breadcrumb bread link%}
  153 +{% endblock %}
  154 +
  155 +{% block content %}
  156 + {% if messages %}
  157 + {% for message in messages %}
  158 + <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">
  159 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  160 + <span aria-hidden="true">&times;</span>
  161 + </button>
  162 + <p>{{ message }}</p>
  163 + </div>
  164 + {% endfor %}
  165 + {% endif %}
  166 + <div class="panel panel-info topic-panel">
  167 + <div class="panel-heading">
  168 + <div class="row">
  169 + <div class="col-md-12 category-header">
  170 + <h4 class="panel-title" style="margin-top: 10px; margin-bottom: 8px">
  171 + <span>{{link}} / {% trans "Reports" %}</span>
  172 + </h4>
  173 + </div>
  174 + </div>
  175 + </div>
  176 + <div class="row">
  177 + <div class="col-md-12 text-center">
  178 + <h4 style="margin-top: 15px; margin-bottom: 10px" ><strong>{% trans "Report of the resource " %}{{link}}</strong></h4>
  179 + </div>
  180 + </div>
  181 + <div class="row">
  182 + <div class="col-md-12">
  183 +
  184 + <ul class="list-inline nav-justified">
  185 + <div id="general-parameters-div">
  186 + <div class="general-parameters-field">
  187 + <li class="text-right"><h4>{% trans "Select the period: " %}</h4></li>
  188 + </div>
  189 + <form id="period-form" action="" method="get">
  190 + <div class="general-parameters-field">
  191 + <li> <input class="form-control datetime-picker" name="init_date" type="text" required="" value="{% if LANGUAGE_CODE == 'pt-br' %}{{init_date|date:'d/m/Y H:i'}} {% else %} {{init_date|date:'m/d/Y H:i P'}} {% endif %}"></li>
  192 + </div>
  193 + <div class="general-parameters-field">
  194 + <li><input id="inputdate" class="form-control datetime-picker" name="end_date" type="text" required="" value="{% if LANGUAGE_CODE == 'pt-br' %}{{end_date|date:'d/m/Y H:i'}} {% else %} {{end_date|date:'m/d/Y H:i P'}} {% endif %}"></li>
  195 + </div>
  196 + <li><input type="submit" value="{% trans 'Search' %}" style="margin-left: 15px;" class="btn btn-success btn-raised"></li>
  197 + </form>
  198 + </div>
  199 + <ul>
  200 + </div>
  201 + </div>
  202 +
  203 + <div class="row">
  204 + <div class="col-md-10 col-md-offset-1">
  205 + <div id="chart_div" style="height: 500px; margin-top: -50px;"></div>
  206 + </div>
  207 + </div>
  208 +
  209 + <div class="row">
  210 + <div class="col-md-10 col-md-offset-1">
  211 + <div class="text-center">
  212 + <ul class="list-inline nav-justified">
  213 + <li>
  214 + <ul id="view-table" class="list-inline text-right">
  215 + <li><h3 id="title-table"></h3></li>
  216 + </ul>
  217 + </li>
  218 + <li>
  219 + <ul class="list-inline text-right">
  220 + <li><p>{% trans "Filter: " %}</p></li>
  221 + <li><input id="search-input" class="form-control" type="text" name="search" value=""></li>
  222 + </ul>
  223 + </li>
  224 + </ul>
  225 + </div>
  226 + <form id="google-chart-checkbox" action="" method="get">
  227 + <div id="table_div"></div>
  228 + </form>
  229 + <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12 text-center">
  230 + <ul class="pagination">
  231 +
  232 + </ul>
  233 + </div>
  234 + </div>
  235 + </div>
  236 + <div id="modal-message"></div>
  237 + <div class="row">
  238 + <br><br>
  239 + </div>
  240 + </div>
  241 +
  242 + <script type="text/javascript">
  243 +
  244 + $("#title-table").text(search.length + " {% trans 'record(s)' %}");
  245 + function putpagination(data = json_history["data"], load_histoty = true){
  246 + var len = Math.ceil(data.length / 20);
  247 + $(".pagination").empty();
  248 + $(".pagination").append('<li class="disabled"><span>«</span></li>');
  249 + $(".pagination").append('<li id="1" class="active">\
  250 + <a href="javascript:void(0);" onclick="return clickPagination(1, '+ load_histoty +');">1</a>\
  251 + </li>');
  252 + for (var i = 2; i <= len;i++){
  253 + $(".pagination").append('<li id="' + i + '">\
  254 + <a href="javascript:void(0);" onclick="return clickPagination(' + i +', ' + load_histoty + ');">' + i + '</a>\
  255 + </li>');
  256 + }
  257 + if (len > 1) $(".pagination").append('<li><a href="javascript:void(0);" onclick="return clickPagination(2, '+ load_histoty +');"><span>»</span></a></li>');
  258 + else $(".pagination").append('<li class="disabled"><span>»</span></li>');
  259 + };
  260 + putpagination();
  261 +
  262 + $('#period-form').submit(function(event) {
  263 + $('<input />').attr('type', 'hidden')
  264 + .attr('name', "language")
  265 + .attr('value', '{{ LANGUAGE_CODE }}')
  266 + .appendTo('#period-form');
  267 + });
  268 + function add(element,local, first = false){
  269 + if (first) $(local).prepend(element);
  270 + else $(local).append(element);
  271 + }
  272 + function text(element){
  273 + return $(element).text();
  274 + }
  275 + function length(element) {
  276 + return $(element).length;
  277 + }
  278 +
  279 + $("#search-input").on("keyup",function(){
  280 + search = [];
  281 + var text = $("#search-input").val();
  282 + searcher(text,tabela_atual);
  283 + });
  284 +
  285 + function searcher(text, load_histoty = false,apaga=false){
  286 + if(apaga){
  287 + $("#search-input").val("");
  288 + }
  289 + var data = [];
  290 + if (!load_histoty){
  291 + data = $.map(json_n_did["data"], function (obj) {
  292 + return $.extend(true, {}, obj);
  293 + });
  294 + } else {
  295 + data = $.map(json_history["data"], function (obj) {
  296 + return $.extend(true, {}, obj);
  297 + });
  298 + }
  299 + if (load_histoty){
  300 + for (var i in data){
  301 + data[i][3] = moment(data[i][3]).format("DD/MM/YYYY HH:mm");
  302 + }
  303 + }
  304 + if (load_histoty){
  305 + for (var i in data){
  306 + if (data[i][0].toLowerCase().includes(text.toLowerCase())
  307 + || data[i][1].toLowerCase().includes(text.toLowerCase())
  308 + || data[i][2].toLowerCase().includes(text.toLowerCase())
  309 + || data[i][3].toLowerCase().includes(text.toLowerCase())){
  310 + search.push(json_history["data"][i]);
  311 + }
  312 + }
  313 + }
  314 + else {
  315 + for (var i in data){
  316 + if (data[i][1].toLowerCase().includes(text.toLowerCase())
  317 + || data[i][2].toLowerCase().includes(text.toLowerCase())
  318 + || data[i][3].toLowerCase().includes(text.toLowerCase())){
  319 + search.push(json_n_did["data"][i]);
  320 + }
  321 + }
  322 + }
  323 + console.log(search);
  324 + if (!load_histoty){
  325 + drawTable(column_n_did,pagination(search,1),false);
  326 + } else {
  327 + drawTable(column_history,pagination(search,1),true,3);
  328 + }
  329 + $("#title-table").text(search.length + " {% trans 'record(s)' %}");
  330 + putpagination(search,load_histoty);
  331 + }
  332 +
  333 + function pagination(data,pag){
  334 + var len = data.length;
  335 + var first = (pag * 20 - 20 < len) ? pag * 20 - 20:len;
  336 + var end = (pag * 20 < len) ? pag * 20:len;
  337 + var search = data.slice(first,end);
  338 + return search;
  339 + }
  340 +
  341 + function clickPagination(pag, load_histoty = false){
  342 + $(".pagination > li").last().remove();
  343 + $(".pagination > li").first().remove();
  344 +
  345 + if (!load_histoty){
  346 + drawTable(column_n_did,pagination(search,pag),false);
  347 + } else {
  348 + drawTable(column_history,pagination(search,pag),true,3);
  349 + }
  350 +
  351 + if (pag < Math.ceil(search.length / 20))
  352 + $(".pagination").append('<li><a href="javascript:void(0);" onclick="return clickPagination(' + (pag + 1) + ', '+ load_histoty +');"><span>»</span></a></li>');
  353 + else $(".pagination").append('<li class="disabled"><span>»</span></li>');
  354 + if (pag > 1)
  355 + $(".pagination").prepend('<li><a href="javascript:void(0);" onclick="return clickPagination(' + (pag - 1) + ', '+ load_histoty +');"><span>«</span></a></li>');
  356 + else $(".pagination").prepend('<li class="disabled"><span>«</span></li>');
  357 + $(".active").removeClass("active");
  358 + $("#" + pag).addClass("active");
  359 + }
  360 +
  361 + function openmodal(){
  362 + $( "#modal-message" ).empty();
  363 + $.get( "{% url 'links:send_message' link.slug %}", function( data ) {
  364 + $( "#modal-message" ).append( data );
  365 + $("#send-message-modal").modal("show");
  366 + });
  367 + }
  368 +
  369 + function sendMessage(){
  370 + $("#send-message-modal").modal("hide");
  371 + var checked = $("#google-chart-checkbox").serializeArray();
  372 + var email = [];
  373 + for (var i in checked){
  374 + email.push(checkbox[checked[i]["name"]]);
  375 + }
  376 + $('<input />').attr('type', 'hidden')
  377 + .attr('name', "users[]")
  378 + .attr('value', email)
  379 + .appendTo('#text_chat_form');
  380 +
  381 + var formData = new FormData($('#text_chat_form').get(0));
  382 + $.ajax({
  383 + url: "{% url 'links:send_message' link.slug %}",
  384 + type: "POST",
  385 + data: formData,
  386 + cache: false,
  387 + processData: false,
  388 + contentType: false,
  389 + success: function(data) {
  390 + if (data["message"]){
  391 + console.log("success");
  392 + $("body").removeClass("modal-open");
  393 + $( "#modal-message" ).empty();
  394 + $(".modal-backdrop.fade.in").remove();
  395 + } else {
  396 + $( "#modal-message" ).empty();
  397 + $(".modal-backdrop.fade.in").remove();
  398 + $( "#modal-message" ).append( data );
  399 + $("#send-message-modal").modal("show");
  400 + }
  401 + },
  402 + error: function(data){
  403 + console.log("erro");
  404 + }
  405 + });
  406 + }
  407 + </script>
  408 +{% endblock %}
... ...
links/templates/links/send_message.html 0 → 100644
... ... @@ -0,0 +1,112 @@
  1 +
  2 + {% load widget_tweaks i18n %}
  3 + <!-- Modal (remember to change the ids!!!) -->
  4 +<div class="modal fade" id="send-message-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  5 + <div class="modal-dialog" role="document">
  6 + <div class="modal-content">
  7 + <!-- Modal Body -->
  8 + <div class="modal-body">
  9 + <form id="text_chat_form" action="" method="POST" enctype="multipart/form-data">
  10 + {% csrf_token %}
  11 + {% comment %}Area para o Texto{% endcomment %}
  12 + <div class="form-group{% if form.has_error %} has-error {% endif %}">
  13 + <label for="{{ form.comment.auto_id }}">{{ form.comment.label }}: <span>*</span></label>
  14 + {% render_field form.comment class='form-control text_simple_wysiwyg' %}
  15 +
  16 + <span id="helpBlock" class="help-block">{{ form.comment.help_text }}</span>
  17 +
  18 + {% if form.comment.errors %}
  19 + <div class="alert alert-danger alert-dismissible" role="alert">
  20 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  21 + <span aria-hidden="true">&times;</span>
  22 + </button>
  23 + <ul>
  24 + {% for error in form.comment.errors %}
  25 + <li>{{ error }}</li>
  26 + {% endfor %}
  27 + </ul>
  28 + </div>
  29 + {% endif %}
  30 + </div>
  31 + {% comment %}Area para anexar a imagem {% endcomment %}
  32 + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">
  33 + {% render_field form.image %}
  34 +
  35 + <div class="filedrag">
  36 + {% trans 'Click or drop the picture here' %}<br />
  37 +
  38 + <small>{% trans 'The picture could not exceed 5MB.' %}</small>
  39 + </div>
  40 +
  41 + {% if form.image.errors %}
  42 + <div class="alert alert-danger alert-dismissible" role="alert">
  43 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  44 + <span aria-hidden="true">&times;</span>
  45 + </button>
  46 + <ul>
  47 + {% for error in form.image.errors %}
  48 + <li>{{ error }}</li>
  49 + {% endfor %}
  50 + </ul>
  51 + </div>
  52 + {% endif %}
  53 +
  54 + </div>
  55 + </form>
  56 + </div>
  57 + <!-- Modal Footer -->
  58 + <div id="delete-category-footer"class="modal-footer">
  59 + <!-- Don't remove that!!! -->
  60 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
  61 + <a href="javascript:void(0)" onclick="return sendMessage()" form="text_chat_form" class="btn btn-success btn-raised erase-button">{% trans "Send" %}</a>
  62 + </div>
  63 + </div>
  64 + </div>
  65 +</div>
  66 +
  67 +<script type="text/javascript">
  68 +
  69 + $('.text_simple_wysiwyg').summernote({
  70 + dialogsInBody: true,
  71 + disableDragAndDrop: true,
  72 + height: 150,
  73 + toolbar: [
  74 + // [groupName, [list of button]]
  75 + ['style', ['bold', 'italic']],
  76 + ['insert', ['link']]
  77 + ]
  78 + });
  79 +
  80 + if (window.File && window.FileList && window.FileReader) {
  81 + Init();
  82 + }
  83 +
  84 + function Init() {
  85 + var small = $("#id_image"),
  86 + filedrag = $(".filedrag"),
  87 + common = $(".common-file-input");
  88 +
  89 + // file select
  90 + small.on("change", FileSelectHandler);
  91 +
  92 + // is XHR2 available?
  93 + var xhr = new XMLHttpRequest();
  94 + if (xhr.upload) {
  95 + // file drop
  96 + filedrag.on("drop", FileSelectHandler);
  97 + filedrag.attr('style', 'display:block');
  98 + common.attr('style', 'display:none');
  99 + }
  100 + }
  101 +
  102 + // file selection
  103 + function FileSelectHandler(e) {
  104 + var files = e.target.files || e.dataTransfer.files,
  105 + parent = $(e.target.offsetParent);
  106 +
  107 + // process all File objects
  108 + for (var i = 0, f; f = files[i]; i++) {
  109 + parent.find('.filedrag').html(f.name);
  110 + }
  111 + }
  112 +</script>
0 113 \ No newline at end of file
... ...
links/urls.py
... ... @@ -7,4 +7,7 @@ urlpatterns = [
7 7 url(r'^create/(?P<slug>[\w_-]+)/$', views.CreateLinkView.as_view(), name='create'),
8 8 url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteLinkView.as_view(), name='delete'),
9 9 url(r'^update/(?P<topic_slug>[\w_-]+)/(?P<slug>[\w_-]+)/$', views.UpdateLinkView.as_view(), name='update'),
10   - url(r'^view/(?P<slug>[\w_-]+)/$', views.DetailLinkView.as_view(), name='view')]
11 10 \ No newline at end of file
  11 + url(r'^view/(?P<slug>[\w_-]+)/$', views.RedirectUrl.as_view(), name='view'),
  12 + url(r'^chart/(?P<slug>[\w_-]+)/$', views.StatisticsView.as_view(), name = 'get_chart'),
  13 + url(r'^send-message/(?P<slug>[\w_-]+)/$', views.SendMessage.as_view(), name = 'send_message'),
  14 +]
... ...
links/views.py
... ... @@ -17,6 +17,14 @@ from pendencies.forms import PendenciesForm
17 17 from amadeus.permissions import has_subject_permissions, has_resource_permissions
18 18  
19 19 from topics.models import Topic
  20 +
  21 +import datetime
  22 +from chat.models import Conversation, TalkMessages
  23 +from users.models import User
  24 +from subjects.models import Subject
  25 +
  26 +from webpage.forms import FormModalMessage
  27 +
20 28 # Create your views here.
21 29 class CreateLinkView(LoginRequiredMixin, LogMixin, generic.edit.CreateView):
22 30 log_component = 'resources'
... ... @@ -181,18 +189,32 @@ class DeleteLinkView(LoginRequiredMixin, LogMixin, generic.edit.DeleteView):
181 189  
182 190 return reverse_lazy('subjects:view', kwargs = {'slug': self.object.topic.subject.slug})
183 191  
  192 +from django.views.generic.base import RedirectView
184 193  
185   -class DetailLinkView(LoginRequiredMixin, LogMixin, generic.detail.DetailView):
  194 +class RedirectUrl(LogMixin, RedirectView):
186 195 log_component = 'resources'
187 196 log_action = 'view'
188 197 log_resource = 'link'
189 198 log_context = {}
190   - login_url = reverse_lazy("users:login")
191   - redirect_field_name = 'next'
192 199  
193   - model = Link
194   - template_name = 'links/view.html'
195   - context_object_name = 'web_link'
  200 + def get_redirect_url(self, *args, **kwargs):
  201 + link = get_object_or_404(Link,slug=self.kwargs.get("slug",""))
  202 + self.log_context['category_id'] = link.topic.subject.category.id
  203 + self.log_context['category_name'] = link.topic.subject.category.name
  204 + self.log_context['category_slug'] = link.topic.subject.category.slug
  205 + self.log_context['subject_id'] = link.topic.subject.id
  206 + self.log_context['subject_name'] = link.topic.subject.name
  207 + self.log_context['subject_slug'] = link.topic.subject.slug
  208 + self.log_context['topic_id'] = link.topic.id
  209 + self.log_context['topic_name'] = link.topic.name
  210 + self.log_context['topic_slug'] = link.topic.slug
  211 + self.log_context['link_id'] = link.id
  212 + self.log_context['link_name'] = link.name
  213 + self.log_context['link_slug'] = link.slug
  214 +
  215 + super(RedirectUrl, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  216 +
  217 + return link.link_url
196 218  
197 219 class UpdateLinkView(LoginRequiredMixin, LogMixin, generic.edit.UpdateView):
198 220  
... ... @@ -311,3 +333,144 @@ class UpdateLinkView(LoginRequiredMixin, LogMixin, generic.edit.UpdateView):
311 333 messages.success(self.request, _('The Website Link "%s" was updated successfully!')%(self.object.name))
312 334  
313 335 return reverse_lazy('subjects:view', kwargs = {'slug': self.object.topic.subject.slug})
  336 +
  337 +
  338 +class StatisticsView(LoginRequiredMixin, LogMixin, generic.DetailView):
  339 + log_component = 'resources'
  340 + log_action = 'view_statistics'
  341 + log_resource = 'link'
  342 + log_context = {}
  343 +
  344 + login_url = reverse_lazy("users:login")
  345 + redirect_field_name = 'next'
  346 + model = Link
  347 + template_name = 'links/relatorios.html'
  348 +
  349 + def dispatch(self, request, *args, **kwargs):
  350 + slug = self.kwargs.get('slug', '')
  351 + link = get_object_or_404(Link, slug = slug)
  352 +
  353 + if not has_subject_permissions(request.user, link.topic.subject):
  354 + return redirect(reverse_lazy('subjects:home'))
  355 +
  356 + return super(StatisticsView, self).dispatch(request, *args, **kwargs)
  357 +
  358 + def get_context_data(self, **kwargs):
  359 + context = super(StatisticsView, self).get_context_data(**kwargs)
  360 +
  361 + self.log_context['category_id'] = self.object.topic.subject.category.id
  362 + self.log_context['category_name'] = self.object.topic.subject.category.name
  363 + self.log_context['category_slug'] = self.object.topic.subject.category.slug
  364 + self.log_context['subject_id'] = self.object.topic.subject.id
  365 + self.log_context['subject_name'] = self.object.topic.subject.name
  366 + self.log_context['subject_slug'] = self.object.topic.subject.slug
  367 + self.log_context['topic_id'] = self.object.topic.id
  368 + self.log_context['topic_name'] = self.object.topic.name
  369 + self.log_context['topic_slug'] = self.object.topic.slug
  370 + self.log_context['link_id'] = self.object.id
  371 + self.log_context['link_name'] = self.object.name
  372 + self.log_context['link_slug'] = self.object.slug
  373 +
  374 + super(StatisticsView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  375 +
  376 +
  377 + context['title'] = _('Links Reports')
  378 +
  379 + slug = self.kwargs.get('slug')
  380 + link = get_object_or_404(Link, slug = slug)
  381 + print (self.request.GET.get('init_date',''))
  382 + date_format = "%d/%m/%Y %H:%M" if self.request.GET.get('language','') == 'pt-br' else "%m/%d/%Y %I:%M %p"
  383 + if self.request.GET.get('language','') == "":
  384 + start_date = datetime.datetime.now() - datetime.timedelta(30)
  385 + end_date = datetime.datetime.now()
  386 + else :
  387 + start_date = datetime.datetime.strptime(self.request.GET.get('init_date',''),date_format)
  388 + end_date = datetime.datetime.strptime(self.request.GET.get('end_date',''),date_format)
  389 + context["init_date"] = start_date
  390 + context["end_date"] = end_date
  391 + alunos = link.students.all()
  392 + if link.all_students :
  393 + alunos = link.topic.subject.students.all()
  394 +
  395 + vis_ou = Log.objects.filter(context__contains={'link_id':link.id},resource="link",action="view",user_email__in=(aluno.email for aluno in alunos), datetime__range=(start_date,end_date + datetime.timedelta(minutes = 1)))
  396 + did,n_did,history = str(_("Realized")),str(_("Unrealized")),str(_("Historic"))
  397 + re = []
  398 + data_n_did,data_history = [],[]
  399 + json_n_did, json_history = {},{}
  400 +
  401 + from django.db.models import Count, Max
  402 + views_user = vis_ou.values("user_email").annotate(views=Count("user_email"))
  403 + date_last = vis_ou.values("user_email").annotate(last=Max("datetime"))
  404 +
  405 + for log_al in vis_ou.order_by("datetime"):
  406 + data_history.append([str(alunos.get(email=log_al.user_email)),
  407 + ", ".join([str(x) for x in link.topic.subject.group_subject.filter(participants__email=log_al.user_email)]),
  408 + log_al.action,log_al.datetime])
  409 + json_history["data"] = data_history
  410 +
  411 + not_view = alunos.exclude(email__in=[log.user_email for log in vis_ou.distinct("user_email")])
  412 + index = 0
  413 + for alun in not_view:
  414 + data_n_did.append([index,str(alun),", ".join([str(x) for x in link.topic.subject.group_subject.filter(participants__email=alun.email)]),str(_('View')), str(alun.email)])
  415 + index += 1
  416 + json_n_did["data"] = data_n_did
  417 +
  418 +
  419 + context["json_n_did"] = json_n_did
  420 + context["json_history"] = json_history
  421 + c_visualizou = vis_ou.distinct("user_email").count()
  422 + column_view = str(_('View'))
  423 + re.append([str(_('Links')),did,n_did])
  424 + re.append([column_view,c_visualizou, alunos.count() - c_visualizou])
  425 + context['topic'] = link.topic
  426 + context['subject'] = link.topic.subject
  427 + context['db_data'] = re
  428 + context['title_chart'] = _('Actions about resource')
  429 + context['title_vAxis'] = _('Quantity')
  430 + context['view'] = column_view
  431 + context["n_did_table"] = n_did
  432 + context["did_table"] = did
  433 + context["history_table"] = history
  434 + return context
  435 +
  436 +
  437 +
  438 +class SendMessage(LoginRequiredMixin, LogMixin, generic.edit.FormView):
  439 + log_component = 'resources'
  440 + log_action = 'send'
  441 + log_resource = 'link'
  442 + log_context = {}
  443 +
  444 + login_url = reverse_lazy("users:login")
  445 + redirect_field_name = 'next'
  446 +
  447 + template_name = 'links/send_message.html'
  448 + form_class = FormModalMessage
  449 +
  450 + def dispatch(self, request, *args, **kwargs):
  451 + slug = self.kwargs.get('slug', '')
  452 + link = get_object_or_404(Link, slug = slug)
  453 + self.link = link
  454 +
  455 + if not has_subject_permissions(request.user, link.topic.subject):
  456 + return redirect(reverse_lazy('subjects:home'))
  457 +
  458 + return super(SendMessage, self).dispatch(request, *args, **kwargs)
  459 +
  460 + def form_valid(self, form):
  461 + message = form.cleaned_data.get('comment')
  462 + image = form.cleaned_data.get("image")
  463 + users = (self.request.POST.get('users[]','')).split(",")
  464 + user = self.request.user
  465 + subject = self.link.topic.subject
  466 + for u in users:
  467 + to_user = User.objects.get(email=u)
  468 + talk, create = Conversation.objects.get_or_create(user_one=user,user_two=to_user)
  469 + created = TalkMessages.objects.create(text=message,talk=talk,user=user,subject=subject,image=image)
  470 + return JsonResponse({"message":"ok"})
  471 +
  472 + def get_context_data(self, **kwargs):
  473 + context = super(SendMessage,self).get_context_data()
  474 + context["link"] = get_object_or_404(Link, slug=self.kwargs.get('slug', ''))
  475 + return context
  476 +
... ...
pdf_file/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-04-28 20:39-0300\n"
  11 +"POT-Creation-Date: 2017-05-05 17:16-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"
... ... @@ -76,7 +76,7 @@ msgstr &quot;Ação não permitida pelo usuário&quot;
76 76  
77 77 #: templates/pdf_file/_form.html:161
78 78 msgid "Wished period"
79   -msgstr ""
  79 +msgstr "Período desejado"
80 80  
81 81 #: templates/pdf_file/_form.html:257
82 82 msgid "Attribute students to file link"
... ... @@ -94,45 +94,73 @@ msgstr &quot;Salvar&quot;
94 94 msgid "Create PDF file"
95 95 msgstr "Criar arquivo PDF"
96 96  
97   -#: templates/pdf_file/relatorios.html:16 templates/pdf_file/relatorios.html:30
98   -#: templates/pdf_file/relatorios.html:37
  97 +#: templates/pdf_file/relatorios.html:17 templates/pdf_file/relatorios.html:37
99 98 msgid "User"
100 99 msgstr "Usuário"
101 100  
102   -#: templates/pdf_file/relatorios.html:16 templates/pdf_file/relatorios.html:30
103   -#: templates/pdf_file/relatorios.html:37
  101 +#: templates/pdf_file/relatorios.html:17 templates/pdf_file/relatorios.html:37
104 102 msgid "Group"
105 103 msgstr "Grupo"
106 104  
107   -#: templates/pdf_file/relatorios.html:16 templates/pdf_file/relatorios.html:30
  105 +#: templates/pdf_file/relatorios.html:17
108 106 msgid "Action"
109 107 msgstr "Ação"
110 108  
111   -#: templates/pdf_file/relatorios.html:16 templates/pdf_file/relatorios.html:30
  109 +#: templates/pdf_file/relatorios.html:17
112 110 msgid "Date of Action"
113 111 msgstr "Data da ação"
114 112  
115   -#: templates/pdf_file/relatorios.html:135
116   -#: templates/pdf_file/relatorios.html:155
  113 +#: templates/pdf_file/relatorios.html:37
  114 +msgid "Send message"
  115 +msgstr "Enviar Mensagem"
  116 +
  117 +#: templates/pdf_file/relatorios.html:37
  118 +#| msgid "Actions about resource"
  119 +msgid "Action don't realized"
  120 +msgstr "Ação não realizada"
  121 +
  122 +#: templates/pdf_file/relatorios.html:151
  123 +#: templates/pdf_file/relatorios.html:171
117 124 msgid "Reports"
118 125 msgstr "Relatórios"
119 126  
120   -#: templates/pdf_file/relatorios.html:162
  127 +#: templates/pdf_file/relatorios.html:178
121 128 msgid "Report of the resource "
122 129 msgstr "Relatórios do recurso "
123 130  
124   -#: templates/pdf_file/relatorios.html:165
  131 +#: templates/pdf_file/relatorios.html:187
125 132 msgid "Select the period: "
126 133 msgstr "Selecione o período: "
127 134  
128   -#: templates/pdf_file/relatorios.html:178
  135 +#: templates/pdf_file/relatorios.html:196
129 136 msgid "Search"
130 137 msgstr "Pesquisar"
131 138  
132   -#: templates/pdf_file/relatorios.html:200
  139 +#: templates/pdf_file/relatorios.html:220
133 140 msgid "Filter: "
134 141 msgstr "Filtro: "
135 142  
  143 +#: templates/pdf_file/relatorios.html:244
  144 +#: templates/pdf_file/relatorios.html:329
  145 +msgid "record(s)"
  146 +msgstr "Relatório(s)"
  147 +
  148 +#: templates/pdf_file/send_message.html:38
  149 +msgid "Click or drop the picture here"
  150 +msgstr "Clique ou arraste a imagem aqui"
  151 +
  152 +#: templates/pdf_file/send_message.html:40
  153 +msgid "The picture could not exceed 5MB."
  154 +msgstr "A imagem não pode exceder 5MB."
  155 +
  156 +#: templates/pdf_file/send_message.html:62
  157 +msgid "Close"
  158 +msgstr "Fechar"
  159 +
  160 +#: templates/pdf_file/send_message.html:63
  161 +msgid "Send"
  162 +msgstr "Enviar"
  163 +
136 164 #: templates/pdf_file/update.html:20
137 165 msgid "Edit: "
138 166 msgstr "Editar: "
... ... @@ -141,16 +169,16 @@ msgstr &quot;Editar: &quot;
141 169 msgid "PDF could not be displayed"
142 170 msgstr "PDF não pode ser mostrado"
143 171  
144   -#: views.py:112 views.py:125 views.py:236 views.py:238 views.py:254
145   -#: views.py:256
  172 +#: views.py:116 views.py:129 views.py:240 views.py:242 views.py:258
  173 +#: views.py:260
146 174 msgid "Visualize"
147 175 msgstr "Visualizar"
148 176  
149   -#: views.py:185
  177 +#: views.py:189
150 178 msgid "Create PDF File"
151 179 msgstr "Criar o arquivo PDF"
152 180  
153   -#: views.py:196
  181 +#: views.py:200
154 182 #, python-format
155 183 msgid ""
156 184 "The PDF File \"%s\" was added to the Topic \"%s\" of the virtual environment "
... ... @@ -159,50 +187,59 @@ msgstr &quot;&quot;
159 187 "O arquivo PDF \"%s\" foi adicionado ao topico \"%s\" do ambiente virtual "
160 188 "\"%s\" com sucesso!"
161 189  
162   -#: views.py:300
  190 +#: views.py:304
163 191 msgid "Update PDF File"
164 192 msgstr "Atualize arquivo PDF"
165 193  
166   -#: views.py:311
  194 +#: views.py:315
167 195 #, python-format
168 196 msgid "The PDF File \"%s\" was updated successfully!"
169 197 msgstr "O arquivo PDF \"%s\" foi atualizado com sucesso!"
170 198  
171   -#: views.py:338
  199 +#: views.py:342
172 200 #, python-format
173 201 msgid ""
174 202 "The PDF File \"%s\" was removed successfully from virtual environment \"%s\"!"
175 203 msgstr ""
176 204 "O arquivo PDF \"%s\" foi removido com sucesso do ambiente virtual \"%s\" "
177 205  
178   -#: views.py:396
  206 +#: views.py:400
179 207 msgid "PDF File Reports"
180 208 msgstr "Relatórios do arquivo de PDF"
181 209  
182   -#: views.py:414
183   -msgid "Users who viewed"
184   -msgstr "Usuário que visualizaram"
  210 +#: views.py:420
  211 +msgid "Realized"
  212 +msgstr "Realizado"
185 213  
186   -#: views.py:414
187   -msgid "Users who did not viewed"
188   -msgstr "Usuários que não visualizaram"
  214 +#: views.py:420
  215 +msgid "Unrealized"
  216 +msgstr "Não Realizado"
189 217  
190   -#: views.py:414
  218 +#: views.py:420
191 219 msgid "Historic"
192 220 msgstr "Histórico"
193 221  
194   -#: views.py:446
195   -msgid "PDF File"
196   -msgstr "Criar o arquivo PDF"
197   -
198   -#: views.py:447
  222 +#: views.py:439 views.py:448
199 223 msgid "View"
200 224 msgstr "Visualizar"
201 225  
202   -#: views.py:451
203   -msgid "Students viewing the PDF File"
204   -msgstr "Estudantes que visualizaram o arquivo PDF"
  226 +#: views.py:447
  227 +msgid "PDF File"
  228 +msgstr "Criar o arquivo PDF"
205 229  
206 230 #: views.py:452
  231 +msgid "Actions about resource"
  232 +msgstr "Ações sobre o recurso"
  233 +
  234 +#: views.py:453
207 235 msgid "Quantity"
208 236 msgstr "Quantidade"
  237 +
  238 +#~ msgid "Users who viewed"
  239 +#~ msgstr "Usuário que visualizaram"
  240 +
  241 +#~ msgid "Users who did not viewed"
  242 +#~ msgstr "Usuários que não visualizaram"
  243 +
  244 +#~ msgid "Students viewing the PDF File"
  245 +#~ msgstr "Estudantes que visualizaram o arquivo PDF"
... ...
pdf_file/templates/pdf_file/relatorios.html
... ... @@ -11,7 +11,7 @@
11 11  
12 12 var array_history = [];
13 13 {%for data_json in json_history.data%}
14   - array_history.push(["{{data_json.0}}","{{data_json.1}}","{{data_json.2}}",{% if data_json.3 is not None %}new Date('{{data_json.3.isoformat}}'){% else%}null{% endif %}]);
  14 + array_history.push(["{{data_json.0}}","{{data_json.1}}","{{view}}",{% if data_json.3 is not None %}new Date('{{data_json.3.isoformat}}'){% else%}null{% endif %}]);
15 15 {% endfor%}
16 16 var json_history = {"data":array_history};
17 17 var column_history = [{"string":"{% trans 'User' %}"},{"string":"{% trans 'Group' %}"},{"string":"{% trans 'Action' %}"},{"date":"{% trans 'Date of Action' %}"}];
... ... @@ -34,7 +34,7 @@
34 34 array_n_did.push([input,"{{data_json.1}}","{{data_json.2}}", "{{data_json.3}}"]);
35 35 {% endfor%}
36 36 var json_n_did = {"data":array_n_did};
37   - var column_n_did = [{"string":'<a href="javascript:void(0);" onclick="return openmodal();"> {% trans "Send message" %}</a>'},{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":"Action don't realized"}];
  37 + var column_n_did = [{"string":'<a href="javascript:void(0);" onclick="return openmodal();"> {% trans "Send message" %}</a>'},{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":"{% trans "Action don't realized" %}"}];
38 38 </script>
39 39  
40 40  
... ... @@ -138,6 +138,7 @@
138 138 table.draw(data_table, options);
139 139 }
140 140 }
  141 +
141 142 var table = new google.visualization.Table(document.getElementById('table_div'));
142 143 google.visualization.events.addListener(table, 'sort', function(e) {ordenar(e)});
143 144 table.draw(data_table, options);
... ... @@ -205,13 +206,13 @@
205 206 </div>
206 207 </div>
207 208  
208   - <div class="row">
  209 + <div class="row">
209 210 <div class="col-md-10 col-md-offset-1">
210 211 <div class="text-center">
211 212 <ul class="list-inline nav-justified">
212 213 <li>
213 214 <ul id="view-table" class="list-inline text-right">
214   - <li><h3 id="title-table">{{history_table}}</h3></li>
  215 + <li><h3 id="title-table"></h3></li>
215 216 </ul>
216 217 </li>
217 218 <li>
... ... @@ -222,8 +223,9 @@
222 223 </li>
223 224 </ul>
224 225 </div>
225   -
226   - <div id="table_div"></div>
  226 + <form id="google-chart-checkbox" action="" method="get">
  227 + <div id="table_div"></div>
  228 + </form>
227 229 <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12 text-center">
228 230 <ul class="pagination">
229 231  
... ... @@ -231,44 +233,14 @@
231 233 </div>
232 234 </div>
233 235 </div>
234   - <!-- Modal (remember to change the ids!!!) -->
235   - <div class="modal fade" id="send-message-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
236   - <div class="modal-dialog" role="document">
237   - <div class="modal-content">
238   - <!-- Modal Body -->
239   - <div class="modal-body">
240   - <!-- Put ONLY your content here!!! -->
241   - <h3>{% trans "Message: " %}</h3>
242   - <form id="text_chat_form" action="" method="GET">
243   - <textarea id="message" name="message" rows="5" cols="80"></textarea>
244   - </form>
245   - </div>
246   - <!-- Modal Footer -->
247   - <div id="delete-category-footer"class="modal-footer">
248   - <!-- Don't remove that!!! -->
249   - <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
250   - <a href="javascript:void(0)" onclick="return sendMessage()" form="text_chat_form" class="btn btn-success btn-raised erase-button">{% trans "Send" %}</a>
251   - </div>
252   - </div>
253   - </div>
254   - </div>
255   -
  236 + <div id="modal-message"></div>
256 237 <div class="row">
257 238 <br><br>
258 239 </div>
259 240 </div>
260 241  
261 242 <script type="text/javascript">
262   - $('#message').summernote({
263   - dialogsInBody: true,
264   - disableDragAndDrop: true,
265   - height: 150,
266   - toolbar: [
267   - // [groupName, [list of button]]
268   - ['style', ['bold', 'italic']],
269   - ['insert', ['link']]
270   - ]
271   - });
  243 +
272 244 $("#title-table").text(search.length + " {% trans 'record(s)' %}");
273 245 function putpagination(data = json_history["data"], load_histoty = true){
274 246 var len = Math.ceil(data.length / 20);
... ... @@ -384,6 +356,15 @@
384 356 $(".active").removeClass("active");
385 357 $("#" + pag).addClass("active");
386 358 }
  359 +
  360 + function openmodal(){
  361 + $( "#modal-message" ).empty();
  362 + $.get( "{% url 'pdf_files:send_message' pdf_file.slug %}", function( data ) {
  363 + $( "#modal-message" ).append( data );
  364 + $("#send-message-modal").modal("show");
  365 + });
  366 + }
  367 +
387 368 function sendMessage(){
388 369 $("#send-message-modal").modal("hide");
389 370 var checked = $("#google-chart-checkbox").serializeArray();
... ... @@ -391,19 +372,36 @@
391 372 for (var i in checked){
392 373 email.push(checkbox[checked[i]["name"]]);
393 374 }
394   - var message = $("#text_chat_form").serializeArray()[0]["value"];
  375 + $('<input />').attr('type', 'hidden')
  376 + .attr('name', "users[]")
  377 + .attr('value', email)
  378 + .appendTo('#text_chat_form');
  379 +
  380 + var formData = new FormData($('#text_chat_form').get(0));
395 381 $.ajax({
396   - type: "GET",
397   - data: {"message":message,"users[]":email},
398   - url: "{% url 'pdf_files:send_message' subject.slug %}",
399   - success: function(msg){
400   - console.log(msg);
401   - $('#message').summernote("reset");
402   - }
403   - });
404   - }
405   - function openmodal(){
406   - $("#send-message-modal").modal("show");
  382 + url: "{% url 'pdf_files:send_message' pdf_file.slug %}",
  383 + type: "POST",
  384 + data: formData,
  385 + cache: false,
  386 + processData: false,
  387 + contentType: false,
  388 + success: function(data) {
  389 + if (data["message"]){
  390 + console.log("success");
  391 + $("body").removeClass("modal-open");
  392 + $( "#modal-message" ).empty();
  393 + $(".modal-backdrop.fade.in").remove();
  394 + } else {
  395 + $( "#modal-message" ).empty();
  396 + $(".modal-backdrop.fade.in").remove();
  397 + $( "#modal-message" ).append( data );
  398 + $("#send-message-modal").modal("show");
  399 + }
  400 + },
  401 + error: function(data){
  402 + console.log("erro");
  403 + }
  404 + });
407 405 }
408 406 </script>
409 407 {% endblock %}
... ...
pdf_file/templates/pdf_file/send_message.html 0 → 100644
... ... @@ -0,0 +1,112 @@
  1 +
  2 + {% load widget_tweaks i18n %}
  3 + <!-- Modal (remember to change the ids!!!) -->
  4 +<div class="modal fade" id="send-message-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  5 + <div class="modal-dialog" role="document">
  6 + <div class="modal-content">
  7 + <!-- Modal Body -->
  8 + <div class="modal-body">
  9 + <form id="text_chat_form" action="" method="POST" enctype="multipart/form-data">
  10 + {% csrf_token %}
  11 + {% comment %}Area para o Texto{% endcomment %}
  12 + <div class="form-group{% if form.has_error %} has-error {% endif %}">
  13 + <label for="{{ form.comment.auto_id }}">{{ form.comment.label }}: <span>*</span></label>
  14 + {% render_field form.comment class='form-control text_simple_wysiwyg' %}
  15 +
  16 + <span id="helpBlock" class="help-block">{{ form.comment.help_text }}</span>
  17 +
  18 + {% if form.comment.errors %}
  19 + <div class="alert alert-danger alert-dismissible" role="alert">
  20 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  21 + <span aria-hidden="true">&times;</span>
  22 + </button>
  23 + <ul>
  24 + {% for error in form.comment.errors %}
  25 + <li>{{ error }}</li>
  26 + {% endfor %}
  27 + </ul>
  28 + </div>
  29 + {% endif %}
  30 + </div>
  31 + {% comment %}Area para anexar a imagem {% endcomment %}
  32 + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">
  33 + {% render_field form.image %}
  34 +
  35 + <div class="filedrag">
  36 + {% trans 'Click or drop the picture here' %}<br />
  37 +
  38 + <small>{% trans 'The picture could not exceed 5MB.' %}</small>
  39 + </div>
  40 +
  41 + {% if form.image.errors %}
  42 + <div class="alert alert-danger alert-dismissible" role="alert">
  43 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  44 + <span aria-hidden="true">&times;</span>
  45 + </button>
  46 + <ul>
  47 + {% for error in form.image.errors %}
  48 + <li>{{ error }}</li>
  49 + {% endfor %}
  50 + </ul>
  51 + </div>
  52 + {% endif %}
  53 +
  54 + </div>
  55 + </form>
  56 + </div>
  57 + <!-- Modal Footer -->
  58 + <div id="delete-category-footer"class="modal-footer">
  59 + <!-- Don't remove that!!! -->
  60 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
  61 + <a href="javascript:void(0)" onclick="return sendMessage()" form="text_chat_form" class="btn btn-success btn-raised erase-button">{% trans "Send" %}</a>
  62 + </div>
  63 + </div>
  64 + </div>
  65 +</div>
  66 +
  67 +<script type="text/javascript">
  68 +
  69 + $('.text_simple_wysiwyg').summernote({
  70 + dialogsInBody: true,
  71 + disableDragAndDrop: true,
  72 + height: 150,
  73 + toolbar: [
  74 + // [groupName, [list of button]]
  75 + ['style', ['bold', 'italic']],
  76 + ['insert', ['link']]
  77 + ]
  78 + });
  79 +
  80 + if (window.File && window.FileList && window.FileReader) {
  81 + Init();
  82 + }
  83 +
  84 + function Init() {
  85 + var small = $("#id_image"),
  86 + filedrag = $(".filedrag"),
  87 + common = $(".common-file-input");
  88 +
  89 + // file select
  90 + small.on("change", FileSelectHandler);
  91 +
  92 + // is XHR2 available?
  93 + var xhr = new XMLHttpRequest();
  94 + if (xhr.upload) {
  95 + // file drop
  96 + filedrag.on("drop", FileSelectHandler);
  97 + filedrag.attr('style', 'display:block');
  98 + common.attr('style', 'display:none');
  99 + }
  100 + }
  101 +
  102 + // file selection
  103 + function FileSelectHandler(e) {
  104 + var files = e.target.files || e.dataTransfer.files,
  105 + parent = $(e.target.offsetParent);
  106 +
  107 + // process all File objects
  108 + for (var i = 0, f; f = files[i]; i++) {
  109 + parent.find('.filedrag').html(f.name);
  110 + }
  111 + }
  112 +</script>
0 113 \ No newline at end of file
... ...
pdf_file/urls.py
... ... @@ -4,10 +4,10 @@ from django.contrib.auth import views as auth_views
4 4 from . import views
5 5  
6 6 urlpatterns = [
7   - url(r'^create/(?P<slug>[\w_-]+)/$', views.PDFFileCreateView.as_view(), name='create'),
8   - url(r'^update/(?P<topic_slug>[\w_-]+)/(?P<slug>[\w_-]+)/$', views.UpdateView.as_view(), name = 'update'),
9   - url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteView.as_view(), name = 'delete'),
10   - url(r'^view/(?P<slug>[\w_-]+)/$', views.ViewPDFFile.as_view(), name = 'view'),
11   - url(r'^chart/(?P<slug>[\w_-]+)/$', views.StatisticsView.as_view(), name = 'get_chart'),
12   - url(r'^send-message/(?P<slug>[\w_-]+)/$', views.sendMessage, name = 'send_message'),
  7 + url(r'^create/(?P<slug>[\w_-]+)/$', views.PDFFileCreateView.as_view(), name='create'),
  8 + url(r'^update/(?P<topic_slug>[\w_-]+)/(?P<slug>[\w_-]+)/$', views.UpdateView.as_view(), name = 'update'),
  9 + url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteView.as_view(), name = 'delete'),
  10 + url(r'^view/(?P<slug>[\w_-]+)/$', views.ViewPDFFile.as_view(), name = 'view'),
  11 + url(r'^chart/(?P<slug>[\w_-]+)/$', views.StatisticsView.as_view(), name = 'get_chart'),
  12 + url(r'^send-message/(?P<slug>[\w_-]+)/$', views.SendMessage.as_view(), name = 'send_message'),
13 13 ]
... ...
pdf_file/views.py
... ... @@ -19,6 +19,10 @@ from topics.models import Topic, Resource
19 19 from .models import PDFFile
20 20 from pendencies.forms import PendenciesForm
21 21  
  22 +from chat.models import Conversation, TalkMessages
  23 +from users.models import User
  24 +from subjects.models import Subject
  25 +from webpage.forms import FormModalMessage
22 26  
23 27  
24 28 class ViewPDFFile(LoginRequiredMixin, LogMixin, generic.TemplateView):
... ... @@ -154,9 +158,6 @@ class PDFFileCreateView(LoginRequiredMixin, LogMixin , generic.CreateView):
154 158 if not self.object.topic.visible and not self.object.topic.repository:
155 159 self.object.visible = False
156 160  
157   - if form.cleaned_data["all_students"]:
158   - self.object.students.add(*self.object.topic.subject.students.all())
159   -
160 161 self.object.save()
161 162  
162 163 pend_form = pendencies_form.save(commit = False)
... ... @@ -412,6 +413,8 @@ class StatisticsView(LoginRequiredMixin, LogMixin, generic.DetailView):
412 413 context["init_date"] = start_date
413 414 context["end_date"] = end_date
414 415 alunos = pdf_file.students.all()
  416 + if pdf_file.all_students :
  417 + alunos = pdf_file.topic.subject.students.all()
415 418  
416 419 vis_ou = Log.objects.filter(context__contains={'pdffile_id':pdf_file.id},resource="pdffile",action="view",user_email__in=(aluno.email for aluno in alunos), datetime__range=(start_date,end_date + datetime.timedelta(minutes = 1)))
417 420 did,n_did,history = str(_("Realized")),str(_("Unrealized")),str(_("Historic"))
... ... @@ -441,32 +444,56 @@ class StatisticsView(LoginRequiredMixin, LogMixin, generic.DetailView):
441 444 context["json_n_did"] = json_n_did
442 445 context["json_history"] = json_history
443 446 c_visualizou = vis_ou.distinct("user_email").count()
  447 + column_view = str(_('View'))
444 448 re.append([str(_('PDF File')),did,n_did])
445   - re.append([str(_('View')),c_visualizou, alunos.count() - c_visualizou])
  449 + re.append([column_view,c_visualizou, alunos.count() - c_visualizou])
446 450 context['topic'] = pdf_file.topic
447 451 context['subject'] = pdf_file.topic.subject
448 452 context['db_data'] = re
449 453 context['title_chart'] = _('Actions about resource')
450 454 context['title_vAxis'] = _('Quantity')
451   -
  455 + context['view'] = column_view
452 456 context["n_did_table"] = n_did
453 457 context["did_table"] = did
454 458 context["history_table"] = history
455 459 return context
456 460  
  461 +class SendMessage(LoginRequiredMixin, LogMixin, generic.edit.FormView):
  462 + log_component = 'resources'
  463 + log_action = 'send'
  464 + log_resource = 'pdffile'
  465 + log_context = {}
  466 +
  467 + login_url = reverse_lazy("users:login")
  468 + redirect_field_name = 'next'
  469 +
  470 + template_name = 'pdf_file/send_message.html'
  471 + form_class = FormModalMessage
  472 +
  473 + def dispatch(self, request, *args, **kwargs):
  474 + slug = self.kwargs.get('slug', '')
  475 + pdf_file = get_object_or_404(PDFFile, slug = slug)
  476 + self.pdf_file = pdf_file
  477 +
  478 + if not has_subject_permissions(request.user, pdf_file.topic.subject):
  479 + return redirect(reverse_lazy('subjects:home'))
  480 +
  481 + return super(SendMessage, self).dispatch(request, *args, **kwargs)
  482 +
  483 + def form_valid(self, form):
  484 + message = form.cleaned_data.get('comment')
  485 + image = form.cleaned_data.get("image")
  486 + users = (self.request.POST.get('users[]','')).split(",")
  487 + user = self.request.user
  488 + subject = self.pdf_file.topic.subject
  489 + for u in users:
  490 + to_user = User.objects.get(email=u)
  491 + talk, create = Conversation.objects.get_or_create(user_one=user,user_two=to_user)
  492 + created = TalkMessages.objects.create(text=message,talk=talk,user=user,subject=subject,image=image)
  493 + return JsonResponse({"message":"ok"})
  494 +
  495 + def get_context_data(self, **kwargs):
  496 + context = super(SendMessage,self).get_context_data()
  497 + context["pdf_file"] = get_object_or_404(PDFFile, slug=self.kwargs.get('slug', ''))
  498 + return context
457 499  
458   -from chat.models import Conversation, TalkMessages
459   -from users.models import User
460   -from subjects.models import Subject
461   -def sendMessage(request, slug):
462   - message = request.GET.get('message','')
463   - users = request.GET.getlist('users[]','')
464   - user = request.user
465   - subject = get_object_or_404(Subject,slug = slug)
466   -
467   - for u in users:
468   - to_user = User.objects.get(email=u)
469   - talk, create = Conversation.objects.get_or_create(user_one=user,user_two=to_user)
470   - created = TalkMessages.objects.create(text=message,talk=talk,user=user,subject=subject)
471   -
472   - return JsonResponse({"message":"ok"})
... ...
themes/urls.py
... ... @@ -5,4 +5,5 @@ urlpatterns = [
5 5 url(r'^$', views.IndexView.as_view(), name = 'manage'),
6 6 url(r'^basic_elements$', views.BasicElementsSettings.as_view(), name = 'basic'),
7 7 url(r'^css_selector$', views.CSSStyleSettings.as_view(), name = 'css'),
  8 + url(r'^contrast$',views.Contrast, name = 'contrast'),
8 9 ]
... ...
themes/views.py
... ... @@ -5,7 +5,7 @@ from django.core.urlresolvers import reverse, reverse_lazy
5 5 from django.utils.translation import ugettext_lazy as _
6 6 from django.http import HttpResponse, JsonResponse, HttpResponseRedirect,HttpRequest
7 7 from django.shortcuts import redirect
8   -
  8 +from log.decorators import log_decorator
9 9 from braces import views as braces_mixins
10 10  
11 11 from .models import Themes
... ... @@ -79,3 +79,8 @@ class CSSStyleSettings(braces_mixins.LoginRequiredMixin, braces_mixins.Staffuser
79 79 context['settings_menu_active'] = "settings_menu_active"
80 80  
81 81 return context
  82 +
  83 +@log_decorator("contrast", "click", "contrast")
  84 +def Contrast(request):
  85 + caminho = request.META.get('HTTP_REFERER')
  86 + return HttpResponseRedirect(caminho)
... ...
topics/templates/resources/list.html
... ... @@ -29,7 +29,15 @@
29 29 </button>
30 30 <ul class="dropdown-menu pull-right" role="menu" aria-labelledby="moreResources">
31 31 <li><a href="{% url resource.update_link topic.slug resource.slug %}" class="edit"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>{% trans 'Edit' %}</a></li>
32   -
  32 + {% if resource|class_name == 'ytvideo' %}
  33 + <li><a href="{% url 'youtube:get_chart' resource.slug %}" class="edit"><i class="fa fa-line-chart fa-fw" aria-hidden="true"></i>{% trans 'Reports' %}</a></li>
  34 + {% endif %}
  35 + {% if resource|class_name == 'link' %}
  36 + <li><a href="{% url 'links:get_chart' resource.slug %}" class="edit"><i class="fa fa-line-chart fa-fw" aria-hidden="true"></i>{% trans 'Reports' %}</a></li>
  37 + {% endif %}
  38 + {% if resource|class_name == 'filelink' %}
  39 + <li><a href="{% url 'file_links:get_chart' resource.slug %}" class="edit"><i class="fa fa-line-chart fa-fw" aria-hidden="true"></i>{% trans 'Reports' %}</a></li>
  40 + {% endif %}
33 41 {% if resource|class_name == 'webpage' %}
34 42 <li><a href="{% url 'webpages:get_chart' resource.slug %}" class="edit"><i class="fa fa-line-chart fa-fw" aria-hidden="true"></i>{% trans 'Reports' %}</a></li>
35 43 {% endif %}
... ...
users/templates/users/login.html
... ... @@ -87,7 +87,7 @@
87 87 <span >[{{LANGUAGE_CODE}}] </span>
88 88  
89 89 </a>
90   - <a href="" id = "contrast_button" style="margin-left:10px;"><i class="glyphicon glyphicon-adjust"></i></a>
  90 + <a href="{% url 'themes:contrast' %}" id = "contrast_button" style="margin-left:10px;"><i class="glyphicon glyphicon-adjust"></i></a>
91 91 <ul class="dropdown-menu">
92 92  
93 93  
... ... @@ -150,11 +150,11 @@
150 150 $("#contrast_button" ).click(function() {
151 151 if (Cookies.get('contrast_check')) {
152 152 Cookies.remove('contrast_check')
153   - location.reload()
  153 + //location.reload()
154 154 }
155 155 else {
156 156 Cookies.set('contrast_check','contrast')
157   - location.reload()
  157 + //location.reload()
158 158 }
159 159  
160 160 });
... ...
webpage/forms.py
... ... @@ -7,91 +7,122 @@ from subjects.models import Tag
7 7  
8 8 from .models import Webpage
9 9  
  10 +from resubmit.widgets import ResubmitFileWidget
  11 +
10 12 class WebpageForm(forms.ModelForm):
11   - subject = None
12   -
13   - def __init__(self, *args, **kwargs):
14   - super(WebpageForm, self).__init__(*args, **kwargs)
15   -
16   - self.subject = kwargs['initial'].get('subject', None)
17   -
18   - if self.instance.id:
19   - self.subject = self.instance.topic.subject
20   - self.initial['tags'] = ", ".join(self.instance.tags.all().values_list("name", flat = True))
21   -
22   - self.fields['students'].queryset = self.subject.students.all()
23   - self.fields['groups'].queryset = self.subject.group_subject.all()
24   -
25   - tags = forms.CharField(label = _('Tags'), required = False)
26   -
27   - class Meta:
28   - model = Webpage
29   - fields = ['name', 'content', 'brief_description', 'all_students', 'students', 'groups', 'show_window', 'visible']
30   - labels = {
31   - 'name': _('Webpage name'),
32   - 'content': _('Webpage content'),
33   - }
34   - widgets = {
35   - 'content': forms.Textarea,
36   - 'brief_description': forms.Textarea,
37   - 'students': forms.SelectMultiple,
38   - 'groups': forms.SelectMultiple,
39   - }
40   -
41   - def clean_name(self):
42   - name = self.cleaned_data.get('name', '')
43   -
44   - topics = self.subject.topic_subject.all()
45   -
46   - for topic in topics:
47   - if self.instance.id:
48   - same_name = topic.resource_topic.filter(name__unaccent__iexact = name).exclude(id = self.instance.id).count()
49   - else:
50   - same_name = topic.resource_topic.filter(name__unaccent__iexact = name).count()
51   -
52   - if same_name > 0:
53   - self._errors['name'] = [_('This subject already has a webpage with this name')]
54   -
55   - return ValueError
56   -
57   - return name
58   -
59   - def clean_content(self):
60   - content = self.cleaned_data.get('content', '')
61   - cleaned_content = strip_tags(content)
62   -
63   - if cleaned_content == '':
64   - self._errors['content'] = [_('This field is required.')]
65   -
66   - return ValueError
67   -
68   - return content
69   -
70   - def save(self, commit = True):
71   - super(WebpageForm, self).save(commit = True)
72   -
73   - self.instance.save()
74   -
75   - previous_tags = self.instance.tags.all()
76   -
77   - tags = self.cleaned_data['tags'].split(",")
  13 + subject = None
  14 +
  15 + def __init__(self, *args, **kwargs):
  16 + super(WebpageForm, self).__init__(*args, **kwargs)
  17 +
  18 + self.subject = kwargs['initial'].get('subject', None)
  19 +
  20 + if self.instance.id:
  21 + self.subject = self.instance.topic.subject
  22 + self.initial['tags'] = ", ".join(self.instance.tags.all().values_list("name", flat = True))
  23 +
  24 + self.fields['students'].queryset = self.subject.students.all()
  25 + self.fields['groups'].queryset = self.subject.group_subject.all()
  26 +
  27 + tags = forms.CharField(label = _('Tags'), required = False)
  28 +
  29 + class Meta:
  30 + model = Webpage
  31 + fields = ['name', 'content', 'brief_description', 'all_students', 'students', 'groups', 'show_window', 'visible']
  32 + labels = {
  33 + 'name': _('Webpage name'),
  34 + 'content': _('Webpage content'),
  35 + }
  36 + widgets = {
  37 + 'content': forms.Textarea,
  38 + 'brief_description': forms.Textarea,
  39 + 'students': forms.SelectMultiple,
  40 + 'groups': forms.SelectMultiple,
  41 + }
  42 +
  43 + def clean_name(self):
  44 + name = self.cleaned_data.get('name', '')
  45 +
  46 + topics = self.subject.topic_subject.all()
  47 +
  48 + for topic in topics:
  49 + if self.instance.id:
  50 + same_name = topic.resource_topic.filter(name__unaccent__iexact = name).exclude(id = self.instance.id).count()
  51 + else:
  52 + same_name = topic.resource_topic.filter(name__unaccent__iexact = name).count()
  53 +
  54 + if same_name > 0:
  55 + self._errors['name'] = [_('This subject already has a webpage with this name')]
  56 +
  57 + return ValueError
  58 +
  59 + return name
  60 +
  61 + def clean_content(self):
  62 + content = self.cleaned_data.get('content', '')
  63 + cleaned_content = strip_tags(content)
  64 +
  65 + if cleaned_content == '':
  66 + self._errors['content'] = [_('This field is required.')]
  67 +
  68 + return ValueError
  69 +
  70 + return content
  71 +
  72 + def save(self, commit = True):
  73 + super(WebpageForm, self).save(commit = True)
  74 +
  75 + self.instance.save()
  76 +
  77 + previous_tags = self.instance.tags.all()
  78 +
  79 + tags = self.cleaned_data['tags'].split(",")
78 80  
79 81 #Excluding unwanted tags
80   - for prev in previous_tags:
81   - if not prev.name in tags:
82   - self.instance.tags.remove(prev)
  82 + for prev in previous_tags:
  83 + if not prev.name in tags:
  84 + self.instance.tags.remove(prev)
83 85  
84   - for tag in tags:
85   - tag = tag.strip()
  86 + for tag in tags:
  87 + tag = tag.strip()
  88 +
  89 + exist = Tag.objects.filter(name = tag).exists()
  90 +
  91 + if exist:
  92 + new_tag = Tag.objects.get(name = tag)
  93 + else:
  94 + new_tag = Tag.objects.create(name = tag)
  95 +
  96 + if not new_tag in self.instance.tags.all():
  97 + self.instance.tags.add(new_tag)
  98 +
  99 + return self.instance
  100 +
  101 +class FormModalMessage(forms.Form):
  102 + MAX_UPLOAD_SIZE = 5*1024*1024
  103 +
  104 + comment = forms.CharField(widget=forms.Textarea,label=_("Message"))
  105 + image = forms.FileField(widget=ResubmitFileWidget(attrs={'accept':'image/*'}))
  106 +
  107 + def clean_comment(self):
  108 + comment = self.cleaned_data.get('comment', '')
  109 + cleaned_comment = strip_tags(comment)
  110 +
  111 + if cleaned_comment == '':
  112 + self._errors['comment'] = [_('This field is required.')]
  113 +
  114 + return ValueError
  115 +
  116 + return comment
86 117  
87   - exist = Tag.objects.filter(name = tag).exists()
  118 + def clean_image(self):
  119 + image = self.cleaned_data.get('image', False)
88 120  
89   - if exist:
90   - new_tag = Tag.objects.get(name = tag)
91   - else:
92   - new_tag = Tag.objects.create(name = tag)
  121 + if image:
  122 + if hasattr(image, '_size'):
  123 + if image._size > self.MAX_UPLOAD_SIZE:
  124 + self._errors['image'] = [_("The image is too large. It should have less than 5MB.")]
93 125  
94   - if not new_tag in self.instance.tags.all():
95   - self.instance.tags.add(new_tag)
  126 + return ValueError
96 127  
97   - return self.instance
98 128 \ No newline at end of file
  129 + return image
99 130 \ No newline at end of file
... ...
webpage/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-04-28 20:41-0300\n"
  11 +"POT-Creation-Date: 2017-05-05 17:59-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,26 +18,35 @@ msgstr &quot;&quot;
18 18 "Content-Transfer-Encoding: 8bit\n"
19 19 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
20 20  
21   -#: forms.py:25
  21 +#: forms.py:27
22 22 msgid "Tags"
23 23 msgstr "Tags"
24 24  
25   -#: forms.py:31
  25 +#: forms.py:33
26 26 msgid "Webpage name"
27 27 msgstr "Nome da Página Web"
28 28  
29   -#: forms.py:32
  29 +#: forms.py:34
30 30 msgid "Webpage content"
31 31 msgstr "Conteúdo da Página Web"
32 32  
33   -#: forms.py:53
  33 +#: forms.py:55
34 34 msgid "This subject already has a webpage with this name"
35 35 msgstr "Esse assunto já possui uma Página Web com esse nome"
36 36  
37   -#: forms.py:64
  37 +#: forms.py:66 forms.py:112
38 38 msgid "This field is required."
39 39 msgstr "Esse campo é obrigatório."
40 40  
  41 +#: forms.py:104
  42 +#| msgid "Send message"
  43 +msgid "Message"
  44 +msgstr "Mensagem"
  45 +
  46 +#: forms.py:124
  47 +msgid "The image is too large. It should have less than 5MB."
  48 +msgstr "A imagem é muito grande. Deve ser menor do que 5MB"
  49 +
41 50 #: models.py:8
42 51 msgid "Webpage Content"
43 52 msgstr "Conteúdo da Página Web"
... ... @@ -82,59 +91,86 @@ msgstr &quot;Atribuir grupos de estudo à Página Web&quot;
82 91 msgid "Save"
83 92 msgstr "Salvar"
84 93  
85   -#: templates/webpages/create.html:20 views.py:221
  94 +#: templates/webpages/create.html:20 views.py:227
86 95 msgid "Create Webpage"
87 96 msgstr "Criar Página Web"
88 97  
89   -#: templates/webpages/relatorios.html:16 templates/webpages/relatorios.html:30
90   -#: templates/webpages/relatorios.html:37
  98 +#: templates/webpages/relatorios.html:17 templates/webpages/relatorios.html:37
91 99 msgid "User"
92 100 msgstr "Usuário"
93 101  
94   -#: templates/webpages/relatorios.html:16 templates/webpages/relatorios.html:30
95   -#: templates/webpages/relatorios.html:37
  102 +#: templates/webpages/relatorios.html:17 templates/webpages/relatorios.html:37
96 103 msgid "Group"
97 104 msgstr "Grupo"
98 105  
99   -#: templates/webpages/relatorios.html:16 templates/webpages/relatorios.html:30
  106 +#: templates/webpages/relatorios.html:17
100 107 msgid "Action"
101 108 msgstr "Ação"
102 109  
103   -#: templates/webpages/relatorios.html:16 templates/webpages/relatorios.html:30
  110 +#: templates/webpages/relatorios.html:17
104 111 msgid "Date of Action"
105 112 msgstr "Data da ação"
106 113  
107   -#: templates/webpages/relatorios.html:135
108   -#: templates/webpages/relatorios.html:155
  114 +#: templates/webpages/relatorios.html:37
  115 +msgid "Send message"
  116 +msgstr "Enviar Mensagem"
  117 +
  118 +#: templates/webpages/relatorios.html:37
  119 +msgid "Action don't realized"
  120 +msgstr "Ação não realizada"
  121 +
  122 +#: templates/webpages/relatorios.html:151
  123 +#: templates/webpages/relatorios.html:171
109 124 msgid "Reports"
110 125 msgstr "Relatórios"
111 126  
112   -#: templates/webpages/relatorios.html:162
  127 +#: templates/webpages/relatorios.html:178
113 128 msgid "Report of the resource "
114 129 msgstr "Relatórios do recurso "
115 130  
116   -#: templates/webpages/relatorios.html:165
  131 +#: templates/webpages/relatorios.html:187
117 132 msgid "Select the period: "
118 133 msgstr "Selecione o período: "
119 134  
120   -#: templates/webpages/relatorios.html:179
  135 +#: templates/webpages/relatorios.html:196
121 136 msgid "Search"
122 137 msgstr "Pesquisar"
123 138  
124   -#: templates/webpages/relatorios.html:201
  139 +#: templates/webpages/relatorios.html:220
125 140 msgid "Filter: "
126 141 msgstr "Filtro: "
127 142  
  143 +#: templates/webpages/relatorios.html:244
  144 +#: templates/webpages/relatorios.html:329
  145 +msgid "record(s)"
  146 +msgstr "Relatório(s)"
  147 +
  148 +#: templates/webpages/send_message.html:38
  149 +msgid "Click or drop the picture here"
  150 +msgstr "Clique ou solte a imagem aqui"
  151 +
  152 +#: templates/webpages/send_message.html:40
  153 +msgid "The picture could not exceed 5MB."
  154 +msgstr "A imagem não pode exceder 5MB."
  155 +
  156 +#: templates/webpages/send_message.html:62
  157 +msgid "Close"
  158 +msgstr "Fechar"
  159 +
  160 +#: templates/webpages/send_message.html:63
  161 +msgid "Send"
  162 +msgstr "Enviar"
  163 +
128 164 #: templates/webpages/update.html:20
129 165 msgid "Edit: "
130 166 msgstr "Editar: "
131 167  
132   -#: views.py:148 views.py:161 views.py:279 views.py:281 views.py:297
133   -#: views.py:299
  168 +#: views.py:155 views.py:168 views.py:285 views.py:287 views.py:303
  169 +#: views.py:305
134 170 msgid "Visualize"
135 171 msgstr "Visualizar"
136 172  
137   -#: views.py:232
  173 +#: views.py:238
138 174 #, python-format
139 175 msgid ""
140 176 "The Webpage \"%s\" was added to the Topic \"%s\" of the virtual environment "
... ... @@ -143,50 +179,59 @@ msgstr &quot;&quot;
143 179 "A Página Web \"%s\" foi adicionado ao tópico \"%s\" do ambiente virtual \"%s"
144 180 "\" com sucesso!"
145 181  
146   -#: views.py:343
  182 +#: views.py:349
147 183 msgid "Update Webpage"
148 184 msgstr "Atualizar Página Web"
149 185  
150   -#: views.py:354
  186 +#: views.py:360
151 187 #, python-format
152 188 msgid "The Webpage \"%s\" was updated successfully!"
153 189 msgstr "A Página Web \"%s\" foi atualizada com sucesso!"
154 190  
155   -#: views.py:390
  191 +#: views.py:396
156 192 #, python-format
157 193 msgid ""
158 194 "The webpage \"%s\" was removed successfully from virtual environment \"%s\"!"
159 195 msgstr ""
160 196 "A Página Web \"%s\" foi removida do ambiente virtual \"%s\" com sucesso!"
161 197  
162   -#: views.py:460
  198 +#: views.py:455
163 199 msgid "Webpage Reports"
164   -msgstr "Nome da Página Web"
  200 +msgstr "Relatórios da Webpage"
165 201  
166   -#: views.py:478
167   -msgid "Users who viewed"
168   -msgstr "Usuários que visualizaram"
  202 +#: views.py:474
  203 +msgid "Realized"
  204 +msgstr "Realizado"
169 205  
170   -#: views.py:478
171   -msgid "Users who did not viewed"
172   -msgstr "Usuários que não visualizaram"
  206 +#: views.py:474
  207 +msgid "Unrealized"
  208 +msgstr "Não Realizado"
173 209  
174   -#: views.py:478
  210 +#: views.py:474
175 211 msgid "Historic"
176 212 msgstr "Histórico"
177 213  
178   -#: views.py:515
179   -msgid "Webpage"
180   -msgstr "Nome da Página Web"
181   -
182   -#: views.py:516
  214 +#: views.py:492 views.py:501
183 215 msgid "View"
184 216 msgstr "Visualizar"
185 217  
186   -#: views.py:520
187   -msgid "Students viewing the webpage"
188   -msgstr "Estudantes que visualizaram a webpage"
  218 +#: views.py:500
  219 +msgid "Webpage"
  220 +msgstr "Nome da Página Web"
  221 +
  222 +#: views.py:505
  223 +msgid "Actions about resource"
  224 +msgstr "Ações sobre o recurso"
189 225  
190   -#: views.py:521
  226 +#: views.py:506
191 227 msgid "Quantity"
192 228 msgstr "Quantidade"
  229 +
  230 +#~ msgid "Users who viewed"
  231 +#~ msgstr "Usuários que visualizaram"
  232 +
  233 +#~ msgid "Users who did not viewed"
  234 +#~ msgstr "Usuários que não visualizaram"
  235 +
  236 +#~ msgid "Students viewing the webpage"
  237 +#~ msgstr "Estudantes que visualizaram a webpage"
... ...
webpage/templates/webpages/relatorios.html
... ... @@ -9,10 +9,9 @@
9 9 <script type="text/javascript">
10 10 var tabela_atual = true;
11 11  
12   -
13 12 var array_history = [];
14   - {%for data_json in json_history.data%}
15   - array_history.push(["{{data_json.0}}","{{data_json.1}}","{{data_json.2}}",{% if data_json.3 is not None %}new Date('{{data_json.3.isoformat}}'){% else%}null{% endif %}]);
  13 + {%for data_json in json_history.data %}
  14 + array_history.push(["{{data_json.0}}","{{data_json.1}}","{{view}}",{% if data_json.3 is not None %}new Date('{{data_json.3.isoformat}}'){% else%}null{% endif %}]);
16 15 {% endfor%}
17 16 var json_history = {"data":array_history};
18 17 var column_history = [{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":'{% trans "Action" %}'},{"date":'{% trans "Date of Action" %}'}];
... ... @@ -35,7 +34,7 @@
35 34 array_n_did.push([input,"{{data_json.1}}","{{data_json.2}}","{{data_json.3}}"]);
36 35 {% endfor%}
37 36 var json_n_did = {"data":array_n_did};
38   - var column_n_did = [{"string":'<a href="javascript:void(0);" onclick="return openmodal();"> {% trans "Send message" %}</a>'},{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":"Action don't realized"}];
  37 + var column_n_did = [{"string":'<a href="javascript:void(0);" onclick="return openmodal();"> {% trans "Send message" %}</a>'},{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":"{% trans "Action don't realized" %}"}];
39 38 </script>
40 39  
41 40  
... ... @@ -75,6 +74,7 @@
75 74 json_n_did["data"][i][2],json_n_did["data"][i][3]]);
76 75 }
77 76 searcher(col, tabela_atual,true);
  77 +
78 78 } else if (col == "{{did_table}}"){
79 79 tabela_atual = true;
80 80 search = [];
... ... @@ -93,6 +93,7 @@
93 93 chart.draw(data, options);
94 94  
95 95 }
  96 +
96 97 var sortAscending = {0:false,1:false,2:false,3:false};
97 98 function drawTable(columns = column_history,rows = pagination(json_history["data"],1),isdate = true,columndate = 3) {
98 99 var data_table = new google.visualization.DataTable();
... ... @@ -198,6 +199,7 @@
198 199 <ul>
199 200 </div>
200 201 </div>
  202 +
201 203 <div class="row">
202 204 <div class="col-md-10 col-md-offset-1">
203 205 <div id="chart_div" style="height: 500px; margin-top: -50px;"></div>
... ... @@ -231,44 +233,14 @@
231 233 </div>
232 234 </div>
233 235 </div>
234   -
235   - <!-- Modal (remember to change the ids!!!) -->
236   - <div class="modal fade" id="send-message-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
237   - <div class="modal-dialog" role="document">
238   - <div class="modal-content">
239   - <!-- Modal Body -->
240   - <div class="modal-body">
241   - <!-- Put ONLY your content here!!! -->
242   - <h3>{% trans "Message: " %}</h3>
243   - <form id="text_chat_form" action="" method="GET">
244   - <textarea id="message" name="message" rows="5" cols="80"></textarea>
245   - </form>
246   - </div>
247   - <!-- Modal Footer -->
248   - <div id="delete-category-footer"class="modal-footer">
249   - <!-- Don't remove that!!! -->
250   - <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
251   - <a href="javascript:void(0)" onclick="return sendMessage()" form="text_chat_form" class="btn btn-success btn-raised erase-button">{% trans "Send" %}</a>
252   - </div>
253   - </div>
254   - </div>
255   - </div>
  236 + <div id="modal-message"></div>
256 237 <div class="row">
257 238 <br><br>
258 239 </div>
259 240 </div>
260 241  
261 242 <script type="text/javascript">
262   - $('#message').summernote({
263   - dialogsInBody: true,
264   - disableDragAndDrop: true,
265   - height: 150,
266   - toolbar: [
267   - // [groupName, [list of button]]
268   - ['style', ['bold', 'italic']],
269   - ['insert', ['link']]
270   - ]
271   - });
  243 +
272 244 $("#title-table").text(search.length + " {% trans 'record(s)' %}");
273 245 function putpagination(data = json_history["data"], load_histoty = true){
274 246 var len = Math.ceil(data.length / 20);
... ... @@ -385,6 +357,15 @@
385 357 $(".active").removeClass("active");
386 358 $("#" + pag).addClass("active");
387 359 }
  360 +
  361 + function openmodal(){
  362 + $( "#modal-message" ).empty();
  363 + $.get( "{% url 'webpages:send_message' webpage.slug %}", function( data ) {
  364 + $( "#modal-message" ).append( data );
  365 + $("#send-message-modal").modal("show");
  366 + });
  367 + }
  368 +
388 369 function sendMessage(){
389 370 $("#send-message-modal").modal("hide");
390 371 var checked = $("#google-chart-checkbox").serializeArray();
... ... @@ -392,19 +373,36 @@
392 373 for (var i in checked){
393 374 email.push(checkbox[checked[i]["name"]]);
394 375 }
395   - var message = $("#text_chat_form").serializeArray()[0]["value"];
  376 + $('<input />').attr('type', 'hidden')
  377 + .attr('name', "users[]")
  378 + .attr('value', email)
  379 + .appendTo('#text_chat_form');
  380 +
  381 + var formData = new FormData($('#text_chat_form').get(0));
396 382 $.ajax({
397   - type: "GET",
398   - data: {"message":message,"users[]":email},
399   - url: "{% url 'webpages:send_message' subject.slug %}",
400   - success: function(msg){
401   - console.log(msg);
402   - $('#message').summernote("reset");
403   - }
404   - });
405   - }
406   - function openmodal(){
407   - $("#send-message-modal").modal("show");
  383 + url: "{% url 'webpages:send_message' webpage.slug %}",
  384 + type: "POST",
  385 + data: formData,
  386 + cache: false,
  387 + processData: false,
  388 + contentType: false,
  389 + success: function(data) {
  390 + if (data["message"]){
  391 + console.log("success");
  392 + $("body").removeClass("modal-open");
  393 + $( "#modal-message" ).empty();
  394 + $(".modal-backdrop.fade.in").remove();
  395 + } else {
  396 + $( "#modal-message" ).empty();
  397 + $(".modal-backdrop.fade.in").remove();
  398 + $( "#modal-message" ).append( data );
  399 + $("#send-message-modal").modal("show");
  400 + }
  401 + },
  402 + error: function(data){
  403 + console.log("erro");
  404 + }
  405 + });
408 406 }
409 407 </script>
410 408 {% endblock %}
... ...
webpage/templates/webpages/send_message.html 0 → 100644
... ... @@ -0,0 +1,112 @@
  1 +
  2 + {% load widget_tweaks i18n %}
  3 + <!-- Modal (remember to change the ids!!!) -->
  4 +<div class="modal fade" id="send-message-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  5 + <div class="modal-dialog" role="document">
  6 + <div class="modal-content">
  7 + <!-- Modal Body -->
  8 + <div class="modal-body">
  9 + <form id="text_chat_form" action="" method="POST" enctype="multipart/form-data">
  10 + {% csrf_token %}
  11 + {% comment %}Area para o Texto{% endcomment %}
  12 + <div class="form-group{% if form.has_error %} has-error {% endif %}">
  13 + <label for="{{ form.comment.auto_id }}">{{ form.comment.label }}: <span>*</span></label>
  14 + {% render_field form.comment class='form-control text_simple_wysiwyg' %}
  15 +
  16 + <span id="helpBlock" class="help-block">{{ form.comment.help_text }}</span>
  17 +
  18 + {% if form.comment.errors %}
  19 + <div class="alert alert-danger alert-dismissible" role="alert">
  20 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  21 + <span aria-hidden="true">&times;</span>
  22 + </button>
  23 + <ul>
  24 + {% for error in form.comment.errors %}
  25 + <li>{{ error }}</li>
  26 + {% endfor %}
  27 + </ul>
  28 + </div>
  29 + {% endif %}
  30 + </div>
  31 + {% comment %}Area para anexar a imagem {% endcomment %}
  32 + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">
  33 + {% render_field form.image %}
  34 +
  35 + <div class="filedrag">
  36 + {% trans 'Click or drop the picture here' %}<br />
  37 +
  38 + <small>{% trans 'The picture could not exceed 5MB.' %}</small>
  39 + </div>
  40 +
  41 + {% if form.image.errors %}
  42 + <div class="alert alert-danger alert-dismissible" role="alert">
  43 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  44 + <span aria-hidden="true">&times;</span>
  45 + </button>
  46 + <ul>
  47 + {% for error in form.image.errors %}
  48 + <li>{{ error }}</li>
  49 + {% endfor %}
  50 + </ul>
  51 + </div>
  52 + {% endif %}
  53 +
  54 + </div>
  55 + </form>
  56 + </div>
  57 + <!-- Modal Footer -->
  58 + <div id="delete-category-footer"class="modal-footer">
  59 + <!-- Don't remove that!!! -->
  60 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
  61 + <a href="javascript:void(0)" onclick="return sendMessage()" form="text_chat_form" class="btn btn-success btn-raised erase-button">{% trans "Send" %}</a>
  62 + </div>
  63 + </div>
  64 + </div>
  65 +</div>
  66 +
  67 +<script type="text/javascript">
  68 +
  69 + $('.text_simple_wysiwyg').summernote({
  70 + dialogsInBody: true,
  71 + disableDragAndDrop: true,
  72 + height: 150,
  73 + toolbar: [
  74 + // [groupName, [list of button]]
  75 + ['style', ['bold', 'italic']],
  76 + ['insert', ['link']]
  77 + ]
  78 + });
  79 +
  80 + if (window.File && window.FileList && window.FileReader) {
  81 + Init();
  82 + }
  83 +
  84 + function Init() {
  85 + var small = $("#id_image"),
  86 + filedrag = $(".filedrag"),
  87 + common = $(".common-file-input");
  88 +
  89 + // file select
  90 + small.on("change", FileSelectHandler);
  91 +
  92 + // is XHR2 available?
  93 + var xhr = new XMLHttpRequest();
  94 + if (xhr.upload) {
  95 + // file drop
  96 + filedrag.on("drop", FileSelectHandler);
  97 + filedrag.attr('style', 'display:block');
  98 + common.attr('style', 'display:none');
  99 + }
  100 + }
  101 +
  102 + // file selection
  103 + function FileSelectHandler(e) {
  104 + var files = e.target.files || e.dataTransfer.files,
  105 + parent = $(e.target.offsetParent);
  106 +
  107 + // process all File objects
  108 + for (var i = 0, f; f = files[i]; i++) {
  109 + parent.find('.filedrag').html(f.name);
  110 + }
  111 + }
  112 +</script>
0 113 \ No newline at end of file
... ...
webpage/urls.py
... ... @@ -10,5 +10,5 @@ urlpatterns = [
10 10 url(r'^window_view/(?P<slug>[\w_-]+)/$', views.NewWindowView.as_view(), name = 'window_view'),
11 11 url(r'^view/(?P<slug>[\w_-]+)/$', views.InsideView.as_view(), name = 'view'),
12 12 url(r'^chart/(?P<slug>[\w_-]+)/$', views.StatisticsView.as_view(), name = 'get_chart'),
13   - url(r'^send-message/(?P<slug>[\w_-]+)/$', views.sendMessage, name = 'send_message'),
  13 + url(r'^send-message/(?P<slug>[\w_-]+)/$', views.SendMessage.as_view(), name = 'send_message'),
14 14 ]
... ...
webpage/views.py
... ... @@ -10,7 +10,6 @@ from amadeus.permissions import has_subject_permissions, has_resource_permission
10 10  
11 11 import time
12 12 import datetime
13   -from log.models import Log
14 13 from log.mixins import LogMixin
15 14  
16 15 from topics.models import Topic
... ... @@ -20,100 +19,108 @@ from pendencies.forms import PendenciesForm
20 19 from .forms import WebpageForm
21 20 from .models import Webpage
22 21  
  22 +from log.models import Log
  23 +from chat.models import Conversation, TalkMessages
  24 +from users.models import User
  25 +from subjects.models import Subject
  26 +
  27 +from .forms import FormModalMessage
  28 +
23 29 class NewWindowView(LoginRequiredMixin, LogMixin, generic.DetailView):
24   - log_component = 'resources'
25   - log_action = 'view'
26   - log_resource = 'webpage'
27   - log_context = {}
  30 + log_component = 'resources'
  31 + log_action = 'view'
  32 + log_resource = 'webpage'
  33 + log_context = {}
28 34  
29   - login_url = reverse_lazy("users:login")
30   - redirect_field_name = 'next'
  35 + login_url = reverse_lazy("users:login")
  36 + redirect_field_name = 'next'
31 37  
32   - template_name = 'webpages/window_view.html'
33   - model = Webpage
34   - context_object_name = 'webpage'
  38 + template_name = 'webpages/window_view.html'
  39 + model = Webpage
  40 + context_object_name = 'webpage'
35 41  
36   - def dispatch(self, request, *args, **kwargs):
37   - slug = self.kwargs.get('slug', '')
38   - webpage = get_object_or_404(Webpage, slug = slug)
  42 + def dispatch(self, request, *args, **kwargs):
  43 + slug = self.kwargs.get('slug', '')
  44 + webpage = get_object_or_404(Webpage, slug=slug)
39 45  
40   - if not has_resource_permissions(request.user, webpage):
41   - return redirect(reverse_lazy('subjects:home'))
  46 + if not has_resource_permissions(request.user, webpage):
  47 + return redirect(reverse_lazy('subjects:home'))
42 48  
43   - return super(NewWindowView, self).dispatch(request, *args, **kwargs)
  49 + return super(NewWindowView, self).dispatch(request, *args, **kwargs)
44 50  
45   - def get_context_data(self, **kwargs):
46   - context = super(NewWindowView, self).get_context_data(**kwargs)
  51 + def get_context_data(self, **kwargs):
  52 + context = super(NewWindowView, self).get_context_data(**kwargs)
47 53  
48   - self.log_context['category_id'] = self.object.topic.subject.category.id
49   - self.log_context['category_name'] = self.object.topic.subject.category.name
50   - self.log_context['category_slug'] = self.object.topic.subject.category.slug
51   - self.log_context['subject_id'] = self.object.topic.subject.id
52   - self.log_context['subject_name'] = self.object.topic.subject.name
53   - self.log_context['subject_slug'] = self.object.topic.subject.slug
54   - self.log_context['topic_id'] = self.object.topic.id
55   - self.log_context['topic_name'] = self.object.topic.name
56   - self.log_context['topic_slug'] = self.object.topic.slug
57   - self.log_context['webpage_id'] = self.object.id
58   - self.log_context['webpage_name'] = self.object.name
59   - self.log_context['webpage_slug'] = self.object.slug
60   - self.log_context['timestamp_start'] = str(int(time.time()))
  54 + self.log_context['category_id'] = self.object.topic.subject.category.id
  55 + self.log_context['category_name'] = self.object.topic.subject.category.name
  56 + self.log_context['category_slug'] = self.object.topic.subject.category.slug
  57 + self.log_context['subject_id'] = self.object.topic.subject.id
  58 + self.log_context['subject_name'] = self.object.topic.subject.name
  59 + self.log_context['subject_slug'] = self.object.topic.subject.slug
  60 + self.log_context['topic_id'] = self.object.topic.id
  61 + self.log_context['topic_name'] = self.object.topic.name
  62 + self.log_context['topic_slug'] = self.object.topic.slug
  63 + self.log_context['webpage_id'] = self.object.id
  64 + self.log_context['webpage_name'] = self.object.name
  65 + self.log_context['webpage_slug'] = self.object.slug
  66 + self.log_context['timestamp_start'] = str(int(time.time()))
61 67  
62   - super(NewWindowView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  68 + super(NewWindowView, self).createLog(self.request.user, self.log_component, self.log_action,
  69 + self.log_resource, self.log_context)
63 70  
64   - self.request.session['log_id'] = Log.objects.latest('id').id
  71 + self.request.session['log_id'] = Log.objects.latest('id').id
65 72  
66   - return context
  73 + return context
67 74  
68 75 class InsideView(LoginRequiredMixin, LogMixin, generic.DetailView):
69   - log_component = 'resources'
70   - log_action = 'view'
71   - log_resource = 'webpage'
72   - log_context = {}
  76 + log_component = 'resources'
  77 + log_action = 'view'
  78 + log_resource = 'webpage'
  79 + log_context = {}
73 80  
74   - login_url = reverse_lazy("users:login")
75   - redirect_field_name = 'next'
  81 + login_url = reverse_lazy("users:login")
  82 + redirect_field_name = 'next'
76 83  
77   - template_name = 'webpages/view.html'
78   - model = Webpage
79   - context_object_name = 'webpage'
  84 + template_name = 'webpages/view.html'
  85 + model = Webpage
  86 + context_object_name = 'webpage'
80 87  
81   - def dispatch(self, request, *args, **kwargs):
82   - slug = self.kwargs.get('slug', '')
83   - webpage = get_object_or_404(Webpage, slug = slug)
  88 + def dispatch(self, request, *args, **kwargs):
  89 + slug = self.kwargs.get('slug', '')
  90 + webpage = get_object_or_404(Webpage, slug=slug)
84 91  
85   - if not has_resource_permissions(request.user, webpage):
86   - return redirect(reverse_lazy('subjects:home'))
  92 + if not has_resource_permissions(request.user, webpage):
  93 + return redirect(reverse_lazy('subjects:home'))
87 94  
88   - return super(InsideView, self).dispatch(request, *args, **kwargs)
  95 + return super(InsideView, self).dispatch(request, *args, **kwargs)
89 96  
90   - def get_context_data(self, **kwargs):
91   - context = super(InsideView, self).get_context_data(**kwargs)
  97 + def get_context_data(self, **kwargs):
  98 + context = super(InsideView, self).get_context_data(**kwargs)
92 99  
93   - context['title'] = self.object.name
  100 + context['title'] = self.object.name
94 101  
95   - context['topic'] = self.object.topic
96   - context['subject'] = self.object.topic.subject
  102 + context['topic'] = self.object.topic
  103 + context['subject'] = self.object.topic.subject
97 104  
98   - self.log_context['category_id'] = self.object.topic.subject.category.id
99   - self.log_context['category_name'] = self.object.topic.subject.category.name
100   - self.log_context['category_slug'] = self.object.topic.subject.category.slug
101   - self.log_context['subject_id'] = self.object.topic.subject.id
102   - self.log_context['subject_name'] = self.object.topic.subject.name
103   - self.log_context['subject_slug'] = self.object.topic.subject.slug
104   - self.log_context['topic_id'] = self.object.topic.id
105   - self.log_context['topic_name'] = self.object.topic.name
106   - self.log_context['topic_slug'] = self.object.topic.slug
107   - self.log_context['webpage_id'] = self.object.id
108   - self.log_context['webpage_name'] = self.object.name
109   - self.log_context['webpage_slug'] = self.object.slug
110   - self.log_context['timestamp_start'] = str(int(time.time()))
  105 + self.log_context['category_id'] = self.object.topic.subject.category.id
  106 + self.log_context['category_name'] = self.object.topic.subject.category.name
  107 + self.log_context['category_slug'] = self.object.topic.subject.category.slug
  108 + self.log_context['subject_id'] = self.object.topic.subject.id
  109 + self.log_context['subject_name'] = self.object.topic.subject.name
  110 + self.log_context['subject_slug'] = self.object.topic.subject.slug
  111 + self.log_context['topic_id'] = self.object.topic.id
  112 + self.log_context['topic_name'] = self.object.topic.name
  113 + self.log_context['topic_slug'] = self.object.topic.slug
  114 + self.log_context['webpage_id'] = self.object.id
  115 + self.log_context['webpage_name'] = self.object.name
  116 + self.log_context['webpage_slug'] = self.object.slug
  117 + self.log_context['timestamp_start'] = str(int(time.time()))
111 118  
112   - super(InsideView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  119 + super(InsideView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
113 120  
114   - self.request.session['log_id'] = Log.objects.latest('id').id
  121 + self.request.session['log_id'] = Log.objects.latest('id').id
115 122  
116   - return context
  123 + return context
117 124  
118 125 class CreateView(LoginRequiredMixin, LogMixin, generic.edit.CreateView):
119 126 log_component = 'resources'
... ... @@ -128,55 +135,55 @@ class CreateView(LoginRequiredMixin, LogMixin, generic.edit.CreateView):
128 135 form_class = WebpageForm
129 136  
130 137 def dispatch(self, request, *args, **kwargs):
131   - slug = self.kwargs.get('slug', '')
132   - topic = get_object_or_404(Topic, slug = slug)
133   -
134   - if not has_subject_permissions(request.user, topic.subject):
135   - return redirect(reverse_lazy('subjects:home'))
  138 + slug = self.kwargs.get('slug', '')
  139 + topic = get_object_or_404(Topic, slug = slug)
  140 +
  141 + if not has_subject_permissions(request.user, topic.subject):
  142 + return redirect(reverse_lazy('subjects:home'))
136 143  
137   - return super(CreateView, self).dispatch(request, *args, **kwargs)
  144 + return super(CreateView, self).dispatch(request, *args, **kwargs)
138 145  
139 146 def get(self, request, *args, **kwargs):
140   - self.object = None
  147 + self.object = None
141 148  
142   - form_class = self.get_form_class()
143   - form = self.get_form(form_class)
  149 + form_class = self.get_form_class()
  150 + form = self.get_form(form_class)
144 151  
145   - slug = self.kwargs.get('slug', '')
146   - topic = get_object_or_404(Topic, slug = slug)
  152 + slug = self.kwargs.get('slug', '')
  153 + topic = get_object_or_404(Topic, slug = slug)
147 154  
148   - pendencies_form = PendenciesForm(initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
  155 + pendencies_form = PendenciesForm(initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
149 156  
150   - return self.render_to_response(self.get_context_data(form = form, pendencies_form = pendencies_form))
  157 + return self.render_to_response(self.get_context_data(form = form, pendencies_form = pendencies_form))
151 158  
152 159 def post(self, request, *args, **kwargs):
153   - self.object = None
  160 + self.object = None
154 161  
155   - form_class = self.get_form_class()
156   - form = self.get_form(form_class)
  162 + form_class = self.get_form_class()
  163 + form = self.get_form(form_class)
157 164  
158   - slug = self.kwargs.get('slug', '')
159   - topic = get_object_or_404(Topic, slug = slug)
  165 + slug = self.kwargs.get('slug', '')
  166 + topic = get_object_or_404(Topic, slug = slug)
160 167  
161   - pendencies_form = PendenciesForm(self.request.POST, initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
  168 + pendencies_form = PendenciesForm(self.request.POST, initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
162 169  
163   - if (form.is_valid() and pendencies_form.is_valid()):
164   - return self.form_valid(form, pendencies_form)
165   - else:
166   - return self.form_invalid(form, pendencies_form)
  170 + if (form.is_valid() and pendencies_form.is_valid()):
  171 + return self.form_valid(form, pendencies_form)
  172 + else:
  173 + return self.form_invalid(form, pendencies_form)
167 174  
168 175 def get_initial(self):
169   - initial = super(CreateView, self).get_initial()
  176 + initial = super(CreateView, self).get_initial()
170 177  
171   - slug = self.kwargs.get('slug', '')
  178 + slug = self.kwargs.get('slug', '')
172 179  
173   - topic = get_object_or_404(Topic, slug = slug)
174   - initial['subject'] = topic.subject
  180 + topic = get_object_or_404(Topic, slug = slug)
  181 + initial['subject'] = topic.subject
175 182  
176   - return initial
  183 + return initial
177 184  
178 185 def form_invalid(self, form, pendencies_form):
179   - return self.render_to_response(self.get_context_data(form = form, pendencies_form = pendencies_form))
  186 + return self.render_to_response(self.get_context_data(form = form, pendencies_form = pendencies_form))
180 187  
181 188 def form_valid(self, form, pendencies_form):
182 189 self.object = form.save(commit = False)
... ... @@ -187,18 +194,15 @@ class CreateView(LoginRequiredMixin, LogMixin, generic.edit.CreateView):
187 194 self.object.order = topic.resource_topic.count() + 1
188 195  
189 196 if not self.object.topic.visible and not self.object.topic.repository:
190   - self.object.visible = False
  197 + self.object.visible = False
191 198  
192   -
193   - if form.cleaned_data["all_students"]:
194   - self.object.students.add(*self.object.topic.subject.students.all())
195 199 self.object.save()
196 200  
197 201 pend_form = pendencies_form.save(commit = False)
198 202 pend_form.resource = self.object
199 203  
200 204 if not pend_form.action == "":
201   - pend_form.save()
  205 + pend_form.save()
202 206  
203 207 self.log_context['category_id'] = self.object.topic.subject.category.id
204 208 self.log_context['category_name'] = self.object.topic.subject.category.name
... ... @@ -218,153 +222,153 @@ class CreateView(LoginRequiredMixin, LogMixin, generic.edit.CreateView):
218 222 return redirect(self.get_success_url())
219 223  
220 224 def get_context_data(self, **kwargs):
221   - context = super(CreateView, self).get_context_data(**kwargs)
  225 + context = super(CreateView, self).get_context_data(**kwargs)
222 226  
223   - context['title'] = _('Create Webpage')
  227 + context['title'] = _('Create Webpage')
224 228  
225   - slug = self.kwargs.get('slug', '')
226   - topic = get_object_or_404(Topic, slug = slug)
  229 + slug = self.kwargs.get('slug', '')
  230 + topic = get_object_or_404(Topic, slug = slug)
227 231  
228   - context['topic'] = topic
229   - context['subject'] = topic.subject
  232 + context['topic'] = topic
  233 + context['subject'] = topic.subject
230 234  
231   - return context
  235 + return context
232 236  
233 237 def get_success_url(self):
234   - messages.success(self.request, _('The Webpage "%s" was added to the Topic "%s" of the virtual environment "%s" successfully!')%(self.object.name, self.object.topic.name, self.object.topic.subject.name))
  238 + messages.success(self.request, _('The Webpage "%s" was added to the Topic "%s" of the virtual environment "%s" successfully!')%(self.object.name, self.object.topic.name, self.object.topic.subject.name))
235 239  
236   - success_url = reverse_lazy('webpages:view', kwargs = {'slug': self.object.slug})
  240 + success_url = reverse_lazy('webpages:view', kwargs = {'slug': self.object.slug})
237 241  
238   - if self.object.show_window:
239   - self.request.session['resources'] = {}
240   - self.request.session['resources']['new_page'] = True
241   - self.request.session['resources']['new_page_url'] = reverse('webpages:window_view', kwargs = {'slug': self.object.slug})
  242 + if self.object.show_window:
  243 + self.request.session['resources'] = {}
  244 + self.request.session['resources']['new_page'] = True
  245 + self.request.session['resources']['new_page_url'] = reverse('webpages:window_view', kwargs = {'slug': self.object.slug})
242 246  
243   - success_url = reverse_lazy('subjects:view', kwargs = {'slug': self.object.topic.subject.slug})
  247 + success_url = reverse_lazy('subjects:view', kwargs = {'slug': self.object.topic.subject.slug})
244 248  
245   - return success_url
  249 + return success_url
246 250  
247 251 class UpdateView(LoginRequiredMixin, LogMixin, generic.UpdateView):
248   - log_component = 'resources'
249   - log_action = 'update'
250   - log_resource = 'webpage'
251   - log_context = {}
  252 + log_component = 'resources'
  253 + log_action = 'update'
  254 + log_resource = 'webpage'
  255 + log_context = {}
252 256  
253   - login_url = reverse_lazy("users:login")
254   - redirect_field_name = 'next'
  257 + login_url = reverse_lazy("users:login")
  258 + redirect_field_name = 'next'
255 259  
256   - template_name = 'webpages/update.html'
257   - model = Webpage
258   - form_class = WebpageForm
  260 + template_name = 'webpages/update.html'
  261 + model = Webpage
  262 + form_class = WebpageForm
259 263  
260   - def dispatch(self, request, *args, **kwargs):
261   - slug = self.kwargs.get('topic_slug', '')
262   - topic = get_object_or_404(Topic, slug = slug)
  264 + def dispatch(self, request, *args, **kwargs):
  265 + slug = self.kwargs.get('topic_slug', '')
  266 + topic = get_object_or_404(Topic, slug = slug)
263 267  
264   - if not has_subject_permissions(request.user, topic.subject):
265   - return redirect(reverse_lazy('subjects:home'))
  268 + if not has_subject_permissions(request.user, topic.subject):
  269 + return redirect(reverse_lazy('subjects:home'))
266 270  
267   - return super(UpdateView, self).dispatch(request, *args, **kwargs)
  271 + return super(UpdateView, self).dispatch(request, *args, **kwargs)
268 272  
269   - def get(self, request, *args, **kwargs):
270   - self.object = self.get_object()
  273 + def get(self, request, *args, **kwargs):
  274 + self.object = self.get_object()
271 275  
272   - form_class = self.get_form_class()
273   - form = self.get_form(form_class)
  276 + form_class = self.get_form_class()
  277 + form = self.get_form(form_class)
274 278  
275   - slug = self.kwargs.get('topic_slug', '')
276   - topic = get_object_or_404(Topic, slug = slug)
  279 + slug = self.kwargs.get('topic_slug', '')
  280 + topic = get_object_or_404(Topic, slug = slug)
277 281  
278   - pend_form = self.object.pendencies_resource.all()
  282 + pend_form = self.object.pendencies_resource.all()
279 283  
280   - if len(pend_form) > 0:
281   - pendencies_form = PendenciesForm(instance = pend_form[0], initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
282   - else:
283   - pendencies_form = PendenciesForm(initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
  284 + if len(pend_form) > 0:
  285 + pendencies_form = PendenciesForm(instance = pend_form[0], initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
  286 + else:
  287 + pendencies_form = PendenciesForm(initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
284 288  
285   - return self.render_to_response(self.get_context_data(form = form, pendencies_form = pendencies_form))
  289 + return self.render_to_response(self.get_context_data(form = form, pendencies_form = pendencies_form))
286 290  
287   - def post(self, request, *args, **kwargs):
288   - self.object = self.get_object()
  291 + def post(self, request, *args, **kwargs):
  292 + self.object = self.get_object()
289 293  
290   - form_class = self.get_form_class()
291   - form = self.get_form(form_class)
  294 + form_class = self.get_form_class()
  295 + form = self.get_form(form_class)
292 296  
293   - slug = self.kwargs.get('topic_slug', '')
294   - topic = get_object_or_404(Topic, slug = slug)
  297 + slug = self.kwargs.get('topic_slug', '')
  298 + topic = get_object_or_404(Topic, slug = slug)
295 299  
296   - pend_form = self.object.pendencies_resource.all()
  300 + pend_form = self.object.pendencies_resource.all()
297 301  
298   - if len(pend_form) > 0:
299   - pendencies_form = PendenciesForm(self.request.POST, instance = pend_form[0], initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
300   - else:
301   - pendencies_form = PendenciesForm(self.request.POST, initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
  302 + if len(pend_form) > 0:
  303 + pendencies_form = PendenciesForm(self.request.POST, instance = pend_form[0], initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
  304 + else:
  305 + pendencies_form = PendenciesForm(self.request.POST, initial = {'subject': topic.subject.id, 'actions': [("", "-------"),("view", _("Visualize"))]})
302 306  
303   - if (form.is_valid() and pendencies_form.is_valid()):
304   - return self.form_valid(form, pendencies_form)
305   - else:
306   - return self.form_invalid(form, pendencies_form)
  307 + if (form.is_valid() and pendencies_form.is_valid()):
  308 + return self.form_valid(form, pendencies_form)
  309 + else:
  310 + return self.form_invalid(form, pendencies_form)
307 311  
308   - def form_invalid(self, form, pendencies_form):
309   - return self.render_to_response(self.get_context_data(form = form, pendencies_form = pendencies_form))
  312 + def form_invalid(self, form, pendencies_form):
  313 + return self.render_to_response(self.get_context_data(form = form, pendencies_form = pendencies_form))
310 314  
311   - def form_valid(self, form, pendencies_form):
312   - self.object = form.save(commit = False)
  315 + def form_valid(self, form, pendencies_form):
  316 + self.object = form.save(commit = False)
313 317  
314   - if not self.object.topic.visible and not self.object.topic.repository:
315   - self.object.visible = False
  318 + if not self.object.topic.visible and not self.object.topic.repository:
  319 + self.object.visible = False
316 320  
317   - self.object.save()
  321 + self.object.save()
318 322  
319   - pend_form = pendencies_form.save(commit = False)
320   - pend_form.resource = self.object
  323 + pend_form = pendencies_form.save(commit = False)
  324 + pend_form.resource = self.object
321 325  
322   - if not pend_form.action == "":
323   - pend_form.save()
  326 + if not pend_form.action == "":
  327 + pend_form.save()
324 328  
325   - self.log_context['category_id'] = self.object.topic.subject.category.id
326   - self.log_context['category_name'] = self.object.topic.subject.category.name
327   - self.log_context['category_slug'] = self.object.topic.subject.category.slug
328   - self.log_context['subject_id'] = self.object.topic.subject.id
329   - self.log_context['subject_name'] = self.object.topic.subject.name
330   - self.log_context['subject_slug'] = self.object.topic.subject.slug
331   - self.log_context['topic_id'] = self.object.topic.id
332   - self.log_context['topic_name'] = self.object.topic.name
333   - self.log_context['topic_slug'] = self.object.topic.slug
334   - self.log_context['webpage_id'] = self.object.id
335   - self.log_context['webpage_name'] = self.object.name
336   - self.log_context['webpage_slug'] = self.object.slug
  329 + self.log_context['category_id'] = self.object.topic.subject.category.id
  330 + self.log_context['category_name'] = self.object.topic.subject.category.name
  331 + self.log_context['category_slug'] = self.object.topic.subject.category.slug
  332 + self.log_context['subject_id'] = self.object.topic.subject.id
  333 + self.log_context['subject_name'] = self.object.topic.subject.name
  334 + self.log_context['subject_slug'] = self.object.topic.subject.slug
  335 + self.log_context['topic_id'] = self.object.topic.id
  336 + self.log_context['topic_name'] = self.object.topic.name
  337 + self.log_context['topic_slug'] = self.object.topic.slug
  338 + self.log_context['webpage_id'] = self.object.id
  339 + self.log_context['webpage_name'] = self.object.name
  340 + self.log_context['webpage_slug'] = self.object.slug
337 341  
338   - super(UpdateView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  342 + super(UpdateView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
339 343  
340   - return redirect(self.get_success_url())
  344 + return redirect(self.get_success_url())
341 345  
342   - def get_context_data(self, **kwargs):
343   - context = super(UpdateView, self).get_context_data(**kwargs)
  346 + def get_context_data(self, **kwargs):
  347 + context = super(UpdateView, self).get_context_data(**kwargs)
344 348  
345   - context['title'] = _('Update Webpage')
  349 + context['title'] = _('Update Webpage')
346 350  
347   - slug = self.kwargs.get('topic_slug', '')
348   - topic = get_object_or_404(Topic, slug = slug)
  351 + slug = self.kwargs.get('topic_slug', '')
  352 + topic = get_object_or_404(Topic, slug = slug)
349 353  
350   - context['topic'] = topic
351   - context['subject'] = topic.subject
  354 + context['topic'] = topic
  355 + context['subject'] = topic.subject
352 356  
353   - return context
  357 + return context
354 358  
355   - def get_success_url(self):
356   - messages.success(self.request, _('The Webpage "%s" was updated successfully!')%(self.object.name))
  359 + def get_success_url(self):
  360 + messages.success(self.request, _('The Webpage "%s" was updated successfully!')%(self.object.name))
357 361  
358   - success_url = reverse_lazy('webpages:view', kwargs = {'slug': self.object.slug})
  362 + success_url = reverse_lazy('webpages:view', kwargs = {'slug': self.object.slug})
359 363  
360   - if self.object.show_window:
361   - self.request.session['resources'] = {}
362   - self.request.session['resources']['new_page'] = True
363   - self.request.session['resources']['new_page_url'] = reverse('webpages:window_view', kwargs = {'slug': self.object.slug})
  364 + if self.object.show_window:
  365 + self.request.session['resources'] = {}
  366 + self.request.session['resources']['new_page'] = True
  367 + self.request.session['resources']['new_page_url'] = reverse('webpages:window_view', kwargs = {'slug': self.object.slug})
364 368  
365   - success_url = reverse_lazy('subjects:view', kwargs = {'slug': self.object.topic.subject.slug})
  369 + success_url = reverse_lazy('subjects:view', kwargs = {'slug': self.object.topic.subject.slug})
366 370  
367   - return success_url
  371 + return success_url
368 372  
369 373 class DeleteView(LoginRequiredMixin, LogMixin, generic.DeleteView):
370 374 log_component = 'resources'
... ... @@ -409,17 +413,6 @@ class DeleteView(LoginRequiredMixin, LogMixin, generic.DeleteView):
409 413 return reverse_lazy('subjects:view', kwargs = {'slug': self.object.topic.subject.slug})
410 414  
411 415  
412   -def get_chart(request,slug):
413   - webpage = get_object_or_404(Webpage, slug=slug)
414   - alunos = webpage.students.all()
415   - visualizou = Log.objects.filter(context__contains={'webpage_id':webpage.id},resource="webpage",action="view",user_email__in=(aluno.email for aluno in alunos)).distinct("user_email")
416   - re = []
417   - c_visualizou = visualizou.count()
418   - re.append(["Página Web","Fez","Não fez"])
419   - re.append(["Visualizar",c_visualizou, alunos.count() - c_visualizou])
420   - return JsonResponse({"dados":re})
421   -
422   -
423 416 class StatisticsView(LoginRequiredMixin, LogMixin, generic.DetailView):
424 417 log_component = 'resources'
425 418 log_action = 'view_statistics'
... ... @@ -474,6 +467,8 @@ class StatisticsView(LoginRequiredMixin, LogMixin, generic.DetailView):
474 467 context["init_date"] = start_date
475 468 context["end_date"] = end_date
476 469 alunos = webpage.students.all()
  470 + if webpage.all_students :
  471 + alunos = webpage.topic.subject.students.all()
477 472  
478 473 vis_ou = Log.objects.filter(context__contains={'webpage_id':webpage.id},resource="webpage",action="view",user_email__in=(aluno.email for aluno in alunos), datetime__range=(start_date,end_date + datetime.timedelta(minutes = 1)))
479 474 did,n_did,history = str(_("Realized")),str(_("Unrealized")),str(_("Historic"))
... ... @@ -502,32 +497,59 @@ class StatisticsView(LoginRequiredMixin, LogMixin, generic.DetailView):
502 497 context["json_n_did"] = json_n_did
503 498 context["json_history"] = json_history
504 499 c_visualizou = vis_ou.distinct("user_email").count()
  500 + column_view = str(_('View'))
505 501 re.append([str(_('Webpage')),did,n_did])
506   - re.append([str(_('View')),c_visualizou, alunos.count() - c_visualizou])
  502 + re.append([column_view,c_visualizou, alunos.count() - c_visualizou])
507 503 context['topic'] = webpage.topic
508 504 context['subject'] = webpage.topic.subject
509 505 context['db_data'] = re
510 506 context['title_chart'] = _('Actions about resource')
511 507 context['title_vAxis'] = _('Quantity')
512   -
  508 + context['view'] = column_view
513 509 context["n_did_table"] = n_did
514 510 context["did_table"] = did
515 511 context["history_table"] = history
516 512 return context
517 513  
518 514  
519   -from chat.models import Conversation, TalkMessages
520   -from users.models import User
521   -from subjects.models import Subject
522   -def sendMessage(request, slug):
523   - message = request.GET.get('message','')
524   - users = request.GET.getlist('users[]','')
525   - user = request.user
526   - subject = get_object_or_404(Subject,slug = slug)
527   -
528   - for u in users:
529   - to_user = User.objects.get(email=u)
530   - talk, create = Conversation.objects.get_or_create(user_one=user,user_two=to_user)
531   - created = TalkMessages.objects.create(text=message,talk=talk,user=user,subject=subject)
532   -
533   - return JsonResponse({"message":"ok"})
  515 +
  516 +class SendMessage(LoginRequiredMixin, LogMixin, generic.edit.FormView):
  517 + log_component = 'resources'
  518 + log_action = 'send'
  519 + log_resource = 'webpage'
  520 + log_context = {}
  521 +
  522 + login_url = reverse_lazy("users:login")
  523 + redirect_field_name = 'next'
  524 +
  525 + template_name = 'webpages/send_message.html'
  526 + form_class = FormModalMessage
  527 +
  528 + def dispatch(self, request, *args, **kwargs):
  529 + slug = self.kwargs.get('slug', '')
  530 + webpage = get_object_or_404(Webpage, slug = slug)
  531 + self.webpage = webpage
  532 +
  533 + if not has_subject_permissions(request.user, webpage.topic.subject):
  534 + return redirect(reverse_lazy('subjects:home'))
  535 +
  536 + return super(SendMessage, self).dispatch(request, *args, **kwargs)
  537 +
  538 + def form_valid(self, form):
  539 + message = form.cleaned_data.get('comment')
  540 + image = form.cleaned_data.get("image")
  541 + users = (self.request.POST.get('users[]','')).split(",")
  542 + user = self.request.user
  543 + subject = self.webpage.topic.subject
  544 + for u in users:
  545 + to_user = User.objects.get(email=u)
  546 + talk, create = Conversation.objects.get_or_create(user_one=user,user_two=to_user)
  547 + created = TalkMessages.objects.create(text=message,talk=talk,user=user,subject=subject,image=image)
  548 + return JsonResponse({"message":"ok"})
  549 +
  550 + def get_context_data(self, **kwargs):
  551 + context = super(SendMessage,self).get_context_data()
  552 + context["webpage"] = get_object_or_404(Webpage, slug=self.kwargs.get('slug', ''))
  553 + return context
  554 +
  555 +
... ...
youtube_video/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-04-15 00:13-0300\n"
  11 +"POT-Creation-Date: 2017-05-05 21:46-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,104 +18,167 @@ msgstr &quot;&quot;
18 18 "Content-Transfer-Encoding: 8bit\n"
19 19 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
20 20  
21   -#: youtube_video/forms.py:36
  21 +#: forms.py:36
22 22 msgid "Tags"
23 23 msgstr "Tags"
24 24  
25   -#: youtube_video/forms.py:42
  25 +#: forms.py:42
26 26 msgid "Video title"
27 27 msgstr "Título do Vídeo"
28 28  
29   -#: youtube_video/forms.py:62
  29 +#: forms.py:62
30 30 msgid "This subject already has a resource with this name"
31 31 msgstr "Esse assunto já possui um recurso com esse nome"
32 32  
33   -#: youtube_video/forms.py:71
  33 +#: forms.py:71
34 34 msgid "Invalid URL. It should be an YouTube link."
35 35 msgstr "URL inválida. Ela deve ser uma URL de um vídeo do YouTube."
36 36  
37   -#: youtube_video/models.py:8
  37 +#: models.py:8
38 38 msgid "URL"
39 39 msgstr "URL"
40 40  
41   -#: youtube_video/models.py:11
  41 +#: models.py:11
42 42 msgid "YTVideo"
43 43 msgstr "Vídeo do YouTube"
44 44  
45   -#: youtube_video/models.py:12
  45 +#: models.py:12
46 46 msgid "YTVideos"
47 47 msgstr "Vídeos do YouTube"
48 48  
49   -#: youtube_video/models.py:30
  49 +#: models.py:30
50 50 msgid "Are you sure you want delete the YouTube Video"
51 51 msgstr "Você tem certeza que deseja deletar o Vídeo do YouTube"
52 52  
53   -#: youtube_video/templates/youtube/_form.html:49
  53 +#: templates/youtube/_form.html:49
54 54 msgid "Common resources settings"
55 55 msgstr "Configurações comuns à todos os recursos"
56 56  
57   -#: youtube_video/templates/youtube/_form.html:98
  57 +#: templates/youtube/_form.html:98
58 58 msgid "Pendencies Notifications"
59 59 msgstr "Notificações de Pendências"
60 60  
61   -#: youtube_video/templates/youtube/_form.html:119
  61 +#: templates/youtube/_form.html:119
62 62 msgid "Action not performed by the user"
63 63 msgstr "Ação não realizada pelo usuário"
64 64  
65   -#: youtube_video/templates/youtube/_form.html:145
  65 +#: templates/youtube/_form.html:145
66 66 msgid "Wished period"
67 67 msgstr "Período desejado"
68 68  
69   -#: youtube_video/templates/youtube/_form.html:242
  69 +#: templates/youtube/_form.html:242
70 70 msgid "Attribute students to YouTube Video"
71 71 msgstr "Atribuir estudantes ao Vídeo do YouTube"
72 72  
73   -#: youtube_video/templates/youtube/_form.html:262
  73 +#: templates/youtube/_form.html:262
74 74 msgid "Attribute groups to YouTube Video"
75 75 msgstr "Atribuir grupos de estudo ao Vídeo do YouTube"
76 76  
77   -#: youtube_video/templates/youtube/_form.html:331
  77 +#: templates/youtube/_form.html:331
78 78 msgid "Save"
79 79 msgstr "Salvar"
80 80  
81   -#: youtube_video/templates/youtube/_form.html:338
  81 +#: templates/youtube/_form.html:338
82 82 msgid "Add new notification"
83 83 msgstr "Adicionar nova notificação"
84 84  
85   -#: youtube_video/templates/youtube/_form.html:339
  85 +#: templates/youtube/_form.html:339
86 86 msgid "Remove this"
87 87 msgstr "Remover essa notificação"
88 88  
89   -#: youtube_video/templates/youtube/create.html:21
  89 +#: templates/youtube/create.html:21
90 90 msgid "Create YouTube Video"
91 91 msgstr "Adicionar Vídeo do YouTube"
92 92  
93   -#: youtube_video/templates/youtube/update.html:21
  93 +#: templates/youtube/relatorios.html:17 templates/youtube/relatorios.html:37
  94 +msgid "User"
  95 +msgstr "Usuário"
  96 +
  97 +#: templates/youtube/relatorios.html:17 templates/youtube/relatorios.html:37
  98 +msgid "Group"
  99 +msgstr "Grupo"
  100 +
  101 +#: templates/youtube/relatorios.html:17
  102 +msgid "Action"
  103 +msgstr "Ação"
  104 +
  105 +#: templates/youtube/relatorios.html:17
  106 +msgid "Date of Action"
  107 +msgstr "Data da ação"
  108 +
  109 +#: templates/youtube/relatorios.html:37
  110 +msgid "Send message"
  111 +msgstr "Enviar Mensagem"
  112 +
  113 +#: templates/youtube/relatorios.html:37
  114 +msgid "Action don't realized"
  115 +msgstr "Ação não realizada"
  116 +
  117 +#: templates/youtube/relatorios.html:212 templates/youtube/relatorios.html:232
  118 +msgid "Reports"
  119 +msgstr "Relatórios"
  120 +
  121 +#: templates/youtube/relatorios.html:239
  122 +msgid "Report of the resource "
  123 +msgstr "Relatórios do recurso "
  124 +
  125 +#: templates/youtube/relatorios.html:248
  126 +msgid "Select the period: "
  127 +msgstr "Selecione o período: "
  128 +
  129 +#: templates/youtube/relatorios.html:257
  130 +msgid "Search"
  131 +msgstr "Pesquisar"
  132 +
  133 +#: templates/youtube/relatorios.html:281
  134 +msgid "Filter: "
  135 +msgstr "Filtro: "
  136 +
  137 +#: templates/youtube/relatorios.html:305 templates/youtube/relatorios.html:390
  138 +#: templates/youtube/relatorios.html:470
  139 +msgid "record(s)"
  140 +msgstr "Relatório(s)"
  141 +
  142 +#: templates/youtube/send_message.html:38
  143 +msgid "Click or drop the picture here"
  144 +msgstr "Clique ou solte a imagem aqui"
  145 +
  146 +#: templates/youtube/send_message.html:40
  147 +msgid "The picture could not exceed 5MB."
  148 +msgstr "A imagem não pode exceder 5MB."
  149 +
  150 +#: templates/youtube/send_message.html:62
  151 +msgid "Close"
  152 +msgstr "Fechar"
  153 +
  154 +#: templates/youtube/send_message.html:63
  155 +msgid "Send"
  156 +msgstr "Enviar"
  157 +
  158 +#: templates/youtube/update.html:21
94 159 msgid "Edit: "
95 160 msgstr "Editar: "
96 161  
97   -#: youtube_video/views.py:46
  162 +#: views.py:56
98 163 #, python-format
99 164 msgid "%s - Video"
100 165 msgstr "%s - Vídeo"
101 166  
102   -#: youtube_video/views.py:148 youtube_video/views.py:161
103   -#: youtube_video/views.py:180 youtube_video/views.py:283
104   -#: youtube_video/views.py:296 youtube_video/views.py:305
  167 +#: views.py:158 views.py:171 views.py:190 views.py:293 views.py:306
  168 +#: views.py:315
105 169 msgid "Visualize"
106 170 msgstr "Visualizar"
107 171  
108   -#: youtube_video/views.py:148 youtube_video/views.py:161
109   -#: youtube_video/views.py:180 youtube_video/views.py:283
110   -#: youtube_video/views.py:296 youtube_video/views.py:305
  172 +#: views.py:158 views.py:171 views.py:190 views.py:293 views.py:306
  173 +#: views.py:315 views.py:549
111 174 msgid "Finish"
112 175 msgstr "Finalizar"
113 176  
114   -#: youtube_video/views.py:227
  177 +#: views.py:237
115 178 msgid "Create Youtube Video"
116 179 msgstr "Adicionar Vídeo do YouTube"
117 180  
118   -#: youtube_video/views.py:238
  181 +#: views.py:248
119 182 #, python-format
120 183 msgid ""
121 184 "The Youtube Video \"%s\" was added to the Topic \"%s\" of the virtual "
... ... @@ -124,16 +187,16 @@ msgstr &quot;&quot;
124 187 "O Vídeo do YouTube \"%s\" foi adicionado ao tópico \"%s\" do ambiente "
125 188 "virtual \"%s\" com sucesso!"
126 189  
127   -#: youtube_video/views.py:346
  190 +#: views.py:356
128 191 msgid "Update YouTube Video"
129 192 msgstr "Atualizar Vídeo do YouTube"
130 193  
131   -#: youtube_video/views.py:357
  194 +#: views.py:367
132 195 #, python-format
133 196 msgid "The YouTube Video \"%s\" was updated successfully!"
134 197 msgstr "O Vídeo do YouTube \"%s\" foi atualizado com sucesso!"
135 198  
136   -#: youtube_video/views.py:393
  199 +#: views.py:403
137 200 #, python-format
138 201 msgid ""
139 202 "The YouTube Video \"%s\" was removed successfully from virtual environment "
... ... @@ -141,3 +204,41 @@ msgid &quot;&quot;
141 204 msgstr ""
142 205 "O Vídeo do YouTube \"%s\" foi removido do ambiente virtual \"%s\" com "
143 206 "sucesso!"
  207 +
  208 +#: views.py:515
  209 +#| msgid "Create Youtube Video"
  210 +msgid "Youtube Video Reports"
  211 +msgstr "Relatórios de Vídeo do YouTube"
  212 +
  213 +#: views.py:534
  214 +msgid "Realized"
  215 +msgstr "Realizado"
  216 +
  217 +#: views.py:534
  218 +msgid "Unrealized"
  219 +msgstr "Não Realizado"
  220 +
  221 +#: views.py:534
  222 +msgid "Historic"
  223 +msgstr "Histórico"
  224 +
  225 +#: views.py:549
  226 +msgid "View"
  227 +msgstr "Visualizar"
  228 +
  229 +#: views.py:549
  230 +msgid "Watch"
  231 +msgstr "Assistir"
  232 +
  233 +#: views.py:575
  234 +#| msgid "Create Youtube Video"
  235 +msgid "Youtube Video"
  236 +msgstr "Vídeo do YouTube"
  237 +
  238 +#: views.py:587
  239 +msgid "Actions about resource"
  240 +msgstr "Ações sobre o recurso"
  241 +
  242 +#: views.py:588
  243 +msgid "Quantity"
  244 +msgstr "Quantidade"
... ...
youtube_video/templates/youtube/relatorios.html 0 → 100644
... ... @@ -0,0 +1,473 @@
  1 +{% extends "youtube/view.html" %}
  2 +
  3 +{% load static i18n pagination permissions_tags subject_counter %}
  4 +{% load django_bootstrap_breadcrumbs %}
  5 +
  6 +{% block javascript%}
  7 + {{ block.super }}
  8 + <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  9 + <script type="text/javascript">
  10 + var tabela_atual = true;
  11 +
  12 + var array_history = [];
  13 + {%for data_json in json_history.data %}
  14 + array_history.push(["{{data_json.0}}","{{data_json.1}}","{% if data_json.2 == 'view' %} {{view}} {% elif data_json.2 == 'watch' %} {{watch}} {% else %} {{finish}} {% endif %}",{% if data_json.3 is not None %}new Date('{{data_json.3.isoformat}}'){% else%}null{% endif %}]);
  15 + {% endfor%}
  16 + var json_history = {"data":array_history};
  17 + var column_history = [{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":'{% trans "Action" %}'},{"date":'{% trans "Date of Action" %}'}];
  18 +
  19 + var search = [];
  20 + for (var i in json_history["data"]){
  21 + search.push([json_history["data"][i][0],json_history["data"][i][1],
  22 + json_history["data"][i][2],json_history["data"][i][3]]);
  23 + }
  24 +
  25 + var array_n_did = [];
  26 + var checkbox = {};
  27 + {%for data_json in json_n_did.data%}
  28 + var input = '<div class="checkbox">\
  29 + <label for="{{data_json.0}}_google_table">\
  30 + <input id="{{data_json.0}}_google_table" name="{{data_json.0}}_google_table" type="checkbox"><span class="checkbox-material"><span class="check"></span></span>\
  31 + </label>\
  32 + </div>'
  33 + checkbox["{{data_json.0}}_google_table"] = "{{data_json.4}}";
  34 + array_n_did.push([input,"{{data_json.1}}","{{data_json.2}}","{{data_json.3}}"]);
  35 + {% endfor%}
  36 + var json_n_did = {"data":array_n_did};
  37 + var column_n_did = [{"string":'<a href="javascript:void(0);" onclick="return openmodal();"> {% trans "Send message" %}</a>'},{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":"{% trans "Action don't realized" %}"}];
  38 + </script>
  39 +
  40 +
  41 + <script type="text/javascript">
  42 + google.charts.load('current', {'packages':['corechart',"table"]});
  43 + google.charts.setOnLoadCallback(drawChart);
  44 + google.charts.setOnLoadCallback(drawTable);
  45 +
  46 + function drawChart() {
  47 + var data = google.visualization.arrayToDataTable({{db_data|safe}});
  48 + var options = {
  49 + title: '{{title_chart}}',
  50 + // legend: {position: 'right', maxLines: 1},
  51 + bar: { groupWidth: '50%' },
  52 + chartArea:{width:"50%"},
  53 + titlePosition: 'out',
  54 + vAxis: {
  55 + title: '{{title_vAxis}}',
  56 + ticks: [0, .20, .40, .60, .80, 1],
  57 + viewWindow: {
  58 + min: 0,
  59 + max: 1
  60 + }
  61 + },
  62 + isStacked: "percent",
  63 + };
  64 +
  65 + function selectHandler() {
  66 + var selectedItem = chart.getSelection()[0];
  67 + console.log(selectedItem.row,selectedItem.column);
  68 + if (selectedItem) {
  69 + if (selectedItem.row == 0 && selectedItem.column == 1){
  70 + tabela_atual = true;
  71 + search = [];
  72 + var text = "{{view}}";
  73 + for (var i in json_history["data"]){
  74 + if (json_history["data"][i][2].toLowerCase().includes(text.toLowerCase())){
  75 + search.push([json_history["data"][i][0],json_history["data"][i][1],
  76 + json_history["data"][i][2],json_history["data"][i][3]]);
  77 + }
  78 + }
  79 + drawTable(column_history,pagination(search,1),true,3);
  80 + alterTitleTable(search.length);
  81 + putpagination(search,tabela_atual);
  82 + } else if(selectedItem.row == 0 && selectedItem.column == 2){
  83 + tabela_atual = false;
  84 + search = [];
  85 + var text = "{{view}}";
  86 + for (var i in json_n_did["data"]){
  87 + if (json_n_did["data"][i][3].toLowerCase().includes(text.toLowerCase())){
  88 + search.push([json_n_did["data"][i][0],json_n_did["data"][i][1],
  89 + json_n_did["data"][i][2],json_n_did["data"][i][3]]);
  90 + }
  91 + }
  92 + drawTable(column_n_did,pagination(search,1),false);
  93 + alterTitleTable(search.length);
  94 + putpagination(search,tabela_atual);
  95 + } else if (selectedItem.row == 1 && selectedItem.column == 1){
  96 + tabela_atual = true;
  97 + search = [];
  98 + var text = "{{watch}}";
  99 + for (var i in json_history["data"]){
  100 + if (json_history["data"][i][2].toLowerCase().includes(text.toLowerCase())){
  101 + search.push([json_history["data"][i][0],json_history["data"][i][1],
  102 + json_history["data"][i][2],json_history["data"][i][3]]);
  103 + }
  104 + }
  105 + drawTable(column_history,pagination(search,1),true,3);
  106 + alterTitleTable(search.length);
  107 + putpagination(search,tabela_atual);
  108 + } else if(selectedItem.row == 1 && selectedItem.column == 2){
  109 + tabela_atual = false;
  110 + search = [];
  111 + var text = "{{watch}}";
  112 + for (var i in json_n_did["data"]){
  113 + if (json_n_did["data"][i][3].toLowerCase().includes(text.toLowerCase())){
  114 + search.push([json_n_did["data"][i][0],json_n_did["data"][i][1],
  115 + json_n_did["data"][i][2],json_n_did["data"][i][3]]);
  116 + }
  117 + }
  118 + drawTable(column_n_did,pagination(search,1),false);
  119 + alterTitleTable(search.length);
  120 + putpagination(search,tabela_atual);
  121 + } else if (selectedItem.row == 2 && selectedItem.column == 1){
  122 + tabela_atual = true;
  123 + search = [];
  124 + var text = "{{finish}}";
  125 + for (var i in json_history["data"]){
  126 + if (json_history["data"][i][2].toLowerCase().includes(text.toLowerCase())){
  127 + search.push([json_history["data"][i][0],json_history["data"][i][1],
  128 + json_history["data"][i][2],json_history["data"][i][3]]);
  129 + }
  130 + }
  131 + drawTable(column_history,pagination(search,1),true,3);
  132 + alterTitleTable(search.length);
  133 + putpagination(search,tabela_atual);
  134 + } else if(selectedItem.row == 2 && selectedItem.column == 2){
  135 + tabela_atual = false;
  136 + search = [];
  137 + var text = "{{finish}}";
  138 + for (var i in json_n_did["data"]){
  139 + if (json_n_did["data"][i][3].toLowerCase().includes(text.toLowerCase())){
  140 + search.push([json_n_did["data"][i][0],json_n_did["data"][i][1],
  141 + json_n_did["data"][i][2],json_n_did["data"][i][3]]);
  142 + }
  143 + }
  144 + drawTable(column_n_did,pagination(search,1),false);
  145 + alterTitleTable(search.length);
  146 + putpagination(search,tabela_atual);
  147 + }
  148 + }
  149 + chart.setSelection([])
  150 + }
  151 +
  152 + var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
  153 + google.visualization.events.addListener(chart, 'select', selectHandler);
  154 + chart.draw(data, options);
  155 +
  156 + }
  157 +
  158 + var sortAscending = {0:false,1:false,2:false,3:false};
  159 + function drawTable(columns = column_history,rows = pagination(json_history["data"],1),isdate = true,columndate = 3) {
  160 + var data_table = new google.visualization.DataTable();
  161 + for (var i in columns){
  162 + for (var item in columns[i]){
  163 + data_table.addColumn(item,columns[i][item]);
  164 + }
  165 + }
  166 +
  167 + data_table.addRows(rows);
  168 + var formate_date = new google.visualization.DateFormat({pattern: 'dd/MM/yyyy HH:mm'});
  169 + if (isdate) formate_date.format(data_table, columndate);
  170 +
  171 + // var methods = [];
  172 + // for (var m in data_table) {
  173 + // if (typeof data_table[m] == "function") {
  174 + // methods.push(m);
  175 + // }
  176 + // }
  177 + // console.log(methods.join(","));
  178 + var options = {
  179 + sort: "event",
  180 + allowHtml: true,
  181 + cssClassNames : {
  182 + tableRow: 'text-center',
  183 + tableCell: 'text-center',
  184 + headerCell: 'text-center'
  185 + },
  186 + showRowNumber: true,
  187 + width: '100%',
  188 + height: '100%',
  189 + }
  190 + function ordenar(properties){
  191 + var columnIndex = properties['column'];
  192 + if (columnIndex > 0) {
  193 + options["sortColumn"] = columnIndex;
  194 + options["sortAscending"] = sortAscending[columnIndex];
  195 + data_table.sort({column:columnIndex,desc:sortAscending[columnIndex]});
  196 + sortAscending = {0:false,1:false,2:false,3:false};
  197 + sortAscending[columnIndex] = !sortAscending[columnIndex];
  198 + // console.log(sortAscending);
  199 + table.draw(data_table, options);
  200 + }
  201 + }
  202 +
  203 + var table = new google.visualization.Table(document.getElementById('table_div'));
  204 + google.visualization.events.addListener(table, 'sort', function(e) {ordenar(e)});
  205 + table.draw(data_table, options);
  206 + }
  207 + </script>
  208 +{% endblock%}
  209 +
  210 +{% block breadcrumbs %}
  211 + {{ block.super }}
  212 + {% trans 'Reports' as bread %}
  213 + {% breadcrumb bread ytvideo%}
  214 +{% endblock %}
  215 +
  216 +{% block content %}
  217 + {% if messages %}
  218 + {% for message in messages %}
  219 + <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">
  220 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  221 + <span aria-hidden="true">&times;</span>
  222 + </button>
  223 + <p>{{ message }}</p>
  224 + </div>
  225 + {% endfor %}
  226 + {% endif %}
  227 + <div class="panel panel-info topic-panel">
  228 + <div class="panel-heading">
  229 + <div class="row">
  230 + <div class="col-md-12 category-header">
  231 + <h4 class="panel-title" style="margin-top: 10px; margin-bottom: 8px">
  232 + <span>{{ytvideo}} / {% trans "Reports" %}</span>
  233 + </h4>
  234 + </div>
  235 + </div>
  236 + </div>
  237 + <div class="row">
  238 + <div class="col-md-12 text-center">
  239 + <h4 style="margin-top: 15px; margin-bottom: 10px" ><strong>{% trans "Report of the resource " %}{{ytvideo}}</strong></h4>
  240 + </div>
  241 + </div>
  242 + <div class="row">
  243 + <div class="col-md-12">
  244 +
  245 + <ul class="list-inline nav-justified">
  246 + <div id="general-parameters-div">
  247 + <div class="general-parameters-field">
  248 + <li class="text-right"><h4>{% trans "Select the period: " %}</h4></li>
  249 + </div>
  250 + <form id="period-form" action="" method="get">
  251 + <div class="general-parameters-field">
  252 + <li> <input class="form-control datetime-picker" name="init_date" type="text" required="" value="{% if LANGUAGE_CODE == 'pt-br' %}{{init_date|date:'d/m/Y H:i'}} {% else %} {{init_date|date:'m/d/Y H:i P'}} {% endif %}"></li>
  253 + </div>
  254 + <div class="general-parameters-field">
  255 + <li><input id="inputdate" class="form-control datetime-picker" name="end_date" type="text" required="" value="{% if LANGUAGE_CODE == 'pt-br' %}{{end_date|date:'d/m/Y H:i'}} {% else %} {{end_date|date:'m/d/Y H:i P'}} {% endif %}"></li>
  256 + </div>
  257 + <li><input type="submit" value="{% trans 'Search' %}" style="margin-left: 15px;" class="btn btn-success btn-raised"></li>
  258 + </form>
  259 + </div>
  260 + <ul>
  261 + </div>
  262 + </div>
  263 +
  264 + <div class="row">
  265 + <div class="col-md-10 col-md-offset-1">
  266 + <div id="chart_div" style="height: 500px; margin-top: -50px;"></div>
  267 + </div>
  268 + </div>
  269 +
  270 + <div class="row">
  271 + <div class="col-md-10 col-md-offset-1">
  272 + <div class="text-center">
  273 + <ul class="list-inline nav-justified">
  274 + <li>
  275 + <ul id="view-table" class="list-inline text-right">
  276 + <li><h3 id="title-table"></h3></li>
  277 + </ul>
  278 + </li>
  279 + <li>
  280 + <ul class="list-inline text-right">
  281 + <li><p>{% trans "Filter: " %}</p></li>
  282 + <li><input id="search-input" class="form-control" type="text" name="search" value=""></li>
  283 + </ul>
  284 + </li>
  285 + </ul>
  286 + </div>
  287 + <form id="google-chart-checkbox" action="" method="get">
  288 + <div id="table_div"></div>
  289 + </form>
  290 + <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12 text-center">
  291 + <ul class="pagination">
  292 +
  293 + </ul>
  294 + </div>
  295 + </div>
  296 + </div>
  297 + <div id="modal-message"></div>
  298 + <div class="row">
  299 + <br><br>
  300 + </div>
  301 + </div>
  302 +
  303 + <script type="text/javascript">
  304 +
  305 + $("#title-table").text(search.length + " {% trans 'record(s)' %}");
  306 + function putpagination(data = json_history["data"], load_histoty = true){
  307 + var len = Math.ceil(data.length / 20);
  308 + $(".pagination").empty();
  309 + $(".pagination").append('<li class="disabled"><span>«</span></li>');
  310 + $(".pagination").append('<li id="1" class="active">\
  311 + <a href="javascript:void(0);" onclick="return clickPagination(1, '+ load_histoty +');">1</a>\
  312 + </li>');
  313 + for (var i = 2; i <= len;i++){
  314 + $(".pagination").append('<li id="' + i + '">\
  315 + <a href="javascript:void(0);" onclick="return clickPagination(' + i +', ' + load_histoty + ');">' + i + '</a>\
  316 + </li>');
  317 + }
  318 + if (len > 1) $(".pagination").append('<li><a href="javascript:void(0);" onclick="return clickPagination(2, '+ load_histoty +');"><span>»</span></a></li>');
  319 + else $(".pagination").append('<li class="disabled"><span>»</span></li>');
  320 + };
  321 + putpagination();
  322 +
  323 + $('#period-form').submit(function(event) {
  324 + $('<input />').attr('type', 'hidden')
  325 + .attr('name', "language")
  326 + .attr('value', '{{ LANGUAGE_CODE }}')
  327 + .appendTo('#period-form');
  328 + });
  329 + function add(element,local, first = false){
  330 + if (first) $(local).prepend(element);
  331 + else $(local).append(element);
  332 + }
  333 + function text(element){
  334 + return $(element).text();
  335 + }
  336 + function length(element) {
  337 + return $(element).length;
  338 + }
  339 +
  340 + $("#search-input").on("keyup",function(){
  341 + search = [];
  342 + var text = $("#search-input").val();
  343 + searcher(text,tabela_atual);
  344 + });
  345 +
  346 + function searcher(text, load_histoty = false,apaga=false){
  347 + if(apaga){
  348 + $("#search-input").val("");
  349 + }
  350 + var data = [];
  351 + if (!load_histoty){
  352 + data = $.map(json_n_did["data"], function (obj) {
  353 + return $.extend(true, {}, obj);
  354 + });
  355 + } else {
  356 + data = $.map(json_history["data"], function (obj) {
  357 + return $.extend(true, {}, obj);
  358 + });
  359 + }
  360 + if (load_histoty){
  361 + for (var i in data){
  362 + data[i][3] = moment(data[i][3]).format("DD/MM/YYYY HH:mm");
  363 + }
  364 + }
  365 + if (load_histoty){
  366 + for (var i in data){
  367 + if (data[i][0].toLowerCase().includes(text.toLowerCase())
  368 + || data[i][1].toLowerCase().includes(text.toLowerCase())
  369 + || data[i][2].toLowerCase().includes(text.toLowerCase())
  370 + || data[i][3].toLowerCase().includes(text.toLowerCase())){
  371 + search.push(json_history["data"][i]);
  372 + }
  373 + }
  374 + }
  375 + else {
  376 + for (var i in data){
  377 + if (data[i][1].toLowerCase().includes(text.toLowerCase())
  378 + || data[i][2].toLowerCase().includes(text.toLowerCase())
  379 + || data[i][3].toLowerCase().includes(text.toLowerCase())){
  380 + search.push(json_n_did["data"][i]);
  381 + }
  382 + }
  383 + }
  384 + console.log(search);
  385 + if (!load_histoty){
  386 + drawTable(column_n_did,pagination(search,1),false);
  387 + } else {
  388 + drawTable(column_history,pagination(search,1),true,3);
  389 + }
  390 + $("#title-table").text(search.length + " {% trans 'record(s)' %}");
  391 + putpagination(search,load_histoty);
  392 + }
  393 +
  394 + function pagination(data,pag){
  395 + var len = data.length;
  396 + var first = (pag * 20 - 20 < len) ? pag * 20 - 20:len;
  397 + var end = (pag * 20 < len) ? pag * 20:len;
  398 + var search = data.slice(first,end);
  399 + return search;
  400 + }
  401 +
  402 + function clickPagination(pag, load_histoty = false){
  403 + $(".pagination > li").last().remove();
  404 + $(".pagination > li").first().remove();
  405 +
  406 + if (!load_histoty){
  407 + drawTable(column_n_did,pagination(search,pag),false);
  408 + } else {
  409 + drawTable(column_history,pagination(search,pag),true,3);
  410 + }
  411 +
  412 + if (pag < Math.ceil(search.length / 20))
  413 + $(".pagination").append('<li><a href="javascript:void(0);" onclick="return clickPagination(' + (pag + 1) + ', '+ load_histoty +');"><span>»</span></a></li>');
  414 + else $(".pagination").append('<li class="disabled"><span>»</span></li>');
  415 + if (pag > 1)
  416 + $(".pagination").prepend('<li><a href="javascript:void(0);" onclick="return clickPagination(' + (pag - 1) + ', '+ load_histoty +');"><span>«</span></a></li>');
  417 + else $(".pagination").prepend('<li class="disabled"><span>«</span></li>');
  418 + $(".active").removeClass("active");
  419 + $("#" + pag).addClass("active");
  420 + }
  421 +
  422 + function openmodal(){
  423 + $( "#modal-message" ).empty();
  424 + $.get( "{% url 'youtube:send_message' ytvideo.slug %}", function( data ) {
  425 + $( "#modal-message" ).append( data );
  426 + $("#send-message-modal").modal("show");
  427 + });
  428 + }
  429 +
  430 + function sendMessage(){
  431 + $("#send-message-modal").modal("hide");
  432 + var checked = $("#google-chart-checkbox").serializeArray();
  433 + var email = [];
  434 + for (var i in checked){
  435 + email.push(checkbox[checked[i]["name"]]);
  436 + }
  437 + $('<input />').attr('type', 'hidden')
  438 + .attr('name', "users[]")
  439 + .attr('value', email)
  440 + .appendTo('#text_chat_form');
  441 +
  442 + var formData = new FormData($('#text_chat_form').get(0));
  443 + $.ajax({
  444 + url: "{% url 'youtube:send_message' ytvideo.slug %}",
  445 + type: "POST",
  446 + data: formData,
  447 + cache: false,
  448 + processData: false,
  449 + contentType: false,
  450 + success: function(data) {
  451 + if (data["message"]){
  452 + console.log("success");
  453 + $("body").removeClass("modal-open");
  454 + $( "#modal-message" ).empty();
  455 + $(".modal-backdrop.fade.in").remove();
  456 + } else {
  457 + $( "#modal-message" ).empty();
  458 + $(".modal-backdrop.fade.in").remove();
  459 + $( "#modal-message" ).append( data );
  460 + $("#send-message-modal").modal("show");
  461 + }
  462 + },
  463 + error: function(data){
  464 + console.log("erro");
  465 + }
  466 + });
  467 + }
  468 +
  469 + function alterTitleTable (quant){
  470 + $("#title-table").text(quant + " {% trans 'record(s)' %}");
  471 + }
  472 + </script>
  473 +{% endblock %}
... ...
youtube_video/templates/youtube/send_message.html 0 → 100644
... ... @@ -0,0 +1,112 @@
  1 +
  2 + {% load widget_tweaks i18n %}
  3 + <!-- Modal (remember to change the ids!!!) -->
  4 +<div class="modal fade" id="send-message-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  5 + <div class="modal-dialog" role="document">
  6 + <div class="modal-content">
  7 + <!-- Modal Body -->
  8 + <div class="modal-body">
  9 + <form id="text_chat_form" action="" method="POST" enctype="multipart/form-data">
  10 + {% csrf_token %}
  11 + {% comment %}Area para o Texto{% endcomment %}
  12 + <div class="form-group{% if form.has_error %} has-error {% endif %}">
  13 + <label for="{{ form.comment.auto_id }}">{{ form.comment.label }}: <span>*</span></label>
  14 + {% render_field form.comment class='form-control text_simple_wysiwyg' %}
  15 +
  16 + <span id="helpBlock" class="help-block">{{ form.comment.help_text }}</span>
  17 +
  18 + {% if form.comment.errors %}
  19 + <div class="alert alert-danger alert-dismissible" role="alert">
  20 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  21 + <span aria-hidden="true">&times;</span>
  22 + </button>
  23 + <ul>
  24 + {% for error in form.comment.errors %}
  25 + <li>{{ error }}</li>
  26 + {% endfor %}
  27 + </ul>
  28 + </div>
  29 + {% endif %}
  30 + </div>
  31 + {% comment %}Area para anexar a imagem {% endcomment %}
  32 + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">
  33 + {% render_field form.image %}
  34 +
  35 + <div class="filedrag">
  36 + {% trans 'Click or drop the picture here' %}<br />
  37 +
  38 + <small>{% trans 'The picture could not exceed 5MB.' %}</small>
  39 + </div>
  40 +
  41 + {% if form.image.errors %}
  42 + <div class="alert alert-danger alert-dismissible" role="alert">
  43 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  44 + <span aria-hidden="true">&times;</span>
  45 + </button>
  46 + <ul>
  47 + {% for error in form.image.errors %}
  48 + <li>{{ error }}</li>
  49 + {% endfor %}
  50 + </ul>
  51 + </div>
  52 + {% endif %}
  53 +
  54 + </div>
  55 + </form>
  56 + </div>
  57 + <!-- Modal Footer -->
  58 + <div id="delete-category-footer"class="modal-footer">
  59 + <!-- Don't remove that!!! -->
  60 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
  61 + <a href="javascript:void(0)" onclick="return sendMessage()" form="text_chat_form" class="btn btn-success btn-raised erase-button">{% trans "Send" %}</a>
  62 + </div>
  63 + </div>
  64 + </div>
  65 +</div>
  66 +
  67 +<script type="text/javascript">
  68 +
  69 + $('.text_simple_wysiwyg').summernote({
  70 + dialogsInBody: true,
  71 + disableDragAndDrop: true,
  72 + height: 150,
  73 + toolbar: [
  74 + // [groupName, [list of button]]
  75 + ['style', ['bold', 'italic']],
  76 + ['insert', ['link']]
  77 + ]
  78 + });
  79 +
  80 + if (window.File && window.FileList && window.FileReader) {
  81 + Init();
  82 + }
  83 +
  84 + function Init() {
  85 + var small = $("#id_image"),
  86 + filedrag = $(".filedrag"),
  87 + common = $(".common-file-input");
  88 +
  89 + // file select
  90 + small.on("change", FileSelectHandler);
  91 +
  92 + // is XHR2 available?
  93 + var xhr = new XMLHttpRequest();
  94 + if (xhr.upload) {
  95 + // file drop
  96 + filedrag.on("drop", FileSelectHandler);
  97 + filedrag.attr('style', 'display:block');
  98 + common.attr('style', 'display:none');
  99 + }
  100 + }
  101 +
  102 + // file selection
  103 + function FileSelectHandler(e) {
  104 + var files = e.target.files || e.dataTransfer.files,
  105 + parent = $(e.target.offsetParent);
  106 +
  107 + // process all File objects
  108 + for (var i = 0, f; f = files[i]; i++) {
  109 + parent.find('.filedrag').html(f.name);
  110 + }
  111 + }
  112 +</script>
0 113 \ No newline at end of file
... ...
youtube_video/urls.py
... ... @@ -11,4 +11,6 @@ urlpatterns = [
11 11 url(r'^view/(?P<slug>[\w_-]+)/$', views.InsideView.as_view(), name = 'view'),
12 12 url(r'^watch/(?P<ytvideo>[\w_-]+)/$', views.ytvideo_watch_log, name = 'watch'),
13 13 url(r'^finish/(?P<ytvideo>[\w_-]+)/$', views.ytvideo_finish_log, name = 'finish'),
  14 + url(r'^chart/(?P<slug>[\w_-]+)/$', views.StatisticsView.as_view(), name = 'get_chart'),
  15 + url(r'^send-message/(?P<slug>[\w_-]+)/$', views.SendMessage.as_view(), name = 'send_message'),
14 16 ]
... ...
youtube_video/views.py
... ... @@ -18,6 +18,16 @@ from topics.models import Topic
18 18 from .forms import YTVideoForm, InlinePendenciesFormset
19 19 from .models import YTVideo
20 20  
  21 +import datetime
  22 +from log.models import Log
  23 +from chat.models import Conversation, TalkMessages
  24 +from users.models import User
  25 +from subjects.models import Subject
  26 +
  27 +from webpage.forms import FormModalMessage
  28 +
  29 +from django.db.models import Q
  30 +
21 31 class NewWindowView(LoginRequiredMixin, LogMixin, generic.DetailView):
22 32 log_component = 'resources'
23 33 log_action = 'view'
... ... @@ -460,4 +470,167 @@ def ytvideo_finish_log(request, ytvideo):
460 470  
461 471 request.log_context = log_context
462 472  
463   - return JsonResponse({'message': 'ok'})
464 473 \ No newline at end of file
  474 + return JsonResponse({'message': 'ok'})
  475 +
  476 +
  477 +class StatisticsView(LoginRequiredMixin, LogMixin, generic.DetailView):
  478 + log_component = 'resources'
  479 + log_action = 'view_statistics'
  480 + log_resource = 'ytvideo'
  481 + log_context = {}
  482 +
  483 + login_url = reverse_lazy("users:login")
  484 + redirect_field_name = 'next'
  485 + model = YTVideo
  486 + template_name = 'youtube/relatorios.html'
  487 +
  488 + def dispatch(self, request, *args, **kwargs):
  489 + slug = self.kwargs.get('slug', '')
  490 + ytvideo = get_object_or_404(YTVideo, slug = slug)
  491 +
  492 + if not has_subject_permissions(request.user, ytvideo.topic.subject):
  493 + return redirect(reverse_lazy('subjects:home'))
  494 +
  495 + return super(StatisticsView, self).dispatch(request, *args, **kwargs)
  496 +
  497 + def get_context_data(self, **kwargs):
  498 + context = super(StatisticsView, self).get_context_data(**kwargs)
  499 +
  500 + self.log_context['category_id'] = self.object.topic.subject.category.id
  501 + self.log_context['category_name'] = self.object.topic.subject.category.name
  502 + self.log_context['category_slug'] = self.object.topic.subject.category.slug
  503 + self.log_context['subject_id'] = self.object.topic.subject.id
  504 + self.log_context['subject_name'] = self.object.topic.subject.name
  505 + self.log_context['subject_slug'] = self.object.topic.subject.slug
  506 + self.log_context['topic_id'] = self.object.topic.id
  507 + self.log_context['topic_name'] = self.object.topic.name
  508 + self.log_context['topic_slug'] = self.object.topic.slug
  509 + self.log_context['ytvideo_id'] = self.object.id
  510 + self.log_context['ytvideo_name'] = self.object.name
  511 + self.log_context['ytvideo_slug'] = self.object.slug
  512 +
  513 + super(StatisticsView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  514 +
  515 +
  516 + context['title'] = _('Youtube Video Reports')
  517 +
  518 + slug = self.kwargs.get('slug')
  519 + ytvideo = get_object_or_404(YTVideo, slug = slug)
  520 + print (self.request.GET.get('init_date',''))
  521 + date_format = "%d/%m/%Y %H:%M" if self.request.GET.get('language','') == 'pt-br' else "%m/%d/%Y %I:%M %p"
  522 + if self.request.GET.get('language','') == "":
  523 + start_date = datetime.datetime.now() - datetime.timedelta(30)
  524 + end_date = datetime.datetime.now()
  525 + else :
  526 + start_date = datetime.datetime.strptime(self.request.GET.get('init_date',''),date_format)
  527 + end_date = datetime.datetime.strptime(self.request.GET.get('end_date',''),date_format)
  528 + context["init_date"] = start_date
  529 + context["end_date"] = end_date
  530 + alunos = ytvideo.students.all()
  531 + if ytvideo.all_students :
  532 + alunos = ytvideo.topic.subject.students.all()
  533 +
  534 + vis_ou = Log.objects.filter(context__contains={'ytvideo_id':ytvideo.id},resource="ytvideo",user_email__in=(aluno.email for aluno in alunos), datetime__range=(start_date,end_date + datetime.timedelta(minutes = 1))).filter(Q(action="view") | Q(action="watch") | Q(action="finish"))
  535 + did,n_did,history = str(_("Realized")),str(_("Unrealized")),str(_("Historic"))
  536 + re = []
  537 + data_n_did,data_history = [],[]
  538 + json_n_did, json_history = {},{}
  539 +
  540 + from django.db.models import Count, Max
  541 + views_user = vis_ou.values("user_email").annotate(views=Count("user_email"))
  542 + date_last = vis_ou.values("user_email").annotate(last=Max("datetime"))
  543 +
  544 + for log_al in vis_ou.order_by("datetime"):
  545 + data_history.append([str(alunos.get(email=log_al.user_email)),
  546 + ", ".join([str(x) for x in ytvideo.topic.subject.group_subject.filter(participants__email=log_al.user_email)]),
  547 + log_al.action,log_al.datetime])
  548 + json_history["data"] = data_history
  549 +
  550 + column_view,column_watch,column_finish = str(_('View')),str(_('Watch')),str(_('Finish'))
  551 +
  552 + not_view = alunos.exclude(email__in=[log.user_email for log in vis_ou.filter(action="view").distinct("user_email")])
  553 + index = 0
  554 + for alun in not_view:
  555 + data_n_did.append([index,str(alun),", ".join([str(x) for x in ytvideo.topic.subject.group_subject.filter(participants__email=alun.email)]),column_view, str(alun.email)])
  556 + index += 1
  557 +
  558 + not_watch = alunos.exclude(email__in=[log.user_email for log in vis_ou.filter(action="watch").distinct("user_email")])
  559 + for alun in not_watch:
  560 + data_n_did.append([index,str(alun),", ".join([str(x) for x in ytvideo.topic.subject.group_subject.filter(participants__email=alun.email)]),column_watch, str(alun.email)])
  561 + index += 1
  562 +
  563 + not_finish = alunos.exclude(email__in=[log.user_email for log in vis_ou.filter(action="finish").distinct("user_email")])
  564 + for alun in not_finish:
  565 + data_n_did.append([index,str(alun),", ".join([str(x) for x in ytvideo.topic.subject.group_subject.filter(participants__email=alun.email)]),column_finish, str(alun.email)])
  566 + index += 1
  567 +
  568 + json_n_did["data"] = data_n_did
  569 +
  570 +
  571 + context["json_n_did"] = json_n_did
  572 + context["json_history"] = json_history
  573 + c_visualizou = vis_ou.filter(action="view").distinct("user_email").count()
  574 + c_watch = vis_ou.filter(action="watch").distinct("user_email").count()
  575 + c_finish = vis_ou.filter(action="finish").distinct("user_email").count()
  576 + re.append([str(_('Youtube Video')),did,n_did])
  577 +
  578 + re.append([column_view,c_visualizou, alunos.count() - c_visualizou])
  579 + re.append([column_watch,c_watch, alunos.count() - c_watch])
  580 + re.append([column_finish,c_finish, alunos.count() - c_finish])
  581 +
  582 + context['view'] = column_view
  583 + context['watch'] = column_watch
  584 + context['finish'] = column_finish
  585 + context['topic'] = ytvideo.topic
  586 + context['subject'] = ytvideo.topic.subject
  587 + context['youtube'] = ytvideo
  588 + context['db_data'] = re
  589 + context['title_chart'] = _('Actions about resource')
  590 + context['title_vAxis'] = _('Quantity')
  591 +
  592 + context["n_did_table"] = n_did
  593 + context["did_table"] = did
  594 + context["history_table"] = history
  595 + return context
  596 +
  597 +
  598 +
  599 +class SendMessage(LoginRequiredMixin, LogMixin, generic.edit.FormView):
  600 + log_component = 'resources'
  601 + log_action = 'send'
  602 + log_resource = 'ytvideo'
  603 + log_context = {}
  604 +
  605 + login_url = reverse_lazy("users:login")
  606 + redirect_field_name = 'next'
  607 +
  608 + template_name = 'youtube/send_message.html'
  609 + form_class = FormModalMessage
  610 +
  611 + def dispatch(self, request, *args, **kwargs):
  612 + slug = self.kwargs.get('slug', '')
  613 + ytvideo = get_object_or_404(YTVideo, slug = slug)
  614 + self.ytvideo = ytvideo
  615 +
  616 + if not has_subject_permissions(request.user, ytvideo.topic.subject):
  617 + return redirect(reverse_lazy('subjects:home'))
  618 +
  619 + return super(SendMessage, self).dispatch(request, *args, **kwargs)
  620 +
  621 + def form_valid(self, form):
  622 + message = form.cleaned_data.get('comment')
  623 + image = form.cleaned_data.get("image")
  624 + users = (self.request.POST.get('users[]','')).split(",")
  625 + user = self.request.user
  626 + subject = self.ytvideo.topic.subject
  627 + for u in users:
  628 + to_user = User.objects.get(email=u)
  629 + talk, create = Conversation.objects.get_or_create(user_one=user,user_two=to_user)
  630 + created = TalkMessages.objects.create(text=message,talk=talk,user=user,subject=subject,image=image)
  631 + return JsonResponse({"message":"ok"})
  632 +
  633 + def get_context_data(self, **kwargs):
  634 + context = super(SendMessage,self).get_context_data()
  635 + context["ytvideo"] = get_object_or_404(YTVideo, slug=self.kwargs.get('slug', ''))
  636 + return context
  637 +
... ...