Verified Commit 71cdbf79 authored by Peter Stanko's avatar Peter Stanko
Browse files

Universal error handler

parent 5ea3f33e
import logging
from portal.database import Submission, SubmissionState, User
from portal.database import Project, Submission, SubmissionState, User
from portal.facade.general_facade import GeneralCRUDFacade
from portal.logger import SUBMIT
from portal.service import errors
......@@ -116,17 +116,24 @@ class SubmissionsFacade(GeneralCRUDFacade):
user_ids=user_ids, project_ids=project_ids,
role_ids=role_ids, group_ids=group_ids)
def is_read_notepad(self, submission: Submission):
def is_read_notepad(self, submission: Submission = None,
project: Project = None, user: User = None):
"""Read IS MUNI notepad for the author's submission
Args:
user(User): User instance
project(Project): project instance
submission(Submission): Submission instance
"""
log.debug(f"[IS] Reading notepad content for {submission.log_name} "
f"by {self.client_name}")
if submission is not None:
project = project or submission.project
user = user or submission.user
note = self._services.is_api(submission.course).read_note(
project=submission.project,
user=submission.user)
project=project,
user=user)
return note
def is_write_notepad(self, submission: Submission, data: dict = None):
......
......@@ -3,6 +3,7 @@ from flask_restplus import Resource
from portal import facade
from portal.database.models import Client
from portal.service import errors
from portal.service.auth import AuthService
from portal.service.find import FindService
from portal.service.permissions import PermissionsService
......@@ -119,3 +120,10 @@ class CustomResource(Resource):
@property
def flask_app(self) -> flask.Flask:
return flask.current_app
def get_query_param(self, name: str, required=False, as_list=False):
method = self.request.args.getlist if as_list else self.request.args.get
value = method(name)
if not value and required:
raise errors.PortalAPIError(message=f"Required query param is missing: {name}")
return value
import flask
import portal.storage
from flask import Flask
from flask_jwt_extended.exceptions import NoAuthorizationError
from marshmallow.exceptions import ValidationError
from sqlalchemy.exc import SQLAlchemyError
import portal.storage
from portal import logger
from portal.rest import rest_api
from portal.service.errors import IncorrectCredentialsError, PortalAPIError, UnauthorizedError
......@@ -81,3 +81,8 @@ def handle_storage_error(ex: portal.storage.errors.KontrStorageError):
def handle_portal_api_error(ex: PortalAPIError):
log.error(f"[API] Api error[{ex.code}]: {ex} ")
return send_response({'message': ex.message}), ex.code
@rest_api.errorhandler(Exception)
def handle_default_exception(ex: Exception):
log.critical(f"[ERROR] Fatal error: {ex}")
import flask
from flask import request
from flask_jwt_extended import jwt_required
from flask_restplus import Namespace
......@@ -158,6 +157,28 @@ class ProjectTestFilesRefresh(CustomResource):
return '', 204
@projects_namespace.route('/courses/<string:cid>/projects/<string:pid>/is_muni/notepad')
@projects_namespace.param('cid', 'Course id')
@projects_namespace.param('pid', 'Project id')
@projects_namespace.response(404, 'Course not found')
@projects_namespace.response(404, 'Project not found')
class ProjectTestFilesRefresh(CustomResource):
@jwt_required
@access_log
@projects_namespace.response(204, 'Project test_files updated')
def get(self, cid: str, pid: str):
course = self.find.course(cid)
project = self.find.project(course, pid)
user_id = self.get_query_param('user_id', required=True)
user = self.find.user(user_id)
# authorization
self.permissions(course=course).require.evaluate_submissions()
log.debug(f"[REST] Get is muni notes for "
f"{project.log_name} by {self.client.log_name}")
self.facades.submissions.is_read_notepad(project=project, user=user)
return '', 204
@projects_namespace.route(
'/courses/<string:cid>/projects/<string:pid>/submissions')
@projects_namespace.param('cid', 'Course id')
......
......@@ -51,10 +51,12 @@ class IsApiWrapper:
ucos = [user.uco for user in users]
if not ucos:
return None
log.info(f"[IS_API_ADAPT] Read notepad for {shortcut} to user {users}")
content = self.is_client.notepad_content(shortcut, *ucos)
return content
def write_notepad(self, user: 'User', content=None, shortcut: str = None):
log.info(f"[IS_API_ADAPT] Write notepad for {shortcut} to user {user.log_name}: {content}")
self.is_client.notepad_update(shortcut=shortcut, uco=user.uco,
override=True, content=content)
......
......@@ -300,3 +300,16 @@ def test_write_is_muni_notepad_for_submission(created_submission, client, portal
surl = f'/submissions/{created_submission.id}/review/is_muni/notepad'
response = rest_tools.make_request(client, surl, json=dict(content=content), method='post')
assert_response(response=response, code=200)
@responses.activate
def test_read_is_muni_notepad_for_submission(created_submission, client, portal_services):
is_wrapper: IsApiWrapper = portal_services.is_api(created_submission.course).is_api
content = "Foo points *2"
operation = f";operace=blok-pis-student-obsah;zkratka={created_submission.project.codename};" \
f"uco={created_submission.user.uco};obsah={content};prepis=a"
url = gen_url(is_wrapper=is_wrapper, operation=operation)
responses.add(responses.GET, url, body="<ZAPIS>Úspěšně uloženo.</ZAPIS>", status=200)
surl = f'/submissions/{created_submission.id}/review/is_muni/notepad'
response = rest_tools.make_request(client, surl, json=dict(content=content), method='post')
assert_response(response=response, code=200)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment