views.py 9.81 KB
Newer Older
Bruno Martin's avatar
Bruno Martin committed
1
from django.db.models import Q
2
from django.db import IntegrityError
3
from django.contrib.auth import get_user_model
4 5

from rest_framework import viewsets, mixins
Bruno Martin's avatar
Bruno Martin committed
6
from rest_framework.response import Response
7
from rest_framework.permissions import IsAuthenticated
8
from rest_framework.decorators import list_route
9

Matheus Miranda's avatar
Matheus Miranda committed
10 11
from .models import (Course, CourseProfessor, CourseStudent, ProfessorMessage,
                     ProfessorMessageRead, Class, Lesson)
12 13
from .serializers import (CourseSerializer, BasicCourseProfessorSerializer,
                          ProfessorMessageSerializer, ProfessorMessageReadSerializer,
Matheus Miranda's avatar
Matheus Miranda committed
14 15
                          LessonSerializer)

16

17 18
from courses.workspaces.serializers import CourseGroupSerializer

19 20 21 22 23
from .permissions import (
    IsProfessorCoordinatorOrAdminPermissionOrReadOnly,
    IsAssistantOrCoordinatorOrAdminOrRecipient,
    IsAdminOrReadOnly,
)
24

Matheus Miranda's avatar
Matheus Miranda committed
25

26
class CourseGroupViewSet(viewsets.ModelViewSet):
Matheus Miranda's avatar
Matheus Miranda committed
27

28 29 30 31 32 33 34 35 36 37
    model = Course
    queryset = Course.objects.all()
    serializer_class = CourseGroupSerializer

    def get_queryset(self):
        queryset = super(CourseGroupViewSet, self).get_queryset()
        course = self.request.query_params.get('id', None)

        if course:
            queryset = queryset.filter(groups__id = course)
Matheus Miranda's avatar
Matheus Miranda committed
38

39 40
        return queryset

41 42 43 44 45 46 47 48 49 50 51 52

class CourseViewSet(viewsets.ModelViewSet):

    model = Course
    queryset = Course.objects.all()
    serializer_class = CourseSerializer
    lookup_field = 'id'
    filter_fields = ('slug', 'home_published',)
    permission_classes = (IsProfessorCoordinatorOrAdminPermissionOrReadOnly,)

    def get_queryset(self):
        queryset = super(CourseViewSet, self).get_queryset()
53 54

        if not self.request.user.is_authenticated:
55
            return queryset.filter(is_public=True, status='published').prefetch_related('professors')
56

57
        if not self.request.user.is_superuser:
Bruno Martin's avatar
Bruno Martin committed
58
            role = self.request.query_params.get('role', None)
59 60 61 62 63 64
            if role:
                queryset = queryset.filter(
                    course_professors__role=role,
                    course_professors__user=self.request.user
                ).prefetch_related('professors')

Bruno Martin's avatar
Bruno Martin committed
65
            # Course must have status status published and (be public or share groups with user)
Glaucia S. Santos's avatar
Glaucia S. Santos committed
66 67 68 69 70
            #query = Q(
            #    Q(status='published') & (
            #        Q(is_public=True, ) | Q(groups__in=self.request.user.groups.all(), status='published')
            #    )
            #)
Matheus Miranda's avatar
Matheus Miranda committed
71 72 73
            from django.utils.translation import get_language
            current_language = get_language()
            query = Q(status='published', lang__contains=[current_language])
Bruno Martin's avatar
Bruno Martin committed
74 75 76 77 78 79 80 81 82 83

            if (CourseProfessor.objects.filter(user=self.request.user, role='coordinator').exists()):
                query.add(Q(
                    course_professors__role='coordinator',
                    course_professors__user=self.request.user
                ), Q.OR)

            queryset = queryset.filter(query)

        queryset = queryset.prefetch_related('professors')
84 85 86 87 88 89 90 91 92 93 94 95 96 97

        return queryset.distinct()

    def post(self, request, **kwargs):
        course = self.get_object()
        serializer = CourseSerializer(course, request.data)

        if serializer.is_valid():
            serializer.save()
            return Response(status=200)
        else:
            return Response(serializer.errors, status=400)

    def metadata(self, request):
Bruno Martin's avatar
Bruno Martin committed
98
        data = super().metadata(request)
99 100 101
        if data.get('actions'):
            data.get('actions').get('POST').get('status').update({'choices': dict(Course.STATES[1:])})
        return data
102 103


104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
class MyCoursesViewSet(viewsets.ModelViewSet):
    model = Course
    queryset = Course.objects.all()
    serializer_class = CourseSerializer
    permission_classes = (IsProfessorCoordinatorOrAdminPermissionOrReadOnly,)

    def get_queryset(self):
        queryset = super(MyCoursesViewSet, self).get_queryset()
        user = self.request.user
        course_students = CourseStudent.objects.filter(user__id=user.id).prefetch_related('course')
        courses_id = list(course_students.values_list('course__id', flat=True))
        queryset = self.queryset.filter(id__in=courses_id)

        return queryset


Matheus Miranda's avatar
Matheus Miranda committed
120 121 122 123 124 125 126 127
class CourseBySlugViewSet(viewsets.ModelViewSet):
    model = Course
    queryset = Course.objects.all()
    serializer_class = CourseSerializer
    permission_classes = (IsAuthenticated,)
    lookup_field = 'slug'


128 129 130 131 132 133 134 135 136 137 138 139 140 141
class BaseCourseProfessorViewSet(viewsets.ModelViewSet):

    model = CourseProfessor
    queryset = CourseProfessor.objects.all()
    # lookup_field = 'id'
    filter_fields = (
        'course',
        'user',
        'role',
    )
    serializer_class = BasicCourseProfessorSerializer
    permission_classes = (IsProfessorCoordinatorOrAdminPermissionOrReadOnly, )


