ska-referee-test/ref-test/app/tools/data.py

88 lines
4.0 KiB
Python
Raw Normal View History

from ..models import Dataset
from ..tools.logs import write
2022-06-19 13:22:05 +01:00
from flask import current_app as app
from flask.helpers import abort, flash, redirect, url_for
from sqlalchemy.exc import SQLAlchemyError
2022-06-11 11:29:15 +01:00
import json
2022-06-19 13:22:05 +01:00
from pathlib import Path
from random import shuffle
from functools import wraps
2022-06-11 11:29:15 +01:00
def load(filename:str):
2022-06-19 13:22:05 +01:00
data_dir = Path(app.config.get('DATA'))
2022-06-11 11:29:15 +01:00
with open(f'./{data_dir}/{filename}') as file:
return json.load(file)
def save(data:dict, filename:str):
2022-06-19 13:22:05 +01:00
data_dir = Path(app.config.get('DATA'))
2022-06-11 11:29:15 +01:00
with open(f'./{data_dir}/{filename}', 'w') as file:
json.dump(data, file, indent=4)
def check_is_json(file):
if not '.' in file.filename or not file.filename.rsplit('.',1)[-1] == 'json': return False
return True
def validate_json(data):
2022-06-15 23:54:44 +01:00
if not isinstance(data, list): return False
2022-06-19 10:48:17 +01:00
for block in data:
block_type = block.get('type', None)
2022-06-19 10:48:17 +01:00
if block_type not in ['block', 'question']: return False
if block_type == 'question':
if not all (key in block for key in ['q_no', 'text', 'options', 'correct', 'q_type', 'tags']): return False
if not isinstance(block['q_no'], int): return False
if not isinstance(block['text'], str): return False
if not isinstance(block['options'], list): return False
for option in block['options']:
if not isinstance(option, str): return False
if not isinstance(block['correct'], int): return False
if not isinstance(block['q_type'], str): return False
if block['q_type'] not in ['Multiple Choice', 'Yes/No', 'List']: return False
if not isinstance(block['tags'], list): return False
for tag in block['tags']:
if not isinstance(tag, str): return False
if block_type == 'block':
if not all (key in block for key in ['question_header', 'questions']): return False
if not isinstance(block['question_header'], str): return False
if not isinstance(block['questions'], list): return False
for question in block['questions']:
if not all (key in question for key in ['q_no', 'text', 'options', 'correct', 'q_type', 'tags']): return False
if not isinstance(question['text'], str): return False
if not isinstance(question['q_no'], int): return False
if not isinstance(question['options'], list): return False
for option in question['options']:
if not isinstance(option, str): return False
if not isinstance(question['correct'], int): return False
if not isinstance(question['q_type'], str): return False
if question['q_type'] not in ['Multiple Choice', 'Yes/No', 'List']: return False
if not isinstance(question['tags'], list): return False
for tag in question['tags']:
if not isinstance(tag, str): return False
2022-06-15 23:54:44 +01:00
return True
def randomise_list(list:list):
_list = list.copy()
shuffle(_list)
return(_list)
def get_tag_list(dataset:list):
output = []
for block in dataset:
if block['type'] == 'question': output = list(set(output) | set(block['tags']))
if block['type'] == 'block':
for question in block['questions']: output = list(set(output) | set(question['tags']))
return output
def check_dataset_exists(function):
@wraps(function)
def wrapper(*args, **kwargs):
try: datasets = Dataset.query.all()
except SQLAlchemyError as exception:
write('system.log', f'Database error when checking existing datasets: {exception}')
return abort(500)
if not datasets:
flash('There are no available question datasets. Please upload a question dataset first, or use the question editor to create a new dataset.', 'error')
return redirect(url_for('admin._questions'))
return function(*args, **kwargs)
return wrapper