Commit 1881b3ab8fde04e7401bd733c19a2ec1ba6de559

Authored by Jailson Dias
2 parents 1c94435d c08c4014

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

reports/migrations/0003_auto_20170323_1517.py 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10.4 on 2017-03-23 18:17
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations, models
  6 +
  7 +
  8 +class Migration(migrations.Migration):
  9 +
  10 + dependencies = [
  11 + ('reports', '0002_reportxls'),
  12 + ]
  13 +
  14 + operations = [
  15 + migrations.AlterField(
  16 + model_name='reportxls',
  17 + name='xls_data',
  18 + field=models.TextField(null=True),
  19 + ),
  20 + ]
... ...
reports/migrations/0004_auto_20170323_1520.py 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10.4 on 2017-03-23 18:20
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations, models
  6 +
  7 +
  8 +class Migration(migrations.Migration):
  9 +
  10 + dependencies = [
  11 + ('reports', '0003_auto_20170323_1517'),
  12 + ]
  13 +
  14 + operations = [
  15 + migrations.AlterField(
  16 + model_name='reportxls',
  17 + name='xls_data',
  18 + field=models.TextField(),
  19 + ),
  20 + ]
... ...
reports/migrations/0005_auto_20170323_1603.py 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10.4 on 2017-03-23 19:03
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations, models
  6 +
  7 +
  8 +class Migration(migrations.Migration):
  9 +
  10 + dependencies = [
  11 + ('reports', '0004_auto_20170323_1520'),
  12 + ]
  13 +
  14 + operations = [
  15 + migrations.AlterField(
  16 + model_name='reportxls',
  17 + name='xls_data',
  18 + field=models.FileField(upload_to='excel/'),
  19 + ),
  20 + ]
... ...
reports/migrations/0006_auto_20170323_1629.py 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +# -*- coding: utf-8 -*-
  2 +# Generated by Django 1.10.4 on 2017-03-23 19:29
  3 +from __future__ import unicode_literals
  4 +
  5 +from django.db import migrations, models
  6 +
  7 +
  8 +class Migration(migrations.Migration):
  9 +
  10 + dependencies = [
  11 + ('reports', '0005_auto_20170323_1603'),
  12 + ]
  13 +
  14 + operations = [
  15 + migrations.AlterField(
  16 + model_name='reportxls',
  17 + name='xls_data',
  18 + field=models.FileField(upload_to='files/'),
  19 + ),
  20 + ]
... ...
reports/models.py
... ... @@ -17,7 +17,7 @@ class ReportCSV(models.Model):
17 17 class ReportXLS(models.Model):
18 18  
19 19 user = models.ForeignKey(User)
20   - xls_data = models.TextField()
  20 + xls_data = models.FileField(upload_to = 'files/')
21 21  
22 22 class Meta:
23 23 verbose_name = "ReportCSV"
... ...
reports/templates/reports/view.html
... ... @@ -65,10 +65,11 @@
65 65 <ul id="report-info">
66 66 <li> {{data.values|length}} {% trans "register(s)" %} </li>
67 67 <li>
68   - <a href="{% url 'subjects:reports:download_report_csv' %}"><i class="fa fa-download" aria-hidden="true"></i> {% trans "Interactions Data" %}</a>
  68 + <a href="{% url 'subjects:reports:download_report_csv' %}"><i class="fa fa-download" aria-hidden="true"></i> {% trans "Interactions Data (.csv)" %}</a>
69 69  
70 70  
71 71 </li>
  72 + <li><a href="{% url 'subjects:reports:download_report_xls' %}"><i class="fa fa-download" aria-hidden="true"></i> {% trans "Interactions Data (.xls)" %}</a></li>
72 73 </ul>
73 74  
74 75  
... ...
reports/urls.py
... ... @@ -8,4 +8,5 @@ urlpatterns = [
8 8 url(r'^get/resources/$', views.get_resources, name='get_resource_and_tags'),
9 9 url(r'^get/tags/$', views.get_tags, name='get_tags'),
10 10 url(r'^post/download_report/$', views.download_report_csv, name="download_report_csv"),
  11 + url(r'^post/download_report/excel$', views.download_report_xls, name="download_report_xls"),
11 12 ]
12 13 \ No newline at end of file
... ...
reports/views.py
... ... @@ -4,9 +4,9 @@ from django.utils.translation import ugettext_lazy as _
4 4  
5 5 from django import forms
6 6 from django.core.urlresolvers import reverse_lazy
7   -
  7 +from amadeus import settings
8 8 from django.contrib import messages
9   -
  9 +from os.path import join
10 10 import django.views.generic as generic
11 11 from mural.models import SubjectPost, Comment, MuralVisualizations
12 12 from django.db.models import Q
... ... @@ -20,6 +20,7 @@ from collections import OrderedDict
20 20 from django.forms import formset_factory
21 21 from .models import ReportCSV, ReportXLS
22 22 import pandas as pd
  23 +from io import BytesIO
