нет времени объяснять

remotes/origin/pm_task_31703
andrey 9 years ago
parent 266fa6ae5d
commit 2856764163
  1. 5
      analytics/urls.py
  2. 212
      analytics/views.py
  3. 37
      templates/analytics.html
  4. 41
      templates/analytics/base.html
  5. 12
      templates/analytics/index.html
  6. 9
      templates/analytics/theme.html

@ -3,5 +3,8 @@ from analytics import views
urlpatterns = [ urlpatterns = [
url(r'^$', views.index_view), url(r'^$', views.index_view),
url(r'^new/$', views.new_view), url(r'^theme/$', views.index_view_access_theme),
url(r'^theme/new/$', views.new_view_access_theme),
url(r'^homework/$', views.index_view_homework_wait),
url(r'^homework/new/$', views.new_view_homework_wait),
] ]

@ -1,88 +1,140 @@
from django.shortcuts import render_to_response, redirect from django.shortcuts import render_to_response, redirect, render
import time, os, csv import time, os, csv
from datetime import date from datetime import date
from lms.settings import MEDIA_ROOT from lms.settings import MEDIA_ROOT
from courses.models import Course, CourseTheme from courses.models import Course, CourseTheme, Homework, Exam
from journals.models import CourseThemeJ from journals.models import CourseThemeJ, HomeworkTry, ExamTry
index_view = lambda request: render_to_response('analytics/index.html')
def index_view(request):
start = request.GET.get('start', '')
end = request.GET.get('end', '') def index_view_decor(url):
def wrap(func):
path = MEDIA_ROOT + '/analytics/s' + start + 'e' + end + 'progress.csv' def get_request(request):
start = request.GET.get('start', '')
try: end = request.GET.get('end', '')
with open(path, newline='') as file:
reader = csv.reader(file, delimiter=',', quotechar='|') path = MEDIA_ROOT + url + 's' + start + 'e' + end + 'progress.csv'
max = 0
res = [] try:
for row in reader: with open(path, newline='') as file:
max = max if max > len(row) else len(row) reader = csv.reader(file, delimiter=',', quotechar='|')
res1 = [] max = 0
for i in row: res = []
k = i.split("$-$") for row in reader:
k = {'value': k[0], 'background': 'none'} if len(i.split("$-$")) == 1 else {'value': k[0], max = max if max > len(row) else len(row)
'background': k[1]} res1 = []
res1.append(k) for i in row:
res.append(res1) k = i.split("$-$")
for i in res: k = {'value': k[0], 'background': 'none'} if len(i.split("$-$")) == 1 else {'value': k[0],
for j in range(max - len(i)): 'background': k[
i.append({'value': 0, 'background': 'none'}) 1]}
first = ['Курсы'] res1.append(k)
for i in range(max - 1): res.append(res1)
first.append("Тема " + str(i + 1)) for i in res:
except FileNotFoundError: for j in range(max - len(i)):
return redirect("/analytics/new/?start=" + start + "&end=" + end) i.append({'value': 0, 'background': 'none'})
first = ['Курсы']
date_create = time.ctime(os.stat(path).st_atime) for i in range(max - 1):
first.append("Тема " + str(i + 1))
return render_to_response('analytics.html', except FileNotFoundError:
{'body': res, 'header': first, 'date_create': date_create, 'start': start, 'end': end}) return redirect(url + "new/?start=" + start + "&end=" + end)
date_create = time.ctime(os.stat(path).st_atime)
def new_view(request):
start = request.GET.get('start', '') context = {'body': res, 'header': first, 'date_create': date_create, 'start': start, 'end': end}
end = request.GET.get('end', '') context.update(func())
path = MEDIA_ROOT + '/analytics/s' + start + 'e' + end + 'progress.csv' return render(request, url[1:-1] + '.html', context=context)
start_date = None return get_request
end_date = None
return wrap
try:
start_date = date(*[int(i) for i in start.split('-')])
end_date = date(*[int(i) for i in end.split('-')]) @index_view_decor("/analytics/theme/")
except ValueError: def index_view_access_theme():
pass return {}
if not check_date_validate(start_date, end_date):
return redirect("/analytics/") @index_view_decor("/analytics/homework/")
def index_view_homework_wait():
try: return {}
with open(path, 'w', newline='') as csvfile:
for course in Course.objects.order_by('sort'):
list = [course.title] def new_view_decor(url):
for i in CourseTheme.objects.filter(course=course): def wrap(func):
kwargs = { def get_request(request):
'material': i, start = request.GET.get('start', '')
'success': True, end = request.GET.get('end', '')
}
if end_date: path = MEDIA_ROOT + url + 's' + start + 'e' + end + 'progress.csv'
kwargs['student__last_time__lte'] = end_date
if start_date: start_date = None
kwargs['student__last_time__gte'] = start_date end_date = None
list.append(str(len(CourseThemeJ.objects.filter(**kwargs))) + (
"$-$yellow" if i._type == 'Ex' or i._type == 'M' else "")) try:
writercsv = csv.writer(csvfile, delimiter=',', quotechar='|') start_date = date(*[int(i) for i in start.split('-')])
writercsv.writerow(list) end_date = date(*[int(i) for i in end.split('-')])
return redirect("/analytics/?start=" + start + "&end=" + end) except ValueError:
pass
except FileNotFoundError:
os.makedirs(MEDIA_ROOT + '/analytics') if not check_date_validate(start_date, end_date):
return redirect("/analytics/new/?start=" + start + "&end=" + end) return redirect(url)
try:
with open(path, 'w', newline='') as csvfile:
func(end_date, start_date, csvfile)
return redirect(url + "?start=" + start + "&end=" + end)
except FileNotFoundError:
os.makedirs(MEDIA_ROOT + url)
return redirect(url + "new/?start=" + start + "&end=" + end)
return get_request
return wrap
@new_view_decor("/analytics/theme/")
def new_view_access_theme(end_date, start_date, csvfile):
for course in Course.objects.order_by('sort'):
list = [course.title]
for i in CourseTheme.objects.filter(course=course):
kwargs = {
'material': i,
'success': True,
}
if end_date:
kwargs['student__last_time__lte'] = end_date
if start_date:
kwargs['student__last_time__gte'] = start_date
list.append(str(len(CourseThemeJ.objects.filter(**kwargs))) + (
"$-$yellow" if i._type == 'Ex' or i._type == 'M' else ""))
writercsv = csv.writer(csvfile, delimiter=',', quotechar='|')
writercsv.writerow(list)
@new_view_decor("/analytics/homework/")
def new_view_homework_wait(end_date, start_date, csvfile):
for course in Course.objects.order_by('sort'):
list = [course.title]
for i in CourseTheme.objects.filter(course=course):
kwargs = {
'success': False,
}
if end_date:
kwargs['student__last_time__lte'] = end_date
if start_date:
kwargs['student__last_time__gte'] = start_date
list.append(str(
len(HomeworkTry.objects.filter(material=Homework.objects.filter(theme=i), **kwargs)) +
len(ExamTry.objects.filter(material=Exam.objects.filter(theme=i), **kwargs))
) + ("$-$yellow" if i._type == 'Ex' or i._type == 'M' else ""))
writercsv = csv.writer(csvfile, delimiter=',', quotechar='|')
writercsv.writerow(list)
def check_date_validate(start=None, end=None): def check_date_validate(start=None, end=None):

