Skip to content
Snippets Groups Projects
Commit a0618abb authored by Carl Schönfelder's avatar Carl Schönfelder
Browse files

Resolve "Fix api response"

parent 833fe128
No related branches found
No related tags found
1 merge request!73Resolve "Fix api response"
Pipeline #41338 passed with warnings
Showing
with 182 additions and 118 deletions
......@@ -7,4 +7,4 @@ htmlcov
.pytest_cache
/.idea
.vs/
*/static
\ No newline at end of file
**/static
\ No newline at end of file
......@@ -17239,7 +17239,8 @@
},
"ssri": {
"version": "6.0.1",
"resolved": "",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
"integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
"requires": {
"figgy-pudding": "^3.5.1"
}
......
......@@ -7,7 +7,7 @@ from app.core.dto import MediaDTO
def create_app(config_name="configmodule.DevelopmentConfig"):
app = Flask(__name__)
app = Flask(__name__, static_url_path="/static", static_folder="static")
app.config.from_object(config_name)
app.url_map.strict_slashes = False
with app.app_context():
......
from functools import wraps
import app.core.http_codes as codes
import app.core.http_codes as http_codes
from flask_jwt_extended import verify_jwt_in_request
from flask_jwt_extended.utils import get_jwt_claims
from flask_restx.errors import abort
def admin_required():
def validate_editor(db_item, *views):
claims = get_jwt_claims()
city_id = int(claims.get("city_id"))
if db_item.city_id != city_id:
abort(http_codes.UNAUTHORIZED)
def check_jwt(editor=False, *views):
def wrapper(fn):
@wraps(fn)
def decorator(*args, **kwargs):
verify_jwt_in_request()
claims = get_jwt_claims()
if claims["role"] == "Admin":
role = claims.get("role")
view = claims.get("view")
if role == "Admin":
return fn(*args, **kwargs)
elif editor and role == "Editor":
return fn(*args, **kwargs)
elif view in views:
return fn(*args, **kwargs)
else:
return {"message:": "Admins only"}, codes.FORBIDDEN
abort(http_codes.UNAUTHORIZED)
return decorator
return wrapper
def text_response(message, code=codes.OK):
def text_response(message, code=http_codes.OK):
return {"message": message}, code
def list_response(items, total=None, code=codes.OK):
def list_response(items, total=None, code=http_codes.OK):
if type(items) is not list:
abort(codes.INTERNAL_SERVER_ERROR)
abort(http_codes.INTERNAL_SERVER_ERROR)
if not total:
total = len(items)
return {"items": items, "count": len(items), "total_count": total}, code
def item_response(item, code=codes.OK):
def item_response(item, code=http_codes.OK):
if isinstance(item, list):
abort(codes.INTERNAL_SERVER_ERROR)
abort(http_codes.INTERNAL_SERVER_ERROR)
return item, code
......
import app.core.http_codes as codes
import app.database.controller as dbc
from app.apis import admin_required, item_response, text_response
from app.apis import check_jwt, item_response, text_response
from app.core.codes import verify_code
from app.core.dto import AuthDTO, CodeDTO
from app.core.parsers import create_user_parser, login_parser
from app.core.parsers import create_user_parser, login_code_parser, login_parser
from app.database.models import User
from flask_jwt_extended import (
create_access_token,
......@@ -21,12 +21,12 @@ list_schema = AuthDTO.list_schema
def get_user_claims(item_user):
return {"role": item_user.role.name, "city": item_user.city.name}
return {"role": item_user.role.name, "city_id": item_user.city_id}
@api.route("/signup")
class AuthSignup(Resource):
@jwt_required
@check_jwt(editor=False)
def post(self):
args = create_user_parser.parse_args(strict=True)
email = args.get("email")
......@@ -41,7 +41,7 @@ class AuthSignup(Resource):
@api.route("/delete/<ID>")
@api.param("ID")
class AuthDelete(Resource):
@jwt_required
@check_jwt(editor=False)
def delete(self, ID):
item_user = dbc.get.user(ID)
......@@ -70,23 +70,22 @@ class AuthLogin(Resource):
return response
@api.route("/login/<code>")
@api.param("code")
class AuthLogin(Resource):
def post(self, code):
@api.route("/login/code")
class AuthLoginCode(Resource):
def post(self):
args = login_code_parser.parse_args()
code = args["code"]
if not verify_code(code):
api.abort(codes.BAD_REQUEST, "Invalid code")
item_code = dbc.get.code_by_code(code)
if not item_code:
api.abort(codes.UNAUTHORIZED, "A presentation with that code does not exist")
item_code = dbc.get.code_by_code(code, True, "A presentation with that code does not exist")
return item_response(CodeDTO.schema.dump(item_code)), codes.OK
@api.route("/logout")
class AuthLogout(Resource):
@jwt_required
@check_jwt(editor=True)
def post(self):
jti = get_raw_jwt()["jti"]
dbc.add.blacklist(jti)
......@@ -95,7 +94,7 @@ class AuthLogout(Resource):
@api.route("/refresh")
class AuthRefresh(Resource):
@jwt_required
@check_jwt(editor=True)
@jwt_refresh_token_required
def post(self):
old_jti = get_raw_jwt()["jti"]
......
import app.database.controller as dbc
from app.apis import admin_required, item_response, list_response
from app.apis import item_response, list_response
from app.core import http_codes as codes
from app.core.dto import CodeDTO
from app.core.parsers import code_parser
from app.database.models import Code, Competition
from flask_jwt_extended import jwt_required
from flask_restx import Resource
from app.apis import check_jwt
api = CodeDTO.api
schema = CodeDTO.schema
......@@ -15,7 +16,7 @@ list_schema = CodeDTO.list_schema
@api.route("/")
@api.param("CID")
class CodesList(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self, CID):
items = dbc.get.code_list(CID)
return list_response(list_schema.dump(items), len(items)), codes.OK
......@@ -24,7 +25,7 @@ class CodesList(Resource):
@api.route("/<code_id>")
@api.param("CID, code_id")
class CodesById(Resource):
@jwt_required
@check_jwt(editor=False)
def put(self, CID, code_id):
item = dbc.get.one(Code, code_id)
item.code = dbc.utils.generate_unique_code()
......
import time
import app.database.controller as dbc
from app.apis import admin_required, item_response, list_response
from app.apis import check_jwt, item_response, list_response
from app.core import rich_schemas
from app.core.dto import CompetitionDTO
from app.core.parsers import competition_parser, competition_search_parser
from app.database.models import Competition
......@@ -8,12 +11,13 @@ from flask_restx import Resource
api = CompetitionDTO.api
schema = CompetitionDTO.schema
rich_schema = CompetitionDTO.rich_schema
list_schema = CompetitionDTO.list_schema
@api.route("/")
class CompetitionsList(Resource):
@jwt_required
@check_jwt(editor=True)
def post(self):
args = competition_parser.parse_args(strict=True)
......@@ -28,12 +32,13 @@ class CompetitionsList(Resource):
@api.route("/<CID>")
@api.param("CID")
class Competitions(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self, CID):
item = dbc.get.one(Competition, CID)
return item_response(schema.dump(item))
item = dbc.get.competition(CID)
return item_response(rich_schema.dump(item))
@jwt_required
@check_jwt(editor=True)
def put(self, CID):
args = competition_parser.parse_args(strict=True)
item = dbc.get.one(Competition, CID)
......@@ -41,7 +46,7 @@ class Competitions(Resource):
return item_response(schema.dump(item))
@jwt_required
@check_jwt(editor=True)
def delete(self, CID):
item = dbc.get.one(Competition, CID)
dbc.delete.competition(item)
......@@ -51,7 +56,7 @@ class Competitions(Resource):
@api.route("/search")
class CompetitionSearch(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self):
args = competition_search_parser.parse_args(strict=True)
items, total = dbc.search.competition(**args)
......
import app.core.http_codes as codes
import app.database.controller as dbc
from app.apis import admin_required, item_response, list_response
from app.apis import check_jwt, item_response, list_response
from app.core.dto import ComponentDTO
from app.core.parsers import component_create_parser, component_parser
from app.database.models import Competition, Component
......@@ -16,19 +16,19 @@ list_schema = ComponentDTO.list_schema
@api.route("/<component_id>")
@api.param("CID, SOrder, component_id")
class ComponentByID(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self, CID, SOrder, component_id):
item = dbc.get.one(Component, component_id)
return item_response(schema.dump(item))
@jwt_required
@check_jwt(editor=True)
def put(self, CID, SOrder, component_id):
args = component_parser.parse_args()
item = dbc.get.one(Component, component_id)
item = dbc.edit.component(item, **args)
return item_response(schema.dump(item))
@jwt_required
@check_jwt(editor=True)
def delete(self, CID, SOrder, component_id):
item = dbc.get.one(Component, component_id)
dbc.delete.component(item)
......@@ -38,12 +38,12 @@ class ComponentByID(Resource):
@api.route("/")
@api.param("CID, SOrder")
class ComponentList(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self, CID, SOrder):
items = dbc.get.component_list(SOrder)
items = dbc.get.component_list(CID, SOrder)
return list_response(list_schema.dump(items))
@jwt_required
@check_jwt(editor=True)
def post(self, CID, SOrder):
args = component_create_parser.parse_args()
item_slide = dbc.get.slide(CID, SOrder)
......
import os
import app.core.http_codes as codes
import app.database.controller as dbc
from app.apis import admin_required, item_response, list_response
from app.apis import check_jwt, item_response, list_response
from app.core.dto import MediaDTO
from app.core.parsers import media_parser_search
from app.database.models import City, Media, MediaType, QuestionType, Role
from flask import request
from flask import current_app, request
from flask_jwt_extended import get_jwt_identity, jwt_required
from flask_restx import Resource, reqparse
from flask_uploads import UploadNotAllowed
from PIL import Image
from sqlalchemy import exc
api = MediaDTO.api
image_set = MediaDTO.image_set
schema = MediaDTO.schema
list_schema = MediaDTO.list_schema
PHOTO_PATH = current_app.config["UPLOADED_PHOTOS_DEST"]
def generate_thumbnail(filename):
with Image.open(f"./static/images/{filename}") as im:
im.thumbnail((120, 120))
im.save(f"./static/images/thumbnail_{filename}")
thumbnail_size = current_app.config["THUMBNAIL_SIZE"]
path = os.path.join(PHOTO_PATH, filename)
thumb_path = os.path.join(PHOTO_PATH, f"thumbnail_{filename}")
with Image.open(path) as im:
im.thumbnail(thumbnail_size)
im.save(thumb_path)
def delete_image(filename):
path = os.path.join(PHOTO_PATH, filename)
thumb_path = os.path.join(PHOTO_PATH, f"thumbnail_{filename}")
os.remove(path)
os.remove(thumb_path)
@api.route("/images")
class ImageList(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self):
args = media_parser_search.parse_args(strict=True)
items, total = dbc.search.image(**args)
return list_response(list_schema.dump(items), total)
@jwt_required
@check_jwt(editor=True)
def post(self):
if "image" not in request.files:
api.abort(codes.BAD_REQUEST, "Missing image in request.files")
try:
filename = image_set.save(request.files["image"])
generate_thumbnail(filename)
print(filename)
item = dbc.add.image(filename, get_jwt_identity())
return item_response(schema.dump(item))
except UploadNotAllowed:
api.abort(codes.BAD_REQUEST, "Could not save the image")
except:
api.abort(codes.INTERNAL_SERVER_ERROR, "Something went wrong when trying to save image")
finally:
return item_response(schema.dump(item))
@api.route("/images/<ID>")
@api.param("ID")
class ImageList(Resource):
@check_jwt(editor=True)
def get(self, ID):
item = dbc.get.one(Media, ID)
return item_response(schema.dump(item))
@check_jwt(editor=True)
def delete(self, ID):
item = dbc.get.one(Media, ID)
try:
delete_image(item.filename)
dbc.delete.default(item)
except OSError:
api.abort(codes.BAD_REQUEST, "Could not delete the file image")
except exc.SQLAlchemyError:
api.abort(codes.INTERNAL_SERVER_ERROR, "Something went wrong when trying to delete image")
finally:
return {}, codes.NO_CONTENT
import app.database.controller as dbc
from app.apis import admin_required, item_response, list_response
from app.apis import check_jwt, item_response, list_response
from app.core.dto import MiscDTO
from app.database.models import City, ComponentType, MediaType, QuestionType, Role, ViewType
from flask_jwt_extended import jwt_required
from flask_restx import Resource, reqparse
api = MiscDTO.api
......@@ -22,7 +21,7 @@ name_parser.add_argument("name", type=str, required=True, location="json")
@api.route("/types")
class TypesList(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self):
result = {}
result["media_types"] = media_type_schema.dump(dbc.get.all(MediaType))
......@@ -34,7 +33,7 @@ class TypesList(Resource):
@api.route("/roles")
class RoleList(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self):
items = dbc.get.all(Role)
return list_response(role_schema.dump(items))
......@@ -42,12 +41,12 @@ class RoleList(Resource):
@api.route("/cities")
class CitiesList(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self):
items = dbc.get.all(City)
return list_response(city_schema.dump(items))
@jwt_required
@check_jwt(editor=False)
def post(self):
args = name_parser.parse_args(strict=True)
dbc.add.city(args["name"])
......@@ -58,7 +57,7 @@ class CitiesList(Resource):
@api.route("/cities/<ID>")
@api.param("ID")
class Cities(Resource):
@jwt_required
@check_jwt(editor=False)
def put(self, ID):
item = dbc.get.one(City, ID)
args = name_parser.parse_args(strict=True)
......@@ -67,7 +66,7 @@ class Cities(Resource):
items = dbc.get.all(City)
return list_response(city_schema.dump(items))
@jwt_required
@check_jwt(editor=False)
def delete(self, ID):
item = dbc.get.one(City, ID)
dbc.delete.default(item)
......
import app.core.http_codes as codes
import app.database.controller as dbc
from app.apis import admin_required, item_response, list_response
from app.apis import check_jwt, item_response, list_response
from app.core.dto import QuestionDTO
from app.core.parsers import question_parser
from app.database.models import Question
......@@ -15,7 +15,7 @@ list_schema = QuestionDTO.list_schema
@api.route("/questions")
@api.param("CID")
class QuestionsList(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self, CID):
items = dbc.get.question_list(CID)
return list_response(list_schema.dump(items))
......@@ -24,7 +24,7 @@ class QuestionsList(Resource):
@api.route("/slides/<SID>/questions")
@api.param("CID, SID")
class QuestionsList(Resource):
@jwt_required
@check_jwt(editor=True)
def post(self, SID, CID):
args = question_parser.parse_args(strict=True)
del args["slide_id"]
......@@ -38,12 +38,12 @@ class QuestionsList(Resource):
@api.route("/slides/<SID>/questions/<QID>")
@api.param("CID, SID, QID")
class Questions(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self, CID, SID, QID):
item_question = dbc.get.question(CID, SID, QID)
return item_response(schema.dump(item_question))
@jwt_required
@check_jwt(editor=True)
def put(self, CID, SID, QID):
args = question_parser.parse_args(strict=True)
......@@ -52,7 +52,7 @@ class Questions(Resource):
return item_response(schema.dump(item_question))
@jwt_required
@check_jwt(editor=True)
def delete(self, CID, SID, QID):
item_question = dbc.get.question(CID, SID, QID)
dbc.delete.question(item_question)
......
import app.core.http_codes as codes
import app.database.controller as dbc
from app.apis import admin_required, item_response, list_response
from app.apis import check_jwt, item_response, list_response
from app.core.dto import SlideDTO
from app.core.parsers import slide_parser
from app.database.models import Competition, Slide
......@@ -15,12 +15,12 @@ list_schema = SlideDTO.list_schema
@api.route("/")
@api.param("CID")
class SlidesList(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self, CID):
items = dbc.get.slide_list(CID)
return list_response(list_schema.dump(items))
@jwt_required
@check_jwt(editor=True)
def post(self, CID):
item_comp = dbc.get.one(Competition, CID)
item_slide = dbc.add.slide(item_comp)
......@@ -32,12 +32,12 @@ class SlidesList(Resource):
@api.route("/<SOrder>")
@api.param("CID,SOrder")
class Slides(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self, CID, SOrder):
item_slide = dbc.get.slide(CID, SOrder)
return item_response(schema.dump(item_slide))
@jwt_required
@check_jwt(editor=True)
def put(self, CID, SOrder):
args = slide_parser.parse_args(strict=True)
title = args.get("title")
......@@ -48,7 +48,7 @@ class Slides(Resource):
return item_response(schema.dump(item_slide))
@jwt_required
@check_jwt(editor=True)
def delete(self, CID, SOrder):
item_slide = dbc.get.slide(CID, SOrder)
......@@ -59,7 +59,7 @@ class Slides(Resource):
@api.route("/<SOrder>/order")
@api.param("CID,SOrder")
class SlidesOrder(Resource):
@jwt_required
@check_jwt(editor=True)
def put(self, CID, SOrder):
args = slide_parser.parse_args(strict=True)
order = args.get("order")
......
import app.core.http_codes as codes
import app.database.controller as dbc
from app.apis import admin_required, item_response, list_response
from app.apis import check_jwt, item_response, list_response
from app.core.dto import TeamDTO
from app.core.parsers import team_parser
from app.database.models import Competition, Team
......@@ -15,12 +15,12 @@ list_schema = TeamDTO.list_schema
@api.route("/")
@api.param("CID")
class TeamsList(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self, CID):
items = dbc.get.team_list(CID)
return list_response(list_schema.dump(items))
@jwt_required
@check_jwt(editor=True)
def post(self, CID):
args = team_parser.parse_args(strict=True)
item_comp = dbc.get.one(Competition, CID)
......@@ -32,11 +32,13 @@ class TeamsList(Resource):
@api.param("CID,TID")
class Teams(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self, CID, TID):
item = dbc.get.team(CID, TID)
return item_response(schema.dump(item))
@jwt_required
@check_jwt(editor=True)
def delete(self, CID, TID):
item_team = dbc.get.team(CID, TID)
......@@ -44,6 +46,7 @@ class Teams(Resource):
return {}, codes.NO_CONTENT
@jwt_required
@check_jwt(editor=True)
def put(self, CID, TID):
args = team_parser.parse_args(strict=True)
name = args.get("name")
......
import app.core.http_codes as codes
import app.database.controller as dbc
from app.apis import admin_required, item_response, list_response
from app.apis import check_jwt, item_response, list_response
from app.core.dto import UserDTO
from app.core.parsers import user_parser, user_search_parser
from app.database.models import User
......@@ -24,12 +24,12 @@ def edit_user(item_user, args):
@api.route("/")
class UsersList(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self):
item = dbc.get.user(get_jwt_identity())
return item_response(schema.dump(item))
@jwt_required
@check_jwt(editor=True)
def put(self):
args = user_parser.parse_args(strict=True)
item = dbc.get.user(get_jwt_identity())
......@@ -40,12 +40,12 @@ class UsersList(Resource):
@api.route("/<ID>")
@api.param("ID")
class Users(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self, ID):
item = dbc.get.user(ID)
return item_response(schema.dump(item))
@jwt_required
@check_jwt(editor=False)
def put(self, ID):
args = user_parser.parse_args(strict=True)
item = dbc.get.user(ID)
......@@ -55,7 +55,7 @@ class Users(Resource):
@api.route("/search")
class UserSearch(Resource):
@jwt_required
@check_jwt(editor=True)
def get(self):
args = user_search_parser.parse_args(strict=True)
items, total = dbc.search.user(**args)
......
......@@ -19,25 +19,26 @@ class MediaDTO:
class AuthDTO:
api = Namespace("auth")
schema = rich_schemas.UserSchemaRich(many=False)
list_schema = rich_schemas.UserSchemaRich(many=True)
schema = schemas.UserSchema(many=False)
list_schema = schemas.UserSchema(many=True)
class UserDTO:
api = Namespace("users")
schema = rich_schemas.UserSchemaRich(many=False)
schema = schemas.UserSchema(many=False)
list_schema = schemas.UserSchema(many=True)
class CompetitionDTO:
api = Namespace("competitions")
schema = rich_schemas.CompetitionSchemaRich(many=False)
schema = schemas.CompetitionSchema(many=False)
list_schema = schemas.CompetitionSchema(many=True)
rich_schema = rich_schemas.CompetitionSchemaRich(many=False)
class CodeDTO:
api = Namespace("codes")
schema = rich_schemas.CodeSchemaRich(many=False)
schema = schemas.CodeSchema(many=False)
list_schema = schemas.CodeSchema(many=True)
......@@ -65,5 +66,5 @@ class MiscDTO:
class QuestionDTO:
api = Namespace("questions")
schema = rich_schemas.QuestionSchemaRich(many=False)
schema = schemas.QuestionSchema(many=False)
list_schema = schemas.QuestionSchema(many=True)
......@@ -86,3 +86,6 @@ component_parser.add_argument("data", type=dict, default=None, location="json")
component_create_parser = component_parser.copy()
component_create_parser.replace_argument("data", type=dict, required=True, location="json")
component_create_parser.add_argument("type_id", type=int, required=True, location="json")
login_code_parser = reqparse.RequestParser()
login_code_parser.add_argument("code", type=str, location="json")
......@@ -11,17 +11,6 @@ class RichSchema(ma.SQLAlchemySchema):
include_relationships = True
class UserSchemaRich(RichSchema):
class Meta(RichSchema.Meta):
model = models.User
id = ma.auto_field()
name = ma.auto_field()
email = ma.auto_field()
role = fields.Nested(schemas.RoleSchema, many=False)
city = fields.Nested(schemas.CitySchema, many=False)
class QuestionSchemaRich(RichSchema):
class Meta(RichSchema.Meta):
model = models.Question
......@@ -30,7 +19,8 @@ class QuestionSchemaRich(RichSchema):
name = ma.auto_field()
total_score = ma.auto_field()
slide_id = ma.auto_field()
type = fields.Nested(schemas.QuestionTypeSchema, many=False)
type_id = ma.auto_field()
alternatives = fields.Nested(schemas.QuestionAlternative, many=True)
class TeamSchemaRich(RichSchema):
......@@ -43,16 +33,6 @@ class TeamSchemaRich(RichSchema):
question_answers = fields.Nested(schemas.QuestionAnswerSchema, many=True)
class CodeSchemaRich(RichSchema):
class Meta(RichSchema.Meta):
model = models.Code
id = ma.auto_field()
code = ma.auto_field()
pointer = ma.auto_field()
view_type = fields.Nested(schemas.ViewTypeSchema, many=False)
class SlideSchemaRich(RichSchema):
class Meta(RichSchema.Meta):
model = models.Slide
......@@ -73,7 +53,7 @@ class CompetitionSchemaRich(RichSchema):
id = ma.auto_field()
name = ma.auto_field()
year = ma.auto_field()
city = fields.Nested(schemas.CitySchema, many=False)
city_id = ma.auto_field()
slides = fields.Nested(
SlideSchemaRich,
many=True,
......
......@@ -68,6 +68,16 @@ class QuestionAnswerSchema(BaseSchema):
team_id = ma.auto_field()
class QuestionAlternative(BaseSchema):
class Meta(BaseSchema.Meta):
model = models.QuestionAlternative
id = ma.auto_field()
text = ma.auto_field()
value = ma.auto_field()
question_id = ma.auto_field()
class RoleSchema(BaseSchema):
class Meta(BaseSchema.Meta):
model = models.Role
......
......@@ -41,7 +41,7 @@ class ExtendedQuery(BaseQuery):
class Dictionary(TypeDecorator):
impl = Text(1024)
impl = Text
def process_bind_param(self, value, dialect):
if value is not None:
......
......@@ -3,6 +3,7 @@ This file contains functionality to get data from the database.
"""
from app.core import db
from app.core import http_codes as codes
from app.database.models import (
City,
Code,
......@@ -18,16 +19,17 @@ from app.database.models import (
User,
ViewType,
)
from sqlalchemy.orm import contains_eager, joinedload, subqueryload
def all(db_type):
""" Gets all elements in the provided table. """
""" Gets lazy db-item in the provided table. """
return db_type.query.all()
def one(db_type, id, required=True, error_msg=None):
""" Gets the element in the table that has the same id. """
""" Get lazy db-item in the table that has the same id. """
return db_type.query.filter(db_type.id == id).first_extended(required, error_msg)
......@@ -38,10 +40,10 @@ def user_exists(email):
return User.query.filter(User.email == email).count() > 0
def code_by_code(code):
def code_by_code(code, required=True, error_msg=None):
""" Gets the code object associated with the provided code. """
return Code.query.filter(Code.code == code.upper()).first()
return Code.query.filter(Code.code == code.upper()).first_extended(required, error_msg, codes.UNAUTHORIZED)
def user(UID, required=True, error_msg=None):
......@@ -76,6 +78,16 @@ def question(CID, SOrder, QID, required=True, error_msg=None):
return Question.query.join(Slide, join_filters).filter(Question.id == QID).first_extended(required, error_msg)
def competition(CID):
""" Get Competition and all it's sub-entities """
""" HOT PATH """
os1 = joinedload(Competition.slides).joinedload(Slide.components)
os2 = joinedload(Competition.slides).joinedload(Slide.questions).joinedload(Question.alternatives)
ot = joinedload(Competition.teams).joinedload(Team.question_answers)
return Competition.query.filter(Competition.id == CID).options(os1).options(os2).options(ot).first()
def code_list(competition_id):
""" Gets a list of all code objects associated with a the provided competition. """
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment