def get(self, request): """ - URI: /mobile/v1/users/courses/grades?username={username}&course_id={course_id} - GET: return a JSON response of the user's course grade and course average * course_id: __required__, The course ID for the course to retrieve grades for * username: __optional__, A staff user can retrieve grades for different users by using this parameter. A regular user can only retrieve their own grades. """ username = request.GET.get('username', None) course_id = request.GET.get('course_id', None) if not course_exists(course_id): return Response({}, status=status.HTTP_404_NOT_FOUND) user = self.request.user course_key = get_course_key(course_id) if username is not None and user.username != username: # Raise a 404 if the specified user doesn't exist or # if they aren't enrolled in this course user = get_object_or_404(User, username=username) if not CourseEnrollment.is_enrolled(user, course_key): return Response({}, status=status.HTTP_404_NOT_FOUND) grades = self._get_user_course_grades(user, course_id) return Response( { 'username': username or self.request.user.username, 'course_key': course_id, 'course_grade': grades['course_grade'], 'course_average_grade': grades['course_average_grade'] }, status=status.HTTP_200_OK)
def _get_user_course_grades(self, user, course_id): """ Get the user's grade for the given course. Note: For performance reasons, we use the cached gradebook data here. Once persistent grades are enabled on the solutions fork, we'll use CourseGradeFactory instead. """ course_key = get_course_key(course_id) data = get_cached_data('grade', course_id, user.id) params = { 'exclude_users': get_aggregate_exclusion_user_ids(course_key, roles=None) } if not data: course_avg = StudentGradebook.course_grade_avg( course_key, **params) user_grade = StudentGradebook.get_user_grade(course_key, user.id) data = {'user_grade': user_grade, 'course_avg': course_avg} cache_course_data('grade', course_id, {'course_avg': course_avg}) cache_course_user_data('grade', course_id, user.id, {'user_grade': user_grade}) return { 'course_grade': data.get('user_grade'), 'course_average_grade': data.get('course_avg') }
def get_course_enrollment_count(course_id, org_id=None, exclude_org_admins=False): """ Get enrollment count of a course if org_id is passed then count is limited to that org's users """ cache_category = 'course_enrollments' if org_id: cache_category = '{}_{}'.format(cache_category, org_id) if exclude_org_admins: cache_category = '{}_exclude_admins'.format(cache_category) enrollment_count = get_cached_data(cache_category, course_id) if enrollment_count is not None: return enrollment_count.get('enrollment_count') course_key = get_course_key(course_id) exclude_user_ids = get_aggregate_exclusion_user_ids(course_key) users_enrolled_qs = CourseEnrollment.objects.users_enrolled_in( course_key).exclude(id__in=exclude_user_ids) if org_id: users_enrolled_qs = users_enrolled_qs.filter( organizations=org_id).distinct() if exclude_org_admins: non_company_users = get_non_actual_company_users( 'mcka_role_company_admin', org_id) users_enrolled_qs.exclude(id__in=non_company_users) enrollment_count = users_enrolled_qs.count() cache_course_data(cache_category, course_id, {'enrollment_count': enrollment_count}) return enrollment_count
def metrics(self, request, pk): """ Provide statistical information for the specified Organization """ response_data = {} grade_avg = 0 grade_complete_match_range = getattr( settings, 'GRADEBOOK_GRADE_COMPLETE_PROFORMA_MATCH_RANGE', 0.01) org_user_grades = StudentGradebook.objects.filter( user__organizations=pk, user__is_active=True) courses_filter = request.query_params.get('courses', None) courses = [] exclude_users = set() if courses_filter: upper_bound = getattr(settings, 'API_LOOKUP_UPPER_BOUND', 100) courses_filter = courses_filter.split(",")[:upper_bound] for course_string in courses_filter: courses.append(get_course_key(course_string)) # fill exclude users for course_key in courses: exclude_users.union( get_aggregate_exclusion_user_ids(course_key)) org_user_grades = org_user_grades.filter( course_id__in=courses).exclude(user_id__in=exclude_users) users_grade_sum = org_user_grades.aggregate(Sum('grade')) if users_grade_sum['grade__sum']: users_enrolled_qs = CourseEnrollment.objects.filter(user__is_active=True, is_active=True, user__organizations=pk)\ .exclude(user_id__in=exclude_users) if courses: users_enrolled_qs = users_enrolled_qs.filter( course_id__in=courses) users_enrolled = users_enrolled_qs.aggregate( Count('user', distinct=True)) total_users = users_enrolled['user__count'] if total_users: # in order to compute avg across organization we need course of courses org has total_courses_in_org = len(courses) if not courses: org_courses = users_enrolled_qs.aggregate( Count('course_id', distinct=True)) total_courses_in_org = org_courses['course_id__count'] grade_avg = float('{0:.3f}'.format( float(users_grade_sum['grade__sum']) / total_users / total_courses_in_org)) response_data['users_grade_average'] = grade_avg users_grade_complete_count = org_user_grades\ .filter(proforma_grade__lte=F('grade') + grade_complete_match_range, proforma_grade__gt=0)\ .aggregate(Count('user', distinct=True)) response_data[ 'users_grade_complete_count'] = users_grade_complete_count[ 'user__count'] or 0 return Response(response_data, status=status.HTTP_200_OK)
def has_permission(self, request, view): user = request.user course_id = request.GET.get('course_id') \ or request.parser_context.get('kwargs', {}).get('course_id', None) course_key = get_course_key(course_id) if course_key: return user.is_staff or CourseEnrollment.is_enrolled( request.user, course_key) return False
def grades(self, request, pk): """ Submit a grade for a Workgroup. The grade will be applied to all members of the workgroup """ # Ensure we received all of the necessary information course_id = request.data.get('course_id') if course_id is None: return Response({}, status=status.HTTP_400_BAD_REQUEST) course_key = get_course_key(course_id) if not course_key: return Response({}, status=status.HTTP_400_BAD_REQUEST) course_descriptor = get_course(course_key) if not course_descriptor: return Response({}, status=status.HTTP_400_BAD_REQUEST) content_id = request.data.get('content_id') if content_id is None: return Response({}, status=status.HTTP_400_BAD_REQUEST) try: usage_key = UsageKey.from_string(content_id) except InvalidKeyError: return Response({}, status=status.HTTP_400_BAD_REQUEST) content_descriptor = modulestore().get_item(usage_key) if content_descriptor is None: return Response({}, status=status.HTTP_400_BAD_REQUEST) grade = request.data.get('grade') if grade is None: return Response({}, status=status.HTTP_400_BAD_REQUEST) max_grade = request.data.get('max_grade') if max_grade is None: return Response({}, status=status.HTTP_400_BAD_REQUEST) if grade > max_grade: max_grade = grade users = User.objects.filter(workgroups=pk) for user in users: SCORE_PUBLISHED.send( sender=None, block=content_descriptor, user=user, raw_earned=grade, raw_possible=max_grade, only_if_higher=None, ) return Response({}, status=status.HTTP_201_CREATED)
def metrics(self, request, pk): """ Provide statistical information for the specified Organization """ response_data = {} grade_avg = 0 grade_complete_match_range = getattr(settings, 'GRADEBOOK_GRADE_COMPLETE_PROFORMA_MATCH_RANGE', 0.01) org_user_grades = StudentGradebook.objects.filter(user__organizations=pk, user__is_active=True) courses_filter = request.query_params.get('courses', None) courses = [] exclude_users = set() if courses_filter: upper_bound = getattr(settings, 'API_LOOKUP_UPPER_BOUND', 100) courses_filter = courses_filter.split(",")[:upper_bound] for course_string in courses_filter: courses.append(get_course_key(course_string)) # fill exclude users for course_key in courses: exclude_users.union(get_aggregate_exclusion_user_ids(course_key)) org_user_grades = org_user_grades.filter(course_id__in=courses).exclude(user_id__in=exclude_users) users_grade_sum = org_user_grades.aggregate(Sum('grade')) if users_grade_sum['grade__sum']: users_enrolled_qs = CourseEnrollment.objects.filter(user__is_active=True, is_active=True, user__organizations=pk)\ .exclude(user_id__in=exclude_users) if courses: users_enrolled_qs = users_enrolled_qs.filter(course_id__in=courses) users_enrolled = users_enrolled_qs.aggregate(Count('user', distinct=True)) total_users = users_enrolled['user__count'] if total_users: # in order to compute avg across organization we need course of courses org has total_courses_in_org = len(courses) if not courses: org_courses = users_enrolled_qs.aggregate(Count('course_id', distinct=True)) total_courses_in_org = org_courses['course_id__count'] grade_avg = float('{0:.3f}'.format( float(users_grade_sum['grade__sum']) / total_users / total_courses_in_org )) response_data['users_grade_average'] = grade_avg users_grade_complete_count = org_user_grades\ .filter(proforma_grade__lte=F('grade') + grade_complete_match_range, proforma_grade__gt=0)\ .aggregate(Count('user', distinct=True)) response_data['users_grade_complete_count'] = users_grade_complete_count['user__count'] or 0 return Response(response_data, status=status.HTTP_200_OK)
def create(self, request): """ Create a new workgroup and its cohort. """ assignment_type = request.data.get('assignment_type', CourseCohort.RANDOM) if assignment_type not in dict(CourseCohort.ASSIGNMENT_TYPE_CHOICES).keys(): message = "Not a valid assignment type, '{}'".format(assignment_type) return Response({'details': message}, status.HTTP_400_BAD_REQUEST) response = super(WorkgroupsViewSet, self).create(request) if response.status_code == status.HTTP_201_CREATED: # create the workgroup cohort workgroup = get_object_or_404(self.queryset, pk=response.data['id']) course_key = get_course_key(workgroup.project.course_id) add_cohort(course_key, workgroup.cohort_name, assignment_type) return response
def _get_user_course_grades(self, user, course_id): """ Get the user's grade for the given course. Note: For performance reasons, we use the cached gradebook data here. Once persistent grades are enabled on the solutions fork, we'll use CourseGradeFactory instead. """ course_key = get_course_key(course_id) try: record = StudentGradebook.objects.get(user=user, course_id=course_key) course_grade = record.grade except StudentGradebook.DoesNotExist: course_grade = 0 course_average = self._get_course_average_grade(course_key) return { 'course_grade': course_grade, 'course_average_grade': course_average }
def create(self, request): """ Create a new workgroup and its cohort. """ assignment_type = request.data.get('assignment_type', CourseCohort.RANDOM) if assignment_type not in dict( CourseCohort.ASSIGNMENT_TYPE_CHOICES).keys(): message = "Not a valid assignment type, '{}'".format( assignment_type) return Response({'details': message}, status.HTTP_400_BAD_REQUEST) response = super(WorkgroupsViewSet, self).create(request) if response.status_code == status.HTTP_201_CREATED: # create the workgroup cohort workgroup = get_object_or_404(self.queryset, pk=response.data['id']) course_key = get_course_key(workgroup.project.course_id) add_cohort(course_key, workgroup.cohort_name, assignment_type) return response
def handle(self, *args, **options): if len(args) < 1 or len(args) > 2: print Command.help return dry_run = True create_log = False msg_string = 'Script started on {}'.format(datetime.datetime.now().ctime()) if 'repair' in args: dry_run = False if 'dryrun' in args: dry_run = True if 'createlog' in args: create_log = True file_handler = logging.FileHandler('repair_internal_admin_instructor_role.log') file_handler.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s') file_handler.setFormatter(formatter) log.addHandler(file_handler) log.info(msg_string) if dry_run: msg_string = 'Script started in dry run mode, this will print for all internal admins courses for which we need to remove or add theirs instructor role' else: msg_string = 'Script started in repair mode, this will permanently remove or add instructor role of internal admins. THIS IS IRREVERSIBLE!' log.info(msg_string) internal_admin_group_name = 'mcka_role_internal_admin' internal_tag_group_type = 'tag:internal' instructor_role = 'instructor' staff_role = 'staff' number_of_removed_roles = 0 number_of_added_roles = 0 #get all internal admins try: internal_admin_group = Group.objects.get(name__icontains=internal_admin_group_name) except ObjectDoesNotExist: internal_admin_group = None if internal_admin_group: internal_admins = internal_admin_group.user_set.all() #get internal tagged courses try: internal_courses_group = Group.objects.get(groupprofile__group_type=internal_tag_group_type) except ObjectDoesNotExist: internal_courses_group = None if internal_courses_group: internal_courses = CourseGroupRelationship.objects.filter(group=internal_courses_group) internal_courses_ids = [] for internal_course in internal_courses: internal_courses_ids.append(internal_course.course_id) #for all internal admins check their roles and remove instructor role on course if he doesn't have staff role on course and course isn't tagged internal for internal_admin in internal_admins: user_roles = CourseAccessRole.objects.filter(user=internal_admin) instructor_courses = [] staff_courses = [] for user_role in user_roles: if user_role.role == instructor_role: instructor_courses.append(user_role.course_id) if user_role.role == staff_role: staff_courses.append(user_role.course_id) for instructor_course in instructor_courses: if str(instructor_course) not in internal_courses_ids and instructor_course not in staff_courses: number_of_removed_roles += 1 if dry_run: msg_string = 'Remove instructor role for internal admin ' + str(internal_admin.id) + ' on course ' + str(instructor_course) + '.' log.info(msg_string) else: role_to_delete = CourseAccessRole.objects.get(user=internal_admin, role=instructor_role, course_id=instructor_course) role_to_delete.delete() #for all internal tagged course check roles and if internal admins don't have instructor role on course add it for internal_course in internal_courses: course_id = get_course_key(internal_course.course_id) course_roles = CourseAccessRole.objects.filter(course_id=course_id) instructor_users = [] for course_role in course_roles: if course_role.role == instructor_role: instructor_users.append(course_role.user_id) for internal_admin in internal_admins: if internal_admin.id not in instructor_users: number_of_added_roles += 1 if dry_run: msg_string = 'Add instructor role for internal admin ' + str(internal_admin.id) + ' on course ' + str(course_id) + '.' log.info(msg_string) else: course = courses.get_course(course_id, 0) new_role = CourseAccessRole(user=internal_admin, role=instructor_role, course_id=course.id, org=course.org) new_role.save() msg_string = 'Number of removed roles: ' + str(number_of_removed_roles) + '.' log.info(msg_string) msg_string = 'Number of added roles: ' + str(number_of_added_roles) + '.' log.info(msg_string) log.info('--------------------------------------------------------------------------------------------------------------------') if create_log: print 'Script started in create log mode, please open repair_internal_admin_instructor_role.log file.'
def users(self, request, pk): """ - URI: ```/api/organizations/{org_id}/users/``` - GET: Returns users in an organization * course_id parameter should filter user by course * include_course_counts parameter should be `true` to get user's enrollment count * include_grades parameter should be `true` to get user's grades * for the course given in the course_id parameter * view parameter can be used to get a particular data .i.e. view=ids to * get list of user ids - POST: Adds a User to an Organization - DELETE: Removes the user(s) given in the `users` param from an Organization. """ if request.method == 'GET': include_course_counts = request.query_params.get( 'include_course_counts', None) include_grades = request.query_params.get('include_grades', None) course_id = request.query_params.get('course_id', None) view = request.query_params.get('view', None) grade_complete_match_range = getattr( settings, 'GRADEBOOK_GRADE_COMPLETE_PROFORMA_MATCH_RANGE', 0.01) course_key = None if course_id: course_key = get_course_key(course_id) users = User.objects.filter(organizations=pk) if course_key: users = users.filter( courseenrollment__course_id__exact=course_key, courseenrollment__is_active=True) if str2bool(include_grades): users = users.prefetch_related('studentgradebook_set') if str2bool(include_course_counts): enrollments = CourseEnrollment.objects.filter( user__in=users).values('user').order_by().annotate( total=Count('user')) enrollments_by_user = {} for enrollment in enrollments: enrollments_by_user[ enrollment['user']] = enrollment['total'] # if we only need ids of users in organization return now if view == 'ids': user_ids = users.values_list('id', flat=True) return Response(user_ids) response_data = [] if users: for user in users: serializer = SimpleUserSerializer(user) user_data = serializer.data if str2bool(include_course_counts): user_data['course_count'] = enrollments_by_user.get( user.id, 0) if str2bool(include_grades) and course_key: user_grades = { 'grade': 0, 'proforma_grade': 0, 'complete_status': False } gradebook = user.studentgradebook_set.filter( course_id=course_key) if gradebook: user_grades['grade'] = gradebook[0].grade user_grades['proforma_grade'] = gradebook[ 0].proforma_grade user_grades['complete_status'] = True if 0 < gradebook[0].proforma_grade <= \ gradebook[0].grade + grade_complete_match_range else False user_data.update(user_grades) response_data.append(user_data) return Response(response_data, status=status.HTTP_200_OK) elif request.method == 'DELETE': user_ids = request.data.get('users') if not user_ids: return Response({"detail": _('users parameter is missing.')}, status.HTTP_400_BAD_REQUEST) try: user_ids = [ int(user_id) for user_id in filter(None, user_ids.split(',')) ] except (ValueError, AttributeError): return Response( { "detail": _('users parameter must be comma separated list of integers.' ) }, status.HTTP_400_BAD_REQUEST) organization = self.get_object() users_to_be_deleted = organization.users.filter(id__in=user_ids) total_users = len(users_to_be_deleted) for user in users_to_be_deleted: organization.users.remove(user) if total_users > 0: return Response( { "detail": _("{users_removed} user(s) removed from organization"). format(users_removed=total_users) }, status=status.HTTP_200_OK) else: return Response(status=status.HTTP_204_NO_CONTENT) else: user_id = request.data.get('id') try: user = User.objects.get(id=user_id) except ObjectDoesNotExist: message = 'User {} does not exist'.format(user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) organization = self.get_object() organization.users.add(user) organization.save() return Response({}, status=status.HTTP_201_CREATED)
def users(self, request, pk): """ - URI: ```/api/organizations/{org_id}/users/``` - GET: Returns users in an organization * course_id parameter should filter user by course * include_course_counts parameter should be `true` to get user's enrollment count * include_grades parameter should be `true` to get user's grades * for the course given in the course_id parameter * view parameter can be used to get a particular data .i.e. view=ids to * get list of user ids - POST: Adds a User to an Organization - DELETE: Removes the user(s) given in the `users` param from an Organization. """ if request.method == 'GET': include_course_counts = request.query_params.get('include_course_counts', None) include_grades = request.query_params.get('include_grades', None) course_id = request.query_params.get('course_id', None) view = request.query_params.get('view', None) grade_complete_match_range = getattr(settings, 'GRADEBOOK_GRADE_COMPLETE_PROFORMA_MATCH_RANGE', 0.01) course_key = None if course_id: course_key = get_course_key(course_id) users = User.objects.filter(organizations=pk) if course_key: users = users.filter(courseenrollment__course_id__exact=course_key, courseenrollment__is_active=True) if str2bool(include_grades): users = users.prefetch_related( Prefetch('studentgradebook_set', queryset=StudentGradebook.objects.filter(course_id=course_key)) ) if str2bool(include_course_counts): enrollments = CourseEnrollment.objects.filter(user__in=users).values('user').order_by().annotate(total=Count('user')) enrollments_by_user = {} for enrollment in enrollments: enrollments_by_user[enrollment['user']] = enrollment['total'] # if we only need ids of users in organization return now if view == 'ids': user_ids = users.values_list('id', flat=True) return Response(user_ids) response_data = [] if users: for user in users: serializer = SimpleUserSerializer(user) user_data = serializer.data if str2bool(include_course_counts): user_data['course_count'] = enrollments_by_user.get(user.id, 0) if str2bool(include_grades) and course_key: user_grades = {'grade': 0, 'proforma_grade': 0, 'complete_status': False} gradebook = user.studentgradebook_set.all() if gradebook: user_grades['grade'] = gradebook[0].grade user_grades['proforma_grade'] = gradebook[0].proforma_grade user_grades['complete_status'] = True if 0 < gradebook[0].proforma_grade <= \ gradebook[0].grade + grade_complete_match_range else False user_data.update(user_grades) response_data.append(user_data) return Response(response_data, status=status.HTTP_200_OK) elif request.method == 'DELETE': user_ids = request.data.get('users') if not user_ids: return Response({"detail": _('users parameter is missing.')}, status.HTTP_400_BAD_REQUEST) try: user_ids = [int(user_id) for user_id in filter(None, user_ids.split(','))] except (ValueError, AttributeError): return Response({ "detail": _('users parameter must be comma separated list of integers.') }, status.HTTP_400_BAD_REQUEST) organization = self.get_object() users_to_be_deleted = organization.users.filter(id__in=user_ids) total_users = len(users_to_be_deleted) if total_users > 0: organization.users.remove(*users_to_be_deleted) return Response({ "detail": _("{users_removed} user(s) removed from organization").format(users_removed=total_users) }, status=status.HTTP_200_OK) else: return Response(status=status.HTTP_204_NO_CONTENT) else: user_id = request.data.get('id') try: user = User.objects.get(id=user_id) except ObjectDoesNotExist: message = 'User {} does not exist'.format(user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) organization = self.get_object() organization.users.add(user) organization.save() return Response({}, status=status.HTTP_201_CREATED)
def handle(self, *args, **options): if len(args) < 1 or len(args) > 2: print(Command.help) return dry_run = True create_log = False msg_string = 'Script started on {}'.format( datetime.datetime.now().ctime()) if 'repair' in args: dry_run = False if 'dryrun' in args: dry_run = True if 'createlog' in args: create_log = True file_handler = logging.FileHandler( 'repair_internal_admin_instructor_role.log') file_handler.setLevel(logging.DEBUG) formatter = logging.Formatter( '%(asctime)s-%(name)s-%(levelname)s-%(message)s') file_handler.setFormatter(formatter) log.addHandler(file_handler) log.info(msg_string) if dry_run: msg_string = 'Script started in dry run mode, this will print for all internal admins courses for which ' \ 'we need to remove or add theirs instructor role' else: msg_string = 'Script started in repair mode, this will permanently remove or add instructor role of ' \ 'internal admins. THIS IS IRREVERSIBLE!' log.info(msg_string) internal_admin_group_name = 'mcka_role_internal_admin' internal_tag_group_type = 'tag:internal' instructor_role = 'instructor' staff_role = 'staff' number_of_removed_roles = 0 number_of_added_roles = 0 #get all internal admins try: internal_admin_group = Group.objects.get( name__icontains=internal_admin_group_name) except ObjectDoesNotExist: internal_admin_group = None if internal_admin_group: internal_admins = internal_admin_group.user_set.all() #get internal tagged courses try: internal_courses_group = Group.objects.get( groupprofile__group_type=internal_tag_group_type) except ObjectDoesNotExist: internal_courses_group = None if internal_courses_group: internal_courses = CourseGroupRelationship.objects.filter( group=internal_courses_group) internal_courses_ids = [] for internal_course in internal_courses: internal_courses_ids.append(internal_course.course_id) # for all internal admins check their roles and remove instructor role on course # if he doesn't have staff role on course and course isn't tagged internal for internal_admin in internal_admins: user_roles = CourseAccessRole.objects.filter(user=internal_admin) instructor_courses = [] staff_courses = [] for user_role in user_roles: if user_role.role == instructor_role: instructor_courses.append(user_role.course_id) if user_role.role == staff_role: staff_courses.append(user_role.course_id) for instructor_course in instructor_courses: if str( instructor_course ) not in internal_courses_ids and instructor_course not in staff_courses: number_of_removed_roles += 1 if dry_run: msg_string = 'Remove instructor role for internal admin ' + str(internal_admin.id) +\ ' on course ' + str(instructor_course) + '.' log.info(msg_string) else: role_to_delete = CourseAccessRole.objects.get( user=internal_admin, role=instructor_role, course_id=instructor_course) role_to_delete.delete() # for all internal tagged course check roles and if internal admins don't have instructor role on course add it for internal_course in internal_courses: course_id = get_course_key(internal_course.course_id) course_roles = CourseAccessRole.objects.filter(course_id=course_id) instructor_users = [] for course_role in course_roles: if course_role.role == instructor_role: instructor_users.append(course_role.user_id) for internal_admin in internal_admins: if internal_admin.id not in instructor_users: number_of_added_roles += 1 if dry_run: msg_string = 'Add instructor role for internal admin ' + str(internal_admin.id) + \ ' on course ' + str(course_id) + '.' log.info(msg_string) else: course = courses.get_course(course_id, 0) new_role = CourseAccessRole(user=internal_admin, role=instructor_role, course_id=course.id, org=course.org) new_role.save() msg_string = 'Number of removed roles: ' + str( number_of_removed_roles) + '.' log.info(msg_string) msg_string = 'Number of added roles: ' + str( number_of_added_roles) + '.' log.info(msg_string) log.info( '---------------------------------------------------------------------------------------------------' ) if create_log: print( 'Script started in create log mode, please open repair_internal_admin_instructor_role.log file.' )
def users(self, request, pk): """ Add a User to a Workgroup """ if request.method == 'GET': users = User.objects.filter(workgroups=pk) response_data = [] if users: for user in users: serializer = UserSerializer(user, context={'request': request}) response_data.append(serializer.data) # pylint: disable=E1101 return Response(response_data, status=status.HTTP_200_OK) elif request.method == 'POST': user_id = request.data.get('id') try: user = User.objects.get(id=user_id) except ObjectDoesNotExist: message = 'User {} does not exist'.format(user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) workgroup = self.get_object() # Ensure the user is not already assigned to a project for this course existing_projects = Project.objects.filter(course_id=workgroup.project.course_id).filter(workgroups__users__id=user.id) if len(existing_projects): message = 'User {} already assigned to a project for this course'.format(user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) try: workgroup.add_user(user) except ValidationError as e: return Response({"detail": unicode(e)}, status.HTTP_400_BAD_REQUEST) workgroup.save() # add user to the workgroup cohort, create it if it doesn't exist (for cases where there is a legacy # workgroup) course_key = get_course_key(workgroup.project.course_id) try: cohort = get_cohort_by_name(course_key, workgroup.cohort_name) add_user_to_cohort(cohort, user.username) except ObjectDoesNotExist: # This use case handles cases where a workgroup might have been created before # the notion of a cohorted discussion. So we need to backfill in the data assignment_type = request.data.get('assignment_type', CourseCohort.RANDOM) if assignment_type not in dict(CourseCohort.ASSIGNMENT_TYPE_CHOICES).keys(): message = "Not a valid assignment type, '{}'".format(assignment_type) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) workgroup = self.get_object() cohort = add_cohort(course_key, workgroup.cohort_name, assignment_type) for workgroup_user in workgroup.users.all(): add_user_to_cohort(cohort, workgroup_user.username) return Response({}, status=status.HTTP_201_CREATED) else: user_id = request.data.get('id') try: user = User.objects.get(id=user_id) except ObjectDoesNotExist: message = 'User {} does not exist'.format(user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) workgroup = self.get_object() course_key = get_course_key(workgroup.project.course_id) cohort = get_cohort_by_name(course_key, workgroup.cohort_name) workgroup.remove_user(user) remove_user_from_cohort(cohort, user.username) return Response({}, status=status.HTTP_204_NO_CONTENT)
def users(self, request, pk): """ Add a User to a Workgroup """ if request.method == 'GET': users = User.objects.filter(workgroups=pk) response_data = [] if users: for user in users: serializer = UserSerializer(user, context={'request': request}) response_data.append(serializer.data) # pylint: disable=E1101 return Response(response_data, status=status.HTTP_200_OK) elif request.method == 'POST': user_id = request.data.get('id') try: user = User.objects.get(id=user_id) except ObjectDoesNotExist: message = 'User {} does not exist'.format(user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) workgroup = self.get_object() # Ensure the user is not already assigned to a project for this course existing_projects = Project.objects.filter( course_id=workgroup.project.course_id).filter( workgroups__users__id=user.id) if len(existing_projects): message = 'User {} already assigned to a project for this course'.format( user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) try: workgroup.add_user(user) except ValidationError as e: return Response({"detail": unicode(e)}, status.HTTP_400_BAD_REQUEST) workgroup.save() # add user to the workgroup cohort, create it if it doesn't exist (for cases where there is a legacy # workgroup) course_key = get_course_key(workgroup.project.course_id) try: cohort = get_cohort_by_name(course_key, workgroup.cohort_name) add_user_to_cohort(cohort, user.username) except ObjectDoesNotExist: # This use case handles cases where a workgroup might have been created before # the notion of a cohorted discussion. So we need to backfill in the data assignment_type = request.data.get('assignment_type', CourseCohort.RANDOM) if assignment_type not in dict( CourseCohort.ASSIGNMENT_TYPE_CHOICES).keys(): message = "Not a valid assignment type, '{}'".format( assignment_type) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) workgroup = self.get_object() cohort = add_cohort(course_key, workgroup.cohort_name, assignment_type) for workgroup_user in workgroup.users.all(): add_user_to_cohort(cohort, workgroup_user.username) return Response({}, status=status.HTTP_201_CREATED) else: user_id = request.data.get('id') try: user = User.objects.get(id=user_id) except ObjectDoesNotExist: message = 'User {} does not exist'.format(user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) workgroup = self.get_object() course_key = get_course_key(workgroup.project.course_id) cohort = get_cohort_by_name(course_key, workgroup.cohort_name) workgroup.remove_user(user) remove_user_from_cohort(cohort, user.username) return Response({}, status=status.HTTP_204_NO_CONTENT)