Esempio n. 1
0
def get_user_agent():
    """
    Endpoint to get user agent information.

    :return: Dictionary with user agent information, or
        an empty dictionary with 404 HTTP code if access was denied.
    """
    if not check_auth():
        return {}, 404
    response = {
        'platform': request.user_agent.platform,
        'browser': request.user_agent.browser,
        'version': request.user_agent.version,
        'message': 'OK',
        'outdated': False,
        'supportedPlatforms': list(Config.c.user_agent_platform.__dict__.keys()),
        'supportedBrowsers': Config.c.user_agent_browser.__dict__,
    }
    if request.user_agent.platform not in Config.c.user_agent_platform.__dict__:
        response['outdated'] = True
    browser_found = False
    for (browser, version) in Config.c.user_agent_browser.__dict__.items():
        if request.user_agent.browser == browser:
            browser_found = True
            if version_util.parse(request.user_agent.version) < version_util.parse(version):
                response['outdated'] = True
                break
    if not browser_found:
        response['outdated'] = True
    return response, 200
Esempio n. 2
0
def handle_presentation_upload():
    """
    Route to handle presentation upload. Calls presentation upload,
        then adds training,
        then redirects to the 'view_training' page.

    :return: Redirection to the 'view_training' page, or
        an empty dictionary with 404 HTTP code if access was denied.
    """
    if not check_auth():
        return {}, 404
    upload_presentation_response, upload_presentation_response_code = upload_presentation(
    )
    if upload_presentation_response.get('message') != 'OK':
        return upload_presentation_response, upload_presentation_response_code
    presentation_file_id = upload_presentation_response['presentation_file_id']
    logger.info('Uploaded file with presentation_file_id = {}.'.format(
        presentation_file_id))
    add_training_response, add_training_response_code = add_training(
        presentation_file_id)
    if add_training_response.get('message') != 'OK':
        return add_training_response, add_training_response_code
    TrainingsDBManager().change_training_status_by_training_id(
        add_training_response['training_id'], TrainingStatus.IN_PROGRESS)
    return redirect(
        url_for(
            'routes_trainings.view_training',
            training_id=add_training_response['training_id'],
        ))
Esempio n. 3
0
def view_presentation_upload():
    """
    Route to view presentation upload.

    :return: Presentation upload page, or
        an empty dictionary with 404 HTTP code if access was denied.
    """
    if not check_auth():
        return {}, 404
    return render_template('upload.html'), 200
Esempio n. 4
0
def get_session_info():
    """
    Endpoint to return session information consists of username and full name.

    :return: Dictionary with username, full name, and  'OK' message, or
        or an empty dictionary with 404 HTTP code if access was denied.
    """
    username = session.get('session_id')
    full_name = session.get('full_name')
    if not check_auth() or username is None:
        return {}, 404
    return {'username': username, 'full_name': full_name, 'message': 'OK'}, 200
Esempio n. 5
0
def get_pres_formats():
    """
    Endpoint to get user-allowed presentation formats.
        If user don't have format-parameter - allow only DEFAULT_EXTENSION ('pdf') 
    :return: Dictionary with formats, or
        an empty dictionary with 404 HTTP code if access was denied.
    """
    if not check_auth():
        return {}, 404
    
    formats = session.get('formats', (DEFAULT_EXTENSION,))

    return { 'formats': formats, 'message': 'OK' }, 200
Esempio n. 6
0
def view_all_trainings():
    """
    Route to show all trainings.

    :return: Page with all trainings,
        or an empty dictionary if access was denied.
    """
    username = request.args.get('username', '')
    full_name = request.args.get('full_name', '')
    authorized = check_auth() is not None
    if not (check_admin() or (authorized and session.get('session_id') == username)):
        return {}, 404
    return render_template('show_all_trainings.html', username=username, full_name=full_name, is_admin="true" if check_admin() else 'false'), 200
Esempio n. 7
0
def get_presentation(presentation_file_id) -> (dict, int):
    """
    Endpoint to get information about a presentation by its identifier.

    :param presentation_file_id: Presentation file identifier.
    :return: Dictionary with information about presentation and 'OK' message, or
        a dictionary with an explanation and 404 HTTP return code if a presentation record file was not found, or
        an empty dictionary with 404 HTTP return code if access was denied.
    #TODO check a presentation was uploaded by the current user?
    """
    if not check_auth():
        return {}, 404
    presentation_file = PresentationFilesDBManager().get_presentation_file(
        file_id=presentation_file_id)
    if presentation_file is None:
        return {
            'message':
            'No presentation file with file_id = {}.'.format(
                presentation_file_id)
        }, 404
    return get_presentation_information(presentation_file), 200
