Merge branch 'new_lms_dev' into 'new_lms_dev(critical)'

# Conflicts:
#   access/views.py
feature/fix_generate_pass
Andrey 8 years ago
commit a541f879c2
  1. 3
      access/admin.py
  2. 45
      access/migrations/0004_auto_20180129_0933.py
  3. 1
      access/models/__init__.py
  4. 46
      access/serializers.py
  5. 4
      access/urls.py
  6. 72
      access/views.py
  7. 3
      api_v1/urls.py
  8. 2
      csv/load_bills.py
  9. 4
      csv/load_comments.py
  10. 3
      csv/load_perm.py
  11. 4
      lms/settings.py
  12. 0
      progress/__init__.py
  13. 8
      progress/admin.py
  14. 6
      progress/apps.py
  15. 58
      progress/migrations/0001_initial.py
  16. 0
      progress/migrations/__init__.py
  17. 0
      progress/models.py
  18. 44
      progress/serializers.py
  19. 3
      progress/tests.py
  20. 11
      progress/urls.py
  21. 117
      progress/views.py

@ -1,12 +1,9 @@
from django.contrib import admin
from access.models.other import Invite, Account, ResetPassword, UserActivity
from access.models.progress import ProgressLesson, Progress
from access.models.user import User
admin.site.register(User)
admin.site.register(Account)
admin.site.register(Progress)
admin.site.register(Invite)
admin.site.register(ResetPassword)
admin.site.register(ProgressLesson)
admin.site.register(UserActivity)

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-01-29 09:33
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('access', '0003_useractivity'),
]
operations = [
migrations.AlterUniqueTogether(
name='progress',
unique_together=set([]),
),
migrations.RemoveField(
model_name='progress',
name='teacher',
),
migrations.RemoveField(
model_name='progress',
name='user',
),
migrations.AlterUniqueTogether(
name='progresslesson',
unique_together=set([]),
),
migrations.RemoveField(
model_name='progresslesson',
name='progress',
),
migrations.RemoveField(
model_name='progresslesson',
name='teacher',
),
migrations.DeleteModel(
name='Progress',
),
migrations.DeleteModel(
name='ProgressLesson',
),
]

@ -1,7 +1,6 @@
# encoding=utf-8
from .other import Account, Invite
from access.models.progress import Progress
from .user import User

@ -2,52 +2,8 @@ from django.contrib.auth import get_user_model
from rest_framework import serializers
from access.models.other import Account
from access.models.progress import ProgressLesson
from access.models import Progress
from achievements.serialers import DiplomaSerializer, AchievementsSerializer
from courses.api import CourseProgressApi
class ProgressLessonSerializer(serializers.ModelSerializer):
teacher = serializers.SerializerMethodField()
class Meta:
model = ProgressLesson
exclude = ('id', 'progress')
@staticmethod
def get_teacher(self):
return self.teacher.get_full_name()
class ProgressAnalyticSerializer(serializers.ModelSerializer):
name = serializers.SerializerMethodField()
email = serializers.SerializerMethodField()
class Meta:
model = Progress
fields = ('name', 'email',)
@staticmethod
def get_name(self):
return self.user.get_full_name()
@staticmethod
def get_email(self):
return self.user.email
class ProgressSerializer(serializers.ModelSerializer):
lessons = serializers.SerializerMethodField()
class Meta:
model = Progress
fields = ('lessons', 'course_token')
@staticmethod
def get_lessons(self):
return [ProgressLessonSerializer(i).data for i in self.progresslesson_set.all()]
from progress.serializers import ProgressSerializer
class AccountSerializer(serializers.ModelSerializer):

@ -13,8 +13,4 @@ urlpatterns = [
url(r'login/$', views.LoginView.as_view()),
url(r'logout/$', views.LogoutView.as_view()),
url(r'reset/$', views.ResetPasswordView.as_view()),
url(r'progress/$', views.UpdateProgress.as_view()),
url(r'progress_detail/upload/(?P<token>[0-9A-Fa-f-]+)/$', views.UploadCourseProgressUserView.as_view()),
url(r'progress_detail/(?P<token>[0-9A-Fa-f-]+)/$', views.CourseProgressUserView.as_view()),
url(r'progress_dynamic/(?P<token>[0-9A-Fa-f-]+)/$', views.CourseProgressDynamicView.as_view()),
]

