Added a whole lot of views.
Finished quiz API views Finished question generator and answer eval
This commit is contained in:
		@@ -1,3 +1,4 @@
 | 
			
		||||
from .entry import Entry
 | 
			
		||||
from .test import Test
 | 
			
		||||
from .user import User
 | 
			
		||||
from .user import User
 | 
			
		||||
from .dataset import Dataset
 | 
			
		||||
							
								
								
									
										82
									
								
								ref-test/app/models/dataset.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								ref-test/app/models/dataset.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
from ..data import data
 | 
			
		||||
from ..modules import db
 | 
			
		||||
from ..tools.logs import write
 | 
			
		||||
 | 
			
		||||
from flask import flash, jsonify
 | 
			
		||||
from flask_login import current_user
 | 
			
		||||
from werkzeug.utils import secure_filename
 | 
			
		||||
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
from json import dump, loads
 | 
			
		||||
from os import path, remove
 | 
			
		||||
from uuid import uuid4
 | 
			
		||||
 | 
			
		||||
class Dataset(db.Model):
 | 
			
		||||
 | 
			
		||||
    id = db.Column(db.String(36), primary_key=True)
 | 
			
		||||
    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)
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        return f'<Dataset {self.id}> was added.'
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def generate_id(self): raise AttributeError('generate_id is not a readable attribute.')
 | 
			
		||||
 | 
			
		||||
    generate_id.setter
 | 
			
		||||
    def generate_id(self): self.id = uuid4.hex()
 | 
			
		||||
 | 
			
		||||
    def make_default(self):
 | 
			
		||||
        for dataset in Dataset.query.all():
 | 
			
		||||
            dataset.default = False
 | 
			
		||||
        self.default = True
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        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')
 | 
			
		||||
            return False, jsonify({'error': message})
 | 
			
		||||
        if Dataset.query.all().count() == 1:
 | 
			
		||||
            message = 'Cannot delete the only dataset.'
 | 
			
		||||
            flash(message, 'error')
 | 
			
		||||
            return False, jsonify({'error': message})
 | 
			
		||||
        write('system.log', f'Dataset {self.id} deleted by {current_user.get_username()}.')
 | 
			
		||||
        filename = secure_filename('.'.join([self.id,'json']))
 | 
			
		||||
        file_path = path.join(data, 'questions', filename)
 | 
			
		||||
        remove(file_path)
 | 
			
		||||
        db.session.delete(self)
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        return True, 'Dataset deleted.'
 | 
			
		||||
    
 | 
			
		||||
    def create(self, upload, default:bool=False):
 | 
			
		||||
        self.generate_id()
 | 
			
		||||
        timestamp = datetime.now()
 | 
			
		||||
        filename = secure_filename('.'.join([self.id,'json']))
 | 
			
		||||
        file_path = path.join(data, 'questions', filename)
 | 
			
		||||
        upload.stream.seek(0)
 | 
			
		||||
        questions = loads(upload.read())
 | 
			
		||||
        with open(file_path, 'w') as file:
 | 
			
		||||
            dump(questions, file, indent=2)
 | 
			
		||||
        self.date = timestamp
 | 
			
		||||
        self.creator = current_user
 | 
			
		||||
        if default: self.make_default()
 | 
			
		||||
        write('system.log', f'New dataset {self.id} added by {current_user.get_username()}.')
 | 
			
		||||
        db.session.add(self)
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        return True, 'Dataset uploaded.'
 | 
			
		||||
 | 
			
		||||
    def check_file(self):
 | 
			
		||||
        filename = secure_filename('.'.join([self.id,'json']))
 | 
			
		||||
        file_path = path.join(data, 'questions', filename)
 | 
			
		||||
        if not path.isfile(file_path): return False, 'Data file is missing.'
 | 
			
		||||
 | 
			
		||||
    def get_file(self):
 | 
			
		||||
        filename = secure_filename('.'.join([self.id,'json']))
 | 
			
		||||
        file_path = path.join(data, 'questions', filename)
 | 
			
		||||
        return file_path
 | 
			
		||||
@@ -8,6 +8,7 @@ from flask import jsonify
 | 
			
		||||
from flask_login import current_user
 | 
			
		||||
 | 
			
		||||
from datetime import datetime, timedelta
 | 
			
		||||
from uuid import uuid4
 | 
			
		||||
 | 
			
		||||
class Entry(db.Model):
 | 
			
		||||
 | 
			
		||||
@@ -25,6 +26,15 @@ class Entry(db.Model):
 | 
			
		||||
    answers = db.Column(JsonEncodedDict, nullable=True)
 | 
			
		||||
    result = db.Column(JsonEncodedDict, nullable=True)
 | 
			
		||||
    
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        return f'<New entry by {self.first_name} {self.surname}> was added with <id {self.id}>.'
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def generate_id(self): raise AttributeError('generate_id is not a readable attribute.')
 | 
			
		||||
 | 
			
		||||
    generate_id.setter
 | 
			
		||||
    def generate_id(self): self.id = uuid4.hex()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def set_first_name(self): raise AttributeError('set_first_name is not a readable attribute.')
 | 
			
		||||
 | 
			
		||||
