예제 #1
0
def basic_lti_launch(request):
    try:
        request.resource
    except AttributeError:
        return no_resource(request)

    client_key = request.POST.get('oauth_consumer_key')
    consumer = LTIConsumer.objects.get(key=client_key)

    user_id = request.LTI.get('user_id')

    user_data = LTIUserData.objects.filter(user=request.user, resource = request.resource, consumer=consumer, consumer_user_id = user_id).last()
    if user_data is None:
        user_data = LTIUserData.objects.create(user=request.user, resource = request.resource, consumer=consumer, consumer_user_id = user_id)

    user_data.lis_result_sourcedid = request.POST.get('lis_result_sourcedid')
    user_data.lis_outcome_service_url = request.POST.get('lis_outcome_service_url')
    user_data.save()

    if request_is_instructor(request):
        if not request.resource.exam:
            return redirect(reverse('create_exam',args=(request.resource.pk,)))
        else:
            return redirect(reverse('dashboard',args=(request.resource.pk,)))
    else:
        if not request.resource.exam:
            return render(request,'numbas_lti/exam_not_set_up.html',{})
        else:
            return redirect(reverse('show_attempts'))
예제 #2
0
def basic_lti_launch(request):
    try:
        request.resource
    except AttributeError:
        return no_resource(request)

    client_key = request.POST.get('oauth_consumer_key')
    consumer = LTIConsumer.objects.get(key=client_key)

    user_data, _ = LTIUserData.objects.get_or_create(
        user=request.user,
        resource=request.resource,
        consumer=consumer,
        consumer_user_id=request.LTI.get('user_id'))
    user_data.lis_result_sourcedid = request.POST.get('lis_result_sourcedid')
    user_data.lis_outcome_service_url = request.POST.get(
        'lis_outcome_service_url')
    user_data.save()

    if request_is_instructor(request):
        if not request.resource.exam:
            return redirect(
                reverse('create_exam', args=(request.resource.pk, )))
        else:
            return redirect(reverse('dashboard', args=(request.resource.pk, )))
    else:
        if not request.resource.exam:
            return render(request, 'numbas_lti/exam_not_set_up.html', {})
        else:
            return redirect(reverse('show_attempts'))
예제 #3
0
def basic_lti_launch(request):
    try:
        request.resource
    except AttributeError:
        return no_resource(request)

    client_key = request.POST.get('oauth_consumer_key')
    consumer = LTIConsumer.objects.get(key=client_key)

    is_instructor = request_is_instructor(request)

    user_id = request.LTI.get('user_id')

    user_data_args = {
        'user': request.user,
        'resource': request.resource,
        'consumer': consumer,
        'consumer_user_id': user_id,
    }
    user_data = LTIUserData.objects.filter(**user_data_args).last()
    if user_data is None:
        user_data = LTIUserData.objects.create(**user_data_args)

    user_data.lis_result_sourcedid = request.POST.get('lis_result_sourcedid')
    user_data.lis_person_sourcedid = request.LTI.get('lis_person_sourcedid',
                                                     '')
    user_data.lis_outcome_service_url = request.POST.get(
        'lis_outcome_service_url')
    user_data.is_instructor = is_instructor
    user_data.save()

    ip_address, ip_routable = get_client_ip(request)

    LTILaunch.objects.create(user=request.user,
                             resource=request.resource,
                             user_agent=request.META.get('HTTP_USER_AGENT'),
                             ip_address=ip_address)

    if is_instructor:
        if not request.resource.exam:
            return redirect(
                reverse('create_exam', args=(request.resource.pk, )))
        else:
            return redirect(
                reverse('resource_dashboard', args=(request.resource.pk, )))
    else:
        if not request.resource.exam:
            return render(request, 'numbas_lti/exam_not_set_up.html', {})
        else:
            return redirect(reverse('show_attempts'))
예제 #4
0
 def form_invalid(self,form):
     url = form.data['url']
     try:
         link = EditorLink.objects.get(url=url)
         return redirect(reverse('edit_editorlink',args=(link.pk,)))
     except EditorLink.DoesNotExist:
         return super(CreateEditorLinkView,self).form_invalid(form)
예제 #5
0
def index(request):
    if not User.objects.filter(is_superuser=True).exists():
        return redirect(reverse('create_superuser'))
    context = {
        'entry_url': get_lti_entry_url(request),
    }
    return render(request,'numbas_lti/index.html',context)
