Changed the layer at which json files are parsed
Updated dataset database model Updated create and edit function to use data list instead of file
This commit is contained in:
parent
6bbdb8fced
commit
c6c62fc34c
@ -5,12 +5,13 @@ from ..tools.forms import get_dataset_choices, get_time_options, send_errors_to_
|
|||||||
from ..tools.data import check_is_json, validate_json
|
from ..tools.data import check_is_json, validate_json
|
||||||
from ..tools.test import answer_options, get_correct_answers
|
from ..tools.test import answer_options, get_correct_answers
|
||||||
|
|
||||||
from flask import Blueprint, jsonify, render_template, redirect, request, session
|
from flask import abort, Blueprint, jsonify, render_template, redirect, request, send_file, session
|
||||||
from flask.helpers import flash, url_for
|
from flask.helpers import flash, url_for
|
||||||
from flask_login import current_user, login_required
|
from flask_login import current_user, login_required
|
||||||
|
|
||||||
from datetime import date, datetime
|
from datetime import date, datetime
|
||||||
from json import loads
|
from json import loads
|
||||||
|
from os import path
|
||||||
import secrets
|
import secrets
|
||||||
|
|
||||||
admin = Blueprint(
|
admin = Blueprint(
|
||||||
@ -207,10 +208,13 @@ def _questions():
|
|||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
upload = form.data_file.data
|
upload = form.data_file.data
|
||||||
if not check_is_json(upload): return jsonify({'error': 'Invalid file. Please upload a JSON file.'}), 400
|
if not check_is_json(upload): return jsonify({'error': 'Invalid file. Please upload a JSON file.'}), 400
|
||||||
if not validate_json(upload): return jsonify({'error': 'The data in the file is invalid.'}), 400
|
upload.stream.seek(0)
|
||||||
|
data = loads(upload.read())
|
||||||
|
if not validate_json(data=data): return jsonify({'error': 'The data in the file is invalid.'}), 400
|
||||||
new_dataset = Dataset()
|
new_dataset = Dataset()
|
||||||
|
new_dataset.set_name(request.form.get('name'))
|
||||||
success, message = new_dataset.create(
|
success, message = new_dataset.create(
|
||||||
upload = upload,
|
data = data,
|
||||||
default = request.form.get('default')
|
default = request.form.get('default')
|
||||||
)
|
)
|
||||||
if success: return jsonify({'success': message}), 200
|
if success: return jsonify({'success': message}), 200
|
||||||
@ -220,18 +224,25 @@ def _questions():
|
|||||||
data = Dataset.query.all()
|
data = Dataset.query.all()
|
||||||
return render_template('/admin/settings/questions.html', form=form, data=data)
|
return render_template('/admin/settings/questions.html', form=form, data=data)
|
||||||
|
|
||||||
@admin.route('/settings/questions/edit/', methods=['POST'])
|
@admin.route('/settings/questions/delete/', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def _edit_questions():
|
def _edit_questions():
|
||||||
id = request.get_json()['id']
|
id = request.get_json()['id']
|
||||||
action = request.get_json()['action']
|
action = request.get_json()['action']
|
||||||
if action not in ['defailt', 'delete']: return jsonify({'error': 'Invalid action.'}), 400
|
if not action == 'delete': return jsonify({'error': 'Invalid action.'}), 400
|
||||||
dataset = Dataset.query.filter_by(id=id).first()
|
dataset = Dataset.query.filter_by(id=id).first()
|
||||||
if action == 'delete': success, message = dataset.delete()
|
if action == 'delete': success, message = dataset.delete()
|
||||||
elif action == 'default': success, message = dataset.make_default()
|
|
||||||
if success: return jsonify({'success': message}), 200
|
if success: return jsonify({'success': message}), 200
|
||||||
return jsonify({'error': message}), 400
|
return jsonify({'error': message}), 400
|
||||||
|
|
||||||
|
@admin.route('/settings/questions/download/<string:id>/')
|
||||||
|
@login_required
|
||||||
|
def _download(id:str):
|
||||||
|
dataset = Dataset.query.filter_by(id=id).first()
|
||||||
|
if not dataset: return abort(404)
|
||||||
|
data_path = path.abspath(dataset.get_file())
|
||||||
|
return send_file(data_path, as_attachment=True, attachment_filename=f'{dataset.get_name()}.json')
|
||||||
|
|
||||||
@admin.route('/tests/<string:filter>/', methods=['GET'])
|
@admin.route('/tests/<string:filter>/', methods=['GET'])
|
||||||
@admin.route('/tests/', methods=['GET'])
|
@admin.route('/tests/', methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from ..extensions import db
|
from ..extensions import db
|
||||||
|
from ..tools.encryption import decrypt, encrypt
|
||||||
from ..tools.logs import write
|
from ..tools.logs import write
|
||||||
|
|
||||||
from flask import flash
|
from flask import flash
|
||||||
@ -7,7 +8,7 @@ from flask_login import current_user
|
|||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from json import dump, loads
|
from json import dump
|
||||||
from os import path, remove
|
from os import path, remove
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
@ -15,13 +16,16 @@ from uuid import uuid4
|
|||||||
class Dataset(db.Model):
|
class Dataset(db.Model):
|
||||||
|
|
||||||
id = db.Column(db.String(36), primary_key=True)
|
id = db.Column(db.String(36), primary_key=True)
|
||||||
|
name = db.Column(db.String(128), nullable=False)
|
||||||
tests = db.relationship('Test', backref='dataset')
|
tests = db.relationship('Test', backref='dataset')
|
||||||
creator_id = db.Column(db.String(36), db.ForeignKey('user.id'))
|
creator_id = db.Column(db.String(36), db.ForeignKey('user.id'))
|
||||||
date = db.Column(db.DateTime, nullable=False)
|
date = db.Column(db.DateTime, nullable=False)
|
||||||
default = db.Column(db.Boolean, default=False, nullable=True)
|
default = db.Column(db.Boolean, default=False, nullable=True)
|
||||||
|
accessed = db.Column(db.DateTime, nullable=True)
|
||||||
|
locked = db.Column(db.Boolean, default=False, nullable=True)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'<Dataset {self.id}> was added.'
|
return f'<Dataset {self.id}>.'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def generate_id(self): raise AttributeError('generate_id is not a readable attribute.')
|
def generate_id(self): raise AttributeError('generate_id is not a readable attribute.')
|
||||||
@ -29,6 +33,14 @@ class Dataset(db.Model):
|
|||||||
generate_id.setter
|
generate_id.setter
|
||||||
def generate_id(self): self.id = uuid4().hex
|
def generate_id(self): self.id = uuid4().hex
|
||||||
|
|
||||||
|
@property
|
||||||
|
def set_name(self): raise AttributeError('set_name is not a readable attribute.')
|
||||||
|
|
||||||
|
set_name.setter
|
||||||
|
def set_name(self, name:str): self.name = encrypt(name)
|
||||||
|
|
||||||
|
def get_name(self): return decrypt(self.name)
|
||||||
|
|
||||||
def make_default(self):
|
def make_default(self):
|
||||||
for dataset in Dataset.query.all():
|
for dataset in Dataset.query.all():
|
||||||
dataset.default = False
|
dataset.default = False
|
||||||
@ -43,7 +55,7 @@ class Dataset(db.Model):
|
|||||||
message = 'Cannot delete the default dataset.'
|
message = 'Cannot delete the default dataset.'
|
||||||
flash(message, 'error')
|
flash(message, 'error')
|
||||||
return False, message
|
return False, message
|
||||||
if Dataset.query.all().count() == 1:
|
if Dataset.query.count() == 1:
|
||||||
message = 'Cannot delete the only dataset.'
|
message = 'Cannot delete the only dataset.'
|
||||||
flash(message, 'error')
|
flash(message, 'error')
|
||||||
return False, message
|
return False, message
|
||||||
@ -56,23 +68,19 @@ class Dataset(db.Model):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
return True, 'Dataset deleted.'
|
return True, 'Dataset deleted.'
|
||||||
|
|
||||||
def create(self, upload, default:bool=False):
|
def create(self, data:list, default:bool=False):
|
||||||
self.generate_id()
|
self.generate_id()
|
||||||
timestamp = datetime.now()
|
timestamp = datetime.now()
|
||||||
filename = secure_filename('.'.join([self.id,'json']))
|
file_path = self.get_file()
|
||||||
data = Path(app.config.get('DATA'))
|
|
||||||
file_path = path.join(data, 'questions', filename)
|
|
||||||
upload.stream.seek(0)
|
|
||||||
questions = loads(upload.read())
|
|
||||||
with open(file_path, 'w') as file:
|
with open(file_path, 'w') as file:
|
||||||
dump(questions, file, indent=2)
|
dump(data, file, indent=2)
|
||||||
self.date = timestamp
|
self.date = timestamp
|
||||||
self.creator = current_user
|
self.creator = current_user
|
||||||
if default: self.make_default()
|
if default: self.make_default()
|
||||||
write('system.log', f'New dataset {self.id} added by {current_user.get_username()}.')
|
write('system.log', f'New dataset {self.get_name()} added by {current_user.get_username()}.')
|
||||||
db.session.add(self)
|
db.session.add(self)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return True, 'Dataset uploaded.'
|
return True, 'Dataset created.'
|
||||||
|
|
||||||
def check_file(self):
|
def check_file(self):
|
||||||
filename = secure_filename('.'.join([self.id,'json']))
|
filename = secure_filename('.'.join([self.id,'json']))
|
||||||
@ -86,3 +94,15 @@ class Dataset(db.Model):
|
|||||||
data = Path(app.config.get('DATA'))
|
data = Path(app.config.get('DATA'))
|
||||||
file_path = path.join(data, 'questions', filename)
|
file_path = path.join(data, 'questions', filename)
|
||||||
return file_path
|
return file_path
|
||||||
|
|
||||||
|
def update(self, data:list=None, default:bool=False):
|
||||||
|
self.date = datetime.now()
|
||||||
|
if default: self.make_default()
|
||||||
|
file_path = self.get_file()
|
||||||
|
with open(file_path, 'w') as file:
|
||||||
|
dump(data, file, indent=2)
|
||||||
|
write('system.log', f'Dataset {self.id} edited by {current_user.get_username()}.')
|
||||||
|
flash(f'Dataset {self.name} successfully edited.', 'success')
|
||||||
|
db.session.add(self)
|
||||||
|
db.session.commit()
|
||||||
|
return True, 'Dataset successfully edited.'
|
Loading…
Reference in New Issue
Block a user