def container_handler(request, tag=None, package_id=None, branch=None, version_guid=None, block=None): """ The restful handler for container xblock requests. GET html: returns the HTML page for editing a container json: not currently supported """ if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'): locator = BlockUsageLocator(package_id=package_id, branch=branch, version_guid=version_guid, block_id=block) try: __, course, xblock, __ = _get_item_in_course(request, locator) except ItemNotFoundError: return HttpResponseBadRequest() ancestor_xblocks = [] parent = get_parent_xblock(xblock) while parent and parent.category != 'sequential': ancestor_xblocks.append(parent) parent = get_parent_xblock(parent) ancestor_xblocks.reverse() unit = ancestor_xblocks[0] if ancestor_xblocks else None unit_publish_state = compute_publish_state(unit) if unit else None return render_to_response('container.html', { 'context_course': course, 'xblock': xblock, 'xblock_locator': locator, 'unit': unit, 'unit_publish_state': unit_publish_state, 'ancestor_xblocks': ancestor_xblocks, }) else: return HttpResponseBadRequest("Only supports html requests")
def _is_xblock_read_only(xblock): """ Returns true if the specified xblock is read-only, meaning that it cannot be edited. """ # We allow direct editing of xblocks in DIRECT_ONLY_CATEGORIES (for example, static pages). if xblock.category in DIRECT_ONLY_CATEGORIES: return False component_publish_state = compute_publish_state(xblock) return component_publish_state == PublishState.public
def test_publish_states_of_nested_xblocks(self): """ Test publishing of a unit page containing a nested xblock """ resp = self.create_xblock(parent_locator=self.seq_locator, display_name="Test Unit", category="vertical") unit_locator = self.response_locator(resp) resp = self.create_xblock(parent_locator=unit_locator, category="wrapper") wrapper_locator = self.response_locator(resp) resp = self.create_xblock(parent_locator=wrapper_locator, category="html") html_locator = self.response_locator(resp) # The unit and its children should be private initially unit_update_url = "/xblock/" + unit_locator unit = self.get_item_from_modulestore(unit_locator, True) html = self.get_item_from_modulestore(html_locator, True) self.assertEqual(compute_publish_state(unit), PublishState.private) self.assertEqual(compute_publish_state(html), PublishState.private) # Make the unit public and verify that the problem is also made public resp = self.client.ajax_post(unit_update_url, data={"publish": "make_public"}) self.assertEqual(resp.status_code, 200) unit = self.get_item_from_modulestore(unit_locator, True) html = self.get_item_from_modulestore(html_locator, True) self.assertEqual(compute_publish_state(unit), PublishState.public) self.assertEqual(compute_publish_state(html), PublishState.public) # Make a draft for the unit and verify that the problem also has a draft resp = self.client.ajax_post( unit_update_url, data={"id": unit_locator, "metadata": {}, "publish": "create_draft"} ) self.assertEqual(resp.status_code, 200) unit = self.get_item_from_modulestore(unit_locator, True) html = self.get_item_from_modulestore(html_locator, True) self.assertEqual(compute_publish_state(unit), PublishState.draft) self.assertEqual(compute_publish_state(html), PublishState.draft)
def _test_html_content(self, xblock, expected_section_tag, expected_breadcrumbs): """ Get the HTML for a container page and verify the section tag is correct and the breadcrumbs trail is correct. """ html = self.get_page_html(xblock) publish_state = compute_publish_state(xblock) self.assertIn(expected_section_tag, html) # Verify the navigation link at the top of the page is correct. self.assertRegexpMatches(html, expected_breadcrumbs) # Verify the link that allows users to change publish status. if publish_state == PublishState.public: expected_message = 'you need to edit unit <a href="/unit/{}">Unit</a> as a draft.' else: expected_message = 'your changes will be published with unit <a href="/unit/{}">Unit</a>.' expected_unit_link = expected_message.format(self.vertical.location) self.assertIn(expected_unit_link, html)
def container_handler(request, tag=None, package_id=None, branch=None, version_guid=None, block=None): """ The restful handler for container xblock requests. GET html: returns the HTML page for editing a container json: not currently supported """ if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'): locator = BlockUsageLocator(package_id=package_id, branch=branch, version_guid=version_guid, block_id=block) try: __, course, xblock, __ = _get_item_in_course(request, locator) except ItemNotFoundError: return HttpResponseBadRequest() ancestor_xblocks = [] parent = get_parent_xblock(xblock) while parent and parent.category != 'sequential': ancestor_xblocks.append(parent) parent = get_parent_xblock(parent) ancestor_xblocks.reverse() unit = ancestor_xblocks[0] if ancestor_xblocks else None unit_publish_state = compute_publish_state(unit) if unit else None return render_to_response( 'container.html', { 'context_course': course, 'xblock': xblock, 'xblock_locator': locator, 'unit': unit, 'unit_publish_state': unit_publish_state, 'ancestor_xblocks': ancestor_xblocks, }) else: return HttpResponseBadRequest("Only supports html requests")
def _test_preview_html(self, xblock): """ Verify that the specified xblock has the expected HTML elements for container preview """ locator = loc_mapper().translate_location(self.course.id, xblock.location, published=False) publish_state = compute_publish_state(xblock) preview_url = '/xblock/{locator}/container_preview'.format(locator=locator) resp = self.client.get(preview_url, HTTP_ACCEPT='application/json') self.assertEqual(resp.status_code, 200) resp_content = json.loads(resp.content) html = resp_content['html'] # Verify that there are no drag handles for public pages drag_handle_html = '<span data-tooltip="Drag to reorder" class="drag-handle action"></span>' if publish_state == PublishState.public: self.assertNotIn(drag_handle_html, html) else: self.assertIn(drag_handle_html, html)
def container_handler(request, usage_key_string): """ The restful handler for container xblock requests. GET html: returns the HTML page for editing a container json: not currently supported """ if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'): usage_key = UsageKey.from_string(usage_key_string) try: course, xblock, __ = _get_item_in_course(request, usage_key) except ItemNotFoundError: return HttpResponseBadRequest() component_templates = _get_component_templates(course) ancestor_xblocks = [] parent = get_parent_xblock(xblock) while parent and parent.category != 'sequential': ancestor_xblocks.append(parent) parent = get_parent_xblock(parent) ancestor_xblocks.reverse() unit = ancestor_xblocks[0] if ancestor_xblocks else None unit_publish_state = compute_publish_state(unit) if unit else None return render_to_response( 'container.html', { 'context_course': course, # Needed only for display of menus at top of page. 'xblock': xblock, 'unit_publish_state': unit_publish_state, 'xblock_locator': usage_key, 'unit': None if not ancestor_xblocks else ancestor_xblocks[0], 'ancestor_xblocks': ancestor_xblocks, 'component_templates': json.dumps(component_templates), }) else: return HttpResponseBadRequest("Only supports html requests")
def container_handler(request, usage_key_string): """ The restful handler for container xblock requests. GET html: returns the HTML page for editing a container json: not currently supported """ if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'): usage_key = UsageKey.from_string(usage_key_string) try: course, xblock, __ = _get_item_in_course(request, usage_key) except ItemNotFoundError: return HttpResponseBadRequest() component_templates = _get_component_templates(course) ancestor_xblocks = [] parent = get_parent_xblock(xblock) while parent and parent.category != 'sequential': ancestor_xblocks.append(parent) parent = get_parent_xblock(parent) ancestor_xblocks.reverse() unit = ancestor_xblocks[0] if ancestor_xblocks else None unit_publish_state = compute_publish_state(unit) if unit else None return render_to_response('container.html', { 'context_course': course, # Needed only for display of menus at top of page. 'xblock': xblock, 'unit_publish_state': unit_publish_state, 'xblock_locator': usage_key, 'unit': None if not ancestor_xblocks else ancestor_xblocks[0], 'ancestor_xblocks': ancestor_xblocks, 'component_templates': json.dumps(component_templates), }) else: return HttpResponseBadRequest("Only supports html requests")
def _test_html_content(self, xblock, branch_name, expected_section_tag, expected_breadcrumbs): """ Get the HTML for a container page and verify the section tag is correct and the breadcrumbs trail is correct. """ url = xblock_studio_url(xblock, self.course) publish_state = compute_publish_state(xblock) resp = self.client.get_html(url) self.assertEqual(resp.status_code, 200) html = resp.content self.assertIn(expected_section_tag, html) # Verify the navigation link at the top of the page is correct. self.assertRegexpMatches(html, expected_breadcrumbs) # Verify the link that allows users to change publish status. expected_message = None if publish_state == PublishState.public: expected_message = 'you need to edit unit <a href="/unit/{branch_name}/Unit">Unit</a> as a draft.' else: expected_message = 'your changes will be published with unit <a href="/unit/{branch_name}/Unit">Unit</a>.' expected_unit_link = expected_message.format( branch_name=branch_name ) self.assertIn(expected_unit_link, html)
def test_publish_states_of_nested_xblocks(self): """ Test publishing of a unit page containing a nested xblock """ resp = self.create_xblock(parent_usage_key=self.seq_usage_key, display_name='Test Unit', category='vertical') unit_usage_key = self.response_usage_key(resp) resp = self.create_xblock(parent_usage_key=unit_usage_key, category='wrapper') wrapper_usage_key = self.response_usage_key(resp) resp = self.create_xblock(parent_usage_key=wrapper_usage_key, category='html') html_usage_key = self.response_usage_key(resp) # The unit and its children should be private initially unit_update_url = reverse_usage_url('xblock_handler', unit_usage_key) unit = self.get_item_from_modulestore(unit_usage_key, True) html = self.get_item_from_modulestore(html_usage_key, True) self.assertEqual(compute_publish_state(unit), PublishState.private) self.assertEqual(compute_publish_state(html), PublishState.private) # Make the unit public and verify that the problem is also made public resp = self.client.ajax_post(unit_update_url, data={'publish': 'make_public'}) self.assertEqual(resp.status_code, 200) unit = self.get_item_from_modulestore(unit_usage_key, True) html = self.get_item_from_modulestore(html_usage_key, True) self.assertEqual(compute_publish_state(unit), PublishState.public) self.assertEqual(compute_publish_state(html), PublishState.public) # Make a draft for the unit and verify that the problem also has a draft resp = self.client.ajax_post(unit_update_url, data={ 'id': unicode(unit_usage_key), 'metadata': {}, 'publish': 'create_draft' }) self.assertEqual(resp.status_code, 200) unit = self.get_item_from_modulestore(unit_usage_key, True) html = self.get_item_from_modulestore(html_usage_key, True) self.assertEqual(compute_publish_state(unit), PublishState.draft) self.assertEqual(compute_publish_state(html), PublishState.draft)
def test_publish_states_of_nested_xblocks(self): """ Test publishing of a unit page containing a nested xblock """ resp = self.create_xblock(parent_usage_key=self.seq_usage_key, display_name='Test Unit', category='vertical') unit_usage_key = self.response_usage_key(resp) resp = self.create_xblock(parent_usage_key=unit_usage_key, category='wrapper') wrapper_usage_key = self.response_usage_key(resp) resp = self.create_xblock(parent_usage_key=wrapper_usage_key, category='html') html_usage_key = self.response_usage_key(resp) # The unit and its children should be private initially unit_update_url = reverse_usage_url('xblock_handler', unit_usage_key) unit = self.get_item_from_modulestore(unit_usage_key, True) html = self.get_item_from_modulestore(html_usage_key, True) self.assertEqual(compute_publish_state(unit), PublishState.private) self.assertEqual(compute_publish_state(html), PublishState.private) # Make the unit public and verify that the problem is also made public resp = self.client.ajax_post( unit_update_url, data={'publish': 'make_public'} ) self.assertEqual(resp.status_code, 200) unit = self.get_item_from_modulestore(unit_usage_key, True) html = self.get_item_from_modulestore(html_usage_key, True) self.assertEqual(compute_publish_state(unit), PublishState.public) self.assertEqual(compute_publish_state(html), PublishState.public) # Make a draft for the unit and verify that the problem also has a draft resp = self.client.ajax_post( unit_update_url, data={ 'id': unicode(unit_usage_key), 'metadata': {}, 'publish': 'create_draft' } ) self.assertEqual(resp.status_code, 200) unit = self.get_item_from_modulestore(unit_usage_key, True) html = self.get_item_from_modulestore(html_usage_key, True) self.assertEqual(compute_publish_state(unit), PublishState.draft) self.assertEqual(compute_publish_state(html), PublishState.draft)
def xblock_view_handler(request, package_id, view_name, tag=None, branch=None, version_guid=None, block=None): """ The restful handler for requests for rendered xblock views. Returns a json object containing two keys: html: The rendered html of the view resources: A list of tuples where the first element is the resource hash, and the second is the resource description """ locator = BlockUsageLocator(package_id=package_id, branch=branch, version_guid=version_guid, block_id=block) if not has_course_access(request.user, locator): raise PermissionDenied() old_location = loc_mapper().translate_locator_to_location(locator) accept_header = request.META.get('HTTP_ACCEPT', 'application/json') if 'application/json' in accept_header: store = get_modulestore(old_location) component = store.get_item(old_location) # wrap the generated fragment in the xmodule_editor div so that the javascript # can bind to it correctly component.runtime.wrappers.append(partial(wrap_xblock, 'StudioRuntime')) if view_name == 'studio_view': try: fragment = component.render('studio_view') # catch exceptions indiscriminately, since after this point they escape the # dungeon and surface as uneditable, unsaveable, and undeletable # component-goblins. except Exception as exc: # pylint: disable=w0703 log.debug("unable to render studio_view for %r", component, exc_info=True) fragment = Fragment( render_to_string('html_error.html', {'message': str(exc)})) # change not authored by requestor but by xblocks. store.update_item(component, None) elif view_name == 'student_view' and component.has_children: # For non-leaf xblocks on the unit page, show the special rendering # which links to the new container page. html = render_to_string( 'container_xblock_component.html', { 'xblock': component, 'locator': locator, 'reordering_enabled': True, }) return JsonResponse({ 'html': html, 'resources': [], }) elif view_name in ('student_view', 'container_preview'): is_container_view = (view_name == 'container_preview') component_publish_state = compute_publish_state(component) is_read_only_view = component_publish_state == PublishState.public # Only show the new style HTML for the container view, i.e. for non-verticals # Note: this special case logic can be removed once the unit page is replaced # with the new container view. context = { 'runtime_type': 'studio', 'container_view': is_container_view, 'read_only': is_read_only_view, 'root_xblock': component, } fragment = get_preview_fragment(request, component, context) # For old-style pages (such as unit and static pages), wrap the preview with # the component div. Note that the container view recursively adds headers # into the preview fragment, so we don't want to add another header here. if not is_container_view: fragment.content = render_to_string( 'component.html', { 'preview': fragment.content, 'label': component.display_name or component.scope_ids.block_type, }) else: raise Http404 hashed_resources = OrderedDict() for resource in fragment.resources: hashed_resources[hash_resource(resource)] = resource return JsonResponse({ 'html': fragment.content, 'resources': hashed_resources.items() }) else: return HttpResponse(status=406)
def subsection_handler(request, usage_key_string): """ The restful handler for subsection-specific requests. GET html: return html page for editing a subsection json: not currently supported """ if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'): usage_key = UsageKey.from_string(usage_key_string) try: course, item, lms_link = _get_item_in_course(request, usage_key) except ItemNotFoundError: return HttpResponseBadRequest() preview_link = get_lms_link_for_item(usage_key, preview=True) # make sure that location references a 'sequential', otherwise return # BadRequest if item.location.category != 'sequential': return HttpResponseBadRequest() parent = get_parent_xblock(item) # remove all metadata from the generic dictionary that is presented in a # more normalized UI. We only want to display the XBlocks fields, not # the fields from any mixins that have been added fields = getattr(item, 'unmixed_class', item.__class__).fields policy_metadata = dict( (field.name, field.read_from(item)) for field in fields.values() if field.name not in ['display_name', 'start', 'due', 'format'] and field.scope == Scope.settings ) can_view_live = False subsection_units = item.get_children() for unit in subsection_units: state = compute_publish_state(unit) if state in (PublishState.public, PublishState.draft): can_view_live = True break return render_to_response( 'edit_subsection.html', { 'subsection': item, 'context_course': course, 'new_unit_category': 'vertical', 'lms_link': lms_link, 'preview_link': preview_link, 'course_graders': json.dumps(CourseGradingModel.fetch(usage_key.course_key).graders), 'parent_item': parent, 'locator': usage_key, 'policy_metadata': policy_metadata, 'subsection_units': subsection_units, 'can_view_live': can_view_live } ) else: return HttpResponseBadRequest("Only supports html requests")
def unit_handler(request, usage_key_string): """ The restful handler for unit-specific requests. GET html: return html page for editing a unit json: not currently supported """ if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'): usage_key = UsageKey.from_string(usage_key_string) try: course, item, lms_link = _get_item_in_course(request, usage_key) except ItemNotFoundError: return HttpResponseBadRequest() component_templates = _get_component_templates(course) xblocks = item.get_children() # TODO (cpennington): If we share units between courses, # this will need to change to check permissions correctly so as # to pick the correct parent subsection containing_subsection = get_parent_xblock(item) containing_section = get_parent_xblock(containing_subsection) # cdodge hack. We're having trouble previewing drafts via jump_to redirect # so let's generate the link url here # need to figure out where this item is in the list of children as the # preview will need this index = 1 for child in containing_subsection.get_children(): if child.location == item.location: break index = index + 1 preview_lms_base = settings.FEATURES.get('PREVIEW_LMS_BASE') preview_lms_link = ( u'//{preview_lms_base}/courses/{org}/{course}/{course_name}/courseware/{section}/{subsection}/{index}' ).format( preview_lms_base=preview_lms_base, lms_base=settings.LMS_BASE, org=course.location.org, course=course.location.course, course_name=course.location.name, section=containing_section.location.name, subsection=containing_subsection.location.name, index=index ) return render_to_response('unit.html', { 'context_course': course, 'unit': item, 'unit_usage_key': usage_key, 'child_usage_keys': [block.scope_ids.usage_id for block in xblocks], 'component_templates': json.dumps(component_templates), 'draft_preview_link': preview_lms_link, 'published_preview_link': lms_link, 'subsection': containing_subsection, 'release_date': ( get_default_time_display(containing_subsection.start) if containing_subsection.start is not None else None ), 'section': containing_section, 'new_unit_category': 'vertical', 'unit_state': compute_publish_state(item), 'published_date': ( get_default_time_display(item.published_date) if item.published_date is not None else None ), }) else: return HttpResponseBadRequest("Only supports html requests")
def xblock_view_handler(request, package_id, view_name, tag=None, branch=None, version_guid=None, block=None): """ The restful handler for requests for rendered xblock views. Returns a json object containing two keys: html: The rendered html of the view resources: A list of tuples where the first element is the resource hash, and the second is the resource description """ locator = BlockUsageLocator(package_id=package_id, branch=branch, version_guid=version_guid, block_id=block) if not has_course_access(request.user, locator): raise PermissionDenied() old_location = loc_mapper().translate_locator_to_location(locator) accept_header = request.META.get('HTTP_ACCEPT', 'application/json') if 'application/json' in accept_header: store = get_modulestore(old_location) component = store.get_item(old_location) # wrap the generated fragment in the xmodule_editor div so that the javascript # can bind to it correctly component.runtime.wrappers.append(partial(wrap_xblock, 'StudioRuntime')) if view_name == 'studio_view': try: fragment = component.render('studio_view') # catch exceptions indiscriminately, since after this point they escape the # dungeon and surface as uneditable, unsaveable, and undeletable # component-goblins. except Exception as exc: # pylint: disable=w0703 log.debug("unable to render studio_view for %r", component, exc_info=True) fragment = Fragment(render_to_string('html_error.html', {'message': str(exc)})) # change not authored by requestor but by xblocks. store.update_item(component, None) elif view_name == 'student_view' and component.has_children: # For non-leaf xblocks on the unit page, show the special rendering # which links to the new container page. html = render_to_string('container_xblock_component.html', { 'xblock': component, 'locator': locator, 'reordering_enabled': True, }) return JsonResponse({ 'html': html, 'resources': [], }) elif view_name in ('student_view', 'container_preview'): is_container_view = (view_name == 'container_preview') component_publish_state = compute_publish_state(component) is_read_only_view = component_publish_state == PublishState.public # Only show the new style HTML for the container view, i.e. for non-verticals # Note: this special case logic can be removed once the unit page is replaced # with the new container view. context = { 'runtime_type': 'studio', 'container_view': is_container_view, 'read_only': is_read_only_view, 'root_xblock': component, } fragment = get_preview_fragment(request, component, context) # For old-style pages (such as unit and static pages), wrap the preview with # the component div. Note that the container view recursively adds headers # into the preview fragment, so we don't want to add another header here. if not is_container_view: fragment.content = render_to_string('component.html', { 'preview': fragment.content, 'label': component.display_name or component.scope_ids.block_type, }) else: raise Http404 hashed_resources = OrderedDict() for resource in fragment.resources: hashed_resources[hash_resource(resource)] = resource return JsonResponse({ 'html': fragment.content, 'resources': hashed_resources.items() }) else: return HttpResponse(status=406)
def block_clone_handler(request, course_key_string): """ Permite clonar o conteúdo de uma dada semana do experimento. Além de clonar, nesta função faz a definição do experimento. o que insere entradas nas tabelas ExperimentDefinition, StrategyRandomization e OpcoesExperiment. :param request: http request com parent_location (location do curso) e mais source_locator (location da section) :param course_key_string: useless :return: json com OK """ letras = ['A', 'B', 'C', 'D'] if request.method in ('PUT', 'POST'): # Get location Course com base no valor passado pelo Json locatorCursokey = UsageKey.from_string(request.json['parent_locator']) locatorSectionKey = UsageKey.from_string(request.json['source_locator']) if not has_course_access(request.user, locatorSectionKey): raise PermissionDenied() # Verifica se já tem um experimento de acordo com o SourceLocation expSection = None try: opcExp = OpcoesExperiment.objects.get(sectionExp='%s' % request.json['source_locator']) temExp = True expSection = opcExp.experimento # pega o experimento para cadastrar a nova versao except: temExp = False # Pesquisa no banco de dados o Curso do qual duplicará os módulos course = modulestore().get_item(locatorCursokey, depth=3) sections = course.get_children() quantidade = 0 for section in sections: if locatorSectionKey == section.location: NewLocatorItemSection = create_item(locatorCursokey, 'chapter', section.display_name_with_default, request) # tem que Mudar para HomeWork, ou qualquer tipo que eu definir SectionLocation = NewLocatorItemSection descript = get_modulestore(NewLocatorItemSection).get_item(NewLocatorItemSection) storeSection = get_modulestore(NewLocatorItemSection) try: existing_item = storeSection.get_item(SectionLocation) field = existing_item.fields['start'] if section.start is not None: print "NÃO É NULO " field.write_to(existing_item, section.start) storeSection.update_item(existing_item, request.user.id) except: print "Start Date and end Date" subsections = section.get_children() quantidade = 0 if temExp: opcExp3 = OpcoesExperiment() opcExp3.experimento = expSection opcExp3.sectionExp = "%s" % NewLocatorItemSection opcExp3.sectionExp_url = '%s' % getURLSection(locatorCursokey, NewLocatorItemSection) lenOpcs = len(OpcoesExperiment.objects.filter(experimento=expSection)) opcExp3.version = letras[lenOpcs] opcExp3.save() st = opcExp3.experimento.strategy st.percents +=';0.0' st.save() else: st = StrategyRandomization() st.strategyType = 'UniformChoice' st.percents = '0.0;0.0' st.save() # Experiment defintion exp = ExperimentDefinition() exp.course = request.json['parent_locator'] exp.userTeacher = request.user now = datetime.datetime.now() exp.descricao='MyExperiment %s ' % now exp.strategy = st exp.save() # Define a primeira versão do experimento opcExp = OpcoesExperiment() opcExp.experimento = exp opcExp.sectionExp = "%s" % locatorSectionKey opcExp.sectionExp_url = "%s" % section.url_name opcExp.version = 'A' opcExp.save() # Define a segunda versão do experimento opcExp2 = OpcoesExperiment() opcExp2.experimento = exp opcExp2.sectionExp = "%s" % NewLocatorItemSection opcExp2.sectionExp_url = '%s' % getURLSection(locatorCursokey, NewLocatorItemSection) opcExp2.version = 'B' opcExp2.save() for subsection in subsections: print print print "Clonando SubSeção: ", subsection.location NewLocatorItemSubsection = create_item(NewLocatorItemSection, 'sequential', subsection.display_name_with_default, request) # Agora iremos testar os Units units_Subsection = subsection.get_children() print "Information about the subsection: " print "subsection.format: ", subsection.format print "subsection.start: ", subsection.start print "Subsection locator: ", NewLocatorItemSubsection # tem que Mudar para HomeWork, ou qualquer tipo que eu definir # subLocation = loc_mapper().translate_locator_to_location(NewLocatorItemSubsection) # print "vert Location: ", subLocation # old_location = course_location.replace(category='course_info', name=block) # # descript = get_modulestore(NewLocatorItemSubsection).get_item(NewLocatorItemSubsection) print "Descript: ", descript CourseGradingModel.update_section_grader_type(descript, subsection.format, request.user) # Start Value storeSection = get_modulestore(NewLocatorItemSubsection) try: existing_item = storeSection.get_item(NewLocatorItemSubsection) field = existing_item.fields['start'] if subsection.start is not None: print "NÃO É NULO " field.write_to(existing_item, subsection.start) storeSection.update_item(existing_item, request.user.id) except: print "Deu erro" # Print all Units for unit in units_Subsection: originalState = compute_publish_state(unit) destinationUnit = duplicate_item(NewLocatorItemSubsection, unit.location, unit.display_name_with_default, request.user) # Nesta parte faz-se a leitura se e privado ou publico, se publico, seta a variavel como publico try: print "Vou fazer o translation -- destinationUnit ", destinationUnit # unitLocation = loc_mapper().translate_locator_to_location(destinationUnit) unitLocation = destinationUnit print "unity location: ", unitLocation # Start Value storeUnit = get_modulestore(unitLocation) print "STORE UNIT" try: existing_itemUnit = storeUnit.get_item(unitLocation) except: print "Deu erro" print "Antes do public" if originalState == 'public': def _publish(block): # This is super gross, but prevents us from publishing something that # we shouldn't. Ideally, all modulestores would have a consistant # interface for publishing. However, as of now, only the DraftMongoModulestore # does, so we have to check for the attribute explicitly. store = get_modulestore(block.location) print "Peguei o Store" if hasattr(store, 'publish'): store.publish(block.location, request.user.id) _xmodule_recurse( existing_itemUnit, _publish ) except: print "Erro ao setar publico" dataR = {'ok': quantidade } # return JsonResponse(dataR)
def unit_handler(request, tag=None, package_id=None, branch=None, version_guid=None, block=None): """ The restful handler for unit-specific requests. GET html: return html page for editing a unit json: not currently supported """ if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'): locator = BlockUsageLocator(package_id=package_id, branch=branch, version_guid=version_guid, block_id=block) try: old_location, course, item, lms_link = _get_item_in_course(request, locator) except ItemNotFoundError: return HttpResponseBadRequest() component_templates = defaultdict(list) for category in COMPONENT_TYPES: component_class = _load_mixed_class(category) # add the default template # TODO: Once mixins are defined per-application, rather than per-runtime, # this should use a cms mixed-in class. (cpennington) if hasattr(component_class, 'display_name'): display_name = component_class.display_name.default or 'Blank' else: display_name = 'Blank' component_templates[category].append(( display_name, category, False, # No defaults have markdown (hardcoded current default) None # no boilerplate for overrides )) # add boilerplates if hasattr(component_class, 'templates'): for template in component_class.templates(): filter_templates = getattr(component_class, 'filter_templates', None) if not filter_templates or filter_templates(template, course): component_templates[category].append(( template['metadata'].get('display_name'), category, template['metadata'].get('markdown') is not None, template.get('template_id') )) # Check if there are any advanced modules specified in the course policy. # These modules should be specified as a list of strings, where the strings # are the names of the modules in ADVANCED_COMPONENT_TYPES that should be # enabled for the course. course_advanced_keys = course.advanced_modules # Set component types according to course policy file if isinstance(course_advanced_keys, list): for category in course_advanced_keys: if category in ADVANCED_COMPONENT_TYPES: # Do I need to allow for boilerplates or just defaults on the # class? i.e., can an advanced have more than one entry in the # menu? one for default and others for prefilled boilerplates? try: component_class = _load_mixed_class(category) component_templates['advanced'].append( ( component_class.display_name.default or category, category, False, None # don't override default data ) ) except PluginMissingError: # dhm: I got this once but it can happen any time the # course author configures an advanced component which does # not exist on the server. This code here merely # prevents any authors from trying to instantiate the # non-existent component type by not showing it in the menu pass else: log.error( "Improper format for course advanced keys! %s", course_advanced_keys ) xblocks = item.get_children() locators = [ loc_mapper().translate_location( course.location.course_id, xblock.location, False, True ) for xblock in xblocks ] # TODO (cpennington): If we share units between courses, # this will need to change to check permissions correctly so as # to pick the correct parent subsection containing_subsection = get_parent_xblock(item) containing_section = get_parent_xblock(containing_subsection) # cdodge hack. We're having trouble previewing drafts via jump_to redirect # so let's generate the link url here # need to figure out where this item is in the list of children as the # preview will need this index = 1 for child in containing_subsection.get_children(): if child.location == item.location: break index = index + 1 preview_lms_base = settings.FEATURES.get('PREVIEW_LMS_BASE') preview_lms_link = ( u'//{preview_lms_base}/courses/{org}/{course}/{course_name}/courseware/{section}/{subsection}/{index}' ).format( preview_lms_base=preview_lms_base, lms_base=settings.LMS_BASE, org=course.location.org, course=course.location.course, course_name=course.location.name, section=containing_section.location.name, subsection=containing_subsection.location.name, index=index ) return render_to_response('unit.html', { 'context_course': course, 'unit': item, 'unit_locator': locator, 'locators': locators, 'component_templates': component_templates, 'draft_preview_link': preview_lms_link, 'published_preview_link': lms_link, 'subsection': containing_subsection, 'release_date': ( get_default_time_display(containing_subsection.start) if containing_subsection.start is not None else None ), 'section': containing_section, 'new_unit_category': 'vertical', 'unit_state': compute_publish_state(item), 'published_date': ( get_default_time_display(item.published_date) if item.published_date is not None else None ), }) else: return HttpResponseBadRequest("Only supports html requests")
def unit_handler(request, tag=None, package_id=None, branch=None, version_guid=None, block=None): """ The restful handler for unit-specific requests. GET html: return html page for editing a unit json: not currently supported """ if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'): locator = BlockUsageLocator(package_id=package_id, branch=branch, version_guid=version_guid, block_id=block) try: old_location, course, item, lms_link = _get_item_in_course( request, locator) except ItemNotFoundError: return HttpResponseBadRequest() component_templates = defaultdict(list) for category in COMPONENT_TYPES: component_class = _load_mixed_class(category) # add the default template # TODO: Once mixins are defined per-application, rather than per-runtime, # this should use a cms mixed-in class. (cpennington) if hasattr(component_class, 'display_name'): display_name = component_class.display_name.default or 'Blank' else: display_name = 'Blank' component_templates[category].append(( display_name, category, False, # No defaults have markdown (hardcoded current default) None # no boilerplate for overrides )) # add boilerplates if hasattr(component_class, 'templates'): for template in component_class.templates(): filter_templates = getattr(component_class, 'filter_templates', None) if not filter_templates or filter_templates( template, course): component_templates[category].append( (template['metadata'].get('display_name'), category, template['metadata'].get('markdown') is not None, template.get('template_id'))) # Check if there are any advanced modules specified in the course policy. # These modules should be specified as a list of strings, where the strings # are the names of the modules in ADVANCED_COMPONENT_TYPES that should be # enabled for the course. course_advanced_keys = course.advanced_modules # Set component types according to course policy file if isinstance(course_advanced_keys, list): for category in course_advanced_keys: if category in ADVANCED_COMPONENT_TYPES: # Do I need to allow for boilerplates or just defaults on the # class? i.e., can an advanced have more than one entry in the # menu? one for default and others for prefilled boilerplates? try: component_class = _load_mixed_class(category) component_templates['advanced'].append(( component_class.display_name.default or category, category, False, None # don't override default data )) except PluginMissingError: # dhm: I got this once but it can happen any time the # course author configures an advanced component which does # not exist on the server. This code here merely # prevents any authors from trying to instantiate the # non-existent component type by not showing it in the menu pass else: log.error("Improper format for course advanced keys! %s", course_advanced_keys) xblocks = item.get_children() locators = [ loc_mapper().translate_location(course.location.course_id, xblock.location, False, True) for xblock in xblocks ] # TODO (cpennington): If we share units between courses, # this will need to change to check permissions correctly so as # to pick the correct parent subsection containing_subsection = get_parent_xblock(item) containing_section = get_parent_xblock(containing_subsection) # cdodge hack. We're having trouble previewing drafts via jump_to redirect # so let's generate the link url here # need to figure out where this item is in the list of children as the # preview will need this index = 1 for child in containing_subsection.get_children(): if child.location == item.location: break index = index + 1 preview_lms_base = settings.FEATURES.get('PREVIEW_LMS_BASE') preview_lms_link = ( u'//{preview_lms_base}/courses/{org}/{course}/{course_name}/courseware/{section}/{subsection}/{index}' ).format(preview_lms_base=preview_lms_base, lms_base=settings.LMS_BASE, org=course.location.org, course=course.location.course, course_name=course.location.name, section=containing_section.location.name, subsection=containing_subsection.location.name, index=index) return render_to_response( 'unit.html', { 'context_course': course, 'unit': item, 'unit_locator': locator, 'locators': locators, 'component_templates': component_templates, 'draft_preview_link': preview_lms_link, 'published_preview_link': lms_link, 'subsection': containing_subsection, 'release_date': (get_default_time_display(containing_subsection.start) if containing_subsection.start is not None else None), 'section': containing_section, 'new_unit_category': 'vertical', 'unit_state': compute_publish_state(item), 'published_date': (get_default_time_display(item.published_date) if item.published_date is not None else None), }) else: return HttpResponseBadRequest("Only supports html requests")