From 1f4c8d2be3c176a093e174ef7e72e89a669a8596 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Fri, 25 Apr 2014 13:57:21 +0400 Subject: [PATCH 1/4] statistics page, filters for fullstat.csv --- lms/djangoapps/courseware/views.py | 95 ++++++++++++++++++++++++++++++ lms/urls.py | 3 +- 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/lms/djangoapps/courseware/views.py b/lms/djangoapps/courseware/views.py index 3d1104b5bc56..7cf303aa1f5a 100644 --- a/lms/djangoapps/courseware/views.py +++ b/lms/djangoapps/courseware/views.py @@ -45,12 +45,107 @@ from xmodule.tabs import CourseTabList, StaffGradingTab, PeerGradingTab, OpenEndedGradingTab import shoppingcart +#new +import csv +import datetime +from django.http import HttpResponse +from django.core.servers.basehttp import FileWrapper +import logging + from microsite_configuration import microsite log = logging.getLogger("edx.courseware") template_imports = {'urllib': urllib} +def stat(request): + context = {} + context['csrf'] = csrf(request)['csrf_token'] + filename = '/edx/app/edxapp/edx-platform/fullstat.csv' + if request.method == 'POST': + if 'download_stat_unfiltered' in request.POST: + return return_fullstat_csv(filename) + elif 'download_stat_filtered' in request.POST: + context['value_error_in_input'] = True + try: + register_date_min = None + register_date_max = None + if request.POST.get('min_date') != '': + register_date_min = datetime.datetime.strptime(request.POST.get('min_date'), "%d/%m/%Y") + if request.POST.get('max_date') != '': + register_date_max = datetime.datetime.strptime(request.POST.get('max_date'), "%d/%m/%Y") + context['value_error_in_input'] = False + return return_filtered_stat_csv(\ + school_login=request.POST.get('school_login'),\ + register_date_min=register_date_min,\ + register_date_max=register_date_max,\ + complete70=request.POST.get('complete70'),\ + complete100=request.POST.get('complete100')\ + ) + except: + return render_to_response('stat.html', context) + + return render_to_response('stat.html', context) + + +def return_fullstat_csv(filename): + """ + Returns fullstat.csv file. + """ + wrapper = FileWrapper(file(filename)) + response = HttpResponse(wrapper, content_type='text/csv') + response['Content-Disposition'] = 'attachment; filename=fullstat.csv' + return response + + +def return_filtered_stat_csv(school_login='', register_date_min=None, register_date_max=None, account_activated=None, complete70=None, complete100=None): + """ + Returns file with data from fullstat.csv filtered according to the parameters given (indices of columns can be changed): + [6] - school_login + [12] - register_date_min & register_date_max + [??] - account_activated (no column yet) + [13] - complete70 + [14] - complete100 + + If no values are chosen, returns a filtered file with all row of fullstat.csv which contain a valid registration date in the corresponding field. + """ + + response = HttpResponse(content_type='text/csv') + response['Content-Disposition'] = 'attachment; filename="stat_filtered.csv"' + writer = csv.writer(response) + + with open("/edx/app/edxapp/edx-platform/fullstat.csv", "r") as fullstatfile: + header_row = True + first_rows = True + for row in csv.reader(fullstatfile): + if header_row: + writer.writerow(row) + header_row = False + elif first_rows: + if len(row)>0 and row[0]=='-': + writer.writerow(row) + else: + first_rows = False + else: + if len(row) >= 15: # must contain at least 15 columns # change if new columns are added + + # no text in a text input --> str type + # no choice in radio input --> NoneType + + try: + register_date = datetime.datetime.strptime(row[12], "%d/%m/%Y") + if (school_login == '' or row[6] == school_login) and\ + (register_date_min == None or register_date_min <= register_date) and\ + (register_date_max == None or register_date <= register_date_max) and\ + (account_activated == None or True) and\ + (complete70 == None or (len(row[13]) == 4) == bool(complete70)) and\ + (complete100 == None or (len(row[14]) == 4) == bool(complete100)): # ultimate hack: len('da') == 4 + writer.writerow(row) + except: + pass + + return response + def user_groups(user): """ diff --git a/lms/urls.py b/lms/urls.py index 357b4be056d3..65bfc4b801be 100644 --- a/lms/urls.py +++ b/lms/urls.py @@ -72,8 +72,9 @@ url(r'^embargo$', 'student.views.embargo', name="embargo"), -url(r'^announcements/announcement_list$', 'student.views.announcement_list', name='announcement_list') + url(r'^stat$', 'courseware.views.stat', name='stat'), + url(r'^announcements/announcement_list$', 'student.views.announcement_list', name='announcement_list'), ) # if settings.FEATURES.get("MULTIPLE_ENROLLMENT_ROLES"): From b6c718a5480b43f434ae14aa5c4c7445225ce99f Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Fri, 25 Apr 2014 17:30:15 +0400 Subject: [PATCH 2/4] stat page centered (with lousy
tag) --- lms/templates/stat.html | 61 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 lms/templates/stat.html diff --git a/lms/templates/stat.html b/lms/templates/stat.html new file mode 100644 index 000000000000..6a4cc8cd7429 --- /dev/null +++ b/lms/templates/stat.html @@ -0,0 +1,61 @@ +<%! from django.utils.translation import ugettext as _ %> +<%! from microsite_configuration import page_title_breadcrumbs %> +<%! from django.core.urlresolvers import reverse %> +<%inherit file="/main.html" /> +<%namespace name='static' file='/static_content.html'/> + +
+

