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'/>
+
+
+
+ Страница статистики
+
+
+Статистика по оценкам
+
+
+
+
+
+
+
+
+
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