threads update

feature/fix_generate_pass
Andrey 8 years ago
parent f9c2b72a6d
commit 554c1b8c6c
  1. 10
      access/models.py
  2. 22
      config_app/management/commands/set_seq.py
  3. 4
      courses/models.py
  4. 11
      courses/views.py
  5. 12
      csv/load_student_teachers_threads.py
  6. 8
      journals/serilizers.py
  7. 1
      journals/urls.py
  8. 46
      journals/views.py
  9. 9
      lms/settings.py
  10. 6
      lms/tools.py
  11. 4
      storage/models.py
  12. 10
      storage/serializers.py

@ -173,13 +173,13 @@ class User(AbstractBaseUser, PermissionsMixin):
class Progress(models.Model): class Progress(models.Model):
user = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name=u'Студент') user = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name='Студент')
course = models.ForeignKey(to=Course, verbose_name=u'Курс') course = models.ForeignKey(to=Course, verbose_name='Курс')
active_obj = models.ForeignKey(to=Vertex, verbose_name=u'Активный объект', blank=True, null=True) active_obj = models.ForeignKey(to=Vertex, verbose_name='Активный объект', blank=True, null=True)
success = models.BooleanField(default=False, verbose_name=u'Завершён ли курс') success = models.BooleanField(default=False, verbose_name='Завершён ли курс')
def __str__(self): def __str__(self):
return u'%s %s %s' % ( return '%s %s %s' % (
self.user.email, self.user.email,
('завершил курс' if self.success else 'в процессе изучения курса'), ('завершил курс' if self.success else 'в процессе изучения курса'),
self.course.title, self.course.title,

@ -0,0 +1,22 @@
from django.contrib.contenttypes.models import ContentType
from django.core.management.base import BaseCommand, CommandError
from django.db import connection
from lms.settings import apps
class Command(BaseCommand):
help = 'Set seq by last id in table.'
def handle(self, **_):
with connection.cursor() as cursor:
for i in ContentType.objects.all():
if i.app_label in apps:
model_name = "%s_%s" % (i.app_label, i.model)
cursor.execute('BEGIN')
cursor.execute('LOCK TABLE %s IN EXCLUSIVE MODE' % model_name)
cursor.execute(
"""SELECT setval('%s_id_seq', COALESCE(
(SELECT MAX(id)+1 FROM %s), 1) ,false
)""" % (model_name, model_name)
)
cursor.execute('COMMIT')

@ -131,8 +131,8 @@ class Course(models.Model):
return { return {
"topic_count": self.get_vertexes('topic').count(), "topic_count": self.get_vertexes('topic').count(),
"tutorial_count": self.get_vertexes('task').count(), "tutorial_count": self.get_vertexes('tutorial').count(),
"task_count": self.get_vertexes('tutorial').count(), "task_count": self.get_vertexes('task').count(),
} }
def get_first(self, vertex_model_list=None): def get_first(self, vertex_model_list=None):

@ -6,6 +6,7 @@ from access.serializers import ExtraPrivilegeSerializer
from courses.models import Course, Vertex from courses.models import Course, Vertex
from access.models import Progress, ExtraPrivilege from access.models import Progress, ExtraPrivilege
from courses.serializers import CourseDetailSerializer, CourseListSerializer, VertexSerializer, CourseTreeSerializer from courses.serializers import CourseDetailSerializer, CourseListSerializer, VertexSerializer, CourseTreeSerializer
from journals.models import Thread
class TreeView(APIView): class TreeView(APIView):
@ -99,6 +100,14 @@ class VertexDetail(APIView):
return Response("permission denied", status=403) return Response("permission denied", status=403)
res = VertexSerializer(vertex).data res = VertexSerializer(vertex).data
res['is_in_progress'] = vertex.course.progress_set.filter(user=request.user)[0].active_obj == vertex progress = vertex.course.progress_set.filter(user=request.user)
try:
journals = Thread.objects.get(key="user_%s__vertex_%s" % (request.user.id, vertex.id)).journal_set.all()
res['is_in_progress'] = progress.exists() and progress[0].active_obj == vertex and \
vertex.content_type.model == 'task' and \
not journals.filter(action_type__in=['no', 'yes']).count() < \
journals.filter(action_type='try').count()
except Thread.DoesNotExist:
pass
return Response(res, status=200) if status == 200 else Response(status=204) return Response(res, status=200) if status == 200 else Response(status=204)

@ -46,21 +46,11 @@ if __name__ == '__main__':
content_type=ct, content_type=ct,
object_id=vertex.id, object_id=vertex.id,
action_type=action, action_type=action,
extra_data=row['text'],
) )
journal.date = row['date'] journal.date = row['date']
journal.save() journal.save()
journal_comment = Journal.objects.create(
thread=child_thread,
user=owner,
content_type=ct,
object_id=vertex.id,
action_type="comment",
extra_data=row['text'],
)
journal_comment.date = row['date']
journal_comment.save()
for file_id in row['files'].split("[")[1].split("]")[0].split(", "): for file_id in row['files'].split("[")[1].split("]")[0].split(", "):
if file_id: if file_id:
journal.files.add(Storage.objects.get(id=file_id)) journal.files.add(Storage.objects.get(id=file_id))