예제 #6
0
def index(request):
    if not User.objects.filter(is_superuser=True).exists():
        return redirect(reverse('create_superuser'))
    context = {
        'entry_url': get_lti_entry_url(request),
    }
    return render(request, 'numbas_lti/index.html', context)
 def form_invalid(self, form):
     url = form.data['url']
     try:
         link = EditorLink.objects.get(url=url)
         return redirect(reverse('edit_editorlink', args=(link.pk, )))
     except EditorLink.DoesNotExist:
         return super(CreateEditorLinkView, self).form_invalid(form)
예제 #8
0
    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)

        resource = self.object
        attempts = resource.unbroken_attempts()

        context['attempts'] = [{
            'pk': a.pk,
            'completion_status': a.completion_status,
            'user': {
                'full_name': a.user.get_full_name(),
                'identifier': a.user_data().identifier(),
            },
        } for a in attempts]

        context['parameters'] = {
            'save_url': reverse('resource_remark_save_data',
                                args=(resource.pk, )),
        }

        source_path = Path(resource.exam.extracted_path) / 'source.exam'
        if source_path.exists():
            with open(str(source_path)) as f:
                text = f.read()
                i = text.find('\n')
                data = json.loads(text[i + 1:])
                context['exam_source'] = data

        return context
예제 #9
0
 def post(self, request, *args, **kwargs):
     resource = self.request.resource
     with transaction.atomic():
         for a in Attempt.objects.filter(resource=resource).exclude(exam=resource.exam):
             a.exam = resource.exam
             a.save()
     messages.add_message(self.request,messages.INFO,_('All attempts now use the active version of this resource\'s exam.'))
     return redirect(reverse('replace_exam',args=(resource.pk,)))
예제 #10
0
def lti_entry(request):
    if request.method != 'POST':
        return not_post(request)

    if request.session.session_key is None:
        request.session.save()
    session_key = request.session.session_key
    return redirect(
        add_query_param(reverse('check_cookie_entry'),
                        {'session_key': session_key}))
예제 #11
0
def set_cookie_entry(request):
    session_key = request.GET.get('session_key')
    resource_link_id = request.GET.get('resource_link_id')
    engine = import_module(settings.SESSION_ENGINE)
    request.session = engine.SessionStore(session_key)
    request.session.modified = True
    return redirect(
        add_query_param(reverse('check_cookie_entry'), {
            'session_key': session_key,
            'resource_link_id': resource_link_id
        }))
예제 #12
0
 def get(self, request, *args, **kwargs):
     attempt = self.get_object()
     e = ScormElement.objects.create(
             attempt=attempt,
             key='cmi.completion_status',
             value='incomplete',
             time=timezone.now(),
             counter=1
         )
     messages.add_message(self.request,messages.SUCCESS,_('{}\'s attempt has been reopened.'.format(attempt.user.get_full_name())))
     return redirect(reverse('manage_attempts',args=(attempt.resource.pk,)))
예제 #13
0
def resource_json(resource):
    consumer = resource.context.consumer if resource.context else None
    return {
        'model': 'resource',
        'id': resource.pk,
        'title': resource.title,
        'consumer': consumer.key if consumer else '',
        'context': resource.context.name if resource.context else '',
        'label': get_template('numbas_lti/management/search/autocomplete_resource.html').render({'resource': resource}),
        'url': reverse('resource_dashboard',args=(resource.pk,)),
        'text': resource.title,
    }
예제 #14
0
def user_json(user):
    consumers = LTIConsumer.objects.filter(contexts__resources__launches__user=user).distinct()
    return {
        'model': 'user',
        'id': user.pk,
        'username': user.username,
        'name': user.get_full_name(),
        'consumers': [c.key for c in consumers],
        'label': get_template('numbas_lti/management/search/autocomplete_user.html').render({'user': user, 'consumers': consumers}),
        'url': reverse('global_user_info', args=(user.pk,)),
        'text': user.username,
    }
예제 #15
0
def check_cookie_entry(request):
    sent_session_key = request.GET.get('session_key')
    resource_link_id = request.GET.get('resource_link_id')
    if sent_session_key == request.session.session_key:
        return do_lti_entry(request)
    else:
        url = add_query_param(reverse('set_cookie_entry'), {
            'session_key': sent_session_key,
            'resource_link_id': resource_link_id
        })
        return render(request, 'numbas_lti/check_cookie_entry.html',
                      {'url': url})
예제 #16
0
 def get(self, request, *args, **kwargs):
     attempt = self.get_object()
     e = ScormElement.objects.create(attempt=attempt,
                                     key='cmi.completion_status',
                                     value='incomplete',
                                     time=timezone.now(),
                                     counter=1)
     messages.add_message(
         self.request, messages.SUCCESS,
         _('{}\'s attempt has been reopened.'.format(
             attempt.user.get_full_name())))
     return redirect(
         reverse('manage_attempts', args=(attempt.resource.pk, )))