@@ -63,10 +73,11 @@ class Entry(db.Model):
 | 
			
		||||
        write('tests.log', f'New test started by {self.get_first_name()} {self.get_surname()}.')
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
 | 
			
		||||
    def complete(self):
 | 
			
		||||
    def complete(self, answers:dict=None, result:dict=None):
 | 
			
		||||
        self.end_time = datetime.now()
 | 
			
		||||
        self.answers = answers
 | 
			
		||||
        write('tests.log', f'Test completed by {self.get_first_name()} {self.get_surname()}.')
 | 
			
		||||
        delta = timedelta(minutes=self.test.time_limit)
 | 
			
		||||
        delta = timedelta(minutes=self.test.time_limit+1)
 | 
			
		||||
        if not self.test.time_limit or self.end_time <= self.start_time + delta:
 | 
			
		||||
            self.status = 'finished'
 | 
			
		||||
            self.valid = True
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ from datetime import datetime
 | 
			
		||||
from json import dump, loads
 | 
			
		||||
import os
 | 
			
		||||
import secrets
 | 
			
		||||
 | 
			
		||||
from uuid import uuid4
 | 
			
		||||
 | 
			
		||||
class Test(db.Model):
 | 
			
		||||
    
 | 
			
		||||
@@ -21,18 +21,33 @@ class Test(db.Model):
 | 
			
		||||
    end_date = db.Column(db.DateTime, nullable=True)
 | 
			
		||||
    time_limit = db.Column(db.Integer, nullable=True)
 | 
			
		||||
    creator_id = db.Column(db.String(36), db.ForeignKey('user.id'))
 | 
			
		||||
    data = db.Column(db.String(36), nullable=False)
 | 
			
		||||
    dataset_id = db.Column(db.String(36), db.ForeignKey('dataset.id'))
 | 
			
		||||
    adjustments = db.Column(JsonEncodedDict, nullable=True)
 | 
			
		||||
    entries = db.relationship('Entry', backref='test')
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        return f'<test with code {self.code} was created by {current_user.get_username()}.>'
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def generate_id(self): raise AttributeError('generate_id is not a readable attribute.')
 | 
			
		||||
 | 
			
		||||
    generate_id.setter
 | 
			
		||||
    def generate_id(self): self.id = uuid4.hex()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def generate_code(self): raise AttributeError('generate_code is not a readable attribute.')
 | 
			
		||||
 | 
			
		||||
    generate_code.setter
 | 
			
		||||
    def generate_code(self): self.code = secrets.token_hex(6).lower()
 | 
			
		||||
 | 
			
		||||
    def get_code(self):
 | 
			
		||||
        code = self.code.upper()
 | 
			
		||||
        return '—'.join([code[:4], code[4:8], code[8:]])
 | 
			
		||||
 | 
			
		||||
    def create(self):
 | 
			
		||||
        self.generate_id()
 | 
			
		||||
        self.generate_code()
 | 
			
		||||
        self.creator = current_user
 | 
			
		||||
        db.session.add(self)
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        write('system.log', f'Test with code {self.code} created by {current_user.get_username()}.')
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ class User(UserMixin, db.Model):
 | 
			
		||||
    reset_token = db.Column(db.String(20), nullable=True)
 | 
			
		||||
    verification_token = db.Column(db.String(20), nullable=True)
 | 
			
		||||
    tests = db.relationship('Test', backref='creator')
 | 
			
		||||
    datasets = db.relationship('Dataset', backref='creator')
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        return f'<user {self.username}> was added with <id {self.id}>.'
 | 
			
		||||
@@ -52,6 +53,7 @@ class User(UserMixin, db.Model):
 | 
			
		||||
    def get_email(self): return decrypt(self.email)
 | 
			
		||||
 | 
			
		||||
    def register(self, notify:bool=False):
 | 
			
		||||
        self.generate_id()
 | 
			
		||||
        users = User.query.all()
 | 
			
		||||
        for user in users:
 | 
			
		||||
            if user.get_username() == self.get_username(): return False, f'Username {self.get_username()} already in use.'
 | 
			
		||||
@@ -88,17 +90,19 @@ class User(UserMixin, db.Model):
 | 
			
		||||
        self.reset_token = self.verification_token = None
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
    
 | 
			
		||||
    def delete(self):
 | 
			
		||||
    def delete(self, notify:bool=False):
 | 
			
		||||
        username = self.get_username()
 | 
			
		||||
        db.session.delete(self)
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        write('users.log', f'User \'{username}\' was deleted by \'{current_user.get_username()}\'.')
 | 
			
		||||
        message = f'User \'{username}\' was deleted by \'{current_user.get_username()}\'.'
 | 
			
		||||
        write('users.log', message)
 | 
			
		||||
        return True, message
 | 
			
		||||
 | 
			
		||||
    def update(self, password:str=None, email:str=None):
 | 
			
		||||
    def update(self, password:str=None, email:str=None, notify:bool=False):
 | 
			
		||||
        if not password and not email: return False, jsonify({'error': 'There were no changes requested.'})
 | 
			
		||||
        if password: self.set_password(password)
 | 
			
		||||
        if email: self.set_email(email)
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        message = f'Information for user {self.get_username()} has been updated by {current_user.get_username()}.'
 | 
			
		||||
        write('system.log', message)
 | 
			
		||||
        return True, jsonify({'success': message})
 | 
			
		||||
        return True, message
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user