harvard-vpal/bridge-adaptivity

View on GitHub
bridge_adaptivity/bridge_lti/consumer.py

Summary

Maintainability
A
0 mins
Test Coverage
import logging
import urllib.parse

from django.conf import settings
from django.http import HttpResponse
from django.shortcuts import render
from django.urls import reverse
from lti import ToolConfig, ToolConsumer

from api.backends.api_client import get_content_providers
from module.models import SequenceItem

log = logging.getLogger(__name__)


def tool_config(request):
    app_title = 'Bridge'
    app_description = 'Bridge for Adaptivity'
    launch_view_name = 'lti_launch'
    launch_url = request.build_absolute_uri(reverse(launch_view_name))

    extensions = {}

    lti_tool_config = ToolConfig(
        title=app_title,
        launch_url=launch_url,
        secure_launch_url=launch_url,
        extensions=extensions,
        description=app_description
    )

    return HttpResponse(lti_tool_config.to_xml(), content_type='text/xml')


def create_lti_launch_params(request, sequence_item_id, consumer_prams):
    """
    Construct lti launch parameters to get Activity from the Source.

    :param request: request
    :param sequence_item_id: id of the sequence_item
    :param consumer_prams: default consumer params
    :return: source_name, source_lti_url, updated consumer_prams
    """
    if sequence_item_id:
        # student flow
        sequence_item = SequenceItem.objects.get(id=sequence_item_id)
        activity = sequence_item.activity

        content_provider = activity.lti_content_source
        consumer_prams['consumer_key'] = content_provider.provider_key
        consumer_prams['consumer_secret'] = content_provider.provider_secret

        source_name = activity.source_name
        source_lti_url = activity.source_launch_url
        lis_outcome_service_url = urllib.parse.urljoin(settings.BRIDGE_HOST, reverse('module:sequence-item-grade'))
        consumer_prams['params'].update({
            'user_id': sequence_item.user_id_for_consumer,
            'context_id': sequence_item.sequence.collection_order.collection.name,
            'resource_link_id': sequence_item.id,
            # Grading required parameters:
            'lis_result_sourcedid': '{sequence_item_id}:{user_id}:{activity}:{suffix}'.format(
                sequence_item_id=sequence_item.id,
                user_id=sequence_item.sequence.lti_user.user_id,
                activity=sequence_item.activity.id,
                suffix=sequence_item.suffix,
            ),
            'lis_outcome_service_url': lis_outcome_service_url,
        })
    else:
        source_name = request.GET.get('source_name')
        source_lti_url = request.GET.get('source_lti_url')
        if source_lti_url is not None:
            # NOTE(wowkalucky): Django converts plus sign to space
            source_lti_url = request.GET.get('source_lti_url').replace(' ', '+')
    return source_name, source_lti_url, consumer_prams


def source_preview(request):
    """View to render Source content block shared through LTI."""
    log.debug("Got request.GET: %s", request.GET)

    content_source_id = request.GET.get('content_source_id')
    # pass source_id to get only on content source

    consumer_prams = {
        'consumer_key': '',
        'consumer_secret': '',
        'params': {
            # Required parameters
            'lti_message_type': 'basic-lti-launch-request',
            'lti_version': 'LTI-1p0',
            'resource_link_id': 'reaource_link_id',
            # Recommended parameters
            'user_id': 'bridge_user',
            'roles': 'Learner',
            'oauth_callback': 'about:blank',
            'context_id': 'bridge_collection'
        },
    }

    # Default impersonal consumer parameters are used for getting problem's preview from the Source via LTI
    sequence_item_id = request.GET.get('sequence_item_id')
    if content_source_id:
        # staff flow
        content_provider = get_content_providers(request, content_source_id).first()

        if not content_provider:
            return render(request, 'bridge_lti/stub.html')

        consumer_prams['consumer_key'] = content_provider.provider_key
        consumer_prams['consumer_secret'] = content_provider.provider_secret

    source_name, source_lti_url, consumer_prams = create_lti_launch_params(request, sequence_item_id, consumer_prams)

    consumer_prams.update({'launch_url': source_lti_url})
    log.debug("Sending parameters are: {}".format(consumer_prams))
    consumer = ToolConsumer(**consumer_prams)
    return render(request, 'bridge_lti/content-source.html', {
        'launch_data': consumer.generate_launch_data(),
        'launch_url': consumer.launch_url,
        'source_name': source_name,
    })