Skip to content
Snippets Groups Projects
Commit a4b6c53f authored by Robin Sonnabend's avatar Robin Sonnabend
Browse files

Benutzeransicht

parent 214505eb
No related branches found
No related tags found
No related merge requests found
"""empty message
Revision ID: 3c75c74bb94
Revises: 256d9df3492
Create Date: 2015-11-08 13:06:23.520483
"""
# revision identifiers, used by Alembic.
revision = '3c75c74bb94'
down_revision = '256d9df3492'
from alembic import op
import sqlalchemy as sa
def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.drop_constraint('events_current_topic_id_fkey', 'events', type_='foreignkey')
### end Alembic commands ###
def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.create_foreign_key('events_current_topic_id_fkey', 'events', 'topics', ['current_topic_id'], ['id'])
### end Alembic commands ###
...@@ -41,15 +41,13 @@ class Event(db.Model): ...@@ -41,15 +41,13 @@ class Event(db.Model):
name = db.Column(db.String, unique=True) name = db.Column(db.String, unique=True)
paused = db.Column(db.Boolean) paused = db.Column(db.Boolean)
paused_until = db.Column(db.DateTime) paused_until = db.Column(db.DateTime)
current_topic_id = db.Column(db.Integer, db.ForeignKey("topics.id")) current_topic_id = db.Column(db.Integer)
current_topic = relationship("Topic", foreign_keys=[current_topic_id])
def __init__(self, name, paused=False, current_topic_id=None): def __init__(self, name, paused=False, current_topic_id=None):
self.name = name self.name = name
self.paused = paused self.paused = paused
self.paused_until = datetime(1970, 1, 1) self.paused_until = datetime(1970, 1, 1)
self.current_topic_id = current_topic_id or 0 self.current_topic_id = current_topic_id or -1
def __repr__(self): def __repr__(self):
return "<Event(id={}, name={}, paused={}, paused_until={})>".format( return "<Event(id={}, name={}, paused={}, paused_until={})>".format(
...@@ -62,6 +60,12 @@ class Event(db.Model): ...@@ -62,6 +60,12 @@ class Event(db.Model):
def sorted_topics(self): def sorted_topics(self):
return sorted(self.topics, key=lambda tp: tp.get_index()) 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]
if len(candidates) < 1:
return None
return candidates[0]
class Topic(db.Model): class Topic(db.Model):
__tablename__ = "topics" __tablename__ = "topics"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
......
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.ext.login import login_required from flask.ext.login import login_required
from models.database import User, Statement, Speaker, Topic from models.database import User, Statement, Speaker, Topic, Event
from models.forms import AddStatementForm from models.forms import AddStatementForm
from shared import db, admin_permission, user_permission from shared import db, admin_permission, user_permission
...@@ -14,142 +14,37 @@ import config ...@@ -14,142 +14,37 @@ import config
speech = Blueprint("speech", __name__) speech = Blueprint("speech", __name__)
"""
def query_statements(mode, topic_id):
statements = db.session.query(Statement).filter_by(topic_id=topic_id).all()
speakers = db.session.query(Speaker).filter_by(topic_id=topic_id).all()
if mode == "balanced" or mode == "pending":
count = { speaker.id: 0 for speaker in speakers }
for statement in statements:
if statement.speaker in count:
count[statement.speaker] += 1
else:
count[statement.speaker] = 1
sorted_speakers = sorted(speakers, key=lambda sp: count[sp.id])
result = []
for speaker in sorted_speakers:
pending_statements = [statement for statement in statements if statement.speaker == speaker.id and not statement.executed]
if len(pending_statements) > 0:
result.append((pending_statements[0], speaker, count[speaker.id]))
return result
if mode == "fifo":
speaker_by_id = { speaker.id: speaker for speaker in speakers }
result = [(statement, speaker_by_id[statement.speaker], 0) for statement in statements if not statement.executed]
return result
print("unknown querying mode {}".format(mode))
"""
@speech.route("/") @speech.route("/")
def index(): def index():
topic_id = request.args.get("topic", None) event_id = request.args.get("event", None)
mode = request.args.get("mode", None) events = []
meta = [] if event_id is not None and event_id.isnumeric() and int(event_id) > -1:
if topic_id is not None and topic_id != "-1": event = Event.query.filter_by(id=event_id).first()
topic = Topic.query.filter_by(id=topic_id).first() if event is not None:
form = AddStatementForm() events.append(event)
form.topic.data = topic.id
meta.append((query_statements(mode if mode is not None else topic.mode, topic_id), form, topic))
else: else:
for topic in Topic.query.all(): events = Event.query.all()
form = AddStatementForm() return render_layout("speech_index.html", events=events, event=-1 if len(events) != 1 else events[0].id)
form.topic.data = topic.id
meta.append((query_statements(mode if mode is not None else topic.mode, topic.id), form, topic))
topic_id = -1
return render_layout("speech_index.html", meta=meta, topic_id=topic_id, mode=mode)
@speech.route("/show")
def show():
topic_id = request.args.get("topic", None)
mode = request.args.get("mode", None)
meta = []
if topic_id is not None and topic_id is not "-1":
topic = Topic.query.filter_by(id=topic_id).first()
meta.append((query_statements(mode if mode is not None else topic.mode, topic_id), topic))
else:
for topic in Topic.query.all():
meta.append((query_statements(mode if mode is not None else topic.mode, topic.id), topic))
return render_layout("speech_show.html", mode=mode, meta=meta, topic_id=topic_id)
@speech.route("/update") @speech.route("/update")
def update(): def update():
topic_id = request.args.get("topic", None) event_id = request.args.get("event", None)
mode = request.args.get("mode", None) events = []
meta = [] if event_id is not None and event_id.isnumeric() and int(event_id) > -1:
if topic_id is not None and topic_id != "-1": event = Event.query.filter_by(id=event_id).first()
topic = Topic.query.filter_by(id=topic_id).first() if event is not None:
meta.append((query_statements(mode if mode is not None else topic.mode, topic_id), topic)) events.append(event)
else: else:
for topic in Topic.query.all(): events = Event.query.all()
meta.append((query_statements(mode if mode is not None else topic.mode, topic.id), topic)) return render_layout("speech_content_index.html", events=events)
return render_layout("speech_content_show.html", mode=mode, meta=meta)
@speech.route("/add", methods=["GET", "POST"])
@user_permission.require()
def add():
speaker_name = request.args.get("speaker", None)
add_form = AddStatementForm()
if add_form.validate_on_submit():
speaker_name = add_form["speaker_name"].data
topic_id = add_form["topic"].data
if speaker_name is None or topic_id is None:
flash("Missing data", "alert-error")
return redirect(url_for(".index"))
speaker = Speaker.query.filter_by(name=speaker_name).filter_by(topic=topic_id).first()
if not speaker:
speaker = Speaker(speaker_name, topic_id)
db.session.add(speaker)
db.session.commit()
if Statement.query.filter_by(speaker=speaker.id).filter_by(topic=topic_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, topic_id)
db.session.add(statement)
db.session.commit()
mode = request.args.get("mode", None)
topic_id = request.args.get("topic", None)
return redirect(url_for(request.args.get("next") or ".index", mode=mode, topic=topic_id))
@speech.route("/cancel")
@user_permission.require()
def cancel():
statement_id = request.args.get("statement", None)
topic_id = request.args.get("topic", -1)
if not statement_id:
flash("Missing statement id", "alert-error")
return redirect(url_for(request.args.get("next") or ".index"))
statement = Statement.query.filter_by(id=statement_id).first()
db.session.delete(statement)
db.session.commit()
flash("Statement canceled", "alert-success")
mode = request.args.get("mode", None)
return redirect(url_for(request.args.get("next") or ".index", mode=mode, topic=topic_id))
@speech.route("/done")
@user_permission.require()
def done():
statement_id = request.args.get("statement", None)
topic_id = request.args.get("topic", -1)
if not statement_id:
flash("Missing statement id", "alert-error")
return redirect(url_for(request.args.get("next") or ".index"))
statement = Statement.query.filter_by(id=statement_id).first()
if statement.done():
db.session.commit()
else:
flash("Statement already done", "alert-error")
mode = request.args.get("mode", None)
return redirect(url_for(request.args.get("next") or ".index", mode=mode, topic=topic_id))
@speech.route("/update_show.js") @speech.route("/update_index.js")
def update_show_js(): def update_index_js():
update_interval = config.UPDATE_SHOW_INTERVAL or 1 update_interval = config.UPDATE_INDEX_INTERVAL or 1
div = "rede-content-div" div = "rede-content-div"
mode = request.args.get("mode", None) mode = request.args.get("mode", None)
topic_id = request.args.get("topic", -1) event_id = request.args.get("event", -1)
target_url = url_for(".update", mode=mode, topic=topic_id) 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_show_") return render_layout("update.js", update_interval=update_interval, div=div, target_url=target_url, prefix="update_index_")
{% for (statement, speaker, count), topic 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-color--white mdl-shadow--2dp mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-cell--4-col-phone mdl-card">
{% if event.current_topic_id != -1 %}
<div class="mdl-card__title"> <div class="mdl-card__title">
<h3 class="mdl-card__title-text">{{ topic.name }}: {{ speaker.name }}</h3> <h3 class="mdl-card__title-text">{{ event.current_topic.name }}: {{ event.current_topic.sorted_statements()[0].speaker.name }}</h3>
</div> </div>
<div class="mdl-card__actions"> {% if event.get_current_topic() %}
{% if current_user.is_authenticated and "user" in current_user.roles %} <table class="mdl-data-table mdl-js-table">
<a href="{{ url_for("speech.index", event=event.id) }}"> {% for statement in event.get_current_topic().sorted_statements() %}
<button type="button" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"> <tr>
<i class="material-icons" role="presentation">build</i> <td>statement.speaker.name</td>
</button> </tr>
</a> {% endfor %}
</table>
{% endif %}
{% else %}
No topic selected
{% endif %} {% endif %}
<a href="{{ url_for("speech.show", topic=event.id) }}">
<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>
</div>
</div> </div>
{% endfor %}
...@@ -79,10 +79,7 @@ ...@@ -79,10 +79,7 @@
</div> </div>
</header> </header>
<nav class="rede-navigation mdl-navigation mdl-color--blue-grey-800"> <nav class="rede-navigation mdl-navigation mdl-color--blue-grey-800">
{% if current_user.is_authenticated and "user" in current_user.roles %} <a class="mdl-navigation__link" href="{{ url_for("speech.index") }}"><i class="mdl-color-text--blue-grey-400 material-icons" role="presentation">announcement</i>Pending speakers</a>
<a class="mdl-navigation__link" href="{{ url_for("speech.index") }}"><i class="mdl-color-text--blue-grey-400 material-icons" role="presentation">build</i>Handle speakers</a>
{% endif %}
<a class="mdl-navigation__link" href="{{ url_for("speech.show") }}"><i class="mdl-color-text--blue-grey-400 material-icons" role="presentation">announcement</i>Pending speakers</a>
{% if current_user.is_authenticated and "admin" in current_user.roles %} {% if current_user.is_authenticated and "admin" in current_user.roles %}
<a class="mdl-navigation__link" href="{{ url_for("admin.index") }}"><i class="mdl-color-text--blue-grey-400 material-icons" role="presentation">computer</i>Administration</a> <a class="mdl-navigation__link" href="{{ url_for("admin.index") }}"><i class="mdl-color-text--blue-grey-400 material-icons" role="presentation">computer</i>Administration</a>
{% block additional_sidelinks %} {% block additional_sidelinks %}
......
{% for event in events %}
<div class="mdl-cell mdl-cell--6-col mdl-cell--8-col-tablet mdl-cell--4-col-phone mdl-card mdl-shadow--2dp">
{% if not event.paused %}
{% if event.current_topic_id != -1 and event.get_current_topic() %}
<div class="mdl-card__title">
{{ event.name }}: {{ event.get_current_topic().name }}
</div>
<table class="mdl-data-table mdl-js-table" style="min-width: 100%">
<thead>
<tr>
<th class="mdl-data-table__cell--non-numeric">Speaker</th>
<th class="mdl-data-table__cell">Count</th>
</tr>
</thead>
<tbody>
{% for statement in event.get_current_topic().sorted_statements() %}
<tr>
<td class="mdl-data-table__cell--non-numeric">{{ statement.speaker.identifier() }}</td>
<td class="mdl-data-table__cell">{{ statement.speaker.count(event.current_topic) }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div class="mdl-card__title">
{{ event.name }}: No topic set
</div>
{% endif %}
{% else %}
<div class="mdl-card__title rede-paused-title">
<h4 class="mdl-card__title-text rede-paused-title-text">
{{ event.name}}: Paused until {{ event.paused_until.strftime("%H:%M") }}
</h4>
</div>
{% endif %}
</div>
{% endfor %}
{% from "macros.html" import render_form %}
{% for statements, topic 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>
<th class="mdl-data-table__cell--non-numeric">Speaker for {{ topic.name }}</th>
</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>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
{% endfor %}
{% extends "layout.html" %} {% extends "layout.html" %}
{% from "macros.html" import render_form %} {% from "macros.html" import render_form %}
{% block title %}Statements{% endblock %} {% block title %}Statements{% endblock %}
{% block additional_js %} {% block additional_js %}
<script src="{{ url_for('static', filename='js/nextbutton.js') }}" async></script> <script src="{{ url_for(".update_index_js", event=event) }}" async></script>
{% endblock %}
{% block additional_sidelinks %}
<a href="#" class="mdl-navigation__link" onclick="setkeyhash()"><i class="mdl-colo-text--blue-grey-400 material-icons" role="presentation">keyboard</i>Set Next Key</a>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{% for statements, add_form, topic in meta %} {% include "speech_content_index.html" %}
<table id="next-speaker-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>
{% if (mode is not none and mode == "balanced") or (mode is none and topic.mode == "balanced") %}
<th>Count</th>
{% endif %}
{% 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 %}
<tr>
<td class="mdl-data-table__cell--non-numeric">
<h5>{{ speaker.name }}</h5>
</td>
{% if (mode is not none and mode == "balanced") or (mode is none and topic.mode == "balanced") %}
<td>
<h5>{{ count }}</h5>
</td>
{% endif %}
{% if "user" in current_user.roles %}
<td class="mdl-data-table__cell--non-numeric">
<a href="{{ url_for(".done", statement=statement.id, next=".index", topic=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", topic=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>
{% 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 %} {% endblock %}
{% extends "layout.html" %}
{% from "macros.html" import render_form %}
{% block title %}Statements{% endblock %}
{% block additional_js %}
<script src="{{ url_for(".update_show_js", mode=mode, topic=event_id) }}" async></script>
{% endblock %}
{% block content %}
{% include "speech_content_show.html" %}
{% endblock %}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment