def move_to_verified_cohort(sender, instance, **kwargs): # pylint: disable=unused-argument """ If the learner has changed modes, update assigned cohort iff the course is using the Automatic Verified Track Cohorting MVP feature. """ course_key = instance.course_id verified_cohort_enabled = VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(course_key) verified_cohort_name = VerifiedTrackCohortedCourse.verified_cohort_name_for_course(course_key) if verified_cohort_enabled and (instance.mode != instance._old_mode): # pylint: disable=protected-access if not is_course_cohorted(course_key): log.error("Automatic verified cohorting enabled for course '%s', but course is not cohorted", course_key) else: existing_cohorts = get_course_cohorts(get_course_by_id(course_key), CourseCohort.MANUAL) if any(cohort.name == verified_cohort_name for cohort in existing_cohorts): args = { 'course_id': unicode(course_key), 'user_id': instance.user.id, 'verified_cohort_name': verified_cohort_name } # Do the update with a 3-second delay in hopes that the CourseEnrollment transaction has been # completed before the celery task runs. We want a reasonably short delay in case the learner # immediately goes to the courseware. sync_cohort_with_mode.apply_async(kwargs=args, countdown=3) # In case the transaction actually was not committed before the celery task runs, # run it again after 5 minutes. If the first completed successfully, this task will be a no-op. sync_cohort_with_mode.apply_async(kwargs=args, countdown=300) else: log.error( "Automatic verified cohorting enabled for course '%s', but cohort named '%s' does not exist.", course_key, verified_cohort_name, )
def make_course_settings(course, user): """ Generate a JSON-serializable model for course settings, which will be used to initialize a DiscussionCourseSettings object on the client. """ return { 'is_cohorted': is_course_cohorted(course.id), 'allow_anonymous': course.allow_anonymous, 'allow_anonymous_to_peers': course.allow_anonymous_to_peers, 'cohorts': [{"id": str(g.id), "name": g.name} for g in get_course_cohorts(course)], 'category_map': utils.get_discussion_category_map(course, user) }
def _section_send_email(course, access): """ Provide data for the corresponding bulk email section """ course_key = course.id # Monkey-patch applicable_aside_types to return no asides for the duration of this render with patch.object(course.runtime, 'applicable_aside_types', null_applicable_aside_types): # This HtmlDescriptor is only being used to generate a nice text editor. html_module = HtmlDescriptor( course.system, DictFieldData({'data': ''}), ScopeIds(None, None, None, course_key.make_usage_key('html', 'fake')) ) fragment = course.system.render(html_module, 'studio_view') fragment = wrap_xblock( 'LmsRuntime', html_module, 'studio_view', fragment, None, extra_data={"course-id": unicode(course_key)}, usage_id_serializer=lambda usage_id: quote_slashes(unicode(usage_id)), # Generate a new request_token here at random, because this module isn't connected to any other # xblock rendering. request_token=uuid.uuid1().get_hex() ) cohorts = [] if is_course_cohorted(course_key): cohorts = get_course_cohorts(course) course_modes = [] if not VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(course_key): course_modes = CourseMode.modes_for_course(course_key, include_expired=True, only_selectable=False) email_editor = fragment.content section_data = { 'section_key': 'send_email', 'section_display_name': _('Email'), 'access': access, 'send_email': reverse('send_email', kwargs={'course_id': unicode(course_key)}), 'editor': email_editor, 'cohorts': cohorts, 'course_modes': course_modes, 'default_cohort_name': DEFAULT_COHORT_NAME, 'list_instructor_tasks_url': reverse( 'list_instructor_tasks', kwargs={'course_id': unicode(course_key)} ), 'email_background_tasks_url': reverse( 'list_background_email_tasks', kwargs={'course_id': unicode(course_key)} ), 'email_content_history_url': reverse( 'list_email_content', kwargs={'course_id': unicode(course_key)} ), } from openedx.stanford.lms.djangoapps.instructor.views.instructor_dashboard import send_email_section_data section_data.update(send_email_section_data()) return section_data
def move_to_verified_cohort(sender, instance, **kwargs): # pylint: disable=unused-argument """ If the learner has changed modes, update assigned cohort iff the course is using the Automatic Verified Track Cohorting MVP feature. """ course_key = instance.course_id verified_cohort_enabled = VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(course_key) verified_cohort_name = VerifiedTrackCohortedCourse.verified_cohort_name_for_course(course_key) if verified_cohort_enabled and (instance.mode != instance._old_mode): # pylint: disable=protected-access if not is_course_cohorted(course_key): log.error("Automatic verified cohorting enabled for course '%s', but course is not cohorted.", course_key) else: course = get_course_by_id(course_key) existing_manual_cohorts = get_course_cohorts(course, CourseCohort.MANUAL) if any(cohort.name == verified_cohort_name for cohort in existing_manual_cohorts): # Get a random cohort to use as the default cohort (for audit learners). # Note that calling this method will create a "Default Group" random cohort if no random # cohort yet exist. random_cohort = get_random_cohort(course_key) args = { 'course_id': unicode(course_key), 'user_id': instance.user.id, 'verified_cohort_name': verified_cohort_name, 'default_cohort_name': random_cohort.name } log.info( "Queuing automatic cohorting for user '%s' in course '%s' " "due to change in enrollment mode from '%s' to '%s'.", instance.user.id, course_key, instance._old_mode, instance.mode # pylint: disable=protected-access ) # Do the update with a 3-second delay in hopes that the CourseEnrollment transaction has been # completed before the celery task runs. We want a reasonably short delay in case the learner # immediately goes to the courseware. sync_cohort_with_mode.apply_async(kwargs=args, countdown=3) # In case the transaction actually was not committed before the celery task runs, # run it again after 5 minutes. If the first completed successfully, this task will be a no-op. sync_cohort_with_mode.apply_async(kwargs=args, countdown=300) else: log.error( "Automatic verified cohorting enabled for course '%s', " "but verified cohort named '%s' does not exist.", course_key, verified_cohort_name, )
def val_cohorts(self): """Проверка наличия в курсе когорт, для каждой вывод их численности либо сообщение об их отсутствии""" course = self.course cohorts = get_course_cohorts(course) names = [getattr(x, "name") for x in cohorts] users = [getattr(x, "users").all() for x in cohorts] report = [] cohort_strs = [] for num, x in enumerate(names): cohort_strs.append([x, str(len(users[num]))]) is_cohorted = get_course_cohort_settings(self.course_key).is_cohorted if not is_cohorted: cohort_strs = [] report.append(_("Cohorts are disabled")) result = Report(name=self.scenarios_names["cohorts"], head=[_(" Cohorts "), _("Population")], body=cohort_strs, warnings=report, ) return result
def _section_send_email(course, access): """ Provide data for the corresponding bulk email section """ course_key = course.id # Monkey-patch applicable_aside_types to return no asides for the duration of this render with patch.object(course.runtime, 'applicable_aside_types', null_applicable_aside_types): # This HtmlDescriptor is only being used to generate a nice text editor. html_module = HtmlDescriptor( course.system, DictFieldData({'data': ''}), ScopeIds(None, None, None, course_key.make_usage_key('html', 'fake'))) fragment = course.system.render(html_module, 'studio_view') fragment = wrap_xblock( 'LmsRuntime', html_module, 'studio_view', fragment, None, extra_data={"course-id": unicode(course_key)}, usage_id_serializer=lambda usage_id: quote_slashes(unicode(usage_id)), # Generate a new request_token here at random, because this module isn't connected to any other # xblock rendering. request_token=uuid.uuid1().get_hex()) cohorts = [] if is_course_cohorted(course_key): cohorts = get_course_cohorts(course) course_modes = [] if not VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled( course_key): course_modes = CourseMode.modes_for_course(course_key, include_expired=True, only_selectable=False) email_editor = fragment.content section_data = { 'section_key': 'send_email', 'section_display_name': _('Email'), 'access': access, 'send_email': reverse('send_email', kwargs={'course_id': unicode(course_key)}), 'editor': email_editor, 'cohorts': cohorts, 'course_modes': course_modes, 'default_cohort_name': DEFAULT_COHORT_NAME, 'list_instructor_tasks_url': reverse('list_instructor_tasks', kwargs={'course_id': unicode(course_key)}), 'email_background_tasks_url': reverse('list_background_email_tasks', kwargs={'course_id': unicode(course_key)}), 'email_content_history_url': reverse('list_email_content', kwargs={'course_id': unicode(course_key)}), } return section_data
def student_view(self, context=None): """ The primary view of the StaffGradedXBlock, shown to students when viewing courses. """ frag = Fragment() frag.add_css(self.resource_string("static/css/staff_graded.css")) loader = ResourceLoader(__name__) _ = self.runtime.service(self, "i18n").ugettext # Add i18n js statici18n_js_url = self._get_statici18n_js_url() if statici18n_js_url: frag.add_javascript_url( self.runtime.local_resource_url(self, statici18n_js_url)) frag.add_javascript( self.resource_string("static/js/src/staff_graded.js")) frag.initialize_js('StaffGradedXBlock') context['id'] = self.location.html_id() context['instructions'] = markdown.markdown(self.instructions) context['display_name'] = self.display_name context['is_staff'] = self.runtime.user_is_staff course_id = self.location.course_key context['available_cohorts'] = [ cohort.name for cohort in get_course_cohorts(course_id=course_id) ] context['available_tracks'] = [ (mode.slug, mode.name) for mode in modes_for_course(course_id, only_selectable=False) ] if context['is_staff']: from crum import get_current_request from django.middleware.csrf import get_token context['import_url'] = self.runtime.handler_url( self, "csv_import_handler") context['export_url'] = self.runtime.handler_url( self, "csv_export_handler") context['poll_url'] = self.runtime.handler_url( self, "get_results_handler") context['csrf_token'] = get_token(get_current_request()) frag.add_javascript( loader.load_unicode('static/js/src/staff_graded.js')) frag.initialize_js('StaffGradedProblem', json_args={ k: context[k] for k in ('csrf_token', 'import_url', 'export_url', 'poll_url', 'id') }) try: score = get_score(self.location, self.runtime.user_id) or {} context['grades_available'] = True except NoSuchServiceError: context['grades_available'] = False else: if score: grade = score['score'] context['score_string'] = _('{score} / {total} points').format( score=grade, total=self.weight) else: context['score_string'] = _('{total} points possible').format( total=self.weight) frag.add_content( loader.render_django_template('static/html/staff_graded.html', context)) return frag
def _section_send_email(course, access): """ Provide data for the corresponding bulk email section """ course_key = course.id # Monkey-patch applicable_aside_types to return no asides for the duration of this render with patch.object(course.runtime, 'applicable_aside_types', null_applicable_aside_types): # This HtmlBlock is only being used to generate a nice text editor. html_module = HtmlBlock( course.system, DictFieldData({'data': ''}), ScopeIds(None, None, None, course_key.make_usage_key('html', 'fake'))) fragment = course.system.render(html_module, 'studio_view') fragment = wrap_xblock( 'LmsRuntime', html_module, 'studio_view', fragment, None, extra_data={"course-id": str(course_key)}, usage_id_serializer=lambda usage_id: quote_slashes(str(usage_id)), # Generate a new request_token here at random, because this module isn't connected to any other # xblock rendering. request_token=uuid.uuid1().hex) cohorts = [] if is_course_cohorted(course_key): cohorts = get_course_cohorts(course) course_modes = CourseMode.modes_for_course(course_key, include_expired=True, only_selectable=False) email_editor = fragment.content section_data = { 'section_key': 'send_email', 'section_display_name': _('Email'), 'access': access, 'send_email': reverse('send_email', kwargs={'course_id': str(course_key)}), 'editor': email_editor, 'cohorts': cohorts, 'course_modes': course_modes, 'default_cohort_name': DEFAULT_COHORT_NAME, 'list_instructor_tasks_url': reverse('list_instructor_tasks', kwargs={'course_id': str(course_key)}), 'email_background_tasks_url': reverse('list_background_email_tasks', kwargs={'course_id': str(course_key)}), 'email_content_history_url': reverse('list_email_content', kwargs={'course_id': str(course_key)}), } if settings.FEATURES.get("ENABLE_NEW_BULK_EMAIL_EXPERIENCE", False) is not False: section_data[ "communications_mfe_url"] = f"{settings.COMMUNICATIONS_MICROFRONTEND_URL}/courses/{str(course_key)}/bulk_email" return section_data