2022-06-19 13:22:05 +01:00
|
|
|
from ..extensions import db
|
2022-06-22 01:55:55 +01:00
|
|
|
from ..tools.encryption import decrypt, encrypt
|
2022-06-14 22:55:11 +01:00
|
|
|
from ..tools.logs import write
|
|
|
|
|
2022-06-19 13:22:05 +01:00
|
|
|
from flask import current_app as app
|
2022-08-20 10:56:43 +01:00
|
|
|
from flask.helpers import flash
|
2022-06-14 22:55:11 +01:00
|
|
|
from flask_login import current_user
|
2022-08-19 13:25:20 +01:00
|
|
|
from sqlalchemy.exc import SQLAlchemyError
|
2022-06-14 22:55:11 +01:00
|
|
|
from werkzeug.utils import secure_filename
|
|
|
|
|
|
|
|
from datetime import datetime
|
2022-06-22 01:55:55 +01:00
|
|
|
from json import dump
|
2022-06-14 22:55:11 +01:00
|
|
|
from os import path, remove
|
2022-06-19 13:22:05 +01:00
|
|
|
from pathlib import Path
|
2022-06-14 22:55:11 +01:00
|
|
|
from uuid import uuid4
|
|
|
|
|
|
|
|
class Dataset(db.Model):
|
|
|
|
|
|
|
|
id = db.Column(db.String(36), primary_key=True)
|
2022-06-22 01:55:55 +01:00
|
|
|
name = db.Column(db.String(128), nullable=False)
|
2022-06-14 22:55:11 +01:00
|
|
|
tests = db.relationship('Test', backref='dataset')
|
|
|
|
creator_id = db.Column(db.String(36), db.ForeignKey('user.id'))
|
|
|
|
date = db.Column(db.DateTime, nullable=False)
|
|
|
|
default = db.Column(db.Boolean, default=False, nullable=True)
|
2022-06-22 01:55:55 +01:00
|
|
|
accessed = db.Column(db.DateTime, nullable=True)
|
|
|
|
locked = db.Column(db.Boolean, default=False, nullable=True)
|
2022-06-14 22:55:11 +01:00
|
|
|
|
|
|
|
def __repr__(self):
|
2022-06-22 01:55:55 +01:00
|
|
|
return f'<Dataset {self.id}>.'
|
2022-06-14 22:55:11 +01:00
|
|
|
|
|
|
|
@property
|
|
|
|
def generate_id(self): raise AttributeError('generate_id is not a readable attribute.')
|
|
|
|
|
|
|
|
generate_id.setter
|
2022-06-15 23:54:44 +01:00
|
|
|
def generate_id(self): self.id = uuid4().hex
|
2022-06-14 22:55:11 +01:00
|
|
|
|
2022-06-22 01:55:55 +01:00
|
|
|
@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)
|
|
|
|
|
2022-06-14 22:55:11 +01:00
|
|
|
def make_default(self):
|
2022-08-19 13:25:20 +01:00
|
|
|
try:
|
2022-08-20 10:56:43 +01:00
|
|
|
for dataset in Dataset.query.all(): dataset.default = False
|
|
|
|
except SQLAlchemyError as exception:
|
|
|
|
write('system.log', f'Database error when setting default dataset {self.id}: {exception}')
|
|
|
|
return False, f'Database error {exception}.'
|
|
|
|
self.default = True
|
|
|
|
try: db.session.commit()
|
2022-08-19 13:25:20 +01:00
|
|
|
except SQLAlchemyError as exception:
|
|
|
|
db.session.rollback()
|
|
|
|
write('system.log', f'Database error when setting default dataset {self.id}: {exception}')
|
|
|
|
return False, f'Database error {exception}.'
|
2022-06-14 22:55:11 +01:00
|
|
|
write('system.log', f'Dataset {self.id} set as default by {current_user.get_username()}.')
|
|
|
|
flash(message='Dataset set as default.', category='success')
|
|
|
|
return True, f'Dataset set as default.'
|
|
|
|
|
|
|
|
def delete(self):
|
|
|
|
if self.default:
|
|
|
|
message = 'Cannot delete the default dataset.'
|
|
|
|
flash(message, 'error')
|
2022-06-15 11:23:38 +01:00
|
|
|
return False, message
|
2022-08-20 10:56:43 +01:00
|
|
|
try:
|
|
|
|
if Dataset.query.count() == 1:
|
|
|
|
message = 'Cannot delete the only dataset.'
|
|
|
|
flash(message, 'error')
|
|
|
|
return False, message
|
|
|
|
except SQLAlchemyError as exception:
|
|
|
|
write('system.log', f'Database error when setting default dataset {self.id}: {exception}')
|
|
|
|
return False, f'Database error {exception}.'
|
2022-06-14 22:55:11 +01:00
|
|
|
write('system.log', f'Dataset {self.id} deleted by {current_user.get_username()}.')
|
|
|
|
filename = secure_filename('.'.join([self.id,'json']))
|
2022-06-19 13:22:05 +01:00
|
|
|
data = Path(app.config.get('DATA'))
|
2022-06-14 22:55:11 +01:00
|
|
|
file_path = path.join(data, 'questions', filename)
|
2022-08-19 13:25:20 +01:00
|
|
|
try:
|
|
|
|
db.session.delete(self)
|
|
|
|
db.session.commit()
|
|
|
|
except SQLAlchemyError as exception:
|
|
|
|
db.session.rollback()
|
|
|
|
write('system.log', f'Database error when trying to delete dataset {self.id}: {exception}')
|
|
|
|
return False, f'Database error: {exception}'
|
2022-06-14 22:55:11 +01:00
|
|
|
remove(file_path)
|
|
|
|
return True, 'Dataset deleted.'
|
|
|
|
|
2022-06-22 01:55:55 +01:00
|
|
|
def create(self, data:list, default:bool=False):
|
2022-06-14 22:55:11 +01:00
|
|
|
self.generate_id()
|
|
|
|
timestamp = datetime.now()
|
2022-06-22 01:55:55 +01:00
|
|
|
file_path = self.get_file()
|
2022-06-14 22:55:11 +01:00
|
|
|
with open(file_path, 'w') as file:
|
2022-06-22 01:55:55 +01:00
|
|
|
dump(data, file, indent=2)
|
2022-06-14 22:55:11 +01:00
|
|
|
self.date = timestamp
|
|
|
|
self.creator = current_user
|
|
|
|
if default: self.make_default()
|
2022-06-22 01:55:55 +01:00
|
|
|
write('system.log', f'New dataset {self.get_name()} added by {current_user.get_username()}.')
|
2022-08-19 13:25:20 +01:00
|
|
|
try:
|
|
|
|
db.session.add(self)
|
|
|
|
db.session.commit()
|
|
|
|
except SQLAlchemyError as exception:
|
|
|
|
db.session.rollback()
|
|
|
|
write('system.log', f'Database error when trying to crreate dataset {self.id}: {exception}')
|
|
|
|
return False, f'Database error: {exception}'
|
2022-06-22 01:55:55 +01:00
|
|
|
return True, 'Dataset created.'
|
2022-06-14 22:55:11 +01:00
|
|
|
|
|
|
|
def check_file(self):
|
|
|
|
filename = secure_filename('.'.join([self.id,'json']))
|
2022-06-19 13:22:05 +01:00
|
|
|
data = Path(app.config.get('DATA'))
|
2022-06-14 22:55:11 +01:00
|
|
|
file_path = path.join(data, 'questions', filename)
|
|
|
|
if not path.isfile(file_path): return False, 'Data file is missing.'
|
2022-06-16 10:44:48 +01:00
|
|
|
return True, 'Data file found.'
|
2022-06-14 22:55:11 +01:00
|
|
|
|
|
|
|
def get_file(self):
|
|
|
|
filename = secure_filename('.'.join([self.id,'json']))
|
2022-06-19 13:22:05 +01:00
|
|
|
data = Path(app.config.get('DATA'))
|
2022-06-14 22:55:11 +01:00
|
|
|
file_path = path.join(data, 'questions', filename)
|
2022-06-22 01:55:55 +01:00
|
|
|
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()}.')
|
2022-06-22 10:46:43 +01:00
|
|
|
flash(f'Dataset {self.get_name()} successfully edited.', 'success')
|
2022-08-19 13:25:20 +01:00
|
|
|
try:
|
|
|
|
db.session.add(self)
|
|
|
|
db.session.commit()
|
|
|
|
except SQLAlchemyError as exception:
|
|
|
|
db.session.rollback()
|
|
|
|
write('system.log', f'Database error when trying to update dataset {self.id}: {exception}')
|
|
|
|
return False, f'Database error: {exception}'
|
2022-06-22 01:55:55 +01:00
|
|
|
return True, 'Dataset successfully edited.'
|