diff --git a/models/database.py b/models/database.py index 08812fa9aa7e987129317f2f448b8a2a3030f76f..be7200331ef098de24ab7b38427990ebb6fca7a2 100644 --- a/models/database.py +++ b/models/database.py @@ -34,44 +34,68 @@ class User(db.Model, UserMixin): ) +class Event(db.Model): + __tablename__ = "events" + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String, unique=True) + date = db.Column(db.Date) + + def __init__(self, name, date): + self.name = name + self.date = date + + def __repr__(self): + return "<Event(id={}, name='{}', date={})>".format( + self.id, + self.name, + self.date + ) + + class Speaker(db.Model): __tablename__ = "speakers" id = db.Column(db.Integer, primary_key=True) - name = db.Column(db.String, unique=True) + name = db.Column(db.String) + event = db.Column(db.Integer, db.ForeignKey("events.id"), nullable=False) - def __init__(self, name): + def __init__(self, name, event): self.name = name + self.event = event def __repr__(self): - return "<Speaker(id={}, name={})>".format(self.id, self.name) + return "<Speaker(id={}, name={}, event={})>".format( + self.id, + self.name, + self.event + ) class Statement(db.Model): __tablename__ = "statements" id = db.Column(db.Integer, primary_key=True) speaker = db.Column(db.Integer, db.ForeignKey("speakers.id"), nullable=False) + event = db.Column(db.Integer, db.ForeignKey("events.id"), nullable=False) insertion_time = db.Column(db.DateTime) executed = db.Column(db.Boolean) execution_time = db.Column(db.DateTime) - def __init__(self, speaker, insertion_time=None, executed=False, execution_time=None): + def __init__(self, speaker, event, insertion_time=None, executed=False, execution_time=None): self.speaker = speaker + self.event = event self.insertion_time = insertion_time or datetime.now() self.executed = executed self.execution_time = execution_time or datetime.now() def __repr__(self): - return "<Statement(id={}, speaker={}, insertion_time={}, executed={}, execution_time={})>".format( + return "<Statement(id={}, speaker={}, event={}, insertion_time={}, executed={}, execution_time={})>".format( self.id, self.speaker, + self.event, self.insertion_time, self.executed, self.execution_time ) - def dump(self): - return { "speaker": self.speaker, "insertion_time": self.insertion_time.timestamp(), "executed": self.executed, "execution_time": self.execution_time.timestamp() } - def done(self): if self.executed: return False diff --git a/models/forms.py b/models/forms.py index a1e163ffc78bd4492414e244d674c8edf6a5001c..5a1072e08bd23878c57db07e6bcc2d9ab3cdc1f4 100644 --- a/models/forms.py +++ b/models/forms.py @@ -1,5 +1,5 @@ from flask.ext.wtf import Form -from wtforms import StringField, PasswordField, BooleanField, SelectMultipleField, SelectField, DateField, IntegerField, TextAreaField +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 @@ -24,3 +24,8 @@ class AdminUserForm(Form): class AddStatementForm(Form): speaker_name = StringField("Speaker", validators=[InputRequired("Entering the speaker is required.")]) + event = HiddenField("Event") + +class NewEventForm(Form): + name = StringField("Name", validators=[InputRequired("Entering the name is required.")]) + date = DateField("Date (DD.MM.YYYY)", validators=[InputRequired("Entering the date is required.")], format="%d.%m.%Y") diff --git a/modules/admin.py b/modules/admin.py index 8775e4bcc4d8ce88ba7f0944b0aae7d0cd0c516d..876457fe4b8196b117e3254e435862c8e9c9f74f 100644 --- a/modules/admin.py +++ b/modules/admin.py @@ -2,8 +2,8 @@ from flask import Blueprint, render_template, redirect, url_for, request, flash, from flask.ext.login import login_required from passlib.hash import pbkdf2_sha256 -from models.database import User -from models.forms import AdminUserForm, NewUserForm +from models.database import User, Event +from models.forms import AdminUserForm, NewUserForm, NewEventForm from shared import db, admin_permission @@ -15,7 +15,8 @@ admin = Blueprint("admin", __name__) @admin_permission.require() def index(): users = User.query.limit(10).all() - return render_template("admin_index.html", users=users) + events = Event.query.limit(10).all() + return render_template("admin_index.html", users=users, events=events) @admin.route("/user/") @login_required @@ -66,3 +67,56 @@ def user_new(): db.session.commit() return redirect(url_for(".user")) return render_template("admin_user_new.html", form=form) + + +@admin.route("/event/new", methods=["GET", "POST"]) +@login_required +@admin_permission.require() +def event_new(): + form = NewEventForm() + if form.validate_on_submit(): + if Event.query.filter_by(name=form.name.data).count() > 0: + flash("There already is an event with that name.", "alert-error") + return render_template("admin_event_new.html", form=form) + event = Event(form.name.data, form.date.data) + db.session.add(event) + db.session.commit() + return redirect(url_for(".event")) + return render_template("admin_event_new.html", form=form) + +@admin.route("/event/delete") +@login_required +@admin_permission.require() +def event_delete(): + event_id = request.args.get("id", None) + if event_id is not None: + event = Event.query.filter_by(id=event_id).first() + db.session.delete(event) + db.session.commit() + flash("Event deleted.", "alert-success") + return redirect(url_for(".event")) + +@admin.route("/event/edit", methods=["GET", "POST"]) +@login_required +@admin_permission.require() +def event_edit(): + event_id = request.args.get("id", None) + if event_id is not None: + event = db.session.query(Event).filter_by(id=event_id).first() + form = NewEventForm(obj=event) + if form.validate_on_submit(): + form.populate_obj(event) + db.session.commit() + return redirect(url_for(".index")) + else: + return render_template("admin_event_edit.html", form=form, id=event_id) + else: + return redirect(url_for(".index")) + +@admin.route("/event/") +@login_required +@admin_permission.require() +def event(): + events = Event.query.all() + print(events) + return render_template("admin_event_index.html", events=events) diff --git a/modules/speech.py b/modules/speech.py index 437c3425c0519919a78d30c9f4e7d17666539b84..ee0ab5d55648c9ae416f1016bd917c8f6c36c1e3 100644 --- a/modules/speech.py +++ b/modules/speech.py @@ -1,7 +1,7 @@ from flask import Blueprint, render_template, redirect, url_for, request, flash, abort, send_file, Response from flask.ext.login import login_required -from models.database import User, Statement, Speaker +from models.database import User, Statement, Speaker, Event from models.forms import AddStatementForm from shared import db, admin_permission, user_permission @@ -15,36 +15,59 @@ def transpose(arr): print(list) return list(map(list, zip(*arr))) -def query_statements(mode): +def query_statements(mode, event_id): statements = [] if mode == "pending": - statements = db.session.query(Statement, Speaker, db.func.count(Statement.speaker).label("total")).group_by(Speaker.id).join(Speaker).order_by("total ASC", Statement.insertion_time).all() + statements = db.session.query(Statement, Speaker, db.func.count(Statement.speaker).label("total")).group_by(Speaker.id).join(Speaker).filter(Statement.event == event_id).order_by("total ASC", Statement.insertion_time).all() elif mode == "all": - statements = db.session.query(Statement, Speaker).join(Speaker).order_by(Statement.insertion_time).all() + statements = db.session.query(Statement, Speaker).join(Speaker).filter(Statement.event == event_id).order_by(Statement.insertion_time).all() elif mode == "past": - statements = db.session.query(Statement, Speaker).join(Speaker).filter(Statement.executed == True).order_by(Statement.execution_time).all() + statements = db.session.query(Statement, Speaker).join(Speaker).filter(Statement.executed == True).filter(Statement.event == event_id).order_by(Statement.execution_time).all() return statements @speech.route("/index") def index(): mode = request.args.get("mode", "pending") - statements = query_statements(mode) - add_form = AddStatementForm() - current = ".index" - return render_template("speech_index.html", statements=statements, add_form=add_form, current=current) + event_id = request.args.get("event", None) + meta = [] + if event_id is not None and event_id != "-1": + event = Event.query.filter_by(id=event_id).first() + form = AddStatementForm() + form.event.data = event.id + meta.append((query_statements(mode, event_id), form, event)) + else: + for event in Event.query.all(): + form = AddStatementForm() + form.event.data = event.id + meta.append((query_statements(mode, event.id), form, event)) + event_id = -1 + return render_template("speech_index.html", meta=meta, event_id=event_id) @speech.route("/show") def show(): mode = request.args.get("mode", "pending") - statements = query_statements(mode) - current = ".show" - return render_template("speech_show.html", statements=statements, current=current, mode=mode) + event_id = request.args.get("event", None) + meta = [] + if event_id is not None and event_id is not "-1": + event = Event.query.filter_by(id=event_id).first() + meta.append((query_statements(mode, event_id), event)) + else: + for event in Event.query.all(): + meta.append((query_statements(mode, event.id), event)) + return render_template("speech_show.html", mode=mode, meta=meta, event_id=event_id) @speech.route("/update") def update(): - mode = request.args.get("mode", "pending") - statements = query_statements(mode) - return render_template("speech_update_show.html", statements=statements, mode=mode) + mode = request.args.get("mode", "pending") + event_id = request.args.get("event", None) + meta = [] + if event_id is not None and event_id != "-1": + event = Event.query.filter_by(id=event_id).first() + meta.append((query_statements(mode, event_id), event)) + else: + for event in Event.query.all(): + meta.append((query_statements(mode, event.id), event)) + return render_template("speech_update_show.html", mode=mode, meta=meta) @speech.route("/add", methods=["GET", "POST"]) @@ -54,28 +77,31 @@ def add(): add_form = AddStatementForm() if add_form.validate_on_submit(): speaker_name = add_form["speaker_name"].data - if speaker_name is None: - flash("Missing speaker name", "alert-error") - return redirect(url_for(".show")) - speaker = Speaker.query.filter_by(name=speaker_name).first() + event_id = add_form["event"].data + if speaker_name is None or event_id is None: + flash("Missing data", "alert-error") + return redirect(url_for(".index")) + speaker = Speaker.query.filter_by(name=speaker_name).filter_by(event=event_id).first() if not speaker: - speaker = Speaker(speaker_name) + speaker = Speaker(speaker_name, event_id) db.session.add(speaker) db.session.commit() - if Statement.query.filter_by(speaker=speaker.id).filter_by(executed=False).count() > 0: + if Statement.query.filter_by(speaker=speaker.id).filter_by(event=event_id).filter_by(executed=False).count() > 0: flash("Speaker already listet", "alert-error") return redirect(url_for(request.args.get("next") or ".show")) - statement = Statement(speaker.id) + statement = Statement(speaker.id, event_id) db.session.add(statement) db.session.commit() mode = request.args.get("mode", "pending") - return redirect(url_for(request.args.get("next") or ".index", mode=mode)) + event_id = request.args.get("event", None) + return redirect(url_for(request.args.get("next") or ".index", mode=mode, event=event_id)) @speech.route("/cancel") @user_permission.require() def cancel(): statement_id = request.args.get("statement", None) + event_id = request.args.get("event", -1) if not statement_id: flash("Missing statement id", "alert-error") return redirect(url_for(request.args.get("next") or ".index")) @@ -84,12 +110,13 @@ def cancel(): db.session.commit() flash("Statement canceled", "alert-success") mode = request.args.get("mode", "pending") - return redirect(url_for(request.args.get("next") or ".index", mode=mode)) + return redirect(url_for(request.args.get("next") or ".index", mode=mode, event=event_id)) @speech.route("/done") @user_permission.require() def done(): statement_id = request.args.get("statement", None) + event_id = request.args.get("event", -1) if not statement_id: flash("Missing statement id", "alert-error") return redirect(url_for(request.args.get("next") or ".index")) @@ -99,10 +126,11 @@ def done(): else: flash("Statement already done", "alert-error") mode = request.args.get("mode", "pending") - return redirect(url_for(request.args.get("next") or ".index", mode=mode)) + return redirect(url_for(request.args.get("next") or ".index", mode=mode, event=event_id)) @speech.route("/update_show.js") def update_show_js(): mode = request.args.get("mode", "pending") - return render_template("update_show.js", mode=mode) + event_id = request.args.get("event", -1) + return render_template("update_show.js", mode=mode, event_id=event_id) diff --git a/server.py b/server.py index 2d5afbd095f79fce281325e4908acbdd0fd2b92e..941869c8479bdf2dc1c1408c69fa69cb92e57ef0 100755 --- a/server.py +++ b/server.py @@ -8,7 +8,7 @@ from passlib.hash import pbkdf2_sha256 import config from shared import db, login_manager from models.forms import LoginForm, NewUserForm -from models.database import User, Statement, Speaker +from models.database import User, Statement, Speaker, Event app = Flask(__name__) app.config.from_object(config) @@ -34,8 +34,23 @@ def index(): user = User(fullname, username, password, ["admin", "user"]) db.session.add(user) db.session.commit() - #return render_template("index.html") - return redirect(url_for("speech.show", mode="pending")) + events = Event.query.all() + meta = [] + for event in events: + meta.append(([ (statement, speaker, count) for (statement, speaker, count) in speech.query_statements("pending", event.id) if not statement.executed ][0], event)) + return render_template("index.html", meta=meta) + +@app.route("/update") +def update(): + events = Event.query.all() + meta = [] + for event in events: + meta.append(([ (statement, speaker, count) for (statement, speaker, count) in speech.query_statements("pending", event.id) if not statement.executed ][0], event)) + return render_template("update_index.html", meta=meta) + +@app.route("/update.js") +def update_js(): + return render_template("update_index.js") @app.route("/login", methods=["GET", "POST"]) def login(): diff --git a/templates/admin_event_edit.html b/templates/admin_event_edit.html new file mode 100644 index 0000000000000000000000000000000000000000..5af4db2c72dfcf8022e4bc81df252f79f074cdec --- /dev/null +++ b/templates/admin_event_edit.html @@ -0,0 +1,7 @@ +{% extends "layout.html" %} +{% from "macros.html" import render_form %} +{% block title %}Edit Event - Administration{% endblock %} + +{% block content %} + {{ render_form(form, action_url=url_for(".event_edit", id=id), action_text="Apply", title="Edit Event") }} +{% endblock %} diff --git a/templates/admin_event_index.html b/templates/admin_event_index.html new file mode 100644 index 0000000000000000000000000000000000000000..63e58870188f12925bc801a43ed5d7dbf7579651 --- /dev/null +++ b/templates/admin_event_index.html @@ -0,0 +1,36 @@ +{% extends "admin_index.html" %} +{% block admin_title %}Events{% endblock %} + +{% block content %} + <div class="mdl-cell mdl-cell--3-col mdl-grid mdl-grid--no-spacing"> + <table class="mdl-data-table mdl-js-table mdl-shadow--2dp mdl-cell mdl-cell--3-col"> + <thead> + <tr> + <th class="mdl-data-table__cell--non-numeric">Name</th> + <th class="mdl-data-table__cell--non-numeric">Date</th> + <th class="mdl-data-table__cell--non-numeric">Delete</th> + </tr> + </thead> + <tbody> + {% for event in events %} + <tr> + <td class="mdl-data-table__cell--non-numeric"><a href="{{ url_for(".event_edit", id=event.id) }}">{{ event.name }}</a></td> + <td class="mdl-data-table__cell--non-numeric">{{ event.date.strftime("%d.%m.%Y") }}</td> + <td class="mdl-data-table__cell--non-numeric"> + <a href="{{ url_for('.event_delete', id=event.id) }}"> + <i class="material-icons">delete</i> + </a> + </td> + </tr> + {% endfor %} + </tbody> + </table> + <div class="rede-separator"> + <div class="mdl-cell mdl-cell--1-col"> + <a class="mdl-button mdl-button--colored mdl-js-button mdl-button--fab mdl-js-ripple-effect" href="{{ url_for('.event_new') }}"> + <i class="material-icons">add</i> + </a> + </div> + </div> + </div> +{% endblock %} diff --git a/templates/admin_event_new.html b/templates/admin_event_new.html new file mode 100644 index 0000000000000000000000000000000000000000..4de07fa2e4c89c47018fe53f15b435ccc8654243 --- /dev/null +++ b/templates/admin_event_new.html @@ -0,0 +1,7 @@ +{% extends "layout.html" %} +{% from "macros.html" import render_form %} +{% block title %}Add Event - Administration{% endblock %} + +{% block content %} + {{ render_form(form, action_url=url_for(".event_new", id=id), action_text="Add", title="Create Event") }} +{% endblock %} diff --git a/templates/admin_index.html b/templates/admin_index.html index a3ca2b6c0c6c00229bfd35c7665941bc8a9d0e2a..138ddc2bc3ea222d3107ace787c4237cdb6155e4 100644 --- a/templates/admin_index.html +++ b/templates/admin_index.html @@ -27,4 +27,28 @@ </a> </div> </div> + <div class="mdl-cell mdl-cell--6-col mdl-cell--8-col-tablet mdl-cell--4-col-phone mdl-grid mdl-grid--no-spacing"> + <table class="mdl-data-table mdl-js-table mdl-shadow--2dp sortable mdl-cell mdl-cell--12-col mdl-cell--8-col-tablet mdl-cell--4-col-phone"> + <thead> + <tr> + <th class="mdl-data-table__cell--non-numeric">Name</th> + <th class="mdl-data-table__cell--non-numeric">Date</th> + </tr> + </thead> + <tbody> + {% for event in events %} + <tr> + <td class="mdl-data-table__cell--non-numeric"><a href="{{ url_for(".event_edit", id=event.id) }}">{{ event.name }}</a></td> + <td class="mdl-data-table__cell--non-numeric">{{ event.date.strftime("%d.%m.%Y") }}</td> + </tr> + {% endfor %} + </tbody> + </table> + <div class="mdl-cell mdl-cell--3-col mdl-cell--3-col-tablet mdl-cell--2-col-phone"> + <a class="mdl-button mdl-button--colored mdl-js-button" href="{{ url_for(".event") }}"> + All events + </a> + </div> + </div> + {% endblock %} diff --git a/templates/index.html b/templates/index.html index 812a0d4c730bbb50ea508ae223ac142261546cb8..f33e84f51d702e8ff0004c130357bb4b4e1a243a 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,8 +1,39 @@ {% extends "layout.html" %} {% block title %}Index{% endblock %} +{% block additional_js %} + <script src="{{ url_for(".update_js") }}" async></script> +{% endblock %} {% block content %} - <div class="rede-nocontent mdl-color--white mdl-shadow--2dp mdl-cell mdl-cell-12-col mdl-grid"> - No content here + {% for (statement, speaker, count), event in meta %} + <div class="mdl-color--white mdl-shadow--2dp mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-cell--4-col-phone mdl-card"> + <div class="mdl-card__title"> + <h3 class="mdl-card__title-text">{{ event.name }}: {{ speaker.name }}</h3> + </div> + <div class="mdl-card__actions"> + {% if current_user.is_authenticated() and "user" in current_user.roles %} + <a href="{{ url_for("speech.index", event=event.id, mode="pending") }}"> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"> + <i class="material-icons" role="presentation">build</i> + </button> + </a> + {% endif %} + <a href="{{ url_for("speech.show", event=event.id, mode="pending") }}"> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"> + <i class="material-icons" role="presentation">announcement</i> + </button> + </a> + <a href="{{ url_for("speech.show", event=event.id, mode="all") }}"> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"> + <i class="material-icons" role="presentation">list</i> + </button> + </a> + <a href="{{ url_for("speech.show", event=event.id, mode="past") }}"> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"> + <i class="material-icons" role="presentation">schedule</i> + </button> + </a> + </div> </div> + {% endfor %} {% endblock %} diff --git a/templates/macros.html b/templates/macros.html index bf9d8ddc37087d3cb9ce3ea02f617651b8d865fb..3150025bde0efe16d9948b9e1e1f209a9af7c794 100644 --- a/templates/macros.html +++ b/templates/macros.html @@ -10,7 +10,7 @@ {% macro render_stringfield(field) -%} <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> - <input id="{{ field.id }}" name="{{ field.id }}" class="mdl-textfield__input" type="text"{% if field.data is not none %}value="{{ field.data }}"{% endif %} /> + <input id="{{ field.id }}" name="{{ field.id }}" class="mdl-textfield__input" type="text" {% if field.data is not none %}value="{{ field.data }}"{% endif %} /> <label class="mdl-textfield__label" for="{{ field.id }}">{{ field.label.text }}</label> {% if field.errors %} {% for e in field.errors %} @@ -55,14 +55,33 @@ {%- endmacro %} {% macro render_selectmultiplefield(field) -%} - <button id="{{ field.id }}-button" class="mdl-button mdl-js-button" type="button"> - {{ field.label.text }} - </button> - <select id="{{ field.id }}" name="{{ field.id }}" multiple class="mdl-menu mdl-js-menu mdl-menu--top-left" for="{{ field.id }}-button"> - {% for name, text in field.choices %} - <option value="{{ name }}" {% if field.data is not none and name in field.data %}selected{% endif %} class="mdl-menu__item" >{{ text }}</option> - {% endfor %} - </select> + <button id="{{ field.id }}-button" class="mdl-button mdl-js-button mdl-button--colored mdl-shadow--2dp mdl-color--grey-100 " type="button"> + {{ field.label.text }} + </button> + <select id="{{ field.id }}" name="{{ field.id }}" multiple class="mdl-menu mdl-js-menu mdl-menu--top-left" for="{{ field.id }}-button"> + {% for name, text in field.choices %} + <option value="{{ name }}" + {% if field.data is not none and name in field.data %} + selected + {% endif %} + class="mdl-menu__item"> + {{ text }} + </option> + {% endfor %} + </select> + {% if field.errors %} + {% for e in field.errors %} + <div class="mdl-card__supporting-text"> + {{ e }} + </div> + {% endfor %} + {% endif %} +{%- endmacro %} + +{% macro render_datefield(field) -%} + <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> + <input id="{{ field.id }}" name="{{ field.id }}" class="mdl-textfield__input" type="text"{% if field.data is not none %} value="{{ field.data.strftime("%d.%m.%Y") }}"{% endif %} /> + <label class="mdl-textfield__label" for="{{ field.id }}">{{ field.label.text }}</label> {% if field.errors %} {% for e in field.errors %} <div class="mdl-card__supporting-text"> @@ -70,12 +89,22 @@ </div> {% endfor %} {% endif %} - </label> + </div> {%- endmacro %} +{% macro render_hiddenfield(field) -%} + <input id="{{ field.id }}" name="{{ field.id }}" type="hidden"{% if field.data is not none %} value="{{ field.data }}"{% endif %} /> + {% if field.errors %} + {% for e in field.errors %} + <div class="mdl-card__supporting-text"> + {{ e }} + </div> + {% endfor %} + {% endif %} +{%- endmacro %} -{% macro render_form(form, action_url="", title=None, action_text="Submit", class_="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-cell--4-col-phone", title_class="mdl-card__title", title_next_class="mdl-card__title-text", content_class="mdl-card__supporting-text", action_class="mdl-card__actions", btn_class="mdl-button mdl-js-button mdl-button--raised mdl-button-colored") -%} +{% macro render_form(form, action_url="", title=None, action_text="Submit", class_="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-cell--4-col-phone", title_class="mdl-card__title", title_text_class="mdl-card__title-text", content_class="mdl-card__supporting-text", action_class="mdl-card__actions", btn_class="mdl-button mdl-js-button mdl-button--raised mdl-button-colored") -%} <div class="{{ class_ }}"> <form method="POST" action="{{ action_url }}"> <div class="{{ title_class }}"> @@ -93,6 +122,10 @@ {{ render_csrftokenfield(f, kwargs) }} {% elif f.type == "SelectMultipleField" %} {{ render_selectmultiplefield(f) }} + {% elif f.type == "DateField" %} + {{ render_datefield(f) }} + {% elif f.type == "HiddenField" %} + {{ render_hiddenfield(f) }} {% else %} {{ f.type }} {{ render_field(f) }} diff --git a/templates/speech_index.html b/templates/speech_index.html index b5135f20c4073aab1568da434919bf73a6b6a9fb..ebd02b7c36505bf31aedd86c8e9bacb4bec008b4 100644 --- a/templates/speech_index.html +++ b/templates/speech_index.html @@ -3,49 +3,51 @@ {% block title %}Statements{% endblock %} {% block content %} - <table class="mdl-data-table mdl-js-table mdl-shadow--2dp mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet mdl-cell--4-col-phone sortable"> - <thead> - <tr> - <th class="mdl-data-table__cell--non-numeric">Speaker</th> - <th>Count</th> - {% if "user" in current_user.roles %} - <th class="mdl-data-table__cell--non-numeric">Done</th> - <th class="mdl-data-table__cell--non-numeric">Cancel</th> + {% for statements, add_form, event in meta %} + <table class="mdl-data-table mdl-js-table mdl-shadow--2dp mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet mdl-cell--4-col-phone sortable"> + <thead> + <tr> + <th class="mdl-data-table__cell--non-numeric">Speaker</th> + <th>Count</th> + {% if "user" in current_user.roles %} + <th class="mdl-data-table__cell--non-numeric">Done</th> + <th class="mdl-data-table__cell--non-numeric">Cancel</th> + {% endif %} + </tr> + </thead> + <tbody> + {% for statement, speaker, count in statements %} + {% if not statement.executed %} + <tr> + <td class="mdl-data-table__cell--non-numeric"> + <h5>{{ speaker.name }}</h5> + </td> + <td> + <h5>{{ count }}</h5> + </td> + {% if "user" in current_user.roles %} + <td class="mdl-data-table__cell--non-numeric"> + <a href="{{ url_for(".done", statement=statement.id, next=".index", event=event_id) }}"> + <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored"> + <i class="material-icons">done</i> + </button> + </a> + </td> + <td class="mdl-data-table__cell--non-numeric"> + <a href="{{ url_for(".cancel", statement=statement.id, next=".index", event=event_id) }}"> + <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab"> + <i class="material-icons">delete</i> + </button> + </a> + </td> + {% endif %} + </tr> {% endif %} - </tr> - </thead> - <tbody> - {% for statement, speaker, count in statements %} - {% if not statement.executed %} - <tr> - <td class="mdl-data-table__cell--non-numeric"> - <h5>{{ speaker.name }}</h5> - </td> - <td> - <h5>{{ count }}</h5> - </td> - {% if "user" in current_user.roles %} - <td class="mdl-data-table__cell--non-numeric"> - <a href="{{ url_for(".done", statement=statement.id) }}"> - <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored"> - <i class="material-icons">done</i> - </button> - </a> - </td> - <td class="mdl-data-table__cell--non-numeric"> - <a href="{{ url_for(".cancel", statement=statement.id) }}"> - <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab"> - <i class="material-icons">delete</i> - </button> - </a> - </td> - {% endif %} - </tr> - {% endif %} - {% endfor %} - </tbody> - </table> - {% if current_user.is_authenticated() and "user" in current_user.roles %} - {{ render_form(add_form, action_url=url_for('.add', next=current), action_text="Add", title="Add Speaker") }} - {% endif %} + {% endfor %} + </tbody> + </table> + {% if current_user.is_authenticated() and "user" in current_user.roles %} + {{ render_form(add_form, action_url=url_for('.add', next=".index", event=event_id), action_text="Add", title="Add Speaker to {}".format(event.name)) }} + {% endif %} + {% endfor %} {% endblock %} diff --git a/templates/speech_show.html b/templates/speech_show.html index 7d6d9d822da16baa7f25e99e7105fed3295ede82..b9b8c1f73743fb8825fa0504921fc74b941b06dd 100644 --- a/templates/speech_show.html +++ b/templates/speech_show.html @@ -2,48 +2,50 @@ {% from "macros.html" import render_form %} {% block title %}Statements{% endblock %} {% block additional_js %} - <script src="{{ url_for(".update_show_js", mode=mode) }}" async></script> + <script src="{{ url_for(".update_show_js", mode=mode, event=event_id) }}" async></script> {% endblock %} {% block content %} - <table class="mdl-data-table mdl-js-table mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-cell--8-col-tablet mdl-cell--4-col-phone"> - <thead> - <tr> - <th class="mdl-data-table__cell--non-numeric">Speaker</th> - {% if mode == "all" or mode == "past" %} - <th class="mdl-data-table__cell--non-numeric">Time</th> - {% endif %} - </tr> - </thead> - <tbody> - {% if mode == "all" or mode == "past" %} - {% for statement, speaker in statements %} + {% for statements, event in meta %} + <table class="mdl-data-table mdl-js-table mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-cell--8-col-tablet mdl-cell--4-col-phone"> + <thead> <tr> - <td class="mdl-data-table__cell--non-numeric"> - {{ speaker.name }} - </td> - {% if mode == "all" %} - <td class="mdl-data-table__cell--non-numeric"> - {{ statement.insertion_time.strftime("%d. %B %Y, %H:%M") }} - </td> - {% elif mode == "past" %} - <td class="mdl-data-table__cell--non-numeric"> - {{ statement.execution_time.strftime("%d. %B %Y, %H:%M") }} - </td> + <th class="mdl-data-table__cell--non-numeric">Speaker for {{ event.name }}</th> + {% if mode == "all" or mode == "past" %} + <th class="mdl-data-table__cell--non-numeric">Time</th> {% endif %} </tr> - {% endfor %} - {% elif mode == "pending" %} - {% for statement, speaker, count in statements %} - {% if not statement.executed %} + </thead> + <tbody> + {% if mode == "all" or mode == "past" %} + {% for statement, speaker in statements %} <tr> <td class="mdl-data-table__cell--non-numeric"> - <h5>{{ speaker.name }}</h5> + {{ speaker.name }} </td> + {% if mode == "all" %} + <td class="mdl-data-table__cell--non-numeric"> + {{ statement.insertion_time.strftime("%d. %B %Y, %H:%M") }} + </td> + {% elif mode == "past" %} + <td class="mdl-data-table__cell--non-numeric"> + {{ statement.execution_time.strftime("%d. %B %Y, %H:%M") }} + </td> + {% endif %} </tr> - {% endif %} - {% endfor %} - {% endif %} - </tbody> - </table> + {% endfor %} + {% elif mode == "pending" %} + {% for statement, speaker, count in statements %} + {% if not statement.executed %} + <tr> + <td class="mdl-data-table__cell--non-numeric"> + <h5>{{ speaker.name }}</h5> + </td> + </tr> + {% endif %} + {% endfor %} + {% endif %} + </tbody> + </table> + {% endfor %} {% endblock %} diff --git a/templates/speech_update_show.html b/templates/speech_update_show.html index bfd35563c4e31b58b2f68cc333f3f738b810e703..6eb69c80880120f19bc2c012ba99905b0a24f80e 100644 --- a/templates/speech_update_show.html +++ b/templates/speech_update_show.html @@ -1,41 +1,43 @@ {% from "macros.html" import render_form %} - <table class="mdl-data-table mdl-js-table mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-cell--8-col-tablet mdl-cell--4-col-phone"> - <thead> - <tr> - <th class="mdl-data-table__cell--non-numeric">Speaker</th> - {% if mode == "all" or mode == "past" %} - <th class="mdl-data-table__cell--non-numeric">Time</th> - {% endif %} - </tr> - </thead> - <tbody> - {% if mode == "all" or mode == "past" %} - {% for statement, speaker in statements %} + {% for statements, event in meta %} + <table class="mdl-data-table mdl-js-table mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-cell--8-col-tablet mdl-cell--4-col-phone"> + <thead> <tr> - <td class="mdl-data-table__cell--non-numeric"> - {{ speaker.name }} - </td> - {% if mode == "all" %} - <td class="mdl-data-table__cell--non-numeric"> - {{ statement.insertion_time.strftime("%d. %B %Y, %H:%M") }} - </td> - {% elif mode == "past" %} - <td class="mdl-data-table__cell--non-numeric"> - {{ statement.execution_time.strftime("%d. %B %Y, %H:%M") }} - </td> + <th class="mdl-data-table__cell--non-numeric">Speaker for {{ event.name }}</th> + {% if mode == "all" or mode == "past" %} + <th class="mdl-data-table__cell--non-numeric">Time</th> {% endif %} </tr> - {% endfor %} - {% elif mode == "pending" %} - {% for statement, speaker, count in statements %} - {% if not statement.executed %} + </thead> + <tbody> + {% if mode == "all" or mode == "past" %} + {% for statement, speaker in statements %} <tr> <td class="mdl-data-table__cell--non-numeric"> - <h5>{{ speaker.name }}</h5> + {{ speaker.name }} </td> + {% if mode == "all" %} + <td class="mdl-data-table__cell--non-numeric"> + {{ statement.insertion_time.strftime("%d. %B %Y, %H:%M") }} + </td> + {% elif mode == "past" %} + <td class="mdl-data-table__cell--non-numeric"> + {{ statement.execution_time.strftime("%d. %B %Y, %H:%M") }} + </td> + {% endif %} </tr> - {% endif %} - {% endfor %} - {% endif %} - </tbody> - </table> + {% endfor %} + {% elif mode == "pending" %} + {% for statement, speaker, count in statements %} + {% if not statement.executed %} + <tr> + <td class="mdl-data-table__cell--non-numeric"> + <h5>{{ speaker.name }}</h5> + </td> + </tr> + {% endif %} + {% endfor %} + {% endif %} + </tbody> + </table> + {% endfor %} diff --git a/templates/update_index.html b/templates/update_index.html new file mode 100644 index 0000000000000000000000000000000000000000..fe78097b3f547d5ed1d0b0307625a515cf4e0028 --- /dev/null +++ b/templates/update_index.html @@ -0,0 +1,31 @@ + {% for (statement, speaker, count), event in meta %} + <div class="mdl-color--white mdl-shadow--2dp mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-cell--4-col-phone mdl-card"> + <div class="mdl-card__title"> + <h3 class="mdl-card__title-text">{{ event.name }}: {{ speaker.name }}</h3> + </div> + <div class="mdl-card__actions"> + {% if current_user.is_authenticated() and "user" in current_user.roles %} + <a href="{{ url_for("speech.index", event=event.id, mode="pending") }}"> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"> + <i class="material-icons" role="presentation">build</i> + </button> + </a> + {% endif %} + <a href="{{ url_for("speech.show", event=event.id, mode="pending") }}"> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"> + <i class="material-icons" role="presentation">announcement</i> + </button> + </a> + <a href="{{ url_for("speech.show", event=event.id, mode="all") }}"> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"> + <i class="material-icons" role="presentation">list</i> + </button> + </a> + <a href="{{ url_for("speech.show", event=event.id, mode="past") }}"> + <button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"> + <i class="material-icons" role="presentation">schedule</i> + </button> + </a> + </div> + </div> + {% endfor %} diff --git a/templates/update_index.js b/templates/update_index.js new file mode 100644 index 0000000000000000000000000000000000000000..ee2e39c6266287d77ec5afe76c38c082a339619b --- /dev/null +++ b/templates/update_index.js @@ -0,0 +1,30 @@ +var returned = true; +var last_content = ""; +function request() { + if (!returned) + return; + returned = false; + var xmlhttp = new XMLHttpRequest(); + xmlhttp.onreadystatechange=function() { + if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { + returned = true; + update(xmlhttp.responseText); + } + }; + var target = "{{ url_for('.update') }}"; + xmlhttp.open("GET", target, true); + xmlhttp.send(); +} + +function update(data) { + if (data != last_content) { + document.getElementById("rede-content-div").innerHTML = data; + last_content = data; + } +} + +window.onload=function() { + window.setInterval(request, 1000); +} + + diff --git a/templates/update_show.js b/templates/update_show.js index 9f5ad37cf2bdbbc93ab13fd4fabee1fbbca6eda8..54ec83995097f3e1fa38093046c17c7315bebc05 100644 --- a/templates/update_show.js +++ b/templates/update_show.js @@ -11,7 +11,7 @@ function request() { update(xmlhttp.responseText); } }; - var target = "{{ url_for('.update', mode=mode) }}"; + var target = "{{ url_for('.update', mode=mode, event=event_id) }}"; xmlhttp.open("GET", target, true); xmlhttp.send(); }