def create_hit(request, item, extra_info=None):
    """
    Given a Django ``request`` object, create an entry in the DB for the hit.

    If the ``item`` is a string, then we assume it is a static item and use
    the dictionary above to look up its "primary key".
    """
    ip_address = get_IP_address(request)
    ua_string = request.META.get('HTTP_USER_AGENT', '')
    if extra_info is None:
        extra_info = request.META.get('HTTP_REFERER', None)
    try:
        page_hit = PageHit(ip_address=ip_address,
                           profile=request.session.get('profile', None),
                           item=item._meta.module_name,
                           item_pk=item.pk,
                           extra_info=extra_info,
                           user_id=request.user.id,
                           userp=request.user.get_profile())
    except AttributeError:
        # in cases when the session profile is not available
        page_hit = PageHit(ip_address=ip_address,
                           ua_string=ua_string, # store as surrogate
                           item=item,
                           item_pk=static_items.get(item, 0),
                           extra_info=extra_info,
                           user_id=request.user.id,
                           userp=request.user.get_profile())

    page_hit.save()
Beispiel #2
0
def create_hit(request, item, extra_info=None):
    """
    Given a Django ``request`` object, create an entry in the DB for the hit.

    If the ``item`` is a string, then we assume it is a static item and use
    the dictionary above to look up its "primary key".
    """
    ip_address = get_IP_address(request)
    ua_string = request.META.get('HTTP_USER_AGENT', '')
    if extra_info is None:
        extra_info = request.META.get('HTTP_REFERER', None)
    if isinstance(item, int):
        page_hit = PageHit(ip_address=ip_address,
                           ua_string=ua_string,
                           item='item',
                           item_pk=item,
                           extra_info=extra_info)
    elif isinstance(item, str):
        page_hit = PageHit(ip_address=ip_address,
                           ua_string=ua_string,
                           item=item,
                           item_pk=static_items.get(item, 0),
                           extra_info=extra_info)

    page_hit.save()
Beispiel #3
0
def page_500_error(request):
    """ Override Django's 500 handler, because we want to log this also.
    """
    ip = get_IP_address(request)
    logger.error('500 from %s for request "%s"' % (ip, request.path))
    t = get_template('500.html')
    html = t.render(RequestContext(request))
    return HttpResponse(html, status=500)
Beispiel #4
0
def page_404_error(request, extra_info=''):
    """ Override Django's 404 handler, because we want to log this also.
    """
    ip = get_IP_address(request)
    logger.info('404 from %s for request "%s"; extra info=%s' %\
                                          (ip, request.path, str(extra_info)))
    t = get_template('404.html')
    c = RequestContext(request)
    c.update({'extra_info': extra_info})
    html = t.render(c)
    return HttpResponse(html, status=404)
Beispiel #5
0
def create_hit(request, item=None, event='', user=None, other_info=None):
    """
    Given a Django ``request`` object, create an entry in the DB for the hit.

    """
    ip_address = get_IP_address(request)
    ua_string = request.META.get('HTTP_USER_AGENT', '')
    referrer = request.META.get('HTTP_REFERER', None)

    try:
        page_hit = Timer(ip_address=ip_address,
                         ua_string=ua_string,
                         item_name=item._meta.model_name,
                         item_pk=item.pk,
                         referrer=referrer,
                         other_info=other_info,
                         user=user,
                         event=event)

        page_hit.save()
    except Exception:
        pass
Beispiel #6
0
def search(request):
    """
    Calls Haystack, but allows us to first log the search query
    """
    if request.GET['q'].strip() == '':
        return redirect(front_page)

    try:
        item_id = int(request.GET['q'])
    except ValueError:
        pass
    else:
        items = Item.objects.filter(id=item_id)
        if items:
            return redirect('lit-view-item', item_id=item_id)
        else:
            pass

    # Avoid duplicate logging if search request results in more than 1 page
    if 'page' not in request.GET:
        create_hit(request, 'haystack_search', request.GET['q'])
        logger.info('SEARCH [%s]: %s' %
                    (get_IP_address(request), request.GET['q']))
    return SearchView().__call__(request)