Esempio n. 8
0
def add_training(presentation_file_id) -> (dict, int):
    """
    Endpoint to add a training based on the presentation file with the given identifier.

    :param presentation_file_id: Presentation file identifier.
    :return: Dictionary with training identifier and 'OK' message, or
        a dictionary with an explanation and 404 HTTP return code if a task attempt or a task was not found, or
        an empty dictionary with 404 HTTP return code if access was denied.

    #TODO check a file was uploaded by the current user???
    """
    if not check_auth():
        return {}, 404
    username = session.get('session_id')
    full_name = session.get('full_name')
    task_attempt_id = session.get('task_attempt_id')
    task_attempt_db = TaskAttemptsDBManager().get_task_attempt(task_attempt_id)
    if task_attempt_db is None:
        return {
            'message':
            'No task attempt with task_attempt_id = {}.'.format(
                task_attempt_id)
        }, 404
    task_id = session.get('task_id')
    task_db = TasksDBManager().get_task(task_id)
    if task_db is None:
        return {'message': 'No task with task_id = {}.'.format(task_id)}, 404
    criteria_pack_id = task_db.criteria_pack_id
    feedback_evaluator_id = session.get('feedback_evaluator_id')
    training_id = TrainingsDBManager().add_training(
        task_attempt_id=task_attempt_id,
        username=username,
        full_name=full_name,
        presentation_file_id=presentation_file_id,
        criteria_pack_id=criteria_pack_id,
        feedback_evaluator_id=feedback_evaluator_id,
    ).pk
    TaskAttemptsDBManager().add_training(task_attempt_id, training_id)
    return {'training_id': str(training_id), 'message': 'OK'}, 200
Esempio n. 9
0
def get_count_page() -> (dict, int):
    username = request.args.get('username', None)
    full_name = request.args.get('full_name', None)

    countItems = request.args.get('count')
    if not countItems:
        countItems = 10
    else:
        countItems = int(countItems)

    authorized = check_auth() is not None
    if not (check_admin() or
            (authorized and session.get('session_id') == username)):
        return {}, 404

    count = TrainingsDBManager().get_count_page(
        remove_blank_and_none({
            'username': username,
            'full_name': full_name
        }), countItems)
    result = {"count": count}
    return result, 200
Esempio n. 10
0
def get_all_trainings() -> (dict, int):
    """
    Endpoint to get information about all trainings. Can be optionally filtered by username or full name.
    :return: Dictionary with information about all trainings and 'OK' message, or
        an empty dictionary with 404 HTTP code if access was denied.
    """
    username = request.args.get('username', None)
    full_name = request.args.get('full_name', None)

    numberPage = request.args.get('page')
    if not numberPage:
        numberPage = 0
    else:
        numberPage = int(numberPage)

    countItems = request.args.get('count')
    if not countItems:
        countItems = 10
    else:
        countItems = int(countItems)

    print(numberPage, countItems)
    authorized = check_auth() is not None
    if not (check_admin() or
            (authorized and session.get('session_id') == username)):
        return {}, 404
    trainings = TrainingsDBManager().get_trainings_filtered(
        remove_blank_and_none({
            'username': username,
            'full_name': full_name
        }), numberPage, countItems)
    trainings_json = {'trainings': {}}
    for i, current_training in enumerate(trainings):
        trainings_json['trainings'][str(
            current_training.pk)] = get_training_information(current_training)
    trainings_json['message'] = 'OK'
    return trainings_json, 200
