Completed admin views
Corrected model method return values
This commit is contained in:
		@@ -1,12 +1,16 @@
 | 
			
		||||
from ..forms.admin import CreateUser, DeleteUser, Login, Register, ResetPassword, UpdatePassword, UpdateUser, UploadData
 | 
			
		||||
from ..models import Dataset, User
 | 
			
		||||
from ..forms.admin import AddTimeAdjustment, CreateTest, CreateUser, DeleteUser, Login, Register, ResetPassword, UpdatePassword, UpdateUser, UploadData
 | 
			
		||||
from ..models import Dataset, Entry, Test, User
 | 
			
		||||
from ..tools.auth import disable_if_logged_in, require_account_creation
 | 
			
		||||
from ..tools.forms import get_dataset_choices, get_time_options
 | 
			
		||||
from ..tools.data import check_is_json, validate_json
 | 
			
		||||
from ..tools.test import get_correct_answers
 | 
			
		||||
 | 
			
		||||
from flask import Blueprint, flash, jsonify, render_template, redirect, request, session
 | 
			
		||||
from flask.helpers import url_for
 | 
			
		||||
from flask import Blueprint, jsonify, render_template, redirect, request, session
 | 
			
		||||
from flask.helpers import flash, url_for
 | 
			
		||||
from flask_login import current_user, login_required
 | 
			
		||||
 | 
			
		||||
from datetime import date, datetime
 | 
			
		||||
from json import loads
 | 
			
		||||
import secrets
 | 
			
		||||
 | 
			
		||||
