Commit 34817c0f312f39881f901daa0af9a273a7e6df91

Authored by Jailson Dias
2 parents 71c243c0 db7f1d1e

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

analytics/static/.sass-cache/01cecb7b42e56765f6ed49ed3c70281ebdc742c7/general.sassc
No preview for this file type
analytics/static/analytics/general.css
@@ -47,8 +47,7 @@ @@ -47,8 +47,7 @@
47 color: #ffffff; } 47 color: #ffffff; }
48 48
49 .tag-name { 49 .tag-name {
50 - color: #ffffff;  
51 - font-size: 10px; } 50 + color: #ffffff; }
52 51
53 #left-data-selector { 52 #left-data-selector {
54 background: linear-gradient(#0e8999, #6bf0ce); 53 background: linear-gradient(#0e8999, #6bf0ce);
@@ -60,7 +59,8 @@ @@ -60,7 +59,8 @@
60 width: 30%; 59 width: 30%;
61 float: left; } 60 float: left; }
62 .chart h4 { 61 .chart h4 {
63 - color: #009688; } 62 + color: #009688;
  63 + text-align: center; }
64 64
65 .selector { 65 .selector {
66 width: 90%; 66 width: 90%;
@@ -115,4 +115,8 @@ @@ -115,4 +115,8 @@
115 .most-accessed-item:hover { 115 .most-accessed-item:hover {
116 background-color: #3aa7ad; } 116 background-color: #3aa7ad; }
117 117
  118 +#month_selector_div {
  119 + text-align: center;
  120 + color: #009688; }
  121 +
118 /*# sourceMappingURL=general.css.map */ 122 /*# sourceMappingURL=general.css.map */
analytics/static/analytics/general.css.map
1 { 1 {
2 "version": 3, 2 "version": 3,
3 -"mappings": "AAEA,YAAY;EACR,MAAM,EAAE,iBAAiB;EACzB,aAAa,EAAE,IAAI;EACnB,OAAO,EAAE,IAAI;EACb,QAAQ,EAAE,IAAI;EACd,KAAK,EAAE,IAAI;EACX,gBAAgB,EAAE,OAAO;;AAE7B,sBAAsB;EAClB,MAAM,EAAE,GAAG;EACX,OAAO,EAAE,KAAK;EACd,yBAAE;IACE,KAAK,EAdC,OAAO;EAgBjB,yBAAE;IACE,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,WAAW;IACpB,KAAK,EAAE,GAAG;IACV,aAAa,EAAE,GAAG;IAElB,4BAAE;MACE,YAAY,EAAE,EAAE;MAChB,KAAK,EAAE,GAAG;MACV,KAAK,EAAE,KAAK;MACZ,SAAS,EAAE,IAAI;MACf,gBAAgB,EAAE,OAAO;MACzB,KAAK,EAAE,IAAI;MACX,UAAU,EAAE,MAAM;MAClB,aAAa,EAAE,IAAI;MACnB,MAAM,EAAE,IAAI;IAGhB,qCAAW;MACP,gBAAgB,EAAE,OAAO;MACzB,KAAK,EAAE,IAAI;MACX,UAAU,EAAE,MAAM;MAClB,aAAa,EAAE,IAAI;;AAM/B,sBAAsB;EAClB,UAAU,EAAE,2CAA2C;EACvD,MAAM,EAAE,IAAI;EACZ,aAAa,EAAE,IAAI;EACnB,KAAK,EAAE,OAAO;EACd,WAAW,EAAE,GAAG;EAChB,UAAU,EAAE,IAAI;EAEhB,yBAAE;IACE,WAAW,EAAE,EAAE;;AAGvB,UAAU;EACN,aAAa,EAAE,IAAI;EACnB,KAAK,EAAE,OAAO;;AAKlB,SAAS;EACL,KAAK,EAAE,OAAO;EACd,SAAS,EAAE,IAAI;;AAGnB,mBAAmB;EACf,UAAU,EAAE,iCAAmC;EAC/C,UAAU,EAAE,EAAE;EACd,WAAW,EAAE,EAAE;EACf,cAAc,EAAE,EAAE;;AAEtB,MAAM;EACF,KAAK,EAAE,GAAG;EACV,KAAK,EAAE,IAAI;EACX,SAAE;IACE,KAAK,EA9EC,OAAO;;AAgFrB,SAAS;EACL,KAAK,EAAE,GAAG;EACV,MAAM,EAAE,IAAI;EACZ,KAAK,EAAE,KAAK;EACZ,YAAY,EAAE,GAAG;EACjB,gBAAgB,EAAE,OAAO;EACzB,UAAU,EAAE,GAAG;EACf,aAAa,EAAE,iBAAiB;EAChC,WAAC;IACG,WAAW,EAAE,IAAI;IACjB,SAAS,EAAE,IAAI;;AAInB,qBAAO;EACH,UAAU,EAAE,MAAM;;AAE1B,aAAa;EACT,UAAU,EAAE,iCAAkC;EAC9C,KAAK,EAAE,KAAK;EACZ,aAAa,EAAE,IAAI;EACnB,OAAO,EAAE,GAAG;;AAEhB,mBAAmB;EACf,gBAAgB,EAAE,OAAO;EACzB,KAAK,EAAE,GAAG;EACV,WAAW,EAAE,EAAE;EACf,UAAU,EAAE,EAAE;EACd,QAAQ,EAAE,QAAQ;EAClB,YAAY,EAAE,CAAC;EACf,KAAK,EAAE,KAAK;EACZ,MAAM,EAAE,iBAAiB;EACzB,UAAU,EAAE,sDAAsD;EAElE,sBAAE;IACE,YAAY,EAAE,EAAE;;AAExB,qDAAqD;EACjD,MAAM,EAAE,IAAI;EACZ,IAAI,EAAE,GAAG;EACT,MAAM,EAAE,iBAAiB;EACzB,OAAO,EAAE,GAAG;EACZ,MAAM,EAAE,CAAC;EACT,KAAK,EAAE,CAAC;EACR,QAAQ,EAAE,QAAQ;EAClB,cAAc,EAAE,IAAI;;AAGxB,0BAA0B;EACtB,YAAY,EAAE,IAAI;EAClB,WAAW,EAAE,IAAI;EACjB,YAAY,EAAE,sBAAsB;EACpC,mBAAmB,EAAE,OAAO;;AAEhC,yBAAyB;EACrB,gBAAgB,EAAE,OAAO", 3 +"mappings": "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",
4 "sources": ["general.sass"], 4 "sources": ["general.sass"],
5 "names": [], 5 "names": [],
6 "file": "general.css" 6 "file": "general.css"
analytics/static/analytics/general.sass
@@ -63,7 +63,6 @@ $title-color: #009688 @@ -63,7 +63,6 @@ $title-color: #009688
63 63
64 .tag-name 64 .tag-name
65 color: #ffffff 65 color: #ffffff
66 - font-size: 10px  
67 66
68 67
69 #left-data-selector 68 #left-data-selector
@@ -75,8 +74,10 @@ $title-color: #009688 @@ -75,8 +74,10 @@ $title-color: #009688
75 .chart 74 .chart
76 width: 30% 75 width: 30%
77 float: left 76 float: left
  77 +
78 h4 78 h4
79 color: $title-color 79 color: $title-color
  80 + text-align: center
80 81
81 .selector 82 .selector
82 width: 90% 83 width: 90%
@@ -133,4 +134,9 @@ $title-color: #009688 @@ -133,4 +134,9 @@ $title-color: #009688
133 border-bottom-color: #52b7bd 134 border-bottom-color: #52b7bd
134 135
135 .most-accessed-item:hover 136 .most-accessed-item:hover
136 - background-color: #3aa7ad  
137 \ No newline at end of file 137 \ No newline at end of file
  138 + background-color: #3aa7ad
  139 +
  140 +
  141 +#month_selector_div
  142 + text-align: center
  143 + color: #009688
138 \ No newline at end of file 144 \ No newline at end of file
analytics/static/analytics/js/behavior.js
1 1
  2 +
  3 +
2 $(document).ready(function(){ 4 $(document).ready(function(){
3 selectors_options.init(); 5 selectors_options.init();
  6 +
  7 + //for month selector
  8 +
  9 + $('#month_selector').change(function(){
  10 + $.get('/analytics/amount_active_users_per_day', {month: $(this).val() }).done(function(data){
  11 + charts.month_heatmap(data, '#right-chart-body');
  12 +
  13 + });
  14 + });
  15 + //week date selector at the right-chart field
  16 + $('input.datepicker').datetimepicker({
  17 + format: 'L',
  18 + defaultDate: new Date(),
  19 + }).on('dp.change', function(ev){
  20 + $.get('/analytics/get_days_of_the_week_log', {date: ev.date._i}).done(function(data){
  21 + charts.month_heatmap(data, '#bottom-right-chart-body');
  22 + });
  23 +
  24 + });
  25 +
  26 +
  27 +
  28 +
4 }); 29 });
5 30
6 31
  32 +
7 var selectors_options = { 33 var selectors_options = {
8 init: function(){ 34 init: function(){
9 selectors = $("div.selector"); 35 selectors = $("div.selector");
@@ -66,3 +92,5 @@ var selectors_options = { @@ -66,3 +92,5 @@ var selectors_options = {
66 $(e).removeAttr("opened"); //remove attribute so it can call API again 92 $(e).removeAttr("opened"); //remove attribute so it can call API again
67 }, 93 },
68 }; 94 };
  95 +
  96 +
analytics/static/analytics/js/charts.js
@@ -348,27 +348,7 @@ var charts = { @@ -348,27 +348,7 @@ var charts = {
348 var width = 800; 348 var width = 800;
349 var height = 300; 349 var height = 300;
350 350
351 - function min(){  
352 - minimum = 100000000000;  
353 - for(var i = 0; i < dataset.length; i++){  
354 - if (dataset[i]['count'] < min){  
355 - minimum = dataset[i]['count'];  
356 - }  
357 - }  
358 -  
359 - return minimum  
360 - }  
361 -  
362 - function max(){  
363 - maximum = 0;  
364 - for(var i = 0; i < dataset.length; i++){  
365 - if (dataset[i]['count'] > max){  
366 - maximum = dataset[i]['count'];  
367 - }  
368 - }  
369 -  
370 - return maximum  
371 - } 351 +
372 352
373 353
374 var container_div = d3.select("#most-used-tags-body"); 354 var container_div = d3.select("#most-used-tags-body");
@@ -378,8 +358,8 @@ var charts = { @@ -378,8 +358,8 @@ var charts = {
378 .style("background","#ddf8e7") 358 .style("background","#ddf8e7")
379 .append('g') 359 .append('g')
380 .attr("transform", "translate(0,0)") 360 .attr("transform", "translate(0,0)")
381 - .style("width", width)  
382 - .attr("height", height); 361 + .attr("width", "100%")
  362 + .attr("height", height - 60);
383 363
384 364
385 var color = d3.scaleLinear() 365 var color = d3.scaleLinear()
@@ -392,7 +372,8 @@ var charts = { @@ -392,7 +372,8 @@ var charts = {
392 return Math.floor(Math.random() * (max - min)) + min; 372 return Math.floor(Math.random() * (max - min)) + min;
393 } 373 }
394 374
395 - var xScale = d3.scaleSqrt().domain([min(), max()]).range([10,80]); 375 + var xScale = d3.scaleSqrt().domain([d3.min(dataset, function(d){ return d['count']}),
  376 + d3.max(dataset, function(d){ return d.count; })]).range([100,200]);
396 var tag_cloud = svg.selectAll('.tag-cloud-div') 377 var tag_cloud = svg.selectAll('.tag-cloud-div')
397 .data(dataset) 378 .data(dataset)
398 .enter() 379 .enter()
@@ -420,23 +401,29 @@ var charts = { @@ -420,23 +401,29 @@ var charts = {
420 .text(function(d){ 401 .text(function(d){
421 return d['name']; 402 return d['name'];
422 }) 403 })
  404 + .attr("text-anchor", "middle")
423 .attr("x", function(d){ 405 .attr("x", function(d){
424 - return xScale(d['count'])*0.2; 406 + return xScale(d['count'])*1.2/2;
425 }) 407 })
426 .attr("y", function(d){ 408 .attr("y", function(d){
427 - return xScale(d["count"])*0.2; 409 + return xScale(d["count"])*0.4/2;
428 }) 410 })
429 .attr("class", "tag-name") 411 .attr("class", "tag-name")
430 - .attr("fill", "#ffffff"); 412 + .attr("fill", "#ffffff")
  413 + .style("font-size", function(d){
  414 + return xScale(d["count"])*0.1 + "px";
  415 + });
431 416
432 417
433 var simulation = d3.forceSimulation() 418 var simulation = d3.forceSimulation()
434 .force("x", d3.forceX(width/2).strength(0.05)) 419 .force("x", d3.forceX(width/2).strength(0.05))
435 .force("y", d3.forceY(height/2).strength(0.05)) 420 .force("y", d3.forceY(height/2).strength(0.05))
436 - .force("collide", d3.forceCollide(function(d){  
437 - return xScale(d['count'])*0.4;  
438 - }));  
439 - 421 + .force("charge", d3.forceManyBody().strength(-120).distanceMax(300)
  422 + .distanceMin(0));
  423 + /*
  424 + .force("collide", d3.forceCollide(function(d){
  425 + return xScale(d['count'])*0.3;
  426 + }))*/
440 //simulation 427 //simulation
441 simulation.nodes(dataset) 428 simulation.nodes(dataset)
442 .on('tick', ticked); //so all data points are attached to it 429 .on('tick', ticked); //so all data points are attached to it
@@ -448,6 +435,65 @@ var charts = { @@ -448,6 +435,65 @@ var charts = {
448 } 435 }
449 436
450 }); 437 });
  438 + },
  439 + month_heatmap: function(data, target){
  440 +
  441 +
  442 + if(target == '#right-chart-body' && $('#month-chart').length != 0){
  443 + $('#month-chart').fadeOut();
  444 + $('#month-chart').remove();
  445 + }
  446 +
  447 + if(target == "#bottom-right-chart-body" && $('#weekly-chart').length != 0){
  448 + $('#weekly-chart').fadeOut();
  449 + $('#weekly-chart').remove();
  450 + }
  451 +
  452 + var svg = d3.select(target).append('svg')
  453 + .attr('width', 300)
  454 + .attr('height', 200);
  455 +
  456 + if (target == "#right-chart-body"){
  457 + svg.attr('id', 'month-chart');
  458 + }
  459 +
  460 + if (target == "#bottom-right-chart-body"){
  461 + svg.attr('id', 'weekly-chart');
  462 + }
  463 +
  464 + //color range
  465 + var color = d3.scaleLinear().range(["#29c8b8", '#149e91']).domain([0, d3.max(data, function(d){ return d.count; })]);
  466 +
  467 + var rects = svg.selectAll("rect")
  468 + .data(data)
  469 + .enter()
  470 + .append("g");
  471 + rect_width = 40;
  472 + rect_height = 40;
  473 + rects.append("rect")
  474 + .attr("width", rect_width)
  475 + .attr("height", rect_height)
  476 + .attr("class", "day_rect")
  477 + .attr("x", function(d, i){
  478 +
  479 + return rect_width* (i % 7);
  480 + }).attr("y", function(d, i){
  481 + return rect_height*(Math.floor(i / 7));
  482 + }).attr("fill", function(d, i ){
  483 + return color(d.count);
  484 + });
  485 +
  486 + rects.append("text")
  487 + .text( function(d){
  488 + return d.day;
  489 + }).attr("fill", "white")
  490 + .attr("text-anchor", "middle")
  491 + .attr("x", function(d, i){
  492 + return rect_width* ( i % 7) + rect_width/2;
  493 + }).attr("y", function(d, i){
  494 + return rect_height*(Math.floor( i / 7)) + rect_height/2;
  495 + });
  496 +
451 } 497 }
452 } 498 }
453 499
analytics/templates/analytics/category.html
@@ -21,5 +21,5 @@ @@ -21,5 +21,5 @@
21 21
22 22
23 {% block content %} 23 {% block content %}
24 - test 24 +
25 {% endblock content %} 25 {% endblock content %}
26 \ No newline at end of file 26 \ No newline at end of file
analytics/templates/analytics/general.html
@@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
7 {% endblock style %} 7 {% endblock style %}
8 8
9 {% block javascript %} 9 {% block javascript %}
  10 +
10 <script type="text/javascript" src="{% static "analytics/js/charts.js" %}"></script> 11 <script type="text/javascript" src="{% static "analytics/js/charts.js" %}"></script>
11 <script type="text/javascript" src=" {% static "analytics/js/behavior.js" %} "></script> 12 <script type="text/javascript" src=" {% static "analytics/js/behavior.js" %} "></script>
12 {% endblock javascript %} 13 {% endblock javascript %}
@@ -68,19 +69,20 @@ @@ -68,19 +69,20 @@
68 <section class="bottom-section"> 69 <section class="bottom-section">
69 <div class="chart left-chart"> 70 <div class="chart left-chart">
70 71
71 - 72 + <h4>{% trans "Most accessed " %}</h4>
72 <div id="left-data-selector"> 73 <div id="left-data-selector">
  74 +
73 75
74 <div class="selector" data-url="categories"> 76 <div class="selector" data-url="categories">
75 - <p> {% trans "most accessed categories" %} </p> 77 + <p> {% trans "Most accessed categories" %} </p>
76 </div> 78 </div>
77 79
78 <div class="selector" data-url="subjects"> 80 <div class="selector" data-url="subjects">
79 - <p> {% trans "most accessed subjects" %} </p> 81 + <p> {% trans "Most accessed subjects" %} </p>
80 </div> 82 </div>
81 83
82 <div class="selector" data-url="resources"> 84 <div class="selector" data-url="resources">
83 - <p> {% trans "most accessed resource" %} </p> 85 + <p> {% trans "Most accessed resource" %} </p>
84 </div> 86 </div>
85 87
86 </div> 88 </div>
@@ -88,13 +90,36 @@ @@ -88,13 +90,36 @@
88 </div> 90 </div>
89 <div class="chart middle-chart"> 91 <div class="chart middle-chart">
90 <article> 92 <article>
91 - <h4>{% trans "most active users" %}</h4> 93 + <h4>{% trans "Most active users" %}</h4>
92 </article> 94 </article>
93 95
94 </div> 96 </div>
95 <div class="chart right-chart"> 97 <div class="chart right-chart">
96 - 98 + <div id="month_selector_div">
  99 + <h4>{% trans "Amount of access in: " %}
  100 + <select id="month_selector">
  101 + {% for month in months %}
  102 + <option>{{month}}</option>
  103 + {% endfor %}
  104 +
  105 + </select>
  106 + </h4>
  107 + </div>
97 108
  109 + <div id="right-chart-body">
  110 +
  111 + </div>
  112 +
  113 + <div class='input-group date'>
  114 + <label>{% trans "Select the begin of the week: " %}</label>
  115 + <input type='text' class="datepicker form-control" />
  116 + <span class="input-group-addon">
  117 + <span class="glyphicon glyphicon-calendar"></span>
  118 + </span>
  119 + </div>
  120 + <div id="bottom-right-chart-body">
  121 +
  122 + </div>
98 </div> 123 </div>
99 </section> 124 </section>
100 125
analytics/urls.py
@@ -4,6 +4,7 @@ from . import views @@ -4,6 +4,7 @@ from . import views
4 4
5 urlpatterns = [ 5 urlpatterns = [
6 url(r'^view/general/$', views.GeneralView.as_view(), name='view_general'), 6 url(r'^view/general/$', views.GeneralView.as_view(), name='view_general'),
  7 + url(r'^view/category/data$', views.CategoryView.as_view(), name='view_category_data'),
7 8
8 #"api" callls 9 #"api" callls
9 url(r'^most_used_tags/$', views.most_used_tags, name="most_used_tags"), 10 url(r'^most_used_tags/$', views.most_used_tags, name="most_used_tags"),
@@ -11,4 +12,6 @@ urlpatterns = [ @@ -11,4 +12,6 @@ urlpatterns = [
11 url(r'^most_accessed_categories/$', views.most_accessed_categories, name = "most_accessed_categories"), 12 url(r'^most_accessed_categories/$', views.most_accessed_categories, name = "most_accessed_categories"),
12 url(r'^most_accessed_resources/$', views.most_accessed_resource_kind, name= "most_accessed_resources"), 13 url(r'^most_accessed_resources/$', views.most_accessed_resource_kind, name= "most_accessed_resources"),
13 url(r'^most_active_users/$', views.most_active_users, name= "most_active_users"), 14 url(r'^most_active_users/$', views.most_active_users, name= "most_active_users"),
  15 + url(r'^amount_active_users_per_day/$', views.most_active_users_in_a_month, name="most_active_users_in_a_month"),
  16 + url(r'^get_days_of_the_week_log/$', views.get_days_of_the_week_log, name="get_days_of_the_week_log"),
14 ] 17 ]
15 \ No newline at end of file 18 \ No newline at end of file
analytics/views.py
@@ -13,6 +13,10 @@ import operator @@ -13,6 +13,10 @@ import operator
13 from django.utils.translation import ugettext_lazy as _ 13 from django.utils.translation import ugettext_lazy as _
14 from django.shortcuts import render, get_object_or_404, redirect 14 from django.shortcuts import render, get_object_or_404, redirect
15 15
  16 +from datetime import date, timedelta, datetime
  17 +import calendar
  18 +from collections import OrderedDict
  19 +
16 20
17 class GeneralView(generic.TemplateView): 21 class GeneralView(generic.TemplateView):
18 template_name = "analytics/general.html" 22 template_name = "analytics/general.html"
@@ -20,20 +24,31 @@ class GeneralView(generic.TemplateView): @@ -20,20 +24,31 @@ class GeneralView(generic.TemplateView):
20 def dispatch(self, request, *args, **kwargs): 24 def dispatch(self, request, *args, **kwargs):
21 25
22 if not request.user.is_staff: 26 if not request.user.is_staff:
23 - self.template_name = "analytics/category.html" 27 + return redirect('analytics:view_category_data')
24 return super(GeneralView, self).dispatch(request, *args, **kwargs) 28 return super(GeneralView, self).dispatch(request, *args, **kwargs)
25 29
26 30
27 def get_context_data(self, **kwargs): 31 def get_context_data(self, **kwargs):
28 context = {} 32 context = {}
  33 +
  34 + context['months'] = [_('January'), _('February'), _('March'), _('April'), _('May'), _('June'), _('July'), _('August'),
  35 + _('September'), _('October'), _('November'), _('December')]
29 36
30 return context 37 return context
31 38
32 39
33 40
34 def most_used_tags(request): 41 def most_used_tags(request):
35 - tags = Tag.objects.all() 42 +
  43 +
  44 + data = get_most_used_tags()
  45 + data = sorted(data.values(), key = lambda x: x['count'], reverse=True )
  46 + data = data[:15] #get top 15 tags
  47 + return JsonResponse(data, safe= False)
  48 +
  49 +def get_most_used_tags():
36 50
  51 + tags = Tag.objects.all()
37 data = {} 52 data = {}
38 #grab all references to that tag 53 #grab all references to that tag
39 for tag in tags: 54 for tag in tags:
@@ -49,17 +64,31 @@ def most_used_tags(request): @@ -49,17 +64,31 @@ def most_used_tags(request):
49 else: 64 else:
50 data[tag.name] = {'name': tag.name} 65 data[tag.name] = {'name': tag.name}
51 data[tag.name]['count'] = resources_count 66 data[tag.name]['count'] = resources_count
52 -  
53 - data = sorted(data.values(), key = lambda x: x['count'], reverse=True )  
54 - data = data[:30] #get top 30 tags  
55 - return JsonResponse(data, safe= False)  
56 -  
57 -  
58 -def heatmap(request):  
59 - return None 67 + return data
  68 +
  69 +
  70 +def most_active_users_in_a_month(request):
  71 + params = request.GET
  72 + days = get_days_of_the_month(params['month'])
  73 + mappings = {_('January'): 1, _('February'): 2, _('March'): 3, _('April'): 4, _('May'): 5, _('June'): 6, _('July'): 7
  74 + , _('August'): 8, _('September'): 9, _('October'): 10, _('November'): 11, _('December'): 12}
  75 +
  76 + days_list = []
  77 + for day in days:
  78 + built_date = date(date.today().year, mappings[params['month']], day)
  79 + days_list.append(built_date)
  80 + data = activity_in_timestamp(days_list)
  81 + data = [{"day": day.day, "count": day_count} for day, day_count in data.items()]
  82 + return JsonResponse(data, safe=False)
60 83
61 84
  85 +def activity_in_timestamp(days):
  86 + data = {}
  87 + for day in days:
  88 + day_count = Log.objects.filter(datetime__date = day).count()
  89 + data[day] = day_count
62 90
  91 + return data
63 """ 92 """
64 Subject view that returns a list of the most used subjects """ 93 Subject view that returns a list of the most used subjects """
65 94
@@ -68,44 +97,45 @@ def most_accessed_subjects(request): @@ -68,44 +97,45 @@ def most_accessed_subjects(request):
68 data = {} #empty response 97 data = {} #empty response
69 98
70 data = Log.objects.filter(resource = 'subject') 99 data = Log.objects.filter(resource = 'subject')
71 - subjects = {}  
72 - for datum in data:  
73 - if datum.context:  
74 - subject_id = datum.context['subject_id']  
75 - if subject_id in subjects.keys():  
76 - subjects[subject_id]['count'] = subjects[subject_id]['count'] + 1  
77 -  
78 - else:  
79 - subjects[subject_id] = {'name': datum.context['subject_name'], 'count': 1 }  
80 - 100 + subjects = get_log_count_of_resource(resource='subject')
81 #order the values of the dictionary by the count in descendent order 101 #order the values of the dictionary by the count in descendent order
82 subjects = sorted(subjects.values(), key = lambda x: x['count'], reverse=True ) 102 subjects = sorted(subjects.values(), key = lambda x: x['count'], reverse=True )
83 subjects = subjects[:5] 103 subjects = subjects[:5]
84 104
85 return JsonResponse(subjects, safe=False) 105 return JsonResponse(subjects, safe=False)
86 106
  107 +def get_log_count_of_resource(resource = ''):
  108 +
  109 + data = Log.objects.filter(resource = resource)
  110 + items = {}
  111 + for datum in data:
  112 + if datum.context:
  113 + item_id = datum.context[resource + '_id']
  114 + if item_id in items.keys():
  115 + items[item_id]['count'] = items[item_id]['count'] + 1
  116 + else:
  117 + items[item_id] = {'name': datum.context[resource+'_name'], 'count': 1}
  118 + return items
87 119
88 120
89 def most_accessed_categories(request): 121 def most_accessed_categories(request):
90 data = {} 122 data = {}
91 123
92 data = Log.objects.filter(resource = 'category') 124 data = Log.objects.filter(resource = 'category')
93 - categories = {}  
94 - for datum in data:  
95 - if datum.context:  
96 - category_id = datum.context['category_id']  
97 - if category_id in categories.keys():  
98 - categories[category_id]['count'] = categories[category_id]['count'] + 1  
99 - else:  
100 - categories[category_id] = {'name': datum.context['category_name'], 'count': 1 } 125 + categories = get_log_count_of_resource('category')
  126 +
  127 +
101 128
102 categories = sorted(categories.values(), key = lambda x: x['count'], reverse = True) 129 categories = sorted(categories.values(), key = lambda x: x['count'], reverse = True)
103 categories = categories[:5] 130 categories = categories[:5]
104 return JsonResponse(categories, safe= False) 131 return JsonResponse(categories, safe= False)
105 132
106 -def most_accessed_resource_kind(request):  
107 - resources = Resource.objects.distinct()  
108 133
  134 +def get_resource_subclasses_count():
  135 + """
  136 + get the amount of objects in each sub_class of resource
  137 + """
  138 + resources = Resource.objects.distinct()
109 data = {} 139 data = {}
110 for resource in resources: 140 for resource in resources:
111 key = resource.__dict__['_my_subclass'] 141 key = resource.__dict__['_my_subclass']
@@ -114,6 +144,13 @@ def most_accessed_resource_kind(request): @@ -114,6 +144,13 @@ def most_accessed_resource_kind(request):
114 else: 144 else:
115 data[key] = {'name': key, 'count': 1} 145 data[key] = {'name': key, 'count': 1}
116 146
  147 + return data
  148 +
  149 +
  150 +def most_accessed_resource_kind(request):
  151 +
  152 + data = get_resource_subclasses_count()
  153 +
117 data = sorted(data.values(), key = lambda x: x['count'], reverse= True) 154 data = sorted(data.values(), key = lambda x: x['count'], reverse= True)
118 mapping = {} 155 mapping = {}
119 mapping['pdffile'] = str(_('PDF File')) 156 mapping['pdffile'] = str(_('PDF File'))
@@ -136,4 +173,46 @@ def most_active_users(request): @@ -136,4 +173,46 @@ def most_active_users(request):
136 user_object = User.objects.get(id=user['user_id']) 173 user_object = User.objects.get(id=user['user_id'])
137 user['image'] = user_object.image_url 174 user['image'] = user_object.image_url
138 user['user'] = user_object.social_name 175 user['user'] = user_object.social_name
139 - return JsonResponse(fifty_users, safe=False)  
140 \ No newline at end of file 176 \ No newline at end of file
  177 + return JsonResponse(fifty_users, safe=False)
  178 +
  179 +
  180 +
  181 +
  182 +def get_days_of_the_month(month):
  183 +
  184 + #get current year
  185 + year = date.today().year
  186 + mappings = {_('January'): 1, _('February'): 2, _('March'): 3, _('April'): 4, _('May'): 5, _('June'): 6, _('July'): 7
  187 + , _('August'): 8, _('September'): 9, _('October'): 10, _('November'): 11, _('December'): 12}
  188 +
  189 + c = calendar.Calendar()
  190 + days = c.itermonthdays(year, mappings[month])
  191 + days_set = set()
  192 + for day in days:
  193 + days_set.add(day)
  194 +
  195 + days_set.remove(0) #because 0 is not aan actual day from that month
  196 + return days_set
  197 +
  198 +
  199 +
  200 +def get_days_of_the_week_log(request):
  201 + date = request.GET['date']
  202 + date = datetime.strptime( date, '%m/%d/%Y',)
  203 + days = get_days_of_the_week(date)
  204 + data = activity_in_timestamp(days)
  205 + data = [{"day": day.day, "count": day_count} for day, day_count in data.items()]
  206 +
  207 + return JsonResponse(data, safe= False)
  208 +
  209 +def get_days_of_the_week(date):
  210 +
  211 + days_set = []
  212 + days_set.append(date)
  213 + for j in range(1, 7):
  214 + days_set.append(date + timedelta(days=j))
  215 + return days_set
  216 +
  217 +
  218 +class CategoryView(generic.TemplateView):
  219 + template_name = "analytics/category.html"
subjects/templates/subjects/home.html
@@ -15,16 +15,21 @@ @@ -15,16 +15,21 @@
15 {% endif %} 15 {% endif %}
16 16
17 17
  18 +{% if news %}
  19 +
  20 +
18 21
19 22
20 <!-- Wrapper for slides --> 23 <!-- Wrapper for slides -->
21 <div id="myCarousel" class="carousel slide " data-ride="carousel"> 24 <div id="myCarousel" class="carousel slide " data-ride="carousel">
22 <!-- Indicators --> 25 <!-- Indicators -->
23 <ol class="carousel-indicators"> 26 <ol class="carousel-indicators">
24 - <li data-target="#myCarousel" data-slide-to="0" class="active"></li>  
25 - <li data-target="#myCarousel" data-slide-to="1"></li>  
26 - <li data-target="#myCarousel" data-slide-to="2"></li>  
27 - <li data-target="#myCarousel" data-slide-to="3"></li> 27 + <li data-target="#myCarousel" data-slide-to="0" class="active"></li>
  28 + {% for new in news %}
  29 + {% if forloop.counter != news.count %}
  30 + <li data-target="#myCarousel" data-slide-to="{{forloop.counter}}"></li>
  31 + {% endif %}
  32 + {% endfor %}
28 </ol> 33 </ol>
29 34
30 <div class="carousel-inner" role="listbox"> 35 <div class="carousel-inner" role="listbox">
@@ -52,6 +57,7 @@ @@ -52,6 +57,7 @@
52 </a> 57 </a>
53 </div> 58 </div>
54 59
  60 +{% endif %}
55 61
56 62
57 63
subjects/views.py
@@ -40,6 +40,7 @@ from io import BytesIO @@ -40,6 +40,7 @@ from io import BytesIO
40 from itertools import chain 40 from itertools import chain
41 from django.core import serializers 41 from django.core import serializers
42 from rest_framework.renderers import JSONRenderer 42 from rest_framework.renderers import JSONRenderer
  43 +from rest_framework.parsers import JSONParser
43 44
44 from users.serializers import UserSerializer 45 from users.serializers import UserSerializer
45 from file_link.serializers import SimpleFileLinkSerializer, CompleteFileLinkSerializer 46 from file_link.serializers import SimpleFileLinkSerializer, CompleteFileLinkSerializer
@@ -871,6 +872,21 @@ def realize_restore(request, subject): @@ -871,6 +872,21 @@ def realize_restore(request, subject):
871 if zip_file: 872 if zip_file:
872 if zipfile.is_zipfile(zip_file): 873 if zipfile.is_zipfile(zip_file):
873 file = zipfile.ZipFile(zip_file) 874 file = zipfile.ZipFile(zip_file)
874 - print(file.namelist()) 875 + total_files = len(file.namelist())
  876 +
  877 + json_file = file.namelist()[total_files-1]
  878 +
  879 + dst_path = os.path.join(settings.MEDIA_ROOT, "tmp")
  880 +
  881 + path = file.extract(json_file, dst_path)
  882 +
  883 + for line in open(path, 'r'):
  884 + print(line)
  885 + #print(json.loads(line))
  886 +
  887 + # with open(path) as bkp_file:
  888 + # data = json.loads(bkp_file.read())
  889 +
  890 + # print(data)
875 891
876 return JsonResponse({'message': 'ok'}) 892 return JsonResponse({'message': 'ok'})
877 \ No newline at end of file 893 \ No newline at end of file