+ Страница статистики +

+

+Статистика по оценкам +

+

+

+ +

+ Логин школы: + +

+

+ Активирован ли аккаунт?
+ Да + Нет +

+

+ Выполнено ли 70 % заданий?
+ Да + Нет +

+

+ Выполнено ли 100 % заданий?
+ Да + Нет +

+

+ Дата регистрации на курс (в формате дд/мм/гггг):
+ От:
+ До: +

+ % if value_error_in_input: +

+ Пожалуйста, введите дату в корректном формате. +

+ % endif +

+ +

+

+ +

+
+

+

+

+ + +
+

+
+ From de0661e3d4789d26b8847ddf0ce73e8233aa04ac Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Tue, 29 Apr 2014 14:04:20 +0400 Subject: [PATCH 3/4] access to stat only if user.is_staff --- lms/djangoapps/courseware/views.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lms/djangoapps/courseware/views.py b/lms/djangoapps/courseware/views.py index 7cf303aa1f5a..8c63ade8dc56 100644 --- a/lms/djangoapps/courseware/views.py +++ b/lms/djangoapps/courseware/views.py @@ -59,6 +59,10 @@ template_imports = {'urllib': urllib} def stat(request): + + if not request.user.is_staff: + raise Http404 + context = {} context['csrf'] = csrf(request)['csrf_token'] filename = '/edx/app/edxapp/edx-platform/fullstat.csv' From 27fcb69651c171e5efacf88069d34fea9e33d97b Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Tue, 29 Apr 2014 14:21:35 +0400 Subject: [PATCH 4/4] account_activated filter added --- lms/djangoapps/courseware/views.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lms/djangoapps/courseware/views.py b/lms/djangoapps/courseware/views.py index 8c63ade8dc56..f014ffc7e652 100644 --- a/lms/djangoapps/courseware/views.py +++ b/lms/djangoapps/courseware/views.py @@ -59,7 +59,7 @@ template_imports = {'urllib': urllib} def stat(request): - + if not request.user.is_staff: raise Http404 @@ -83,6 +83,7 @@ def stat(request): school_login=request.POST.get('school_login'),\ register_date_min=register_date_min,\ register_date_max=register_date_max,\ + account_activated=request.POST.get('activated'),\ complete70=request.POST.get('complete70'),\ complete100=request.POST.get('complete100')\ ) @@ -106,10 +107,10 @@ def return_filtered_stat_csv(school_login='', register_date_min=None, register_d """ Returns file with data from fullstat.csv filtered according to the parameters given (indices of columns can be changed): [6] - school_login - [12] - register_date_min & register_date_max - [??] - account_activated (no column yet) - [13] - complete70 - [14] - complete100 + [13] - register_date_min & register_date_max (changed) + [09] - account_activated + [14] - complete70 + [15] - complete100 If no values are chosen, returns a filtered file with all row of fullstat.csv which contain a valid registration date in the corresponding field. """ @@ -131,19 +132,19 @@ def return_filtered_stat_csv(school_login='', register_date_min=None, register_d else: first_rows = False else: - if len(row) >= 15: # must contain at least 15 columns # change if new columns are added + if len(row) >= 16: # must contain at least 16 columns # change if new columns are added # no text in a text input --> str type # no choice in radio input --> NoneType try: - register_date = datetime.datetime.strptime(row[12], "%d/%m/%Y") + register_date = datetime.datetime.strptime(row[13], "%d/%m/%Y") if (school_login == '' or row[6] == school_login) and\ (register_date_min == None or register_date_min <= register_date) and\ (register_date_max == None or register_date <= register_date_max) and\ - (account_activated == None or True) and\ - (complete70 == None or (len(row[13]) == 4) == bool(complete70)) and\ - (complete100 == None or (len(row[14]) == 4) == bool(complete100)): # ultimate hack: len('da') == 4 + (account_activated == None or (len(row[9]) == 4) == bool(account_activated)) and\ + (complete70 == None or (len(row[14]) == 4) == bool(complete70)) and\ + (complete100 == None or (len(row[15]) == 4) == bool(complete100)): # ultimate hack: len('da') == 4 writer.writerow(row) except: pass