def upload_submission(request, learner, trigger, no_thumbnail=True):
    """
    Handles the upload of the user's submission.
    """
    base_dir_for_file_uploads = settings.MEDIA_ROOT
    thumbnail_file_name_django = ''
    entry_point = trigger.entry_point

    files = request.FILES.getlist('file_upload', None)
    if files is None:
        return None

    # Is the storage space reachable?
    deepest_dir = base_dir_for_file_uploads + 'uploads/{0}/tmp/'.format(
        entry_point.id)

    try:
        os.makedirs(deepest_dir)
    except OSError:
        if not os.path.isdir(deepest_dir):
            logger.error(
                'Cannot create directory for upload: {0}'.format(deepest_dir))
            raise

    if len(files) == 1:
        filename = files[0].name
        extension = filename.split('.')[-1].lower()
        submitted_file_name_django = 'uploads/{0}/{1}'.format(
            entry_point.id,
            generate_random_token(token_length=16) + '.' + extension)
        full_path = base_dir_for_file_uploads + submitted_file_name_django
        with open(full_path, 'wb+') as dst:
            for chunk in files[0].chunks():
                dst.write(chunk)

        f_size = os.path.getsize(full_path)
        if f_size > trigger.max_file_upload_size_MB * 1024 * 1024:
            logger.warning(
                'File too large {0}'.format(submitted_file_name_django))
            return None, ('File too large ({0} MB); it must be less than '
                          '{1} MB.'.format(
                              round(float(f_size / 1024.0 / 1024.0), 1),
                              trigger.max_file_upload_size_MB))

    else:  #if trigger.allow_multiple_files: this is removed for now
        filename = ''
        extension = ''
        submitted_file_name_django = ''
        full_path = ''

    # Check that the file format is PDF, if that is required.
    strike1 = False
    if 'pdf' in trigger.accepted_file_types_comma_separated.lower() and \
       extension in ('pdf',):
        try:
            mime = magic.from_file(full_path, mime=True)
            if not (isinstance(mime, str)):
                mime = mime.decode('utf-8')
        except Exception as exp:
            logger.error('Could not determine MIME type: ' + str(exp))
            mime = ''
            strike1 = True

        if 'application/pdf' not in mime.lower():
            strike1 = True

        if strike1:
            logger.debug('Invalid PDF upload: {0} [{1}]'.format(
                mime, full_path))
            #return None, 'Invalid file uploaded. Uploaded file must be a PDF.'

        doc = PdfFileReader(full_path)
        if doc.isEncrypted:
            logger.debug('Encrypted PDF upload: {0}'.format(full_path))
            return None, ('An encrypted PDF cannot be uploaded. Please remove '
                          'the encryption and try again.')

    strike1 = False
    if (('jpeg' in trigger.accepted_file_types_comma_separated.lower()) or \
       ('jpg' in trigger.accepted_file_types_comma_separated.lower())) and \
       extension in ('jpg', 'jpeg'):

        try:
            mime = magic.from_file(full_path, mime=True)
            if not (isinstance(mime, str)):
                mime = mime.decode('utf-8')
        except Exception as exp:
            logger.error('Could not determine MIME type: ' + str(exp))
            mime = ''
            strike1 = True

        if 'image/jpeg' not in mime.lower():
            strike1 = True

        if strike1:
            logger.debug('Invalid JPG upload: {0} [{1}]'.format(
                mime, full_path))
            return None, ('Invalid file. Uploaded image should be a valid '
                          'and readable JPEG file.')

    strike1 = False
    if ('png' in trigger.accepted_file_types_comma_separated.lower()) and \
       extension in ('png',):

        try:
            mime = magic.from_file(full_path, mime=True)
            if not (isinstance(mime, str)):
                mime = mime.decode('utf-8')
        except Exception as exp:
            logger.error('Could not determine MIME type: ' + str(exp))
            mime = ''
            strike1 = True

        if 'image/png' not in mime.lower():
            strike1 = True

        if strike1:
            logger.debug('Invalid PNG upload: {0} [{1}]'.format(
                mime, full_path))
            return None, ('Invalid file. Uploaded image should be a valid '
                          'and readable PNG file.')

    strike2 = False
    if extension.lower() not in \
                            trigger.accepted_file_types_comma_separated.lower():
        logger.debug('Invalid file type upload: received ".{0}"; [{1}]'.format(\
                                                    extension, full_path))
        return None, ('Invalid file uploaded. Uploaded file must be: {}'.format(\
                                 trigger.accepted_file_types_comma_separated))

    if trigger == entry_point:
        # In some instances we don't use triggers, just entry_points
        prior = Submission.objects.filter(status='S',
                                          submitted_by=learner,
                                          entry_point=entry_point,
                                          is_valid=True)
    else:
        prior_indiv = Q(status='S',
                        submitted_by=learner,
                        entry_point=entry_point,
                        trigger=trigger,
                        is_valid=True)

        # We need this here, but also for the code later in the next
        # if (trigger==entry_point) part

        # Default returned by this function is ``None`` if the user is not
        # enrolled in a group, or if this course simply does not use groups.
        group_submitted = is_group_submission(learner, entry_point)
        if is_group_submission(learner, entry_point):
            group_submitted = group_submitted.group

            prior_group = Q(status='S',
                            group_submitted=group_submitted,
                            entry_point=entry_point,
                            trigger=trigger,
                            is_valid=True)
        else:
            prior_group = Q()

        prior = Submission.objects.filter(prior_indiv | prior_group)

    for item in prior:
        logger.debug(('Setting prior submission to False: {0} and name '
                      '"{1}"'.format(str(item), item.submitted_file_name)))
        item.is_valid = False
        item.save()

    if trigger == entry_point:
        # In some instances we don't use triggers, just entry_points
        sub = Submission(
            submitted_by=learner,
            group_submitted=None,
            status='S',
            entry_point=entry_point,
            is_valid=True,
            file_upload=submitted_file_name_django,
            thumbnail=thumbnail_file_name_django,
            submitted_file_name=filename,
            ip_address=get_IP_address(request),
        )
        sub.save()
    else:

        sub = Submission(
            submitted_by=learner,
            group_submitted=group_submitted,
            status='S',
            entry_point=entry_point,
            trigger=trigger,
            is_valid=True,
            file_upload=submitted_file_name_django,
            thumbnail=thumbnail_file_name_django,
            submitted_file_name=filename,
            ip_address=get_IP_address(request),
        )
        sub.save()

    if 'pdf' in trigger.accepted_file_types_comma_separated.lower() and \
                                                         extension in ('pdf',):
        clean_PDF(sub)

    return sub