admin = Blueprint(
 | 
			
		||||
@@ -21,7 +25,17 @@ admin = Blueprint(
 | 
			
		||||
@admin.route('/dashboard/')
 | 
			
		||||
@login_required
 | 
			
		||||
def _home():
 | 
			
		||||
    return 'Home Page' # TODO Dashboard
 | 
			
		||||
    tests = Test.query.all()
 | 
			
		||||
    results = Entry.query.all()
 | 
			
		||||
    current_tests = [ test for test in tests if test['expiry_date'].date() >= datetime.now().date() and test['start_date'].date() <= date.today() ]
 | 
			
		||||
    current_tests.sort(key= lambda x: x['expiry_date'], reverse=True)
 | 
			
		||||
    upcoming_tests = [ test for test in tests if test['start_date'].date() > datetime.now().date()]
 | 
			
		||||
    upcoming_tests.sort(key= lambda x: x['start_date'])
 | 
			
		||||
    recent_results = [result for result in results if not result['status'] == 'started' ]
 | 
			
		||||
    recent_results.sort(key= lambda x: x['end_time'], reverse=True)
 | 
			
		||||
    for result in recent_results:
 | 
			
		||||
        result['percent'] = round(100*result['result']['score']/result['result']['max'])
 | 
			
		||||
    return render_template('/admin/index.html', current_tests = current_tests, upcomimg_tests = upcoming_tests, recent_results = recent_results)
 | 
			
		||||
 | 
			
		||||
@admin.route('/settings/')
 | 
			
		||||
@login_required
 | 
			
		||||
@@ -216,14 +230,159 @@ def _quesitons():
 | 
			
		||||
 | 
			
		||||
@admin.route('/settings/questions/edit/', methods=['POST'])
 | 
			
		||||
@login_required
 | 
			
		||||
def _delete_questions():
 | 
			
		||||
def _edit_questions():
 | 
			
		||||
    id = request.get_json()['id']
 | 
			
		||||
    action = request.get_json()['action']
 | 
			
		||||
    if action not in ['defailt', 'delete']: return jsonify({'error': 'Invalid action.'}), 400
 | 
			
		||||
    dataset = Dataset.query.filter_by(id=id).first()
 | 
			
		||||
    if action == 'delete': success, message = dataset.delete()
 | 
			
		||||
    elif action == 'default': success, message = dataset.make_default()
 | 
			
		||||
    if success: return jsonify({'success': message}), 200
 | 
			
		||||
    return jsonify({'error': message}), 400
 | 
			
		||||
 | 
			
		||||
# TODO Test views
 | 
			
		||||
# TODO Result views
 | 
			
		||||
@admin.route('/tests/<string:filter>/', methods=['GET'])
 | 
			
		||||
@admin.route('/tests/', methods=['GET'])
 | 
			
		||||
@login_required
 | 
			
		||||
def _tests(filter:str=None):
 | 
			
		||||
    datasets = Dataset.query.all()
 | 
			
		||||
    tests = None
 | 
			
		||||
    _tests = Test.query.all()
 | 
			
		||||
    form = None
 | 
			
		||||
    if not datasets:
 | 
			
		||||
        flash('There are no available question datasets. Please upload a question dataset in order to set up an exam.', 'error')
 | 
			
		||||
        return redirect(url_for('admin._questions'))
 | 
			
		||||
    if filter not in [None, '', 'create','active','scheduled','expired','all']: return redirect(url_for('admin._tests'))
 | 
			
		||||
    if filter == 'create':
 | 
			
		||||
        form = CreateTest()
 | 
			
		||||
        form.time_limit.choices = get_time_options()
 | 
			
		||||
        form.dataset.choices = get_dataset_choices
 | 
			
		||||
        form.time_limit.default='none'
 | 
			
		||||
        form.process()
 | 
			
		||||
        display_title = ''
 | 
			
		||||
        error_none = ''
 | 
			
		||||
    if filter in [None, '', 'active']:
 | 
			
		||||
        tests = [ test for test in _tests if test['expiry_date'].date() >= date.today() and test['start_date'].date() <= date.today() ]
 | 
			
		||||
        display_title = 'Active Exams'
 | 
			
		||||
        error_none = 'There are no exams that are currently active. You can create one using the Creat Exam form.'
 | 
			
		||||
    if filter == 'expired':
 | 
			
		||||
        tests = [ test for test in _tests if test['expiry_date'].date() < date.today() ]
 | 
			
		||||
        display_title = 'Expired Exams'
 | 
			
		||||
        error_none = 'There are no expired exams. Exams will appear in this category after their expiration date has passed.'
 | 
			
		||||
    if filter == 'scheduled':
 | 
			
		||||
        tests = [ test for test in _tests if test['start_date'].date() > date.today()]
 | 
			
		||||
        display_title = 'Scheduled Exams'
 | 
			
		||||
        error_none = 'There are no scheduled exams pending. You can schedule an exam for the future using the Create Exam form.'
 | 
			
		||||
    if filter == 'all':
 | 
			
		||||
        tests = _tests
 | 
			
		||||
        display_title = 'All Exams'
 | 
			
		||||
        error_none = 'There are no exams set up. You can create one using the Create Exam form.'
 | 
			
		||||
    return render_template('/admin/tests.html', form = form, tests=tests, display_title=display_title, error_none=error_none, filter=filter)
 | 
			
		||||
 | 
			
		||||
@admin.route('/tests/create/', methods=['POST'])
 | 
			
		||||
@login_required
 | 
			
		||||
def _create_test():
 | 
			
		||||
    form = CreateTest()
 | 
			
		||||
    form.dataset.choices = get_dataset_choices()
 | 
			
		||||
    form.time_limit.choices = get_time_options()
 | 
			
		||||
    if form.validate_on_submit():
 | 
			
		||||
        new_test = Test()
 | 
			
		||||
        new_test.start_date = request.form.get('start_date')
 | 
			
		||||
        new_test.start_date = datetime.strptime(new_test.start_date, '%Y-%m-%d')
 | 
			
		||||
        new_test.end_date = request.form.get('expiry_date')
 | 
			
		||||
        new_test.end_date = datetime.strptime(new_test.end_date, '%Y-%m-%d')
 | 
			
		||||
        dataset = request.form.get('dataset')
 | 
			
		||||
        new_test.dataset = Dataset.query.filter_by(id=dataset)
 | 
			
		||||
        success, message = new_test.create()
 | 
			
		||||
        if success:
 | 
			
		||||
            flash(message=message, category='success')
 | 
			
		||||
            return jsonify({'success': message}), 200
 | 
			
		||||
        return jsonify({'error': message}), 400
 | 
			
		||||
    else:
 | 
			
		||||
        errors = [*form.start_date.errors, *form.expiry_date.errors, *form.time_limit.errors]
 | 
			
		||||
        return jsonify({ 'error': errors}), 400
 | 
			
		||||
 | 
			
		||||
@admin.route('/tests/edit/', methods=['POST'])
 | 
			
		||||
@login_required
 | 
			
		||||
def _edit_test():
 | 
			
		||||
    id = request.get_json()['id']
 | 
			
		||||
    action = request.get_json()['action']
 | 
			
		||||
    if action not in ['start', 'delete', 'end']: return jsonify({'error': 'Invalid action.'}), 400
 | 
			
		||||
    test = Test.query.filter_by(id=id).first()
 | 
			
		||||
    if not test: return jsonify({'error': 'Could not find the corresponding test to delete.'}), 404
 | 
			
		||||
    if action == 'delete': success, message = test.delete()
 | 
			
		||||
    if action == 'start': success, message = test.start()
 | 
			
		||||
    if action == 'end': success, message = test.end()
 | 
			
		||||
    if success:
 | 
			
		||||
        flash(message=message, category='success')
 | 
			
		||||
        return jsonify({'success': message}), 200
 | 
			
		||||
    return jsonify({'error': message}), 400
 | 
			
		||||
 | 
			
		||||
@admin.route('/test/<string:id>/', methods=['GET','POST'])
 | 
			
		||||
@login_required
 | 
			
		||||
def _view_test(id:str=None):    
 | 
			
		||||
    form = AddTimeAdjustment()
 | 
			
		||||
    test = Test.query.filter_by(id=id).first()
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        if not test: return jsonify({'error': 'Invalid test ID.'}), 404
 | 
			
		||||
        if form.validate_on_submit():
 | 
			
		||||
            time = int(request.form.get('time'))
 | 
			
		||||
            success, message = test.add_adjustment(time)
 | 
			
		||||
            if success: return jsonify({'success': message}), 200
 | 
			
		||||
            return jsonify({'error': message}), 400
 | 
			
		||||
        return jsonify({'error': form.time.errors }), 400
 | 
			
		||||
    if not test:
 | 
			
		||||
        flash('Invalid test ID.', 'error')
 | 
			
		||||
        return redirect(url_for('admin._tests'))
 | 
			
		||||
    return render_template('/admin/test.html', test = test, form = form)
 | 
			
		||||
 | 
			
		||||
@admin.route('/test/<string:id>/delete-adjustment/', methods=['POST'])
 | 
			
		||||
@login_required
 | 
			
		||||
def _delete_adjustment(id:str=None):
 | 
			
		||||
    test = Test.query.filter_by(id=id).first()
 | 
			
		||||
    if not test: return jsonify({'error': 'Invalid test ID.'}), 404
 | 
			
		||||
    user_code = request.get_json()['user_code'].lower()
 | 
			
		||||
    success, message = test.remove_adjustment(user_code)
 | 
			
		||||
    if success: return jsonify({'success': message}), 200
 | 
			
		||||
    return jsonify({'error': message}), 400
 | 
			
		||||
 | 
			
		||||
@admin.route('/results/')
 | 
			
		||||
@login_required
 | 
			
		||||
def _view_entries():
 | 
			
		||||
    entries = Entry.query.all()
 | 
			
		||||
    return render_template('/admin/results.html', entries = entries)
 | 
			
		||||
 | 
			
		||||
@admin.route('/results/<string:id>/', methods = ['GET', 'POST'])
 | 
			
		||||
@login_required
 | 
			
		||||
def _view_entry(id:str=None):
 | 
			
		||||
    entry = Entry.query.filter_by(id=id)
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        if not entry: return jsonify({'error': 'Invalid entry ID.'}), 404
 | 
			
		||||
        action = request.get_json()['action']
 | 
			
		||||
        if action not in ['validate', 'delete']: return jsonify({'error': 'Invalid action.'}), 400
 | 
			
		||||
        if action == 'validate':
 | 
			
		||||
            success, message = entry.validate()
 | 
			
		||||
        if action == 'delete':
 | 
			
		||||
            success, message = entry.delete()
 | 
			
		||||
        if success:
 | 
			
		||||
            flash(message, 'success')
 | 
			
		||||
            return jsonify({'success': message}), 200
 | 
			
		||||
        return jsonify({'error': message}),400
 | 
			
		||||
    if not entry:
 | 
			
		||||
        flash('Invalid entry ID.', 'error')
 | 
			
		||||
        return redirect(url_for('admin._view_entries'))
 | 
			
		||||
    test = entry['test']
 | 
			
		||||
    dataset = test['dataset']
 | 
			
		||||
    dataset_path = dataset.get_file()
 | 
			
		||||
    with open(dataset_path, 'r') as _dataset:
 | 
			
		||||
        data = loads(_dataset.read())
 | 
			
		||||
    correct = get_correct_answers(dataset=data)
 | 
			
		||||
    return render_template('/admin/result-detail.html', entry = entry, correct = correct)
 | 
			
		||||
 | 
			
		||||
@admin.route('/certificate/',methods=['POST'])
 | 
			
		||||
@login_required
 | 
			
		||||
def _generate_certificate():
 | 
			
		||||
    from main import db
 | 
			
		||||
    id = request.get_json()['id']
 | 
			
		||||
    entry = Entry.query.filter_by(id=id).first()
 | 
			
		||||
    if not entry: return jsonify({'error': 'Invalid entry ID.'}), 404
 | 
			
		||||
    return render_template('/admin/components/certificate.html', entry = entry)
 | 
			
		||||
@@ -2,7 +2,7 @@ from ..data import data
 | 
			
		||||
from ..modules import db
 | 
			
		||||
from ..tools.logs import write
 | 
			
		||||
 | 
			
		||||
from flask import flash, jsonify
 | 
			
		||||
from flask import flash
 | 
			
		||||
from flask_login import current_user
 | 
			
		||||
from werkzeug.utils import secure_filename
 | 
			
		||||
 | 
			
		||||
@@ -41,11 +41,11 @@ class Dataset(db.Model):
 | 
			
		||||
        if self.default:
 | 
			
		||||
            message = 'Cannot delete the default dataset.'
 | 
			
		||||
            flash(message, 'error')
 | 
			
		||||
            return False, jsonify({'error': message})
 | 
			
		||||
            return False, message
 | 
			
		||||
        if Dataset.query.all().count() == 1:
 | 
			
		||||
            message = 'Cannot delete the only dataset.'
 | 
			
		||||
            flash(message, 'error')
 | 
			
		||||
            return False, jsonify({'error': message})
 | 
			
		||||
            return False, 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)
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@ from ..tools.encryption import decrypt, encrypt
 | 
			
		||||
from ..tools.logs import write
 | 
			
		||||
from .test import Test
 | 
			
		||||
 | 
			
		||||
from flask import jsonify
 | 
			
		||||
from flask_login import current_user
 | 
			
		||||
 | 
			
		||||
from datetime import datetime, timedelta
 | 
			
		||||
@@ -79,7 +78,7 @@ class Entry(db.Model):
 | 
			
		||||
        write('tests.log', f'Test completed by {self.get_first_name()} {self.get_surname()}.')
 | 
			
		||||
        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.status = 'completed'
 | 
			
		||||
            self.valid = True
 | 
			
		||||
        else:
 | 
			
		||||
            self.status = 'late'
 | 
			
		||||
@@ -87,10 +86,18 @@ class Entry(db.Model):
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
 | 
			
		||||
    def validate(self):
 | 
			
		||||
        if self.valid: return False, jsonify({'error':f'The entry is already valid.'})
 | 
			
		||||
        if self.status == 'started': return False, jsonify({'error':f'The entry is still pending.'})
 | 
			
		||||
        if self.valid: return False, f'The entry is already valid.'
 | 
			
		||||
        if self.status == 'started': return False, 'The entry is still pending.'
 | 
			
		||||
        self.valid = True
 | 
			
		||||
        self.status = 'completed'
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        message = f'The entry {self.id} has been validated by {current_user.get_username()}.'
 | 
			
		||||
        return True, jsonify({'success': message})
 | 
			
		||||
        write('system.log', f'The entry {self.id} has been validated by {current_user.get_username()}.')
 | 
			
		||||
        return True, f'The entry {self.id} has been validated.'
 | 
			
		||||
 | 
			
		||||
    def delete(self):
 | 
			
		||||
        id = self.id
 | 
			
		||||
        name = f'{self.get_first_name()} {self.get_surname()}'
 | 
			
		||||
        db.session.delete(self)
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        write('system.log', f'The entry {id} by {name} has been deleted by {current_user.get_username()}.')
 | 
			
		||||
        return True, 'Entry deleted.'
 | 
			
		||||
@@ -3,11 +3,9 @@ from ..tools.encryption import decrypt, encrypt
 | 
			
		||||
from ..tools.forms import JsonEncodedDict
 | 
			
		||||
from ..tools.logs import write
 | 
			
		||||
 | 
			
		||||
from flask import jsonify
 | 
			
		||||
from flask.helpers import flash
 | 
			
		||||
from flask_login import current_user
 | 
			
		||||
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
from datetime import date, datetime
 | 
			
		||||
from json import dump, loads
 | 
			
		||||
import os
 | 
			
		||||
import secrets
 | 
			
		||||
@@ -48,35 +46,45 @@ class Test(db.Model):
 | 
			
		||||
        self.generate_id()
 | 
			
		||||
        self.generate_code()
 | 
			
		||||
        self.creator = current_user
 | 
			
		||||
        errors = []
 | 
			
		||||
        if self.start_date.date() < date.today():
 | 
			
		||||
            errors.append('The start date cannot be in the past.')
 | 
			
		||||
        if self.end_date.date() < date.today():
 | 
			
		||||
            errors.append('The expiry date cannot be in the past.')
 | 
			
		||||
        if self.end_date < self.start_date:
 | 
			
		||||
            errors.append('The expiry date cannot be before the start date.')
 | 
			
		||||
        if errors:
 | 
			
		||||
            return False, errors
 | 
			
		||||
        db.session.add(self)
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        write('system.log', f'Test with code {self.code} created by {current_user.get_username()}.')
 | 
			
		||||
        write('system.log', f'Test with code {self.get_code()} created by {current_user.get_username()}.')
 | 
			
		||||
        return True, f'Test with code {self.get_code()} has been created.'
 | 
			
		||||
    
 | 
			
		||||
    def delete(self):
 | 
			
		||||
        code = self.code
 | 
			
		||||
        if self.entries: return False, f'Cannot delete a test with submitted entries.'
 | 
			
		||||
        db.session.delete(self)
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        write('system.log', f'Test with code {code} deleted by {current_user.get_username()}.')
 | 
			
		||||
        write('system.log', f'Test with code {code} has been deleted by {current_user.get_username()}.')
 | 
			
		||||
        return True, f'Test with code {code} has been deleted.'
 | 
			
		||||
    
 | 
			
		||||
    def start(self):
 | 
			
		||||
        now = datetime.now()
 | 
			
		||||
        if self.start_date > now:
 | 
			
		||||
        if self.start_date.date() > now.date():
 | 
			
		||||
            self.start_date = now
 | 
			
		||||
            db.session.commit()
 | 
			
		||||
            message = f'Test with code {self.code} started by {current_user.get_username()}.'
 | 
			
		||||
            write('system.log', message)
 | 
			
		||||
            return True, jsonify({'success': message})
 | 
			
		||||
        return False, jsonify({'error': f'Test with code {self.code} has already started.'})
 | 
			
		||||
            write('system.log', f'Test with code {self.code} has been started by {current_user.get_username()}.')
 | 
			
		||||
            return True,  f'Test with code {self.code} has been started.'
 | 
			
		||||
        return False, f'Test with code {self.code} has already started.'
 | 
			
		||||
 | 
			
		||||
    def end(self):
 | 
			
		||||
        now = datetime.now()
 | 
			
		||||
        if self.end_date > now:
 | 
			
		||||
        if self.end_date.date() > now.date():
 | 
			
		||||
            self.end_date = now
 | 
			
		||||
            db.session.commit()
 | 
			
		||||
            message = f'Test with code {self.code} ended by {current_user.get_username()}.'
 | 
			
		||||
            write('system.log', message)
 | 
			
		||||
            return True, jsonify({'success': message})
 | 
			
		||||
        return False, jsonify({'error': f'Test with code {self.code} has already started.'})
 | 
			
		||||
            write('system.log', f'Test with code {self.code} ended by {current_user.get_username()}.')
 | 
			
		||||
            return True, f'Test with code {self.code} has been ended.'
 | 
			
		||||
        return False, f'Test with code {self.code} has already ended.'
 | 
			
		||||
 | 
			
		||||
    def add_adjustment(self, time:int):
 | 
			
		||||
        adjustments = self.adjustments if self.adjustments is not None else {}
 | 
			
		||||
@@ -85,23 +93,21 @@ class Test(db.Model):
 | 
			
		||||
        self.adjustments = adjustments
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        write('system.log', f'Time adjustment for {time} minutes with code {code} added to test {self.get_code()} by {current_user.get_username()}.')
 | 
			
		||||
        return True, jsonify({'success': f'Time adjustment for {time} minutes added to test {self.get_code()}. This can be accessed using the user code {code.upper()}.'})
 | 
			
		||||
        return True, f'Time adjustment for {time} minutes added to test {self.get_code()}. This can be accessed using the user code {code.upper()}.'
 | 
			
		||||
 | 
			
		||||
    def remove_adjustment(self, code:str):
 | 
			
		||||
        if not self.adjustments: return False, jsonify({'error': f'There are no adjustments configured for test {self.get_code()}.'})
 | 
			
		||||
        if not self.adjustments: return False, f'There are no adjustments configured for test {self.get_code()}.'
 | 
			
		||||
        self.adjustments.pop(code)
 | 
			
		||||
        if not self.adjustments: self.adjustments = None
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        message = f'Time adjustment for with code {code} removed from test {self.get_code()} by {current_user.get_username()}.'
 | 
			
		||||
        write('system.log', message)
 | 
			
		||||
        return True, jsonify({'success': message})
 | 
			
		||||
        write('system.log', f'Time adjustment for with code {code} has been removed from test {self.get_code()} by {current_user.get_username()}.')
 | 
			
		||||
        return True, f'Time adjustment for with code {code} has been removed from test {self.get_code()}.'
 | 
			
		||||
 | 
			
		||||
    def update(self, start_date:datetime=None, end_date:datetime=None, time_limit:int=None):
 | 
			
		||||
        if not start_date and not end_date and time_limit is None: return False, jsonify({'error': 'There were no changes requested.'})
 | 
			
		||||
        if not start_date and not end_date and time_limit is None: return False, 'There were no changes requested.'
 | 
			
		||||
        if start_date: self.start_date = start_date
 | 
			
		||||
        if end_date: self.end_date = end_date
 | 
			
		||||
        if time_limit is not None: self.time_limit = time_limit
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        message = f'Test with code {self.get_code()} has been updated by user {current_user.get_username()}'
 | 
			
		||||
        write('system.log', message)
 | 
			
		||||
        return True, jsonify({'success': message})
 | 
			
		||||
        write('system.log', f'Test with code {self.get_code()} has been updated by user {current_user.get_username()}.')
 | 
			
		||||
        return True, f'Test with code {self.get_code()} has been updated by.'
 | 
			
		||||
@@ -99,7 +99,7 @@ class User(UserMixin, db.Model):
 | 
			
		||||
        return True, message
 | 
			
		||||
 | 
			
		||||
    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 not password and not email: return False, 'There were no changes requested.'
 | 
			
		||||
        if password: self.set_password(password)
 | 
			
		||||
        if email: self.set_email(email)
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
 | 
			
		||||
from ..models import Dataset
 | 
			
		||||
from ..modules import db
 | 
			
		||||
 | 
			
		||||
from wtforms.validators import ValidationError
 | 
			
		||||
@@ -42,4 +43,14 @@ def get_time_options():
 | 
			
		||||
        ('90', '1 hour 30 minutes'),
 | 
			
		||||
        ('120', '2 hours')
 | 
			
		||||
    ]
 | 
			
		||||
    return time_options
 | 
			
		||||
    return time_options
 | 
			
		||||
 | 
			
		||||
def get_dataset_choices():
 | 
			
		||||
    datasets = Dataset.query.all()
 | 
			
		||||
    dataset_choices = []
 | 
			
		||||
    for dataset in datasets:
 | 
			
		||||
        label = dataset['date'].strftime('%Y%m%d%H%M%S')
 | 
			
		||||
        label = f'{label} (Default)' if dataset.default else label
 | 
			
		||||
        choice = (dataset['id'], label)
 | 
			
		||||
        dataset_choices.append(choice)
 | 
			
		||||
    return dataset_choices
 | 
			
		||||
		Reference in New Issue
	
	Block a user