@ -1,15 +1,17 @@
from rest_framework import serializers from rest_framework import serializers
from journals.models import Thread, Journal from journals.models import Thread, Journal
from storage.serializers import StorageSerializer
class JournalSerializer(serializers.ModelSerializer): class JournalSerializer(serializers.ModelSerializer):
user = serializers.SerializerMethodField() user = serializers.SerializerMethodField()
files = serializers.SerializerMethodField()
label = serializers.SerializerMethodField() label = serializers.SerializerMethodField()
class Meta: class Meta:
model = Journal model = Journal
fields = ('label', 'date', 'user', 'files', 'action_type') fields = ('label', 'date', 'user', 'files', 'action_type', 'object_id', )
@staticmethod @staticmethod
def get_user(self): def get_user(self):
@ -20,6 +22,10 @@ class JournalSerializer(serializers.ModelSerializer):
return self.extra_data if self.extra_data else """%s %s"""\ return self.extra_data if self.extra_data else """%s %s"""\
% (self.user.get_full_name(), self.get_action_type_display()) % (self.user.get_full_name(), self.get_action_type_display())
@staticmethod
def get_files(self):
return [StorageSerializer(i).data for i in self.files.all()]
class ThreadDetailSerializer(serializers.ModelSerializer): class ThreadDetailSerializer(serializers.ModelSerializer):
journals = serializers.SerializerMethodField() journals = serializers.SerializerMethodField()

@ -5,4 +5,5 @@ urlpatterns = [
url(r'thread/$', views.ThreadAdminListView.as_view()), url(r'thread/$', views.ThreadAdminListView.as_view()),
url(r'pay-stat/([0-9]{1,99})/$', views.get_pay_stat), url(r'pay-stat/([0-9]{1,99})/$', views.get_pay_stat),
url(r'thread/(?P<key>[-\w]+)/$', views.ThreadDetailView.as_view()), url(r'thread/(?P<key>[-\w]+)/$', views.ThreadDetailView.as_view()),
url(r'journal/$', views.JournalCreateView.as_view()),
] ]

