From 3e8ac38769d2f90f93fbf84df658bb8699f781c8 Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 27 Feb 2018 15:32:24 +0300 Subject: [PATCH 1/9] migrate update --- progress/views.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/progress/views.py b/progress/views.py index f744103..1ed2ba4 100644 --- a/progress/views.py +++ b/progress/views.py @@ -23,18 +23,19 @@ class StudentWorkView(APIView): @staticmethod def get(request, teacher_token): client_status = request.GET.get('status', 'in_progress') - client_max_body = 50 last_id = request.GET.get('last_id', 0) server_status = Q(status='fail') if \ - client_status == 'not_done' else Q(status='wait') if client_status == 'in_progress' else Q(status='done') + client_status == 'not_done' else Q(status='wait') if client_status == 'in_progress'\ + else Q(status='done') if request.user.is_authenticated() and request.user.groups.filter(name__in=['teachers', 'admin']).exists(): try: progress_lessons = ProgressLesson.objects.filter( ~Q(progress__user__out_key=teacher_token), + ~Q(comment_tokens__len=0), server_status, checker__out_key=teacher_token, - id__gt=last_id - )[:client_max_body] + id__gt=last_id, + )[last_id:50] return Response([ProgressLessonSerializer(i).data for i in progress_lessons], status=200) except ValidationError: return Response("Bad request", status=400) From a6072dc424ff6d1175a5ad1bd61f88bba9e751be Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 28 Feb 2018 11:06:28 +0300 Subject: [PATCH 2/9] migrate update --- courses/serializers.py | 2 +- .../migrations/0008_auto_20180227_1803.py | 24 +++++++++++++++++++ progress/models.py | 6 +---- progress/serializers.py | 2 +- progress/views.py | 2 +- 5 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 progress/migrations/0008_auto_20180227_1803.py diff --git a/courses/serializers.py b/courses/serializers.py index 3309f1e..3dcf85b 100644 --- a/courses/serializers.py +++ b/courses/serializers.py @@ -19,7 +19,7 @@ class MiniLessonSerializer(serializers.ModelSerializer): class Meta: model = Lesson - fields = ('title', 'free', 'token') + fields = ('title', 'free', 'token', 'is_hm') class LessonSerializer(MiniLessonSerializer): diff --git a/progress/migrations/0008_auto_20180227_1803.py b/progress/migrations/0008_auto_20180227_1803.py new file mode 100644 index 0000000..b1cd9b6 --- /dev/null +++ b/progress/migrations/0008_auto_20180227_1803.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2018-02-27 18:03 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('progress', '0007_progresslesson_last_update'), + ] + + operations = [ + migrations.RemoveField( + model_name='progress', + name='hidden_lessons', + ), + migrations.AddField( + model_name='progress', + name='only_watch', + field=models.BooleanField(default=False, verbose_name='Только просмотр'), + ), + ] diff --git a/progress/models.py b/progress/models.py index 12a4274..2a6e5dc 100644 --- a/progress/models.py +++ b/progress/models.py @@ -7,16 +7,12 @@ from lms.tools import get_empty_list class Progress(models.Model): - hidden_lessons = ArrayField( - models.UUIDField(verbose_name="Токен урока", unique=True, editable=False), - default=get_empty_list, - verbose_name='Список скрытых уроков', - ) teacher = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name="Преподователь по умолчанию", related_name='teacher_progress') user = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name='Студент') course_token = models.UUIDField(verbose_name="Токен курса", editable=False) is_finish = models.BooleanField(verbose_name="Окончен ли курс", default=False) + only_watch = models.BooleanField(verbose_name="Только просмотр", default=False) def progress_status(self, sorted_token_list): """ diff --git a/progress/serializers.py b/progress/serializers.py index e156bd3..ea27df1 100644 --- a/progress/serializers.py +++ b/progress/serializers.py @@ -8,7 +8,7 @@ class ProgressSerializer(serializers.ModelSerializer): class Meta: model = Progress - fields = ('lessons', 'course_token') + fields = ('lessons', 'course_token', 'only_watch') @staticmethod def get_lessons(self): diff --git a/progress/views.py b/progress/views.py index 1ed2ba4..40aef45 100644 --- a/progress/views.py +++ b/progress/views.py @@ -31,7 +31,7 @@ class StudentWorkView(APIView): try: progress_lessons = ProgressLesson.objects.filter( ~Q(progress__user__out_key=teacher_token), - ~Q(comment_tokens__len=0), + # ~Q(comment_tokens__len=0), server_status, checker__out_key=teacher_token, id__gt=last_id, From a3fba6fff4900e7de8ed5cc2100a4345c10db192 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 28 Feb 2018 11:43:16 +0300 Subject: [PATCH 3/9] migrate update --- progress/views.py | 2 +- requirements.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/progress/views.py b/progress/views.py index 40aef45..dd8ab83 100644 --- a/progress/views.py +++ b/progress/views.py @@ -35,7 +35,7 @@ class StudentWorkView(APIView): server_status, checker__out_key=teacher_token, id__gt=last_id, - )[last_id:50] + )[last_id:100] return Response([ProgressLessonSerializer(i).data for i in progress_lessons], status=200) except ValidationError: return Response("Bad request", status=400) diff --git a/requirements.txt b/requirements.txt index 80ea9e5..696753c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,6 +15,7 @@ psycopg2==2.7.3.1 raven==6.2.1 requests==2.18.4 Unidecode==0.4.21 +PyJWT==1.5.3 # amqp==2.2.2 # Babel==2.5.1 From 54cde7d395c466f454cb2ce8ff3e1218e30dc7b1 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 28 Feb 2018 12:53:50 +0300 Subject: [PATCH 4/9] migrate update --- lms/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lms/settings.py b/lms/settings.py index f1abae0..5ca938e 100644 --- a/lms/settings.py +++ b/lms/settings.py @@ -67,7 +67,7 @@ DATABASES = { SESSION_ENGINE = 'redis_sessions.session' CELERY_EMAIL_CHUNK_SIZE = 1 -DATA_UPLOAD_MAX_MEMORY_SIZE = 12621440 +DATA_UPLOAD_MAX_MEMORY_SIZE = 300000000 CACHES = { 'default': env.cache(), From 3fab7048d0cd0cf9caf9983c1db7f73cc0e0708a Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 28 Feb 2018 13:18:37 +0300 Subject: [PATCH 5/9] migrate update --- storage/api.py | 4 ++-- storage/models.py | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/storage/api.py b/storage/api.py index 2b80a8b..1afcf62 100644 --- a/storage/api.py +++ b/storage/api.py @@ -1,11 +1,11 @@ from storage.models import Comment, File -def upload_file(original=None, name=None, base64=None, **_kwargs) -> File: +def upload_file(ext=None, original=None, name=None, base64=None, **_kwargs) -> File: if original: new_file = File.objects.create(original=original) else: - new_file = File.objects.upload_as_base64(base64) + new_file = File.objects.upload_as_base64(base64, ext) if name: new_file.name = name diff --git a/storage/models.py b/storage/models.py index 9946f71..eb66371 100755 --- a/storage/models.py +++ b/storage/models.py @@ -8,11 +8,10 @@ from django.db import models class FileManager(models.Manager): - def upload_as_base64(self, file_base64): + def upload_as_base64(self, file_base64, ext): if "data:" in file_base64: my_str = file_base64[file_base64.index(";base64,")+8:] - content_type = file_base64[:file_base64.index(";base64,")].split('/')[1] - file_source = ContentFile(base64.b64decode(my_str), name='time.' + content_type) + file_source = ContentFile(base64.b64decode(my_str), name='time.' + ext) file = self.create(original=file_source) return file raise ValueError() From 3a0b2020f97603063b8aa5b7c978f3508091598b Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 28 Feb 2018 13:19:37 +0300 Subject: [PATCH 6/9] migrate update --- storage/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/models.py b/storage/models.py index eb66371..8e1b9d7 100755 --- a/storage/models.py +++ b/storage/models.py @@ -1,4 +1,5 @@ # encoding=utf-8 + import base64 import uuid From 0e2cdfcb904f2bac0ca5ad7f5cfc999766b2007e Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 28 Feb 2018 14:09:05 +0300 Subject: [PATCH 7/9] migrate update --- progress/urls.py | 1 + progress/views.py | 44 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/progress/urls.py b/progress/urls.py index b78ac8f..44b7bd1 100644 --- a/progress/urls.py +++ b/progress/urls.py @@ -7,4 +7,5 @@ urlpatterns = [ url(r'student/$', views.StudentUpdateProgress.as_view()), url(r'teacher/$', views.TeacherUpdateProgress.as_view()), url(r'set-progress/$', views.SetProgress.as_view()), + url(r'get_hw_pay/$', views.get_teachers_pay), ] \ No newline at end of file diff --git a/progress/views.py b/progress/views.py index dd8ab83..32d58df 100644 --- a/progress/views.py +++ b/progress/views.py @@ -3,7 +3,7 @@ import datetime from django.contrib.auth import get_user_model from django.core.exceptions import ValidationError -from django.http import HttpResponse +from django.http import HttpResponse, HttpResponseForbidden from rest_framework.permissions import IsAuthenticated from rest_framework.renderers import JSONRenderer from rest_framework.response import Response @@ -13,7 +13,7 @@ from django.db.models import Q from courses.models import Course from progress.models import ProgressLesson, Progress from progress.serializers import ProgressAnalyticSerializer, ProgressLessonSerializer, ProgressSerializer -from courses.api import CourseProgressApi +from courses.api import CourseProgressApi, CourseParamsApi from progress.tasks import add_next_lesson @@ -349,3 +349,43 @@ class SetProgress(APIView): else: return Response("Эта функция доступна только сотрудникам персонала", status=403) + + +def get_teachers_pay(request): + if not request.user.is_authenticated and (request.user.groups.filter(name="support") or request.user.is_superuser): + return HttpResponseForbidden() + + date_from = request.GET.get('from', None) + date_to = request.GET.get('to', None) + email = request.GET.get('email', None) + + file_name = "teacher_pay_%s" % email + file_name = file_name + "__from_%s" % date_from if date_from else file_name + file_name = file_name + "__to_%s" % date_to if date_to else file_name + + progress_lessons = ProgressLesson.objects.filter( + ~Q(comment_tokens__len=0), + checker__email=email, + status='done', + ) + + progress_lessons = progress_lessons.filter(finish_date__lt=date_to) if date_to else progress_lessons + progress_lessons = progress_lessons.filter(finish_date__gte=date_from) if date_from else progress_lessons + + response = HttpResponse(content_type='text/csv') + response['Content-Disposition'] = 'attachment; filename="%s.csv"' % file_name + + writer = csv.writer(response) + writer.writerow(['Почта студента', 'Имя студента', 'Курс', 'Дата', 'Время',]) + + for i in progress_lessons.order_by('-finish_date'): + course_api = CourseParamsApi(i.progress.course_token) + writer.writerow([ + i.progress.user.email, + i.progress.user.get_full_name(), + course_api.get_slug_and_title()['title'], + i.finish_date.date(), + i.finish_date.time(), + ]) + + return response From 4bfcefd701d5ea9e1e7abdb6c497908a190cf044 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 28 Feb 2018 16:32:40 +0300 Subject: [PATCH 8/9] migrate update --- progress/views.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/progress/views.py b/progress/views.py index 32d58df..ac2a869 100644 --- a/progress/views.py +++ b/progress/views.py @@ -23,19 +23,25 @@ class StudentWorkView(APIView): @staticmethod def get(request, teacher_token): client_status = request.GET.get('status', 'in_progress') - last_id = request.GET.get('last_id', 0) - server_status = Q(status='fail') if \ - client_status == 'not_done' else Q(status='wait') if client_status == 'in_progress'\ - else Q(status='done') if request.user.is_authenticated() and request.user.groups.filter(name__in=['teachers', 'admin']).exists(): try: - progress_lessons = ProgressLesson.objects.filter( - ~Q(progress__user__out_key=teacher_token), - # ~Q(comment_tokens__len=0), - server_status, - checker__out_key=teacher_token, - id__gt=last_id, - )[last_id:100] + if client_status == 'done': + date_from = datetime.datetime.now() - datetime.timedelta(days=7) + progress_lessons = ProgressLesson.objects.filter( + ~Q(progress__user__out_key=teacher_token), + ~Q(comment_tokens__len=0), + status='done', + checker__out_key=teacher_token, + finish_date__gte=date_from, + ).order_by('-finish_date') + + else: + server_status = Q(status='fail') if client_status == 'not_done' else Q(status='wait') + progress_lessons = ProgressLesson.objects.filter( + ~Q(progress__user__out_key=teacher_token), + server_status, + checker__out_key=teacher_token, + ).order_by('-last_update') return Response([ProgressLessonSerializer(i).data for i in progress_lessons], status=200) except ValidationError: return Response("Bad request", status=400) From 7765ebef40effb42d33e4b34ae4257dff7436c84 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 28 Feb 2018 17:15:49 +0300 Subject: [PATCH 9/9] migrate update --- progress/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/progress/views.py b/progress/views.py index ac2a869..6536517 100644 --- a/progress/views.py +++ b/progress/views.py @@ -33,7 +33,7 @@ class StudentWorkView(APIView): status='done', checker__out_key=teacher_token, finish_date__gte=date_from, - ).order_by('-finish_date') + ).order_by('finish_date') else: server_status = Q(status='fail') if client_status == 'not_done' else Q(status='wait')