23 24  
24 25 class ReportView(LoginRequiredMixin, generic.FormView):
25 26 template_name = "reports/create.html"
... ... @@ -133,11 +134,13 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
133 134 context['end_date'] = params_data['end_date']
134 135 context['subject'] = subject
135 136  
  137 + #I used getlist method so it can get more than one tag and one resource class_name
136 138 resources = params_data.getlist('resource')
137 139 tags = params_data.getlist('tag')
  140 +
138 141 self.from_mural = params_data['from_mural']
139   - #I used getlist method so it can get more than one tag and one resource class_name
140   - context['data'], context['header'] = self.get_mural_data(subject, params_data['init_date'], params_data['end_date'],
  142 +
  143 + context['data'], context['header'] = self.get_mural_data(subject, context['topic_name'], params_data['init_date'], params_data['end_date'],
141 144 resources, tags )
142 145  
143 146  
... ... @@ -154,19 +157,32 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
154 157 report.save()
155 158  
156 159 #for excel files
157   - """ if ReportXLS.objects.filter(user= self.request.user).count() > 0:
  160 + if ReportXLS.objects.filter(user= self.request.user).count() > 0:
158 161 report = ReportXLS.objects.get(user=self.request.user)
159 162 report.delete()
160 163  
161   - df.drop(df.columns[[0]], axis=1, inplace=True)
162   - writer = pd.ExcelWriter('pandas_simple.xlsx')
163   - report = ReportXLS(user= self.request.user, xls_data = df.to_excel(writer))
164   - report.save()"""
165   -
  164 + path = join(settings.MEDIA_ROOT, 'files' , 'report'+str(self.request.user.id)+'.xls')
  165 + writer = pd.ExcelWriter(path)
  166 + df.to_excel(writer, sheet_name='first_sheet')
  167 + writer.save()
  168 + report = ReportXLS(user= self.request.user )
  169 + report.xls_data.name = path
  170 + report.save()
166 171  
167 172 return context
168 173  
169   - def get_mural_data(self, subject, init_date, end_date, resources_id, tags_id):
  174 +
  175 + def get_mural_data(self, subject, topics_query, init_date, end_date, resources_type_names, tags_id):
  176 + """
  177 +
  178 + Process all the data to be brough by the report
  179 + Subject: subject where the report is being created
  180 + topics_query: it's either one of the topics or all of them
  181 + init_date: When the reports filter of dates stars
  182 + end_date: When the reports filter of dates end
  183 + resources_type_names: resources subclasses name that were selected
  184 + tags_id = ID of tag objects that were selected
  185 + """
170 186 data = {}
171 187 students = subject.students.all()
172 188 formats = ["%d/%m/%Y", "%m/%d/%Y", "%Y-%m-%d"] #so it accepts english and portuguese date formats
... ... @@ -177,7 +193,10 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
177 193  
178 194 except ValueError:
179 195 pass
180   -
  196 + if topics_query == _("All"):
  197 + topics = subject.topic_subject.all()
  198 + else:
  199 + topics = Topic.objects.get(id=topics_query)
181 200 header = ['User']
182 201  
183 202 #I use this so the system can gather data up to end_date 11h59 p.m.
... ... @@ -186,9 +205,9 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
186 205  
187 206 #For each student in the subject
188 207 for student in students:
189   - data[student] = []
  208 + data[student.id] = []
190 209  
191   - data[student].append(student.social_name)
  210 + data[student.id].append(student.social_name)
192 211  
193 212 interactions = OrderedDict()
194 213  
... ... @@ -240,26 +259,26 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
240 259  
241 260  
242 261 #VAR08 through VAR_019 of documenttation:
243   - if len(resources_id) > 0:
244   - resources_data = self.get_resources_and_tags_data(resources_id, tags_id, student, subject, init_date, end_date)
  262 + if len(resources_type_names) > 0:
  263 + resources_data = self.get_resources_and_tags_data(resources_type_names, tags_id, student, subject, topics, init_date, end_date)
245 264 for key, value in resources_data.items():
246 265 interactions[key] = value
247 266  
248 267  
249 268 #VAR20 - number of access to mural between 6 a.m to 12a.m.
250 269 interactions[_('Number of access to mural between 6 a.m to 12a.m. .')] = Log.objects.filter(action="access", resource="subject",
251   - user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (5, 11)).count()
  270 + user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (5, 11), datetime__range=(init_date,end_date)).count()
252 271  
253 272 #VAR21 - number of access to mural between 0 p.m to 6p.m.
254 273 interactions[_('Number of access to mural between 0 p.m to 6p.m. .')] = Log.objects.filter(action="access", resource="subject",
255   - user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (11, 17)).count()
  274 + user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (11, 17), datetime__range=(init_date,end_date)).count()