@ -16,10 +16,7 @@ from rest_framework.response import Response
from rest_framework.views import APIView
from access.models.other import Invite, ResetPassword
from access.models.progress import ProgressLesson
from access.models import Progress
from access.serializers import UserSelfSerializer, UserSearchSerializer, ProgressLessonSerializer, \
ProgressAnalyticSerializer
from access.serializers import UserSelfSerializer, UserSearchSerializer
from courses.api import CourseProgressApi
@ -311,73 +308,6 @@ class UserGuardView(APIView):
return res_403
class CourseProgressDynamicView(APIView):
renderer_classes = (JSONRenderer,)
@staticmethod
def get(request, token):
if request.user.is_authenticated() and request.user.is_staff:
try:
progresses = Progress.objects.filter(course_token=token)
res = {}
for i in progresses:
key = i.progresslesson_set.filter(status="done").count()
res[key] = 1 if not key in res.keys() else res[key] + 1
return Response(res, status=200)
except ValidationError:
return Response("Bad request", status=400)
return Response(status=403)
class CourseProgressUserView(APIView):
renderer_classes = (JSONRenderer,)
@staticmethod
def get(request, token):
if request.user.is_authenticated() and request.user.is_staff:
try:
res = []
sorted_token_list = CourseProgressApi.get_topic_lesson(token)
for p in Progress.objects.filter(course_token=token):
progress = ProgressAnalyticSerializer(p).data
progress['progress_course'] = p.progress_status(sorted_token_list)
res.append(progress)
return Response(res, status=200)
except ValidationError:
return Response("Bad request", status=400)
return Response(status=403)
class UploadCourseProgressUserView(APIView):
renderer_classes = (JSONRenderer,)
@staticmethod
def get(request, token):
if request.user.is_authenticated() and request.user.is_staff:
try:
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="%s.csv"' % token
sorted_token_list = CourseProgressApi.get_topic_lesson(token)
writer = csv.writer(response)
writer.writerow(['Имя', 'Почта', 'Последняя тема', 'Последний урок'])
for p in Progress.objects.filter(course_token=token):
progress = ProgressAnalyticSerializer(p).data
progress['progress_course'] = p.progress_status(sorted_token_list)
writer.writerow([
progress['name'],
progress['email'],
progress['progress_course'] and progress['progress_course'][0],
progress['progress_course'] and progress['progress_course'][1],
])
return response
except ValidationError:
return Response("Bad request", status=400)
return Response(status=403)
class MinUserView(APIView):
renderer_classes = (JSONRenderer,)

@ -6,4 +6,5 @@ urlpatterns = [
url(r'library/', include('library.urls')),
url(r'finance/', include('finance.urls')),
url(r'storage/', include('storage.urls')),
]
url(r'progress/', include('progress.urls')),
]

@ -15,7 +15,7 @@ django.setup()
from yandex_money.models import Payment
from finance.models import Bill, Invoice
from access.models import Progress
from progress.models import Progress
from courses.models import Course
if __name__ == '__main__':

@ -1,6 +1,4 @@
import csv
import random
import string
import django
import os
@ -15,7 +13,7 @@ django.setup()
from storage.models import Comment, File
from courses.models import Lesson
from access.models.progress import ProgressLesson, Progress
from progress.models import ProgressLesson, Progress
if __name__ == '__main__':
csv.field_size_limit(500 * 1024 * 1024)

@ -14,8 +14,7 @@ django.setup()
from django.contrib.auth.models import Group
from django.contrib.auth import get_user_model
from access.models.progress import ProgressLesson
from access.models import Progress
from progress.models import ProgressLesson, Progress
from courses.models import Lesson, Course

@ -113,6 +113,7 @@ apps = (
'library',
'achievements',
'config_app',
'progress',
)
INSTALLED_APPS = libs + apps
@ -185,3 +186,6 @@ STATIC_URL = '/static/'
RAVEN_CONFIG = {
'dsn': 'http://caaea487274f4e23a9107862484c79f3:3d463ad4717942508536f7a659921950@sentry.skillbox.ru/3'
}
DEBUG = env('DEBUG')

@ -0,0 +1,8 @@
from django.contrib import admin
# Register your models here.
from progress.models import ProgressLesson, Progress
admin.site.register(Progress)
admin.site.register(ProgressLesson)

@ -0,0 +1,6 @@
from django.apps import AppConfig
class ProgressConfig(AppConfig):
name = 'progress'
verbose_name = 'Прогресс'

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-01-29 09:31
from __future__ import unicode_literals
from django.conf import settings
import django.contrib.postgres.fields
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Progress',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('hidden_lessons', django.contrib.postgres.fields.ArrayField(base_field=models.UUIDField(editable=False, unique=True, verbose_name='Токен урока'), default=[], size=None, verbose_name='Список скрытых уроков')),
('course_token', models.UUIDField(editable=False, verbose_name='Токен курса')),
('teacher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='teacher_progress', to=settings.AUTH_USER_MODEL, verbose_name='Преподователь по умолчанию')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Студент')),
],
options={
'verbose_name': 'Прогресс пользователя',
'verbose_name_plural': 'Прогресс пользователя',
},
),
migrations.CreateModel(
name='ProgressLesson',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('lesson_token', models.UUIDField(editable=False, verbose_name='Токен урока')),
('date', models.DateTimeField(blank=True, null=True, verbose_name='Дата зачтения задания')),
('status', models.CharField(choices=[('done', 'done'), ('wait', 'wait'), ('fail', 'fail')], default='wait', max_length=20)),
('comment_tokens', django.contrib.postgres.fields.ArrayField(base_field=models.UUIDField(editable=False, verbose_name='Токен комента'), default=[], size=None)),
('progress', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='progress.Progress')),
('teacher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Преподователь')),
],
options={
'verbose_name': 'Прохождение уроков',
'verbose_name_plural': 'Прохождение урока',
},
),
migrations.AlterUniqueTogether(
name='progresslesson',
unique_together=set([('progress', 'lesson_token')]),
),
migrations.AlterUniqueTogether(
name='progress',
unique_together=set([('user', 'course_token')]),
),
]