@ -1,12 +1,16 @@
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.renderers import JSONRenderer from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response from rest_framework.response import Response
import csv import csv
from django.http import HttpResponse, HttpResponseForbidden from django.http import HttpResponse, HttpResponseForbidden
from access.models import Progress
from journals.models import Thread, Journal from journals.models import Thread, Journal
from journals.serilizers import ThreadDetailSerializer, ThreadAdminSerializer from journals.serilizers import ThreadDetailSerializer, ThreadAdminSerializer, JournalSerializer
from lms.tools import decode_base64
from storage.models import Storage
class ThreadAdminListView(APIView): class ThreadAdminListView(APIView):
@ -81,3 +85,43 @@ def get_pay_stat(request, pk):
]) ])
return response return response
class JournalCreateView(APIView):
renderer_classes = (JSONRenderer,)
status_code = 200
def post(self, request):
pk = request.JSON.get('thread_id', None)
try:
thread = Thread.objects.get(id=pk)
if request.user.is_authenticated and thread.check_perm(request.user):
action_type = request.JSON.get('action_type', None)
extra_data = request.JSON.get('extra_data', None)
object_id = request.JSON.get('object_id', None)
content_type__model = request.JSON.get('content_type__model', None)
content_type__app_label = request.JSON.get('content_type__app_label', None)
content_type = ContentType.objects.get(model=content_type__model, app_label=content_type__app_label)
files = request.JSON.get('files', [])
files = [{'data': decode_base64(i['data']), 'name': i['name']} for i in files]
journal = Journal.objects.create(
action_type=action_type, extra_data=extra_data, thread=thread,
content_type=content_type, object_id=object_id,
user=request.user
)
for i in files:
s = Storage.objects.create(original=decode_base64(i['data']), name=i['name'])
journal.files.add(s)
if journal.action_type == 'yes':
p = Progress.objects.get(course=journal.content_object.course, user=journal.thread.subscribers.all()[0])
p.active_obj = journal.content_object.get_next(['tutorial', 'task'])
p.save()
return Response(ThreadDetailSerializer(thread).data, status=200)
return Response("permission denied", status=403)
except Thread.DoesNotExist:
return Response("Thread doesn't exist.", self.status_code,)

@ -90,7 +90,7 @@ EMAIL_BACKEND = 'djcelery_email.backends.CeleryEmailBackend'
SECRET_KEY = env('SECRET_KEY') SECRET_KEY = env('SECRET_KEY')
INSTALLED_APPS = [ libs = (
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.auth', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.contenttypes',
@ -102,6 +102,9 @@ INSTALLED_APPS = [
"djcelery_email", "djcelery_email",
'yandex_money', 'yandex_money',
'raven.contrib.django.raven_compat', 'raven.contrib.django.raven_compat',
)
apps = (
'access', 'access',
'courses', 'courses',
'storage', 'storage',
@ -109,7 +112,9 @@ INSTALLED_APPS = [
'journals', 'journals',
'library', 'library',
'config_app', 'config_app',
] )
INSTALLED_APPS = libs + apps
MIDDLEWARE_CLASSES = [ MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',

@ -1,10 +1,14 @@
import base64 import base64
from django.conf import settings from django.conf import settings
from django.core.files.base import ContentFile
def decode_base64(my_str, upload_to): def decode_base64(my_str, upload_to=None):
if "data:" in my_str: if "data:" in my_str:
my_str = my_str[my_str.index("base64,")+7:] my_str = my_str[my_str.index("base64,")+7:]
if not upload_to:
ext = my_str.split('/')[-1]
return ContentFile(base64.b64decode(my_str), name='temp.' + ext)
path = "%s/%s" % (settings.MEDIA_ROOT, upload_to) path = "%s/%s" % (settings.MEDIA_ROOT, upload_to)
url = "%s%s" % (settings.MEDIA_URL, upload_to) url = "%s%s" % (settings.MEDIA_URL, upload_to)
with open(path, "wb") as fh: with open(path, "wb") as fh:

@ -3,8 +3,8 @@ from django.db import models
class Storage(models.Model): class Storage(models.Model):
original = models.FileField(verbose_name='Файл', upload_to="files") original = models.FileField(max_length=255, verbose_name='Файл', upload_to="files")
name = models.CharField(max_length=63, null=True, blank=True, verbose_name='Видимое имя файла') name = models.CharField(max_length=255, null=True, blank=True, verbose_name='Видимое имя файла')
def __str__(self): def __str__(self):
return '%s' % self.original return '%s' % self.original

@ -0,0 +1,10 @@
from rest_framework import serializers
from storage.models import Storage
class StorageSerializer(serializers.ModelSerializer):
class Meta:
model = Storage
exclude = ('id',)
Loading…
Cancel
Save