diff --git a/models/database.py b/models/database.py index ca5842e22f05aa9cdfc03beafc34fea843ba9c67..61a441de7ac76c12355057554a6c47293deec0e5 100644 --- a/models/database.py +++ b/models/database.py @@ -7,6 +7,7 @@ from shared import db from sqlalchemy.orm import relationship, backref + class User(db.Model, UserMixin): __tablename__ = "users" id = db.Column(db.Integer, primary_key=True) @@ -16,7 +17,7 @@ class User(db.Model, UserMixin): roles = db.Column(db.PickleType) temp_key = db.Column(db.String) temp_key_timestamp = db.Column(db.DateTime) - + def __init__(self, fullname, username, password, roles=None): self.fullname = fullname self.username = username @@ -24,18 +25,19 @@ class User(db.Model, UserMixin): self.roles = roles self.temp_key = "" self.temp_key_timestamp = datetime(1970, 1, 1, 0, 0) - + def __repr__(self): return "<User(id={}, fullname='{}', username='{}', password='{}', roles={}, temp_key='{}', temp_key_timestamp={})>".format( - self.id, - self.fullname, - self.username, - self.password, + self.id, + self.fullname, + self.username, + self.password, self.roles, self.temp_key, - self.temp_key_timestamp + self.temp_key_timestamp, ) - + + class Event(db.Model): __tablename__ = "events" id = db.Column(db.Integer, primary_key=True) @@ -43,33 +45,37 @@ class Event(db.Model): paused = db.Column(db.Boolean) paused_until = db.Column(db.DateTime) current_topic_id = db.Column(db.Integer) - - topics = relationship("Topic", backref=backref("event"), cascade="all, delete-orphan") - speakers = relationship("Speaker", backref=backref("event"), cascade="all, delete-orphan") - + + topics = relationship( + "Topic", backref=backref("event"), cascade="all, delete-orphan" + ) + speakers = relationship( + "Speaker", backref=backref("event"), cascade="all, delete-orphan" + ) + def __init__(self, name, paused=False, current_topic_id=None): self.name = name self.paused = paused self.paused_until = datetime(1970, 1, 1) self.current_topic_id = current_topic_id or -1 - + def __repr__(self): return "<Event(id={}, name={}, paused={}, paused_until={})>".format( - self.id, - self.name, - self.paused, - self.paused_until + self.id, self.name, self.paused, self.paused_until ) - + def sorted_topics(self): return sorted(self.topics, key=lambda tp: tp.get_index()) - + def get_current_topic(self): - candidates = [topic for topic in self.topics if topic.id == self.current_topic_id] + candidates = [ + topic for topic in self.topics if topic.id == self.current_topic_id + ] if len(candidates) < 1: return None return candidates[0] + class Topic(db.Model): __tablename__ = "topics" id = db.Column(db.Integer, primary_key=True) @@ -78,34 +84,44 @@ class Topic(db.Model): event_id = db.Column(db.Integer, db.ForeignKey("events.id")) index = db.Column(db.Integer) - statements = relationship("Statement", backref=backref("topic"), cascade="all, delete-orphan") - + statements = relationship( + "Statement", backref=backref("topic"), cascade="all, delete-orphan" + ) + def __init__(self, name, mode, event_id): self.name = name self.mode = mode self.event_id = event_id self.index = None - + def __repr__(self): return "<Topic(id={}, name='{}', mode='{}', event_id={}, index={})>".format( - self.id, - self.name, - self.mode, - self.event_id, - self.index + self.id, self.name, self.mode, self.event_id, self.index ) - + def sorted_statements(self): - statements = [statement for statement in self.statements if not statement.executed] + statements = [ + statement for statement in self.statements if not statement.executed + ] if self.mode == "fifo": - return sorted(statements, key=lambda st:-2 if st.is_current else -1 if st.is_meta else st.id) + return sorted( + statements, + key=lambda st: -2 if st.is_current else -1 if st.is_meta else st.id, + ) elif self.mode == "balanced": - return sorted(statements, key=lambda st:(-2,st.id) if st.is_current else (-1,st.id) if st.is_meta else (st.speaker.count(self), st.id)) + return sorted( + statements, + key=lambda st: (-2, st.id) + if st.is_current + else (-1, st.id) + if st.is_meta + else (st.speaker.count(self), st.id), + ) elif self.mode == "random": - return sorted(statements, key=lambda st:random.random()) + return sorted(statements, key=lambda st: random.random()) else: return statements - + def swap_topics(self, other): other.index, self.index = self.get_index(), other.get_index() @@ -113,14 +129,14 @@ class Topic(db.Model): if self.index == None: return self.id return self.index - + def get_next_index(self): topics = self.event.sorted_topics() i = topics.index(self) + 1 if i >= len(topics): i = -1 return topics[i].id - + def get_previous_index(self): topics = self.event.sorted_topics() i = topics.index(self) - 1 @@ -128,6 +144,7 @@ class Topic(db.Model): i = 0 return topics[i].id + class Speaker(db.Model): __tablename__ = "speakers" id = db.Column(db.Integer, primary_key=True) @@ -135,21 +152,20 @@ class Speaker(db.Model): number = db.Column(db.Integer) event_id = db.Column(db.Integer, db.ForeignKey("events.id")) - statements = relationship("Statement", backref=backref("speaker"), cascade="all, delete-orphan") - + statements = relationship( + "Statement", backref=backref("speaker"), cascade="all, delete-orphan" + ) + def __init__(self, name, number, event_id): self.name = name self.number = number self.event_id = event_id - + def __repr__(self): return "<Speaker(id={}, number={}, name='{}', event_id={})>".format( - self.id, - self.number, - self.name, - self.event_id + self.id, self.number, self.name, self.event_id ) - + def identifier(self): if self.number == 0: return self.name @@ -157,16 +173,38 @@ class Speaker(db.Model): return self.number else: return "{} ({})".format(self.name, self.number) - + def count(self, topic): - return len([statement for statement in self.statements if statement.topic == topic and not statement.is_meta]) - + return len( + [ + statement + for statement in self.statements + if statement.topic == topic and not statement.is_meta + ] + ) + def count_active(self, topic): - return len([statement for statement in self.statements if statement.topic == topic and not statement.executed and not statement.is_meta]) - + return len( + [ + statement + for statement in self.statements + if statement.topic == topic + and not statement.executed + and not statement.is_meta + ] + ) + def count_active_meta(self, topic): - return len([statement for statement in self.statements if statement.topic == topic and not statement.executed and statement.is_meta]) - + return len( + [ + statement + for statement in self.statements + if statement.topic == topic + and not statement.executed + and statement.is_meta + ] + ) + class Statement(db.Model): __tablename__ = "statements" @@ -179,8 +217,16 @@ class Statement(db.Model): is_meta = db.Column(db.Boolean, default=False) is_current = db.Column(db.Boolean, default=False) - - def __init__(self, speaker_id, topic_id, insertion_time=None, executed=False, execution_time=None, is_meta=False, is_current=False): + def __init__( + self, + speaker_id, + topic_id, + insertion_time=None, + executed=False, + execution_time=None, + is_meta=False, + is_current=False, + ): self.speaker_id = speaker_id self.topic_id = topic_id self.insertion_time = insertion_time or datetime.now() @@ -188,33 +234,35 @@ class Statement(db.Model): self.execution_time = execution_time or datetime.now() self.is_meta = is_meta self.is_current = is_current - + def __repr__(self): return "<Statement(id={}, speaker={}, topic_id={}, insertion_time={}, executed={}, execution_time={}, is_meta={}, is_current={})>".format( - self.id, + self.id, self.speaker, self.topic_id, self.insertion_time, self.executed, self.execution_time, self.is_meta, - self.is_current + self.is_current, ) - + def done(self): if self.executed: return False self.executed = True self.is_current = False self.execution_time = datetime.now() - if self.topic.sorted_statements() is not None and self.topic.sorted_statements(): + if ( + self.topic.sorted_statements() is not None + and self.topic.sorted_statements() + ): self.topic.sorted_statements()[0].is_current = True return True - + def undo(self): if not self.executed: return False self.topic.sorted_statements()[0].is_current = False self.executed = False self.is_current = True - diff --git a/models/forms.py b/models/forms.py index a5ac485859d5091e4832feb0d2a8dc51ee38fab8..2b049f6764f44708aa28d929aa9a1041baea0172 100644 --- a/models/forms.py +++ b/models/forms.py @@ -1,41 +1,106 @@ from flask_wtf import Form -from wtforms import StringField, PasswordField, BooleanField, SelectMultipleField, SelectField, DateField, IntegerField, TextAreaField, HiddenField -from wtforms.validators import InputRequired, Length, EqualTo, Email, Optional, Length, NumberRange, AnyOf +from wtforms import ( + StringField, + PasswordField, + BooleanField, + SelectMultipleField, + SelectField, + DateField, + IntegerField, + TextAreaField, + HiddenField, +) +from wtforms.validators import ( + InputRequired, + Length, + EqualTo, + Email, + Optional, + Length, + NumberRange, + AnyOf, +) from models.database import User import shared class LoginForm(Form): - username = StringField("Username", validators=[InputRequired("Entering your username is required.")]) - password = PasswordField("Password", validators=[InputRequired("Entering your password is required.")]) + username = StringField( + "Username", validators=[InputRequired("Entering your username is required.")] + ) + password = PasswordField( + "Password", validators=[InputRequired("Entering your password is required.")] + ) remember_me = BooleanField("Remember me?") + class NewUserForm(Form): - fullname = StringField("Full name", validators=[InputRequired("Entering your name is required.")]) - username = StringField("Username", validators=[InputRequired("Entering your username is required.")]) - password = PasswordField("Password", validators=[InputRequired("Entering your password is required.")]) - confirm = PasswordField("Repeat Password", validators=[InputRequired("Entering your password is required."), EqualTo("password", message="Your passwords must match.")]) + fullname = StringField( + "Full name", validators=[InputRequired("Entering your name is required.")] + ) + username = StringField( + "Username", validators=[InputRequired("Entering your username is required.")] + ) + password = PasswordField( + "Password", validators=[InputRequired("Entering your password is required.")] + ) + confirm = PasswordField( + "Repeat Password", + validators=[ + InputRequired("Entering your password is required."), + EqualTo("password", message="Your passwords must match."), + ], + ) + class AdminUserForm(Form): - fullname = StringField("Full name", validators=[InputRequired("Entering the name is required.")]) - username = StringField("Username", validators=[InputRequired("Entering the username is required.")]) - roles = SelectMultipleField("User roles", choices=[(x.lower().strip(), x) for x in shared.roles]) + fullname = StringField( + "Full name", validators=[InputRequired("Entering the name is required.")] + ) + username = StringField( + "Username", validators=[InputRequired("Entering the username is required.")] + ) + roles = SelectMultipleField( + "User roles", choices=[(x.lower().strip(), x) for x in shared.roles] + ) + class AddStatementForm(Form): - speaker_name = StringField("Speaker", validators=[InputRequired("Entering the speaker name or number is required.")]) + speaker_name = StringField( + "Speaker", + validators=[InputRequired("Entering the speaker name or number is required.")], + ) topic = HiddenField("Topic") - + + class EditSpeakerForm(Form): - name = StringField("Speaker", validators=[InputRequired("Entering the speaker is required.")]) + name = StringField( + "Speaker", validators=[InputRequired("Entering the speaker is required.")] + ) number = IntegerField("Number", validators=[Optional(), NumberRange(min=0)]) topic_id = HiddenField("Topic_id") id = HiddenField("Speaker_id") + class NewEventForm(Form): - name = StringField("Name", validators=[InputRequired("Entering the name is required.")]) + name = StringField( + "Name", validators=[InputRequired("Entering the name is required.")] + ) + class NewTopicForm(Form): - name = StringField("Name", validators=[InputRequired("Entering the name is required.")]) - mode = StringField("Mode", validators=[InputRequired("Entering the mode is required."), AnyOf(values=["balanced", "fifo", "random"], message="Must be 'balanced', 'fifo' or 'random' atm.")]) + name = StringField( + "Name", validators=[InputRequired("Entering the name is required.")] + ) + mode = StringField( + "Mode", + validators=[ + InputRequired("Entering the mode is required."), + AnyOf( + values=["balanced", "fifo", "random"], + message="Must be 'balanced', 'fifo' or 'random' atm.", + ), + ], + ) event_id = HiddenField("Event_id") diff --git a/modules/admin.py b/modules/admin.py index be99b00e9a503369f5b21601e62356144f8d4369..158a1e01152c00a92841c5da4fc29d8e30c7599a 100644 --- a/modules/admin.py +++ b/modules/admin.py @@ -1,11 +1,27 @@ -from flask import Blueprint, redirect, url_for, request, flash, abort, send_file, Response +from flask import ( + Blueprint, + redirect, + url_for, + request, + flash, + abort, + send_file, + Response, +) from flask_login import login_required from passlib.hash import pbkdf2_sha256 from datetime import datetime, timedelta from models.database import User, Topic, Event, Speaker, Statement -from models.forms import AdminUserForm, NewUserForm, NewTopicForm, NewEventForm, AddStatementForm, EditSpeakerForm +from models.forms import ( + AdminUserForm, + NewUserForm, + NewTopicForm, + NewEventForm, + AddStatementForm, + EditSpeakerForm, +) from shared import db, admin_permission from utils import render_layout, speaker_by_name_or_number @@ -21,6 +37,7 @@ def index(): events = Event.query.limit(10).all() return render_layout("admin_index.html", users=users, events=events) + @admin.route("/user/") @login_required @admin_permission.require() @@ -28,6 +45,7 @@ def user(): users = User.query.all() return render_layout("admin_user_index.html", users=users) + @admin.route("/user/edit", methods=["GET", "POST"]) @login_required @admin_permission.require() @@ -44,7 +62,7 @@ def user_edit(): return render_layout("admin_user_edit.html", form=form, id=user_id) else: return redirect(url_for(".index")) - + @admin.route("/user/delete") @login_required @@ -58,26 +76,30 @@ def user_delete(): flash("User deleted.", "alert-success") return redirect(url_for(".user")) + @admin.route("/user/new", methods=["GET", "POST"]) @login_required @admin_permission.require() def user_new(): form = NewUserForm() if form.validate_on_submit(): - password_hash = pbkdf2_sha256.encrypt(form.password.data, rounds=200000, salt_size=16) + password_hash = pbkdf2_sha256.encrypt( + form.password.data, rounds=200000, salt_size=16 + ) user = User(form.fullname.data, form.username.data, password_hash) db.session.add(user) db.session.commit() return redirect(url_for(".user")) return render_layout("admin_user_new.html", form=form) + @admin.route("/event/") @login_required @admin_permission.require() def event(): events = Event.query.all() return render_layout("admin_event_index.html", events=events) - + @admin.route("/event/show") @login_required @@ -118,6 +140,7 @@ def event_delete(): flash("Event deleted.", "alert-success") return redirect(url_for(".event")) + @admin.route("/event/edit", methods=["GET", "POST"]) @login_required @admin_permission.require() @@ -149,10 +172,24 @@ def topic_show(): form.topic.data = topic.id statements = topic.sorted_statements() topics = topic.event.sorted_topics() - can_undo = len(Statement.query.filter_by(executed=True, topic_id=topic_id).order_by(db.desc(Statement.execution_time)).all()) > 0 - return render_layout("admin_topic_show.html", topic=topic, form=form, statements=statements, topics=topics, can_undo_statement=can_undo) + can_undo = ( + len( + Statement.query.filter_by(executed=True, topic_id=topic_id) + .order_by(db.desc(Statement.execution_time)) + .all() + ) + > 0 + ) + return render_layout( + "admin_topic_show.html", + topic=topic, + form=form, + statements=statements, + topics=topics, + can_undo_statement=can_undo, + ) return redirect(url_for(".index")) - + @admin.route("/topic/new", methods=["GET", "POST"]) @login_required @@ -174,18 +211,20 @@ def topic_new(): form.event_id.data = event_id return render_layout("admin_topic_new.html", form=form, event=event) + @admin.route("/topic/delete") @login_required @admin_permission.require() def topic_delete(): topic_id = request.args.get("id", None) if topic_id is not None: - topic = Topic.query.filter_by(id=topic_id).first() + topic = Topic.query.filter_by(id=topic_id).first() db.session.delete(topic) db.session.commit() flash("Topic deleted.", "alert-success") return redirect(url_for(".topic")) + @admin.route("/topic/edit", methods=["GET", "POST"]) @login_required @admin_permission.require() @@ -203,6 +242,7 @@ def topic_edit(): else: return redirect(url_for(".index")) + @admin.route("/topic/") @login_required @admin_permission.require() @@ -210,6 +250,7 @@ def topic(): topics = Topic.query.all() return render_layout("admin_topic_index.html", topics=topics) + @admin.route("/topic/swap/up") @login_required @admin_permission.require() @@ -221,11 +262,12 @@ def topic_swap_up(): topics = topic.event.sorted_topics() index = topics.index(topic) if index != 0: - topic.swap_topics(topics[index-1]) + topic.swap_topics(topics[index - 1]) db.session.commit() return redirect(url_for(".topic_show", id=original_id)) return redirect(url_for(".index")) + @admin.route("/topic/swap/down") @login_required @admin_permission.require() @@ -237,35 +279,37 @@ def topic_swap_down(): topics = topic.event.sorted_topics() index = topics.index(topic) if index != len(topics) - 1: - topic.swap_topics(topics[index+1]) + topic.swap_topics(topics[index + 1]) db.session.commit() return redirect(url_for(".topic_show", id=original_id)) return redirect(url_for(".index")) + @admin.route("/speaker/rename", methods=["GET", "POST"]) @login_required @admin_permission.require() def speaker_edit(): - #speaker = Speaker.query.filter_by(number=number,event).first() - #if speaker is not None: - #id=statement.speaker.identifier(), topic_id=topic.id) + # speaker = Speaker.query.filter_by(number=number,event).first() + # if speaker is not None: + # id=statement.speaker.identifier(), topic_id=topic.id) speaker_id = request.args.get("id", None) topic_id = request.args.get("topic_id", None) speaker = Speaker.query.filter_by(id=speaker_id).first() form = EditSpeakerForm(obj=speaker) - form.topic_id.data=topic_id - + form.topic_id.data = topic_id + if speaker is not None: if form.validate_on_submit(): speaker.name = form.name.data speaker.number = form.number.data db.session.commit() - return redirect(url_for(".topic_show",id=form.topic_id.data)) - else: - return render_layout("admin_speaker_edit.html", form=form, speaker=speaker, topic_id=topic_id) + return redirect(url_for(".topic_show", id=form.topic_id.data)) + else: + return render_layout( + "admin_speaker_edit.html", form=form, speaker=speaker, topic_id=topic_id + ) else: return redirect(url_for(".index")) - @admin.route("/statement/") @@ -275,26 +319,33 @@ def statement(): statements = Statement.query.all() return render_layout("admin_statement_index.html", statement=statement) + @admin.route("/statement/new", methods=["GET", "POST"]) @login_required @admin_permission.require() def statement_new(): form = AddStatementForm() if form.validate_on_submit(): - statement = request.form.get("submit","add_statement") + statement = request.form.get("submit", "add_statement") topic = Topic.query.filter_by(id=form.topic.data).first() speaker = speaker_by_name_or_number(form.speaker_name.data, topic.event.id) if topic is not None and speaker is not None: - if speaker.count_active(topic) == 0 or (statement == "add_meta_statement" - and speaker.count_active_meta(topic) == 0) : - statement = Statement(speaker.id, topic.id, - is_meta=(statement == "add_meta_statement"), - is_current=(not topic.sorted_statements())) + if speaker.count_active(topic) == 0 or ( + statement == "add_meta_statement" + and speaker.count_active_meta(topic) == 0 + ): + statement = Statement( + speaker.id, + topic.id, + is_meta=(statement == "add_meta_statement"), + is_current=(not topic.sorted_statements()), + ) db.session.add(statement) db.session.commit() return redirect(url_for(".topic_show", id=topic.id)) return render_layout("admin_statement_new.html", form=form) + @admin.route("/statement/done") @login_required @admin_permission.require() @@ -310,6 +361,7 @@ def statement_done(): return redirect(url_for(".topic_show", id=topic_id)) return redirect(url_for(".index")) + @admin.route("/statement/delete") @login_required @admin_permission.require() @@ -320,7 +372,7 @@ def statement_delete(): statement = Statement.query.filter_by(id=statement_id).first() if statement is not None: topic = Topic.query.filter_by(id=topic_id).first() - if len(topic.sorted_statements()) > 1: + if len(topic.sorted_statements()) > 1: topic.sorted_statements()[1].is_current = True db.session.delete(statement) db.session.commit() @@ -328,17 +380,23 @@ def statement_delete(): return redirect(url_for(".topic_show", id=topic_id)) return redirect(url_for(".index")) + @admin.route("/statement/undo") @login_required @admin_permission.require() def statement_undo(): topic_id = request.args.get("topic_id", None) if topic_id is not None: - statement = Statement.query.filter_by(executed=True, topic_id=topic_id).order_by(db.desc(Statement.execution_time)).first() + statement = ( + Statement.query.filter_by(executed=True, topic_id=topic_id) + .order_by(db.desc(Statement.execution_time)) + .first() + ) statement.undo() db.session.commit() return redirect(url_for(".topic_show", id=topic_id)) + @admin.route("/pause", methods=["GET", "POST"]) @login_required @admin_permission.require() @@ -354,7 +412,7 @@ def pause(): rawtime = float(request.form["timeslider"]) delta = timedelta(seconds=rawtime) print(delta) - event.paused_until = datetime.now() + delta + event.paused_until = datetime.now() + delta db.session.commit() topic_id = request.args.get("original", None) return redirect(url_for(".topic_show", id=topic_id)) diff --git a/modules/speech.py b/modules/speech.py index 5a5d84bc0ff9ce421c0ed32d07ad4fb500e4c892..af5e5ff0c6c53f8b06329f99e1e3c03e9a29c3bb 100644 --- a/modules/speech.py +++ b/modules/speech.py @@ -1,4 +1,13 @@ -from flask import Blueprint, redirect, url_for, request, flash, abort, send_file, Response +from flask import ( + Blueprint, + redirect, + url_for, + request, + flash, + abort, + send_file, + Response, +) from flask_login import login_required from models.database import User, Statement, Speaker, Topic, Event @@ -25,7 +34,12 @@ def index(): events.append(event) else: events = Event.query.all() - return render_layout("speech_index.html", events=events, event=-1 if len(events) != 1 else events[0].id) + return render_layout( + "speech_index.html", + events=events, + event=-1 if len(events) != 1 else events[0].id, + ) + @speech.route("/update") def update(): @@ -39,6 +53,7 @@ def update(): events = Event.query.all() return render_layout("speech_content_index.html", events=events) + @speech.route("/update_index.js") def update_index_js(): update_interval = config.UPDATE_INDEX_INTERVAL or 1 @@ -46,4 +61,14 @@ def update_index_js(): mode = request.args.get("mode", None) event_id = request.args.get("event", -1) target_url = url_for(".update", event=event_id) - return render_layout("update.js", update_interval=update_interval, div=div, target_url=target_url, prefix="update_index_"), 200, {'Content-Type': 'text/javascript; charset=utf-8'} + return ( + render_layout( + "update.js", + update_interval=update_interval, + div=div, + target_url=target_url, + prefix="update_index_", + ), + 200, + {"Content-Type": "text/javascript; charset=utf-8"}, + ) diff --git a/server.py b/server.py index 9e3492887ea3efef141bd3435694c7378b2da391..146aaa94de7e7ceeb2f98b6184e67a8a515a08d8 100755 --- a/server.py +++ b/server.py @@ -1,9 +1,29 @@ #!/usr/bin/env python3 -from flask import Flask, g, current_app, request, session, flash, redirect, url_for, abort, render_template, Response +from flask import ( + Flask, + g, + current_app, + request, + session, + flash, + redirect, + url_for, + abort, + render_template, + Response, +) import click from flask_login import login_user, logout_user, login_required, current_user -from flask_principal import Principal, Identity, AnonymousIdentity, identity_changed, identity_loaded, UserNeed, RoleNeed +from flask_principal import ( + Principal, + Identity, + AnonymousIdentity, + identity_changed, + identity_loaded, + UserNeed, + RoleNeed, +) from flask_migrate import Migrate from passlib.hash import pbkdf2_sha256 @@ -28,6 +48,7 @@ from modules import admin, speech app.register_blueprint(admin.admin, url_prefix="/admin") app.register_blueprint(speech.speech, url_prefix="/speech") + @app.cli.command() @click.option("--username", prompt=True) @click.option("--realname", prompt=True) @@ -42,6 +63,7 @@ def addadmin(username, realname, password): else: print("The provided data was invalid.") + @app.cli.command() @click.option("--username", prompt=True) @click.option("--realname", prompt=True) @@ -57,58 +79,92 @@ def adduser(): else: print("The provided data was invalid.") + @app.route("/") def index(): events = Event.query.all() return render_layout("index.html", events=events) + @app.route("/update") def update(): events = Event.query.all() return render_layout("content_index.html", events=events) - + + @app.route("/update.js") def update_js(): update_interval = config.UPDATE_INDEX_INTERVAL or 1 div = "rede-content-div" target_url = url_for(".update") - return render_layout("update.js", update_interval=update_interval, div=div, target_url=target_url, prefix="index_"), 200, {'Content-Type': 'text/javascript; charset=utf-8'} + return ( + render_layout( + "update.js", + update_interval=update_interval, + div=div, + target_url=target_url, + prefix="index_", + ), + 200, + {"Content-Type": "text/javascript; charset=utf-8"}, + ) + @app.route("/update_time") def update_time(): return render_layout("content_time.html") + @app.route("/update_time.js") def update_time_js(): update_interval = config.UPDATE_TIME_INTERVAL or 10 div = "rede-time-div" target_url = url_for("update_time") - return render_layout("update.js", update_interval=update_interval, div=div, target_url=target_url, prefix="time_"), 200, {'Content-Type': 'text/javascript; charset=utf-8'} + return ( + render_layout( + "update.js", + update_interval=update_interval, + div=div, + target_url=target_url, + prefix="time_", + ), + 200, + {"Content-Type": "text/javascript; charset=utf-8"}, + ) + @app.route("/login", methods=["GET", "POST"]) def login(): form = LoginForm() if form.validate_on_submit(): user = db.session.query(User).filter_by(username=form.username.data).first() - if (user is not None) and (pbkdf2_sha256.verify(form.password.data, user.password)): + if (user is not None) and ( + pbkdf2_sha256.verify(form.password.data, user.password) + ): login_user(user, remember=form.remember_me.data) - identity_changed.send(current_app._get_current_object(), identity=Identity(user.id)) + identity_changed.send( + current_app._get_current_object(), identity=Identity(user.id) + ) flash("Welcome back, {}!".format(user.fullname), "alert-success") return redirect(request.args.get("next") or url_for(".index")) else: flash("Invalid username or wrong password", "alert-error") return render_layout("login.html", form=form) + @app.route("/logout", methods=["GET", "POST"]) @login_required def logout(): logout_user() for key in ("identity.name", "identiy.auth_type"): session.pop(key, None) - identity_changed.send(current_app._get_current_object(), identity=AnonymousIdentity()) + identity_changed.send( + current_app._get_current_object(), identity=AnonymousIdentity() + ) flash("You have been logged out.", "alert-success") return redirect(url_for(".index")) + """ @app.route("/register", methods=["GET", "POST"]) def register(): @@ -127,28 +183,32 @@ def register(): return render_layout("register.html", form=form) """ + @app.route("/icon-font.css") def icon_font(): return Response(render_template("icon-font.css"), mimetype="text/css") + @identity_loaded.connect_via(app) def on_identity_loaded(sender, identity): # Set the identity user object identity.user = current_user - + # Add the UserNeed to the identity if hasattr(current_user, "id"): identity.provides.add(UserNeed(current_user.id)) - + # Assuming the User Model has a list of roles, update the identity # with the roles that the user provides if hasattr(current_user, "roles") and current_user.roles is not None: for role in current_user.roles: identity.provides.add(RoleNeed(role)) + @login_manager.user_loader def load_user(user_id): return db.session.query(User).filter_by(id=user_id).first() + if __name__ == "__main__": app.run() diff --git a/shared.py b/shared.py index 9d3b32f459829cc24d8ec05a8c56e7f1d8c2cc74..8e0726e78beff4587f805ee02c97ecd6c7db3ce9 100644 --- a/shared.py +++ b/shared.py @@ -8,4 +8,3 @@ login_manager = LoginManager() admin_permission = Permission(RoleNeed("admin")) user_permission = Permission(RoleNeed("user")) roles = ["user", "admin"] - diff --git a/utils.py b/utils.py index b41f856e0d4169020e22c54a7cc975da5a2e3171..43b5cbfe211b1ac08506d4ff2d936eee35a80f67 100644 --- a/utils.py +++ b/utils.py @@ -5,10 +5,12 @@ from models.database import Speaker from shared import db + def render_layout(template, **kwargs): current_time = datetime.now() return render_template(template, current_time=current_time, **kwargs) - + + def speaker_by_name_or_number(name_or_number, event_id): if name_or_number.isnumeric(): number = int(name_or_number) @@ -30,4 +32,3 @@ def speaker_by_name_or_number(name_or_number, event_id): db.session.add(speaker) db.session.commit() return speaker -