142 143
class ProfessorMessageViewSet(viewsets.ModelViewSet):
    model = ProfessorMessage
144 145
    queryset = ProfessorMessage.objects.all()
    filter_fields = ('course', 'classrooms')
146
    serializer_class = ProfessorMessageSerializer
147 148
    # permission_classes = (IsAssistantOrCoordinatorOrAdminOrRecipient)
    permission_classes = (IsAdminOrReadOnly, )
149 150

    def perform_create(self, serializer):
151
        classes = serializer.context['request'].data.get('classes', None)
152
        recipients = serializer.context['request'].data.get('users', None)
153
        classrooms = serializer.context['request'].data.get('classroom', None)
154

155 156
        users_to_be_added = []
        User = get_user_model()
157

158
        # Otherwise, user the recipients list
159
        if recipients:
160 161
            for user_id in serializer.context['request'].data['users']:
                users_to_be_added.append(User.objects.get(id=user_id))
162 163 164 165 166
        elif classes:
            for class_id in classes:
                klass = Class.objects.get(id=class_id)
                for user in klass.students.all():
                    users_to_be_added.append(user.id)
167 168 169 170
        elif classrooms:
            for classrooms_id in classrooms:
                classrooms = Classrooms.objects.get(id=classrooms_id)
                users_to_be_added = classrooms.group.user_set.all()
171 172

        obj = serializer.save(professor=self.request.user, users=users_to_be_added)
173 174 175 176
        if obj:
            obj.send()

    def get_queryset(self):
177
        queryset = super().get_queryset()
Matheus Miranda's avatar
Matheus Miranda committed
178 179 180 181 182 183 184

        query = Q(
            Q(users=self.request.user)
            | Q(groups__in=self.request.user.groups.all())
            | Q(professor=self.request.user)
        )
        queryset = queryset.filter(query).order_by('-id').distinct()
185 186 187 188

        classroom = self.request.query_params.get('classroom', None)
        if classroom:
            queryset = queryset.filter(classrooms=classroom)
189 190 191 192 193 194 195 196 197 198

        unread = self.request.query_params.get('unread', None)
        if unread:
            # Exclude read messages
            queryset = queryset.exclude(read_status__is_read=True, read_status__user=self.request.user)

        limit_to = self.request.query_params.get('limit_to', None)
        if limit_to:
            queryset = queryset[:int(limit_to)]

199
        return queryset.prefetch_related('classrooms', 'classes', 'users', 'groups',).select_related('course', 'professor')
Matheus Miranda's avatar
Matheus Miranda committed
200

201 202 203 204
    @list_route(methods=['get'], permission_classes=[IsAssistantOrCoordinatorOrAdminOrRecipient])
    def count_message(self, request):
        messages = self.get_queryset()
        return Response({'count': messages.count()})
205 206


207 208 209 210 211
class ProfessorGlobalMessageViewSet(ProfessorMessageViewSet):
    """
    This view creates ProfessorMessages targeting specific users and with no ties to any course
    Only site admins can create messages using this endpoint
    """
212
    model = ProfessorMessage
213
    serializer_class = ProfessorMessageSerializer
214 215
    permission_classes = (IsAdminOrReadOnly,)

216 217 218
    def perform_create(self, serializer):
        User = get_user_model()
        users_to_be_added = []
Matheus Miranda's avatar
Matheus Miranda committed
219

220 221 222
        all_students = serializer.context['request'].data.get('all_students', None)
        recipients = serializer.context['request'].data.get('users', None)
        groups = serializer.context['request'].data.get('groups', None)
223 224 225 226

        if all_students:
            # If all_students was set to True by the client, this is a global message
            users_to_be_added = User.objects.all()
227 228 229 230 231 232 233 234
                # If groups were specified, their users are the recipients
        elif groups:
            users_to_be_added = User.objects.filter(groups__in=groups)
        # Otherwise, user the recipients list
        elif recipients:
            for user_id in serializer.context['request'].data['users']:
                users_to_be_added.append(User.objects.get(id=user_id))

235 236 237 238
        obj = serializer.save(professor=self.request.user, users=users_to_be_added)
        if obj:
            obj.send()

239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261

class ProfessorMessageReadViewSet(viewsets.ModelViewSet):
    model = ProfessorMessageRead
    lookup_field = 'message'
    serializer_class = ProfessorMessageReadSerializer
    permission_classes = (IsAuthenticated,)

    def perform_create(self, serializer):
        try:
            read_info = serializer.save(user=self.request.user, is_read=True)
        except IntegrityError as e:
            read_info = ProfessorMessageRead.objects.get(message=self.request.data['message'], user=self.request.user)
            read_info.is_read = True
            read_info.save()

    def get_queryset(self):
        queryset = ProfessorMessageRead.objects.filter(user=self.request.user).order_by('-id')

        limit_to = self.request.query_params.get('limit_to', None)
        if limit_to:
            queryset = queryset[:int(limit_to)]

        return queryset
Matheus Miranda's avatar
Matheus Miranda committed
262 263 264 265 266 267 268 269 270 271 272 273


class LessonViewSet(viewsets.ModelViewSet):
    model = Lesson
    queryset = Lesson.objects.all()
    serializer_class = LessonSerializer
    ordering = ('position',)

    def get_queryset(self):
        queryset = super(LessonViewSet, self).get_queryset()
        course_id = self.kwargs['course_id']
        return queryset.filter(status='published', course_id=course_id)