1
0
Fork 0
mirror of https://codeberg.org/Mo8it/AdvLabDB.git synced 2024-12-12 23:02:11 +00:00

Added black and isort

This commit is contained in:
Mo 2021-06-02 23:43:41 +02:00
parent 050189ee68
commit 418b1f66ac
12 changed files with 316 additions and 82 deletions

View file

@ -1,3 +1,6 @@
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)
# Requirements
You need to have Python 3 and Poetry installed. To install Poetry, follow the instructions [here](https://python-poetry.org/docs/#installation).

View file

@ -1,16 +1,16 @@
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
from flask_security import Security, SQLAlchemyUserDatastore
from flask_security.models import fsqla_v2 as fsqla
from flask_admin import Admin
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.debug = True # DEBUG
app.debug = True # DEBUG
app.config["SERVER_NAME"] = "127.0.0.1:5000" # DEBUG
app.config["SERVER_NAME"] = "127.0.0.1:5000" # DEBUG
app.config["SECRET_KEY"] = "dev"
app.config["SECURITY_PASSWORD_SALT"] = "devSalt" # os.environ.get("SECURITY_PASSWORD_SALT", "")
app.config["SECURITY_PASSWORD_SALT"] = "devSalt" # os.environ.get("SECURITY_PASSWORD_SALT", "")
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///../advLab.db"
db = SQLAlchemy(app)
@ -18,10 +18,13 @@ db = SQLAlchemy(app)
fsqla.FsModels.set_db_info(db)
from advlabdb import customClasses
admin = Admin(app,
name="Admin@AdvLabDB",
template_mode="bootstrap3",
index_view=customClasses.SecureAdminIndexView(template="admin_index.html"))
admin = Admin(
app,
name="Admin@AdvLabDB",
template_mode="bootstrap3",
index_view=customClasses.SecureAdminIndexView(template="admin_index.html"),
)
from advlabdb import models
@ -29,5 +32,4 @@ from advlabdb import models
user_datastore = SQLAlchemyUserDatastore(db, models.User, models.Role)
Security(app, user_datastore)
from advlabdb import routes
from advlabdb import modelViews
from advlabdb import modelViews, routes

View file

@ -1,8 +1,9 @@
import json
def getConfig(label):
with open("config.json", "r") as f:
return json.load(f)[label] # TODO error handling
return json.load(f)[label] # TODO error handling
def setConfig(label, value, new=False):

View file

@ -1,6 +1,6 @@
from flask_admin import AdminIndexView
from flask_security import current_user
from flask_admin.contrib.sqla import ModelView
from flask_security import current_user
def adminViewIsAccessible():

View file

@ -1,15 +1,35 @@
from flask import url_for, flash, request
from flask_admin.menu import MenuLink
from flask import flash, request, url_for
from flask_admin.contrib.sqla.filters import BaseSQLAFilter
from flask_admin.menu import MenuLink
from flask_security import hash_password
from wtforms import BooleanField, SelectField, TextField
from wtforms.validators import DataRequired, Email
from advlabdb import admin, app, user_datastore, db
from advlabdb.utils import randomPassword, userActiveSemester, partFromLabelInUserActiveSemester, setActiveSemester
from advlabdb.customClasses import SecureModelView
from advlabdb.models import User, Role, Semester, Part, Student, PartStudent, Group, GroupExperiment, Experiment, Assistant, Appointment, PartExperiment, ExperimentMark
from advlabdb import admin, app, db, user_datastore
from advlabdb.configUtils import getConfig
from advlabdb.customClasses import SecureModelView
from advlabdb.models import (
Appointment,
Assistant,
Experiment,
ExperimentMark,
Group,
GroupExperiment,
Part,
PartExperiment,
PartStudent,
Role,
Semester,
Student,
User,
)
from advlabdb.utils import (
partFromLabelInUserActiveSemester,
randomPassword,
setActiveSemester,
userActiveSemester,
)
class UserModelView(SecureModelView):
column_list = ["email", "active", "roles", "assistant"]
@ -20,7 +40,7 @@ class UserModelView(SecureModelView):
form_args = {
"email": {"validators": [Email()]},
"active": {"default": True},
"roles": {"validators": [DataRequired(message="A role is required!")]}
"roles": {"validators": [DataRequired(message="A role is required!")]},
}
def create_model(self, form):
@ -35,7 +55,9 @@ class UserModelView(SecureModelView):
model = user_datastore.create_user(email=email, password=passwordHash, roles=roles)
db.session.commit()
flash(f"{email} registered with roles: {', '.join([role.name for role in form.roles.data])}.", category="success")
flash(
f"{email} registered with roles: {', '.join([role.name for role in form.roles.data])}.", category="success"
)
flash(f"Random password: {password}", category="warning")
return model
@ -61,9 +83,13 @@ class SemesterModelView(SecureModelView):
model.createParts()
if is_created:
admin.add_link(MenuLink(name=model.label,
url=url_for("set_semester") + "?semester_id=" + str(model.id),
category="Active semester"))
admin.add_link(
MenuLink(
name=model.label,
url=url_for("set_semester") + "?semester_id=" + str(model.id),
category="Active semester",
)
)
setActiveSemester(model.id)
@ -90,15 +116,19 @@ class StudentModelView(SecureModelView):
partChoices = ["-"] + getConfig("partsLabels")
form_extra_fields = {
"new_part_student_part": SelectField("Part", choices=list(zip(partChoices, partChoices)), default=partChoices[0]),
"new_part_student_group_number": TextField("Group number")
"new_part_student_part": SelectField(
"Part", choices=list(zip(partChoices, partChoices)), default=partChoices[0]
),
"new_part_student_group_number": TextField("Group number"),
}
def validate_form(self, form):
if request.method == "POST":
partLabel = form.new_part_student_part.data
groupNumber = form.new_part_student_group_number.data
if (partLabel != self.partChoices[0] and groupNumber == "") or (partLabel == self.partChoices[0] and groupNumber != ""):
if (partLabel != self.partChoices[0] and groupNumber == "") or (
partLabel == self.partChoices[0] and groupNumber != ""
):
flash("You have to assign both part and group if you want to add a part student!", "danger")
return False
if partLabel != self.partChoices[0] and not partFromLabelInUserActiveSemester(partLabel):
@ -174,6 +204,10 @@ admin.add_view(RoleModelView(Role, db.session))
with app.app_context():
semesters = Semester.query.all()[::-1]
for semester in semesters:
admin.add_link(MenuLink(name=semester.label,
url=url_for("set_semester") + "?semester_id=" + str(semester.id),
category="Active semester"))
admin.add_link(
MenuLink(
name=semester.label,
url=url_for("set_semester") + "?semester_id=" + str(semester.id),
category="Active semester",
)
)

View file

@ -7,7 +7,7 @@ https://flask-sqlalchemy.palletsprojects.com/en/2.x/models/
"""
# Imports
from flask_security.models.fsqla_v2 import FsUserMixin, FsRoleMixin
from flask_security.models.fsqla_v2 import FsRoleMixin, FsUserMixin
# Importing the database instance
from advlabdb import db
@ -69,7 +69,7 @@ class Experiment(db.Model):
building = db.Column(db.String(100), nullable=False)
responsibility = db.Column(db.String(200), nullable=True)
duration_in_days = db.Column(db.Integer, nullable=False)
deprecated = db.Column(db.Boolean, nullable=False, default=False) # To not be deleted!
deprecated = db.Column(db.Boolean, nullable=False, default=False) # To not be deleted!
oral_weighting = db.Column(db.Float, nullable=False)
protocol_weighting = db.Column(db.Float, nullable=False)
final_weighting = db.Column(db.Float, nullable=False)
@ -80,11 +80,11 @@ class Experiment(db.Model):
# Helper table for the many to many relationship between Assistant and PartExperiment
experiment_assistant = db.Table("experiment_assistant",
db.Column("part_experiment_id", db.Integer, db.ForeignKey("part_experiment.id"),
primary_key=True),
db.Column("assistant_id", db.Integer, db.ForeignKey("assistant.id"),
primary_key=True))
experiment_assistant = db.Table(
"experiment_assistant",
db.Column("part_experiment_id", db.Integer, db.ForeignKey("part_experiment.id"), primary_key=True),
db.Column("assistant_id", db.Integer, db.ForeignKey("assistant.id"), primary_key=True),
)
class PartExperiment(db.Model):
@ -92,8 +92,9 @@ class PartExperiment(db.Model):
id = db.Column(db.Integer, primary_key=True)
experiment_id = db.Column(db.Integer, db.ForeignKey("experiment.id"), nullable=False)
part_id = db.Column(db.Integer, db.ForeignKey("part.id"), nullable=False)
assistants = db.relationship("Assistant", secondary=experiment_assistant, lazy=True,
backref=db.backref("part_experiments", lazy=True))
assistants = db.relationship(
"Assistant", secondary=experiment_assistant, lazy=True, backref=db.backref("part_experiments", lazy=True)
)
group_experiments = db.relationship("GroupExperiment", backref="part_experiment", lazy=True)
@ -116,15 +117,15 @@ class Assistant(db.Model):
class Appointment(db.Model):
id = db.Column(db.Integer, primary_key=True)
date = db.Column(db.DateTime, nullable=False) # To be specified with the python package "datetime"
special = db.Column(db.Boolean, nullable=False) # In the break or not
date = db.Column(db.DateTime, nullable=False) # To be specified with the python package "datetime"
special = db.Column(db.Boolean, nullable=False) # In the break or not
group_experiment_id = db.Column(db.Integer, db.ForeignKey("group_experiment.id"), nullable=False)
assistant_id = db.Column(db.Integer, db.ForeignKey("assistant.id"), nullable=False)
class Part(db.Model):
id = db.Column(db.Integer, primary_key=True)
label = db.Column(db.String(100), nullable=False) # A/1, A/2, B/1, B/2
label = db.Column(db.String(100), nullable=False) # A/1, A/2, B/1, B/2
semester_id = db.Column(db.Integer, db.ForeignKey("semester.id"), nullable=False)
part_experiments = db.relationship("PartExperiment", backref="part", lazy=True)
part_students = db.relationship("PartStudent", backref="part", lazy=True)
@ -136,7 +137,7 @@ class Part(db.Model):
class Semester(db.Model):
id = db.Column(db.Integer, primary_key=True)
label = db.Column(db.String(100), nullable=False, unique=True) # WS2122 for example
label = db.Column(db.String(100), nullable=False, unique=True) # WS2122 for example
parts = db.relationship("Part", backref="semester", lazy=True)
def __repr__(self):
@ -155,8 +156,9 @@ class ExperimentMark(db.Model):
protocol_mark = db.Column(db.Integer, nullable=True)
part_student_id = db.Column(db.Integer, db.ForeignKey("part_student.id"), nullable=False)
group_experiment_id = db.Column(db.Integer, db.ForeignKey("group_experiment.id"), nullable=False)
assistant_id = db.Column(db.Integer, db.ForeignKey("assistant.id"),
nullable=True) # The assistant who gives the mark
assistant_id = db.Column(
db.Integer, db.ForeignKey("assistant.id"), nullable=True
) # The assistant who gives the mark
class User(db.Model, FsUserMixin):

View file

@ -1,9 +1,9 @@
from advlabdb import app, db
from flask import render_template, request, url_for, flash, redirect
from flask import flash, redirect, render_template, request, url_for
from flask_security import auth_required, current_user
from advlabdb.utils import titleToTemplate, userActiveSemester, setActiveSemester
from advlabdb import app, db
from advlabdb.models import Semester
from advlabdb.utils import setActiveSemester, titleToTemplate, userActiveSemester
@app.context_processor
@ -12,8 +12,15 @@ def util_processor():
semesters = Semester.query.all()
items = []
for semester in semesters:
items.append('<li><a class="dropdown-item" href="' + url_for("set_semester") + "?semester_id=" +
str(semester.id) + '">' + semester.label + '</a></li>')
items.append(
'<li><a class="dropdown-item" href="'
+ url_for("set_semester")
+ "?semester_id="
+ str(semester.id)
+ '">'
+ semester.label
+ "</a></li>"
)
return items
def navbarItems(title):
@ -42,14 +49,15 @@ def util_processor():
else:
active = ""
items.append('<a class="nav-link' + active + '" href="' + titleToTemplate(page) + '">' + page + '</a>')
items.append('<a class="nav-link' + active + '" href="' + titleToTemplate(page) + '">' + page + "</a>")
return items
return dict(semesterDropDownItems=semesterDropDownItems,
userActiveSemester=userActiveSemester,
navbarItems=navbarItems,
current_user=current_user,
)
return dict(
semesterDropDownItems=semesterDropDownItems,
userActiveSemester=userActiveSemester,
navbarItems=navbarItems,
current_user=current_user,
)
@app.route("/")

View file

@ -1,10 +1,11 @@
from random import choice
from string import digits, ascii_letters
from flask_security import current_user
from flask import flash
from string import ascii_letters, digits
from flask import flash
from flask_security import current_user
from advlabdb.models import Semester
from advlabdb import db
from advlabdb.models import Semester
def makeTable(headerAndDataList, rows, tableId="table"):
@ -20,13 +21,16 @@ def makeTable(headerAndDataList, rows, tableId="table"):
return cell
def td(cell):
return '<td>' + cellString(cell) + '</td>'
return "<td>" + cellString(cell) + "</td>"
def th(cell):
return '<th data-sortable="true" data-field="' + titleToTemplate(cell) + '">' + cellString(cell) + '</th>'
return '<th data-sortable="true" data-field="' + titleToTemplate(cell) + '">' + cellString(cell) + "</th>"
table = '''<table
id="''' + tableId + '''"
table = (
'''<table
id="'''
+ tableId
+ """"
data-classes="table table-bordered table-striped"
data-toggle="table"
data-thead-classes="table-dark"
@ -38,26 +42,27 @@ data-show-export="true"
data-export-types="['json', 'xml', 'csv', 'txt', 'sql', 'pdf']">
<thead>
<tr>
<th data-field="state" data-checkbox="true"></th>'''
<th data-field="state" data-checkbox="true"></th>"""
)
for i in headerAndDataList:
table += th(i[0])
table += '''</tr>
table += """</tr>
</thead>
<tbody>\n'''
<tbody>\n"""
for row in rows:
table += '<tr><td></td>'
table += "<tr><td></td>"
for i in headerAndDataList:
table += td(eval(i[1]))
table += '</tr>\n'
table += "</tr>\n"
table += '''</tbody>
table += """</tbody>
</table>
<br>
<hr>
<br>'''
<br>"""
return table
@ -66,7 +71,7 @@ def appointmentDate(date):
def randomPassword():
return ''.join(choice(ascii_letters + digits) for i in range(12))
return "".join(choice(ascii_letters + digits) for i in range(12))
def titleToTemplate(page):

View file

@ -1,5 +1,6 @@
from os.path import exists
from shutil import copytree, rmtree
from flask_admin import __file__ as flaskAdminPath
@ -13,7 +14,9 @@ def copyAdminTemplates():
dist = "advlabdb/templates/admin"
if exists(dist):
while True:
ans = input(f"The directory {dist} already exists. Enter 'o' to override it and update the templates or enter 's' to stop the process: ").lower()
ans = input(
f"The directory {dist} already exists. Enter 'o' to override it and update the templates or enter 's' to stop the process: "
).lower()
if ans == "s":
print("Process stopped!")
return False

146
poetry.lock generated
View file

@ -1,3 +1,33 @@
[[package]]
name = "appdirs"
version = "1.4.4"
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "black"
version = "21.5b2"
description = "The uncompromising code formatter."
category = "dev"
optional = false
python-versions = ">=3.6.2"
[package.dependencies]
appdirs = "*"
click = ">=7.1.2"
mypy-extensions = ">=0.4.3"
pathspec = ">=0.8.1,<1"
regex = ">=2020.1.8"
toml = ">=0.10.1"
[package.extras]
colorama = ["colorama (>=0.4.3)"]
d = ["aiohttp (>=3.6.0)", "aiohttp-cors (>=0.4.0)"]
python2 = ["typed-ast (>=1.4.2)"]
uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "blinker"
version = "1.4"
@ -187,6 +217,19 @@ category = "main"
optional = false
python-versions = ">=3.5"
[[package]]
name = "isort"
version = "5.8.0"
description = "A Python utility / library to sort Python imports."
category = "dev"
optional = false
python-versions = ">=3.6,<4.0"
[package.extras]
pipfile_deprecated_finder = ["pipreqs", "requirementslib"]
requirements_deprecated_finder = ["pipreqs", "pip-api"]
colors = ["colorama (>=0.4.3,<0.5.0)"]
[[package]]
name = "itsdangerous"
version = "2.0.1"
@ -225,6 +268,14 @@ category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "mypy-extensions"
version = "0.4.3"
description = "Experimental type system extensions for programs checked with the mypy typechecker."
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "passlib"
version = "1.7.4"
@ -239,6 +290,14 @@ bcrypt = ["bcrypt (>=3.1.0)"]
build_docs = ["sphinx (>=1.6)", "sphinxcontrib-fulltoc (>=1.2.0)", "cloud-sptheme (>=1.10.1)"]
totp = ["cryptography"]
[[package]]
name = "pathspec"
version = "0.8.1"
description = "Utility library for gitignore style pattern matching of file paths."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "pycodestyle"
version = "2.7.0"
@ -255,6 +314,14 @@ category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "regex"
version = "2021.4.4"
description = "Alternative regular expression module, to replace re."
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "sqlalchemy"
version = "1.4.17"
@ -286,6 +353,14 @@ postgresql_psycopg2cffi = ["psycopg2cffi"]
pymysql = ["pymysql (<1)", "pymysql"]
sqlcipher = ["sqlcipher3-binary"]
[[package]]
name = "toml"
version = "0.10.2"
description = "Python Library for Tom's Obvious, Minimal Language"
category = "dev"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
[[package]]
name = "werkzeug"
version = "2.0.1"
@ -315,10 +390,18 @@ locale = ["Babel (>=1.3)"]
[metadata]
lock-version = "1.1"
python-versions = ">=3.9"
content-hash = "e938a304735e2b3e8ec26364f2494860d7d3e7df506f0d6f832f9fe123fbd54a"
python-versions = "^3.9"
content-hash = "db7a8f38d58cc2d8c8a1f7ca99dc8d3ab7a544b1b1899022c2bae7ffe5fa3aa2"
[metadata.files]
appdirs = [
{file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
{file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
]
black = [
{file = "black-21.5b2-py3-none-any.whl", hash = "sha256:e5cf21ebdffc7a9b29d73912b6a6a9a4df4ce70220d523c21647da2eae0751ef"},
{file = "black-21.5b2.tar.gz", hash = "sha256:1fc0e0a2c8ae7d269dfcf0c60a89afa299664f3e811395d40b1922dff8f854b5"},
]
blinker = [
{file = "blinker-1.4.tar.gz", hash = "sha256:471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6"},
]
@ -423,6 +506,10 @@ idna = [
{file = "idna-3.2-py3-none-any.whl", hash = "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a"},
{file = "idna-3.2.tar.gz", hash = "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"},
]
isort = [
{file = "isort-5.8.0-py3-none-any.whl", hash = "sha256:2bb1680aad211e3c9944dbce1d4ba09a989f04e238296c87fe2139faa26d655d"},
{file = "isort-5.8.0.tar.gz", hash = "sha256:0a943902919f65c5684ac4e0154b1ad4fac6dcaa5d9f3426b732f1c8b5419be6"},
]
itsdangerous = [
{file = "itsdangerous-2.0.1-py3-none-any.whl", hash = "sha256:5174094b9637652bdb841a3029700391451bd092ba3db90600dea710ba28e97c"},
{file = "itsdangerous-2.0.1.tar.gz", hash = "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0"},
@ -471,10 +558,18 @@ mccabe = [
{file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
]
mypy-extensions = [
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
]
passlib = [
{file = "passlib-1.7.4-py2.py3-none-any.whl", hash = "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1"},
{file = "passlib-1.7.4.tar.gz", hash = "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04"},
]
pathspec = [
{file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"},
{file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"},
]
pycodestyle = [
{file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"},
{file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"},
@ -483,6 +578,49 @@ pyflakes = [
{file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"},
{file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"},
]
regex = [
{file = "regex-2021.4.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:619d71c59a78b84d7f18891fe914446d07edd48dc8328c8e149cbe0929b4e000"},
{file = "regex-2021.4.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:47bf5bf60cf04d72bf6055ae5927a0bd9016096bf3d742fa50d9bf9f45aa0711"},
{file = "regex-2021.4.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:281d2fd05555079448537fe108d79eb031b403dac622621c78944c235f3fcf11"},
{file = "regex-2021.4.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:bd28bc2e3a772acbb07787c6308e00d9626ff89e3bfcdebe87fa5afbfdedf968"},
{file = "regex-2021.4.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:7c2a1af393fcc09e898beba5dd59196edaa3116191cc7257f9224beaed3e1aa0"},
{file = "regex-2021.4.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c38c71df845e2aabb7fb0b920d11a1b5ac8526005e533a8920aea97efb8ec6a4"},
{file = "regex-2021.4.4-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:96fcd1888ab4d03adfc9303a7b3c0bd78c5412b2bfbe76db5b56d9eae004907a"},
{file = "regex-2021.4.4-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:ade17eb5d643b7fead300a1641e9f45401c98eee23763e9ed66a43f92f20b4a7"},
{file = "regex-2021.4.4-cp36-cp36m-win32.whl", hash = "sha256:e8e5b509d5c2ff12f8418006d5a90e9436766133b564db0abaec92fd27fcee29"},
{file = "regex-2021.4.4-cp36-cp36m-win_amd64.whl", hash = "sha256:11d773d75fa650cd36f68d7ca936e3c7afaae41b863b8c387a22aaa78d3c5c79"},
{file = "regex-2021.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d3029c340cfbb3ac0a71798100ccc13b97dddf373a4ae56b6a72cf70dfd53bc8"},
{file = "regex-2021.4.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:18c071c3eb09c30a264879f0d310d37fe5d3a3111662438889ae2eb6fc570c31"},
{file = "regex-2021.4.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:4c557a7b470908b1712fe27fb1ef20772b78079808c87d20a90d051660b1d69a"},
{file = "regex-2021.4.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:01afaf2ec48e196ba91b37451aa353cb7eda77efe518e481707e0515025f0cd5"},
{file = "regex-2021.4.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:3a9cd17e6e5c7eb328517969e0cb0c3d31fd329298dd0c04af99ebf42e904f82"},
{file = "regex-2021.4.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:90f11ff637fe8798933fb29f5ae1148c978cccb0452005bf4c69e13db951e765"},
{file = "regex-2021.4.4-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:919859aa909429fb5aa9cf8807f6045592c85ef56fdd30a9a3747e513db2536e"},
{file = "regex-2021.4.4-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:339456e7d8c06dd36a22e451d58ef72cef293112b559010db3d054d5560ef439"},
{file = "regex-2021.4.4-cp37-cp37m-win32.whl", hash = "sha256:67bdb9702427ceddc6ef3dc382455e90f785af4c13d495f9626861763ee13f9d"},
{file = "regex-2021.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:32e65442138b7b76dd8173ffa2cf67356b7bc1768851dded39a7a13bf9223da3"},
{file = "regex-2021.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1e1c20e29358165242928c2de1482fb2cf4ea54a6a6dea2bd7a0e0d8ee321500"},
{file = "regex-2021.4.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:314d66636c494ed9c148a42731b3834496cc9a2c4251b1661e40936814542b14"},
{file = "regex-2021.4.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6d1b01031dedf2503631d0903cb563743f397ccaf6607a5e3b19a3d76fc10480"},
{file = "regex-2021.4.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:741a9647fcf2e45f3a1cf0e24f5e17febf3efe8d4ba1281dcc3aa0459ef424dc"},
{file = "regex-2021.4.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4c46e22a0933dd783467cf32b3516299fb98cfebd895817d685130cc50cd1093"},
{file = "regex-2021.4.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:e512d8ef5ad7b898cdb2d8ee1cb09a8339e4f8be706d27eaa180c2f177248a10"},
{file = "regex-2021.4.4-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:980d7be47c84979d9136328d882f67ec5e50008681d94ecc8afa8a65ed1f4a6f"},
{file = "regex-2021.4.4-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:ce15b6d103daff8e9fee13cf7f0add05245a05d866e73926c358e871221eae87"},
{file = "regex-2021.4.4-cp38-cp38-win32.whl", hash = "sha256:a91aa8619b23b79bcbeb37abe286f2f408d2f2d6f29a17237afda55bb54e7aac"},
{file = "regex-2021.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:c0502c0fadef0d23b128605d69b58edb2c681c25d44574fc673b0e52dce71ee2"},
{file = "regex-2021.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:598585c9f0af8374c28edd609eb291b5726d7cbce16be6a8b95aa074d252ee17"},
{file = "regex-2021.4.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:ee54ff27bf0afaf4c3b3a62bcd016c12c3fdb4ec4f413391a90bd38bc3624605"},
{file = "regex-2021.4.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7d9884d86dd4dd489e981d94a65cd30d6f07203d90e98f6f657f05170f6324c9"},
{file = "regex-2021.4.4-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:bf5824bfac591ddb2c1f0a5f4ab72da28994548c708d2191e3b87dd207eb3ad7"},
{file = "regex-2021.4.4-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:563085e55b0d4fb8f746f6a335893bda5c2cef43b2f0258fe1020ab1dd874df8"},
{file = "regex-2021.4.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9c3db21af35e3b3c05764461b262d6f05bbca08a71a7849fd79d47ba7bc33ed"},
{file = "regex-2021.4.4-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:3916d08be28a1149fb97f7728fca1f7c15d309a9f9682d89d79db75d5e52091c"},
{file = "regex-2021.4.4-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:fd45ff9293d9274c5008a2054ecef86a9bfe819a67c7be1afb65e69b405b3042"},
{file = "regex-2021.4.4-cp39-cp39-win32.whl", hash = "sha256:fa4537fb4a98fe8fde99626e4681cc644bdcf2a795038533f9f711513a862ae6"},
{file = "regex-2021.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:97f29f57d5b84e73fbaf99ab3e26134e6687348e95ef6b48cfd2c06807005a07"},
{file = "regex-2021.4.4.tar.gz", hash = "sha256:52ba3d3f9b942c49d7e4bc105bb28551c44065f139a65062ab7912bef10c9afb"},
]
sqlalchemy = [
{file = "SQLAlchemy-1.4.17-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:c367ed95d41df584f412a9419b5ece85b0d6c2a08a51ae13ae47ef74ff9a9349"},
{file = "SQLAlchemy-1.4.17-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:fdad4a33140b77df61d456922b7974c1f1bb2c35238f6809f078003a620c4734"},
@ -515,6 +653,10 @@ sqlalchemy = [
{file = "SQLAlchemy-1.4.17-cp39-cp39-win_amd64.whl", hash = "sha256:7eb55d5583076c03aaf1510473fad2a61288490809049cb31028af56af7068ee"},
{file = "SQLAlchemy-1.4.17.tar.gz", hash = "sha256:651cdb3adcee13624ba22d5ff3e96f91e16a115d2ca489ddc16a8e4c217e8509"},
]
toml = [
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
]
werkzeug = [
{file = "Werkzeug-2.0.1-py3-none-any.whl", hash = "sha256:6c1ec500dcdba0baa27600f6a22f6333d8b662d22027ff9f6202e3367413caa8"},
{file = "Werkzeug-2.0.1.tar.gz", hash = "sha256:1de1db30d010ff1af14a009224ec49ab2329ad2cde454c8a708130642d579c42"},

View file

@ -6,7 +6,7 @@ authors = ["Mohamad Bitar <mohamad.bit@protonmail.com>"]
readme = "README.md"
[tool.poetry.dependencies]
python = ">=3.9"
python = "^3.9"
Flask = ">=2.0.1"
Flask-SQLAlchemy = ">=2.5.1"
SQLAlchemy = ">=1.4.17"
@ -17,7 +17,15 @@ Flask-Admin = ">=1.5.8"
[tool.poetry.dev-dependencies]
flake8 = "*"
black = "*"
isort = "*"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.black]
line-length = 120
[tool.isort]
profile = "black"

View file

@ -1,5 +1,7 @@
from datetime import datetime
from flask_security import hash_password
from advlabdb import app, db, user_datastore
from advlabdb.models import *
@ -41,11 +43,29 @@ with app.app_context():
db.session.add(ps2)
db.session.add(ps3)
ex1 = Experiment(number=1, name="exp", room="123", building="phy", responsibility="none", duration_in_days=2,
oral_weighting=0.5, protocol_weighting=0.5, final_weighting=1)
ex1 = Experiment(
number=1,
name="exp",
room="123",
building="phy",
responsibility="none",
duration_in_days=2,
oral_weighting=0.5,
protocol_weighting=0.5,
final_weighting=1,
)
ex2 = Experiment(number=2, name="exp2", room="123", building="phy", responsibility="none", duration_in_days=2,
oral_weighting=0.5, protocol_weighting=0.5, final_weighting=1)
ex2 = Experiment(
number=2,
name="exp2",
room="123",
building="phy",
responsibility="none",
duration_in_days=2,
oral_weighting=0.5,
protocol_weighting=0.5,
final_weighting=1,
)
db.session.add(ex1)
db.session.add(ex2)
@ -70,8 +90,14 @@ with app.app_context():
us1 = user_datastore.create_user(email="test@protonmail.com", password=hash_password("h1"), roles=["assistant"])
us2 = user_datastore.create_user(email="test2@protonmail.com", password=hash_password("h2"), roles=["assistant"])
as1 = Assistant(first_name="As1", last_name="l", email="test@test.com", phone_number="012333212",
mobile_phone_number="012334123", user=us1)
as1 = Assistant(
first_name="As1",
last_name="l",
email="test@test.com",
phone_number="012333212",
mobile_phone_number="012334123",
user=us1,
)
as2 = Assistant(first_name="As2", last_name="l", email="test2@test.com", user=us2)
as1.part_experiments.append(px1)