@ -1,37 +0,0 @@
<h2>Дата создания отчёта {{ date_create }}</h2>
<button><a href="new?start={{ start }}&end={{ end }}">Сгенирировать отчёт</a></button>
<button style="margin-bottom: 20px"><a href="/media/analytics/s{{ start }}e{{ end }}progress.csv">Скачать отчёт</a></button>
<form action="">
<label>от</label>
<input name="start" type="date" value="{{ start }}">
<label>до</label>
<input name="end" type="date" value="{{ end }}">
<button type="submit">Подготовить отчёт</button>
</form>
<table border="1px">
<tr>
{% for i in header %}
<th>{{ i }}</th>
{% endfor %}
</tr>
{% for i in body %}
<tr>
{% for j in i %}
<td style="background: {{j.background}}">{{ j.value }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<p>
В данной таблице представлены данные о том, сколько студентов прошло заданную тему. <br>
Темы не всегда проходятся последовательно, поэтому порой тему с большим порядковым номером прошло большее количество пользовавтелей. <br>
Вы можите выставить фильтр по последней акутивности пользователя, фильтр может быть ограничивающим с одной стороны или может отсутствовать, <br>
в случае ввода невалидных данных ошибки не происходит вас просто перенапровляет на начальную страницу. <br>
Вы можите скачать отчёт в формате csv метка $-$yellow говорит о том что в данной теме есть экзамен,<br>
в таблице темы содержашие экзамен подсвечены жёлтым светом
</p>
<h2>Внимание! Новый отчёт генерируется 1 раз! Следите за записью в хедоре страницы, если вы нуждаетесь в обновлении <br>
данных жмите кнопку "Сгенерировать отчёт" таким образом вы получите обновлённые данные для заданных пораметров фильтрации</h2>

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Аналитика</title>
</head>
<body>
<h2>Дата создания отчёта {{ date_create }}</h2>
<button><a href="new?start={{ start }}&end={{ end }}">Сгенирировать отчёт</a></button>
<button style="margin-bottom: 20px"><a href="/media/analytics/theme/s{{ start }}e{{ end }}progress.csv">Скачать отчёт</a></button>
<button><a href="/analytics">На главную</a></button>
<form action="">
<label>от</label>
<input name="start" type="date" value="{{ start }}">
<label>до</label>
<input name="end" type="date" value="{{ end }}">
<button type="submit">Подготовить отчёт</button>
</form>
<table border="1px">
<tr>
{% for i in header %}
<th>{{ i }}</th>
{% endfor %}
</tr>
{% for i in body %}
<tr>
{% for j in i %}
<td style="background: {{j.background}}">{{ j.value }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<p>
{% block description %}{% endblock %}
</p>
<h2>Внимание! Новый отчёт генерируется 1 раз! Следите за записью в хедоре страницы, если вы нуждаетесь в обновлении <br>
данных жмите кнопку "Сгенерировать отчёт" таким образом вы получите обновлённые данные для заданных пораметров фильтрации</h2>
</body>
</html>

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Аналитика</title>
</head>
<body>
<h2>Меню поиска</h2>
<h4><a href="theme">Студентов успешно прошедших тему</a></h4>
<h4><a href="homework">Студентов ожидающих проверки домашки</a></h4>
</body>
</html>

@ -0,0 +1,9 @@
{% extends 'analytics/base.html' %}
{% block description %}
В данной таблице представлены данные о том, сколько студентов прошло заданную тему. <br>
Темы не всегда проходятся последовательно, поэтому порой тему с большим порядковым номером прошло большее количество пользовавтелей. <br>
Вы можите выставить фильтр по последней акутивности пользователя, фильтр может быть ограничивающим с одной стороны или может отсутствовать, <br>
в случае ввода невалидных данных ошибки не происходит вас просто перенапровляет на начальную страницу. <br>
Вы можите скачать отчёт в формате csv метка $-$yellow говорит о том что в данной теме есть экзамен,<br>
в таблице темы содержашие экзамен подсвечены жёлтым светом
{% endblock %}
Loading…
Cancel
Save