256 275 #VAR22
257 276 interactions[_('Number of access to mural between 6 p.m to 12p.m. .')] = Log.objects.filter(action="access", resource="subject",
258   - user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (17, 23)).count()
  277 + user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (17, 23), datetime__range=(init_date,end_date)).count()
259 278  
260 279 #VAR23
261 280 interactions[_('Number of access to mural between 0 a.m to 6a.m. .')] = Log.objects.filter(action="access", resource="subject",
262   - user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (23, 5)).count()
  281 + user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__hour__range = (23, 5), datetime__range=(init_date,end_date)).count()
263 282  
264 283 #VAR24 through 30
265 284 day_numbers = [0, 1, 2, 3, 4, 5, 6]
... ... @@ -267,7 +286,7 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
267 286 distinct_days = 0
268 287 for day_num in day_numbers:
269 288 interactions[_('Number of access to the subject on ')+ day_names[day_num]] = Log.objects.filter(action="access", resource="subject",
270   - user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__week_day = day_num).count()
  289 + user_id= student.id, context__contains = {'subject_id' : subject.id}, datetime__week_day = day_num, datetime__range = (init_date, end_date)).count()
271 290 #to save the distinct days the user has accessed
272 291 if interactions[_('Number of access to the subject on ')+ day_names[day_num]] > 0:
273 292 distinct_days += 1
... ... @@ -276,25 +295,39 @@ class ViewReportView(LoginRequiredMixin, generic.TemplateView):
276 295 interactions[_("Class")] = ""
277 296 interactions[_("Performance")] = ""
278 297 for value in interactions.values():
279   - data[student].append(value)
  298 + data[student.id].append(value)
280 299  
281 300  
282 301 for key in interactions.keys():
283 302 header.append(key)
284 303 return data, header
285 304  
286   - def get_resources_and_tags_data(self, resources_types, tags, student, subject, init_date, end_date):
  305 + def get_resources_and_tags_data(self, resources_types, tags, student, subject, topics, init_date, end_date):
287 306 data = OrderedDict()
288   -
  307 +
289 308 for i in range(len(resources_types)):
290 309  
291   - resources = Resource.objects.select_related(resources_types[i].lower()).filter(tags__in = tags, topic__in=subject.topic_subject.all())
  310 + if isinstance(topics,Topic):
  311 + resources = Resource.objects.select_related(resources_types[i].lower()).filter(tags__in = tags, topic=topics)
  312 + else:
  313 + resources = Resource.objects.select_related(resources_types[i].lower()).filter(tags__in = tags, topic__in=topics)
292 314 distinct_resources = 0
293 315 total_count = 0
  316 +
294 317 for resource in resources:
295   - count = Log.objects.filter(action="view", resource=resources_types[i].lower(),
296   - user_id = student.id, context__contains = {'subject_id': subject.id,
297   - resources_types[i].lower()+'_id': resource.id}, datetime__range=(init_date, end_date)).count()
  318 + if isinstance(topics,Topic):
  319 + #or it selected only one topic to work with
  320 + count = Log.objects.filter(action="view", resource=resources_types[i].lower(),
  321 + user_id = student.id, context__contains = {'subject_id': subject.id,
  322 + resources_types[i].lower()+'_id': resource.id, 'topic_id': topics.id}, datetime__range=(init_date, end_date)).count()
  323 +
  324 + else:
  325 + #or the user selected all
  326 +
  327 + count = Log.objects.filter(action="view", resource=resources_types[i].lower(),
  328 + user_id = student.id, context__contains = {'subject_id': subject.id,
  329 + resources_types[i].lower()+'_id': resource.id}, datetime__range=(init_date, end_date)).count()
  330 +
298 331 if count > 0:
299 332 distinct_resources += 1
300 333 total_count += count
... ... @@ -366,7 +399,7 @@ def get_tags(request):
366 399  
367 400 #adding empty tag for the purpose of giving the user this option for adicional behavior
368 401 tags = list(tags)
369   - tags.append(Tag(name=""))
  402 + tags.append(Tag(name=" "))
370 403 data['tags'] = [ {'id':tag.id, 'name':tag.name} for tag in tags]
371 404 return JsonResponse(data)
372 405  
... ... @@ -377,4 +410,12 @@ def download_report_csv(request):
377 410 response = HttpResponse(report.csv_data,content_type='text/csv')
378 411 response['Content-Disposition'] = 'attachment; filename="report.csv"'
379 412  
  413 + return response
  414 +
  415 +def download_report_xls(request):
  416 + report = ReportXLS.objects.get(user= request.user)
  417 +
  418 + response = HttpResponse(report.xls_data,content_type='application/ms-excel')
  419 + response['Content-Disposition'] = 'attachment; filename="report.xls"'
  420 +
380 421 return response
381 422 \ No newline at end of file
... ...