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 47 color: #ffffff; }
48 48  
49 49 .tag-name {
50   - color: #ffffff;
51   - font-size: 10px; }
  50 + color: #ffffff; }
52 51  
53 52 #left-data-selector {
54 53 background: linear-gradient(#0e8999, #6bf0ce);
... ... @@ -60,7 +59,8 @@
60 59 width: 30%;
61 60 float: left; }
62 61 .chart h4 {
63   - color: #009688; }
  62 + color: #009688;
  63 + text-align: center; }
64 64  
65 65 .selector {
66 66 width: 90%;
... ... @@ -115,4 +115,8 @@
115 115 .most-accessed-item:hover {
116 116 background-color: #3aa7ad; }
117 117  
  118 +#month_selector_div {
  119 + text-align: center;
  120 + color: #009688; }
  121 +
118 122 /*# sourceMappingURL=general.css.map */
... ...
analytics/static/analytics/general.css.map
1 1 {
2 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 4 "sources": ["general.sass"],
5 5 "names": [],
6 6 "file": "general.css"
... ...
analytics/static/analytics/general.sass
... ... @@ -63,7 +63,6 @@ $title-color: #009688
63 63  
64 64 .tag-name
65 65 color: #ffffff
66   - font-size: 10px
67 66  
68 67  
69 68 #left-data-selector
... ... @@ -75,8 +74,10 @@ $title-color: #009688
75 74 .chart
76 75 width: 30%
77 76 float: left
  77 +
78 78 h4
79 79 color: $title-color
  80 + text-align: center
80 81  
81 82 .selector
82 83 width: 90%
... ... @@ -133,4 +134,9 @@ $title-color: #009688
133 134 border-bottom-color: #52b7bd
134 135  
135 136 .most-accessed-item:hover
136   - background-color: #3aa7ad
137 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 144 \ No newline at end of file
... ...
analytics/static/analytics/js/behavior.js
1 1  
  2 +
  3 +
2 4 $(document).ready(function(){
3 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 33 var selectors_options = {
8 34 init: function(){
9 35 selectors = $("div.selector");
... ... @@ -66,3 +92,5 @@ var selectors_options = {
66 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 348 var width = 800;
349 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 354 var container_div = d3.select("#most-used-tags-body");
... ... @@ -378,8 +358,8 @@ var charts = {
378 358 .style("background","#ddf8e7")
379 359 .append('g')
380 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 365 var color = d3.scaleLinear()
... ... @@ -392,7 +372,8 @@ var charts = {
392 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 377 var tag_cloud = svg.selectAll('.tag-cloud-div')
397 378 .data(dataset)
398 379 .enter()
... ... @@ -420,23 +401,29 @@ var charts = {
420 401 .text(function(d){
421 402 return d['name'];
422 403 })
  404 + .attr("text-anchor", "middle")
423 405 .attr("x", function(d){
424   - return xScale(d['count'])*0.2;
  406 + return xScale(d['count'])*1.2/2;
425 407 })
426 408 .attr("y", function(d){
427   - return xScale(d["count"])*0.2;
  409 + return xScale(d["count"])*0.4/2;
428 410 })
429 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 418 var simulation = d3.forceSimulation()
434 419 .force("x", d3.forceX(width/2).strength(0.05))
435 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 427 //simulation
441 428 simulation.nodes(dataset)
442 429 .on('tick', ticked); //so all data points are attached to it
... ... @@ -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 21  
22 22  
23 23 {% block content %}
24   - test
  24 +
25 25 {% endblock content %}
26 26 \ No newline at end of file
... ...
analytics/templates/analytics/general.html
... ... @@ -7,6 +7,7 @@
7 7 {% endblock style %}
8 8  
9 9 {% block javascript %}
  10 +
10 11 <script type="text/javascript" src="{% static "analytics/js/charts.js" %}"></script>
11 12 <script type="text/javascript" src=" {% static "analytics/js/behavior.js" %} "></script>
12 13 {% endblock javascript %}
... ... @@ -68,19 +69,20 @@
68 69 <section class="bottom-section">
69 70 <div class="chart left-chart">
70 71  
71   -
  72 + <h4>{% trans "Most accessed " %}</h4>
72 73 <div id="left-data-selector">
  74 +
73 75  
74 76 <div class="selector" data-url="categories">
75   - <p> {% trans "most accessed categories" %} </p>
  77 + <p> {% trans "Most accessed categories" %} </p>
76 78 </div>
77 79  
78 80 <div class="selector" data-url="subjects">
79   - <p> {% trans "most accessed subjects" %} </p>
  81 + <p> {% trans "Most accessed subjects" %} </p>
80 82 </div>
81 83  
82 84 <div class="selector" data-url="resources">
83   - <p> {% trans "most accessed resource" %} </p>
  85 + <p> {% trans "Most accessed resource" %} </p>
84 86 </div>
85 87  
86 88 </div>
... ... @@ -88,13 +90,36 @@
88 90 </div>
89 91 <div class="chart middle-chart">
90 92 <article>
91   - <h4>{% trans "most active users" %}</h4>
  93 + <h4>{% trans "Most active users" %}</h4>
92 94 </article>
93 95  
94 96 </div>
95 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 123 </div>
99 124 </section>
100 125  
... ...
analytics/urls.py
... ... @@ -4,6 +4,7 @@ from . import views
4 4  
5 5 urlpatterns = [
6 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 9 #"api" callls
9 10 url(r'^most_used_tags/$', views.most_used_tags, name="most_used_tags"),
... ... @@ -11,4 +12,6 @@ urlpatterns = [
11 12 url(r'^most_accessed_categories/$', views.most_accessed_categories, name = "most_accessed_categories"),
12 13 url(r'^most_accessed_resources/$', views.most_accessed_resource_kind, name= "most_accessed_resources"),
13 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 18 \ No newline at end of file
... ...
analytics/views.py
... ... @@ -13,6 +13,10 @@ import operator
13 13 from django.utils.translation import ugettext_lazy as _
14 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 21 class GeneralView(generic.TemplateView):
18 22 template_name = "analytics/general.html"
... ... @@ -20,20 +24,31 @@ class GeneralView(generic.TemplateView):
20 24 def dispatch(self, request, *args, **kwargs):
21 25  
22 26 if not request.user.is_staff:
23   - self.template_name = "analytics/category.html"
  27 + return redirect('analytics:view_category_data')
24 28 return super(GeneralView, self).dispatch(request, *args, **kwargs)
25 29  
26 30  
27 31 def get_context_data(self, **kwargs):
28 32 context = {}
  33 +
  34 + context['months'] = [_('January'), _('February'), _('March'), _('April'), _('May'), _('June'), _('July'), _('August'),
  35 + _('September'), _('October'), _('November'), _('December')]
29 36  
30 37 return context
31 38  
32 39  
33 40  
34 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 52 data = {}
38 53 #grab all references to that tag
39 54 for tag in tags:
... ... @@ -49,17 +64,31 @@ def most_used_tags(request):
49 64 else:
50 65 data[tag.name] = {'name': tag.name}
51 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 93 Subject view that returns a list of the most used subjects """
65 94  
... ... @@ -68,44 +97,45 @@ def most_accessed_subjects(request):
68 97 data = {} #empty response
69 98  
70 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 101 #order the values of the dictionary by the count in descendent order
82 102 subjects = sorted(subjects.values(), key = lambda x: x['count'], reverse=True )
83 103 subjects = subjects[:5]
84 104  
85 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 121 def most_accessed_categories(request):
90 122 data = {}
91 123  
92 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 129 categories = sorted(categories.values(), key = lambda x: x['count'], reverse = True)
103 130 categories = categories[:5]
104 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 139 data = {}
110 140 for resource in resources:
111 141 key = resource.__dict__['_my_subclass']
... ... @@ -114,6 +144,13 @@ def most_accessed_resource_kind(request):
114 144 else:
115 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 154 data = sorted(data.values(), key = lambda x: x['count'], reverse= True)
118 155 mapping = {}
119 156 mapping['pdffile'] = str(_('PDF File'))
... ... @@ -136,4 +173,46 @@ def most_active_users(request):
136 173 user_object = User.objects.get(id=user['user_id'])
137 174 user['image'] = user_object.image_url
138 175 user['user'] = user_object.social_name
139   - return JsonResponse(fifty_users, safe=False)
140 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 15 {% endif %}
16 16  
17 17  
  18 +{% if news %}
  19 +
  20 +
18 21  
19 22  
20 23 <!-- Wrapper for slides -->
21 24 <div id="myCarousel" class="carousel slide " data-ride="carousel">
22 25 <!-- Indicators -->
23 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 33 </ol>
29 34  
30 35 <div class="carousel-inner" role="listbox">
... ... @@ -52,6 +57,7 @@
52 57 </a>
53 58 </div>
54 59  
  60 +{% endif %}
55 61  
56 62  
57 63  
... ...
subjects/views.py
... ... @@ -40,6 +40,7 @@ from io import BytesIO
40 40 from itertools import chain
41 41 from django.core import serializers
42 42 from rest_framework.renderers import JSONRenderer
  43 +from rest_framework.parsers import JSONParser
43 44  
44 45 from users.serializers import UserSerializer
45 46 from file_link.serializers import SimpleFileLinkSerializer, CompleteFileLinkSerializer
... ... @@ -871,6 +872,21 @@ def realize_restore(request, subject):
871 872 if zip_file:
872 873 if zipfile.is_zipfile(zip_file):
873 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 892 return JsonResponse({'message': 'ok'})
877 893 \ No newline at end of file
... ...