@ -0,0 +1,44 @@
from rest_framework import serializers
from progress.models import ProgressLesson, Progress
class ProgressLessonSerializer(serializers.ModelSerializer):
teacher = serializers.SerializerMethodField()
class Meta:
model = ProgressLesson
exclude = ('id', 'progress')
@staticmethod
def get_teacher(self):
return self.teacher.get_full_name()
class ProgressAnalyticSerializer(serializers.ModelSerializer):
name = serializers.SerializerMethodField()
email = serializers.SerializerMethodField()
class Meta:
model = Progress
fields = ('name', 'email',)
@staticmethod
def get_name(self):
return self.user.get_full_name()
@staticmethod
def get_email(self):
return self.user.email
class ProgressSerializer(serializers.ModelSerializer):
lessons = serializers.SerializerMethodField()
class Meta:
model = Progress
fields = ('lessons', 'course_token')
@staticmethod
def get_lessons(self):
return [ProgressLessonSerializer(i).data for i in self.progresslesson_set.all()]

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

@ -0,0 +1,11 @@
from django.conf.urls import url
from progress import views
urlpatterns = [
url(r'$', views.UpdateProgress.as_view()),
url(r'progress_detail/upload/(?P<token>[0-9A-Fa-f-]+)/$', views.UploadCourseProgressUserView.as_view()),
url(r'progress_detail/(?P<token>[0-9A-Fa-f-]+)/$', views.CourseProgressUserView.as_view()),
url(r'progress_dynamic/(?P<token>[0-9A-Fa-f-]+)/$', views.CourseProgressDynamicView.as_view()),
]

@ -0,0 +1,117 @@
import datetime
import csv
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
from rest_framework.exceptions import ValidationError
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
from courses.api import CourseProgressApi
from progress.models import Progress, ProgressLesson
from progress.serializers import ProgressLessonSerializer, ProgressAnalyticSerializer
class UpdateProgress(APIView):
renderer_classes = (JSONRenderer,)
@staticmethod
def post(request):
"""
На вход обязательно передаётся параметр id (id узла).
"""
lesson_token = request.JSON.get('lesson_token', None)
course_token = request.JSON.get('course_token', None)
if lesson_token is None or course_token is None:
return Response('Не передан слаг курса или токен урока', status=400)
try:
p = Progress.objects.get(user=request.user, course_token=course_token)
try:
pv = ProgressLesson.objects.get(
progress=p,
lesson_token=lesson_token,
)
except ProgressLesson.DoesNotExist:
pv = ProgressLesson.objects.create(
date=datetime.datetime.now(),
teacher=p.teacher,
progress=p,
lesson_token=lesson_token,
)
pv.status = ProgressLesson.STATUSES.done
pv.save()
return Response(ProgressLessonSerializer(pv).data, status=200)
except Progress.DoesNotExist:
return Response('Не найден прогресс по заданным параметрам', status=404)
class CourseProgressDynamicView(APIView):
renderer_classes = (JSONRenderer,)
@staticmethod
def get(request, token):
if request.user.is_authenticated() and request.user.is_staff:
try:
progresses = Progress.objects.filter(course_token=token)
res = {}
for i in progresses:
key = i.progresslesson_set.filter(status="done").count()
res[key] = 1 if not key in res.keys() else res[key] + 1
return Response(res, status=200)
except ValidationError:
return Response("Bad request", status=400)
return Response(status=403)
class CourseProgressUserView(APIView):
renderer_classes = (JSONRenderer,)
@staticmethod
def get(request, token):
if request.user.is_authenticated() and request.user.is_staff:
try:
res = []
sorted_token_list = CourseProgressApi.get_topic_lesson(token)
for p in Progress.objects.filter(course_token=token):
progress = ProgressAnalyticSerializer(p).data
progress['progress_course'] = p.progress_status(sorted_token_list)
res.append(progress)
return Response(res, status=200)
except ValidationError:
return Response("Bad request", status=400)
return Response(status=403)
class UploadCourseProgressUserView(APIView):
renderer_classes = (JSONRenderer,)
@staticmethod
def get(request, token):
if request.user.is_authenticated() and request.user.is_staff:
try:
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="%s.csv"' % token
sorted_token_list = CourseProgressApi.get_topic_lesson(token)
writer = csv.writer(response)
writer.writerow(['Имя', 'Почта', 'Последняя тема', 'Последний урок'])
for p in Progress.objects.filter(course_token=token):
progress = ProgressAnalyticSerializer(p).data
progress['progress_course'] = p.progress_status(sorted_token_list)
writer.writerow([
progress['name'],
progress['email'],
progress['progress_course'] and progress['progress_course'][0],
progress['progress_course'] and progress['progress_course'][1],
])
return response
except ValidationError:
return Response("Bad request", status=400)
return Response(status=403)
Loading…
Cancel
Save