Esempio n. 11
0
def upload_presentation() -> (dict, int):
    """
    Endpoint to upload a presentation.

    :return: Dictionary with presentation file and preview identifiers and 'OK' message, or
        a dictionary with an explanation and 404 HTTP return code if uploaded file is not a pdf or too large, or
        an empty dictionary with 404 HTTP return code if access was denied.
    """
    if not check_auth():
        return {}, 404
    if 'presentation' not in request.files:
        return {
            'message': 'request.files[\'presentation\'] is not filled.'
        }, 404
    if request.content_length > float(
            Config.c.constants.presentation_file_max_size_in_megabytes
    ) * BYTES_PER_MEGABYTE:
        return {
            'message':
            'Presentation file should not exceed {}MB.'.format(
                Config.c.constants.presentation_file_max_size_in_megabytes)
        }, 404
    presentation_file = request.files['presentation']

    # check extension and mimetype of file
    extension = presentation_file.filename.rsplit('.', 1)[-1].lower()
    passed, filemime = check_file_mime(presentation_file, extension)
    if not passed:
        msg = 'Presentation file has not allowed extension: {} (mimetype: {}).'.format(
            extension, filemime)
        logger.warning(
            f"{msg} Presentation name: {presentation_file.filename}. task_id={session.get('task_id')} criteria_pack_id={session.get('criteria_pack_id')} username={session.get('session_id')} full_name={session.get('full_name')}"
        )
        return {'message': msg}, 200

    nonconverted_file_id = None
    if is_convertible(extension):
        # change extension for new file
        original_name = presentation_file.filename
        converted_name = 'pdf'.join(
            presentation_file.filename.rsplit(extension, 1))
        # convert to pdf
        converted_pdf_file = convert_to_pdf(presentation_file)
        if not converted_pdf_file:
            msg = f"Cannot convert uploaded presentation file {original_name}."
            logger.warning(
                f"{msg} Presentation name: {presentation_file.filename}. task_id={session['task_id']} task_id={session['criteria_pack_id']} username={session.get('session_id')} full_name={session.get('full_name')}"
            )
            return {'message': msg}, 200
        # swap converted and nonconverted files for further work
        presentation_file, non_converted_file = converted_pdf_file, presentation_file
        presentation_file.filename = converted_name
        # save nonconverted file with original_name
        nonconverted_file_id = DBManager().add_file(non_converted_file,
                                                    original_name)

    presentation_file_id = DBManager().add_file(presentation_file,
                                                presentation_file.filename)
    presentation_file_preview = get_presentation_file_preview(
        DBManager().get_file(presentation_file_id))
    presentation_file_preview_id = DBManager().read_and_add_file(
        presentation_file_preview.name,
        presentation_file_preview.name,
    )
    presentation_file_preview.close()
    PresentationFilesDBManager().add_presentation_file(
        presentation_file_id, presentation_file.filename,
        presentation_file_preview_id, extension, nonconverted_file_id)
    return {
        'presentation_file_id': str(presentation_file_id),
        'presentation_file_preview_id': str(presentation_file_preview_id),
        'message': 'OK',
    }, 200
Esempio n. 12
0
def view_training_greeting():
    """
    Route to view training greeting page. It shows information about the current task.

    :return: Training greeting page, or
        a dictionary with an explanation and 404 HTTP return code if task was not found, or
        an empty dictionary with 404 HTTP return code if access was denied.
    """
    user_session = check_auth()
    if not user_session:
        return {}, 404
    username = session.get('session_id')
    task_id = session.get('task_id')
    task_db = TasksDBManager().get_task(task_id)
    if task_db is None:
        return {'message': 'No task with id {}.'.format(task_id)}, 404
    task_description = task_db.task_description
    required_points = task_db.required_points
    attempt_count = task_db.attempt_count
    current_task_attempt = TaskAttemptsDBManager().get_current_task_attempt(username, task_id)
    if current_task_attempt is not None:
        training_number = len(current_task_attempt.training_scores) + 1
    else:
        training_number = 1
    if current_task_attempt is None or training_number > attempt_count:
        current_task_attempt = TaskAttemptsDBManager().add_task_attempt(
            username,
            task_id,
            user_session.tasks.get(task_id, {}).get('params_for_passback', ''),
            attempt_count,
        )
        training_number = 1
    task_attempt_count = TaskAttemptsDBManager().get_attempts_count(username, task_id)
    current_points_sum = \
        sum([score if score is not None else 0 for score in current_task_attempt.training_scores.values()])
    session['task_attempt_id'] = str(current_task_attempt.pk)
    criteria_pack_id = session.get('criteria_pack_id')
    criteria_pack = CriteriaPackFactory().get_criteria_pack(criteria_pack_id)
    criteria_pack_id = criteria_pack.name
    maximal_points = attempt_count * 1
    criteria_pack_description = criteria_pack.get_criteria_pack_weights_description(
        CriterionPackDBManager().get_criterion_pack_by_name(criteria_pack_id).criterion_weights,
    )
    # immediately create training if task has presentation 
    presentation_id, training_id = (str(task_db.presentation_id), add_training(str(task_db.presentation_id))[0].get('training_id')) if task_db.presentation_id else (None, None)

    return render_template(
        'training_greeting.html',
        task_id=task_id,
        task_description=task_description,
        current_points_sum='{:.2f}'.format(current_points_sum),
        required_points=required_points,
        maximal_points=maximal_points,
        attempt_number=task_attempt_count,
        training_number=training_number,
        attempt_count=attempt_count,
        criteria_pack_id=criteria_pack_id,
        criteria_pack_description=criteria_pack_description.replace('\n', '\\n').replace('\'', ''),
        training_id=training_id,
        presentation_id=presentation_id
    )