예제 #17
0
def new_attempt(request):
    if not request.resource.can_start_new_attempt(request.user):
        raise PermissionDenied(ugettext("You can't start a new attempt at this exam"))

    if Attempt.objects.filter(resource=request.resource,user=request.user).count() == request.resource.max_attempts > 0:
        AccessToken.objects.filter(resource=request.resource,user=request.user).first().delete()

    attempt = Attempt.objects.create(
        resource = request.resource,
        exam = request.resource.exam,
        user = request.user
    )
    return redirect(reverse('run_attempt',args=(attempt.pk,)))
예제 #18
0
def new_attempt(request):
    if not request.resource.can_start_new_attempt(request.user):
        raise PermissionDenied(
            ugettext("You can't start a new attempt at this exam."))

    if Attempt.objects.filter(
            resource=request.resource,
            user=request.user).count() == request.resource.max_attempts > 0:
        AccessToken.objects.filter(resource=request.resource,
                                   user=request.user).first().delete()

    attempt = Attempt.objects.create(resource=request.resource,
                                     exam=request.resource.exam,
                                     user=request.user)
    return redirect(reverse('run_attempt', args=(attempt.pk, )))
예제 #19
0
def get_lti_entry_url(request):
    return request.build_absolute_uri(reverse('lti_entry',exclude_resource_link_id=True))
예제 #20
0
 def get_success_url(self):
     print(self.object)
     return reverse('view_consumer',args=(self.get_object().pk,))
예제 #21
0
 def get_success_url(self):
     return reverse('consumer_manage_time_periods',args=(self.get_object().consumer.pk,))
예제 #22
0
 def render_to_response(self,context):
     process = self.get_object()
     process.dismissed = True
     process.save()
     return redirect(reverse('dashboard',args=(process.resource.pk,)))
예제 #23
0
 def get_success_url(self):
     return reverse('dashboard',args=(self.request.resource.pk,))
예제 #24
0
 def get_success_url(self):
     return reverse('manage_attempts', args=(self.request.resource.pk, ))
예제 #25
0
def remove_access_token(request,resource_id,user_id):
    resource = Resource.objects.get(pk=resource_id)
    user = User.objects.get(id=user_id)
    AccessToken.objects.filter(user=user,resource=resource).first().delete()

    return redirect(reverse('dashboard',args=(resource.pk,)))
예제 #26
0
 def get_absolute_url(self):
     return reverse('view_stresstest',args=(self.pk,))
예제 #27
0
 def get_success_url(self):
     return reverse('manage_attempts',args=(self.request.resource.pk,))
예제 #28
0
 def get_success_url(self):
     return reverse('view_consumer', args=(self.get_object().pk, ))
예제 #29
0
 def dispatch(self,request,*args,**kwargs):
     if User.objects.filter(is_superuser=True).exists():
         return redirect(reverse('index'))
     else:
         return super(CreateSuperuserView,self).dispatch(request,*args,**kwargs)
예제 #30
0
 def render_to_response(self, context):
     process = self.get_object()
     process.dismissed = True
     process.save()
     return redirect(
         reverse('resource_dashboard', args=(process.resource.pk, )))
예제 #31
0
def grant_access_token(request, resource_id, user_id):
    resource = Resource.objects.get(pk=resource_id)
    user = User.objects.get(id=user_id)
    AccessToken.objects.create(user=user, resource=resource)

    return redirect(reverse('resource_dashboard', args=(resource.pk, )))
예제 #32
0
    def dispatch(self,*args,**kwargs):
        resource = self.get_resource()
        if resource.exam is None:
            return redirect(reverse('create_exam',args=(resource.pk,)))

        return super(MustHaveExamMixin,self).dispatch(*args,**kwargs)
예제 #33
0
def get_config_url(request):
    return request.build_absolute_uri(reverse('config_xml',exclude_resource_link_id=True))
예제 #34
0
    def dispatch(self,*args,**kwargs):
        resource = self.get_resource()
        if resource.exam is None:
            return redirect(reverse('create_exam',args=(resource.pk,)))

        return super(MustHaveExamMixin,self).dispatch(*args,**kwargs)
예제 #35
0
 def redirect_url(self):
     return reverse('not_authorized')+'?originalurl='+urllib.parse.quote(self.request.path+'?'+self.request.META.get('QUERY_STRING',''))
예제 #36
0
 def get_success_url(self):
     if LTIConsumer.objects.exists():
         return reverse('list_consumers')
     else:
         return reverse('create_consumer')
예제 #37
0
 def get_success_url(self):
     return reverse('resource_dashboard', args=(self.get_object().pk, ))
예제 #38
0
    def get_context_data(self, *args, **kwargs):
        context = super(RunAttemptView, self).get_context_data(*args, **kwargs)

        attempt = self.get_object()

        if attempt.completion_status == 'not attempted':
            entry = 'ab-initio'
        elif attempt.scormelements.filter(key='cmi.suspend_data').exists():
            entry = 'resume'
        else:
            # Not enough data was saved last time. Mark this attempt as broken, and create a new one.
            # This isn't ideal, because what's happening isn't made clear to the student, but this should only occur when the student didn't really start the attempt they're resuming
            broken_attempt = attempt
            broken_attempt.broken = True
            broken_attempt.save()

            attempt = Attempt.objects.create(resource=broken_attempt.resource,
                                             exam=broken_attempt.exam,
                                             user=broken_attempt.user)
            entry = 'ab-initio'
            context['attempt'] = attempt

        if attempt.completed():
            mode = 'review'
        else:
            mode = 'normal'

        if attempt.user != self.request.user:
            if request_is_instructor(self.request):
                mode = 'review'
            else:
                raise PermissionDenied(
                    ugettext("You're not allowed to review this attempt."))

        context['mode'] = self.mode = mode

        user = attempt.user
        user_data = attempt.resource.user_data(user)

        scorm_cmi = attempt.scorm_cmi()

        dynamic_cmi = {
            'cmi.mode':
            mode,
            'cmi.entry':
            entry,
            'numbas.user_role':
            'instructor' if request_is_instructor(self.request) else 'student',
        }
        now = datetime.datetime.now().timestamp()
        dynamic_cmi = {
            k: {
                'value': v,
                'time': now
            }
            for k, v in dynamic_cmi.items()
        }
        scorm_cmi.update(dynamic_cmi)

        context['support_name'] = getattr(settings, 'SUPPORT_NAME', None)
        context['support_url'] = getattr(settings, 'SUPPORT_URL', None)

        context['scorm_cmi'] = simplejson.encoder.JSONEncoderForHTML().encode(
            scorm_cmi)
        context['available_until'] = attempt.resource.available_until

        context['js_vars'] = {
            'exam_url':
            attempt.exam.extracted_url + '/index.html',
            'scorm_cmi':
            scorm_cmi,
            'attempt_pk':
            attempt.pk,
            'fallback_url':
            reverse('attempt_scorm_data_fallback', args=(attempt.pk, )),
            'show_attempts_url':
            reverse('show_attempts'),
            'allow_review_from':
            attempt.resource.allow_review_from.isoformat()
            if attempt.resource.allow_review_from else None,
            'available_from':
            attempt.resource.available_from.isoformat()
            if attempt.resource.available_from else None,
            'available_until':
            attempt.resource.available_until.isoformat()
            if attempt.resource.available_until else None,
        }

        return context
예제 #39
0
def remove_access_token(request, resource_id, user_id):
    resource = Resource.objects.get(pk=resource_id)
    user = User.objects.get(id=user_id)
    AccessToken.objects.filter(user=user, resource=resource).first().delete()

    return redirect(reverse('resource_dashboard', args=(resource.pk, )))
예제 #40
0
def get_lti_entry_url(request):
    return request.build_absolute_uri(reverse('lti_entry',exclude_resource_link_id=True))
예제 #41
0
 def get_success_url(self):
     return reverse('resource_dashboard', args=(self.request.resource.pk, ))
예제 #42
0
 def get_success_url(self):
     return reverse('resource_settings', args=(self.request.resource.pk, ))
예제 #43
0
 def get_success_url(self):
     return reverse('consumer_manage_time_periods',
                    args=(self.get_object().consumer.pk, ))
예제 #44
0
 def get_success_url(self):
     return reverse('edit_editorlink',args=(self.object.pk,))
예제 #45
0
 def get_success_url(self):
     if LTIConsumer.objects.exists():
         return reverse('list_consumers')
     else:
         return reverse('create_consumer')
예제 #46
0
 def get_success_url(self):
     return reverse('dashboard',args=(self.get_object().pk,))
예제 #47
0
 def get_absolute_url(self):
     return reverse('view_stresstest', args=(self.pk, ))
예제 #48
0
def grant_access_token(request,resource_id,user_id):
    resource = Resource.objects.get(pk=resource_id)
    user = User.objects.get(id=user_id)
    AccessToken.objects.create(user=user,resource=resource)

    return redirect(reverse('dashboard',args=(resource.pk,)))
예제 #49
0
 def get_success_url(self):
     return reverse('replace_exam', args=(self.request.resource.pk, ))
예제 #50
0
def get_config_url(request):
    return request.build_absolute_uri(reverse('config_xml',exclude_resource_link_id=True))