From ba1343dafa74a4a7d6bc697047ce96602f056ac6 Mon Sep 17 00:00:00 2001 From: YSelf Tool <yselftool@gmail.com> Date: Fri, 11 Sep 2015 19:07:49 +0200 Subject: [PATCH] Changed mode to sorting type, implemented balanced and fifo --- models/database.py | 14 +++---- models/forms.py | 2 +- modules/admin.py | 3 +- modules/speech.py | 65 +++++++++++++++++------------- server.py | 8 ++-- templates/admin_event_index.html | 4 +- templates/admin_index.html | 4 +- templates/content_index.html | 14 +------ templates/layout.html | 6 +-- templates/speech_content_show.html | 32 +++------------ templates/speech_index.html | 6 ++- templates/update.js | 38 ++++++++--------- 12 files changed, 88 insertions(+), 108 deletions(-) diff --git a/models/database.py b/models/database.py index be72003..5f72d62 100644 --- a/models/database.py +++ b/models/database.py @@ -38,19 +38,19 @@ 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) + mode = db.Column(db.String) - def __init__(self, name, date): + def __init__(self, name, mode): self.name = name - self.date = date + self.mode = mode def __repr__(self): - return "<Event(id={}, name='{}', date={})>".format( + return "<Event(id={}, name='{}', mode='{}')>".format( self.id, self.name, - self.date + self.mode ) - + class Speaker(db.Model): __tablename__ = "speakers" @@ -63,7 +63,7 @@ class Speaker(db.Model): self.event = event def __repr__(self): - return "<Speaker(id={}, name={}, event={})>".format( + return "<Speaker(id={}, name='{}', event={})>".format( self.id, self.name, self.event diff --git a/models/forms.py b/models/forms.py index 5a1072e..146488d 100644 --- a/models/forms.py +++ b/models/forms.py @@ -28,4 +28,4 @@ class AddStatementForm(Form): 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") + mode = StringField("Mode", validators=[InputRequired("Entering the mode is required."), AnyOf(values=["balanced", "fifo"], message="Must be 'balanced' or 'fifo' atm.")]) diff --git a/modules/admin.py b/modules/admin.py index d18ca5c..74efba1 100644 --- a/modules/admin.py +++ b/modules/admin.py @@ -78,7 +78,7 @@ def event_new(): if Event.query.filter_by(name=form.name.data).count() > 0: flash("There already is an event with that name.", "alert-error") return render_layout("admin_event_new.html", form=form) - event = Event(form.name.data, form.date.data) + event = Event(form.name.data, form.mode.data) db.session.add(event) db.session.commit() return redirect(url_for(".event")) @@ -118,5 +118,4 @@ def event_edit(): @admin_permission.require() def event(): events = Event.query.all() - print(events) return render_layout("admin_event_index.html", events=events) diff --git a/modules/speech.py b/modules/speech.py index 56b2bb4..e7a62a9 100644 --- a/modules/speech.py +++ b/modules/speech.py @@ -13,62 +13,73 @@ import config speech = Blueprint("speech", __name__) -def transpose(arr): - print(list) - return list(map(list, zip(*arr))) - 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).filter(Statement.event == event_id).order_by("total ASC", Statement.insertion_time).all() - elif mode == "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).filter(Statement.event == event_id).order_by(Statement.execution_time).all() - return statements + statements = db.session.query(Statement).filter_by(event=event_id).all() + speakers = db.session.query(Speaker).filter_by(event=event_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("/index") def index(): - mode = request.args.get("mode", "pending") event_id = request.args.get("event", None) + mode = request.args.get("mode", 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)) + meta.append((query_statements(mode if mode is not None else event.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)) + meta.append((query_statements(mode if mode is not None else event.mode, event.id), form, event)) event_id = -1 - return render_layout("speech_index.html", meta=meta, event_id=event_id) + return render_layout("speech_index.html", meta=meta, event_id=event_id, mode=mode) @speech.route("/show") def show(): - mode = request.args.get("mode", "pending") event_id = request.args.get("event", None) + mode = request.args.get("mode", 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)) + meta.append((query_statements(mode if mode is not None else event.mode, event_id), event)) else: for event in Event.query.all(): - meta.append((query_statements(mode, event.id), event)) + meta.append((query_statements(mode if mode is not None else event.mode, event.id), event)) return render_layout("speech_show.html", mode=mode, meta=meta, event_id=event_id) @speech.route("/update") def update(): - mode = request.args.get("mode", "pending") event_id = request.args.get("event", None) + mode = request.args.get("mode", 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)) + meta.append((query_statements(mode if mode is not None else event.mode, event_id), event)) else: for event in Event.query.all(): - meta.append((query_statements(mode, event.id), event)) + meta.append((query_statements(mode if mode is not None else event.mode, event.id), event)) return render_layout("speech_content_show.html", mode=mode, meta=meta) @@ -94,7 +105,7 @@ def add(): statement = Statement(speaker.id, event_id) db.session.add(statement) db.session.commit() - mode = request.args.get("mode", "pending") + mode = request.args.get("mode", None) event_id = request.args.get("event", None) return redirect(url_for(request.args.get("next") or ".index", mode=mode, event=event_id)) @@ -111,7 +122,7 @@ def cancel(): db.session.delete(statement) db.session.commit() flash("Statement canceled", "alert-success") - mode = request.args.get("mode", "pending") + mode = request.args.get("mode", None) return redirect(url_for(request.args.get("next") or ".index", mode=mode, event=event_id)) @speech.route("/done") @@ -127,15 +138,15 @@ def done(): db.session.commit() else: flash("Statement already done", "alert-error") - mode = request.args.get("mode", "pending") + mode = request.args.get("mode", None) return redirect(url_for(request.args.get("next") or ".index", mode=mode, event=event_id)) @speech.route("/update_show.js") def update_show_js(): update_interval = config.UPDATE_SHOW_INTERVAL or 1 div = "rede-content-div" - mode = request.args.get("mode", "pending") + mode = request.args.get("mode", None) event_id = request.args.get("event", -1) target_url = url_for(".update", mode=mode, event=event_id) - return render_layout("update.js", update_interval=update_interval, div=div, target_url=target_url) + return render_layout("update.js", update_interval=update_interval, div=div, target_url=target_url, prefix="update_show_") diff --git a/server.py b/server.py index 42c4241..e08a739 100755 --- a/server.py +++ b/server.py @@ -37,7 +37,7 @@ def index(): events = Event.query.all() meta = [] for event in events: - ls = [ (statement, speaker, count) for (statement, speaker, count) in speech.query_statements("pending", event.id) if not statement.executed ] + ls = speech.query_statements(event.mode, event.id) no_speaker = Speaker("No Speaker", event) no_statement = Statement(no_speaker, event) meta.append((ls[0] if len(ls) > 0 else (no_statement, no_speaker, ()), event)) @@ -48,7 +48,7 @@ def update(): events = Event.query.all() meta = [] for event in events: - ls = [ (statement, speaker, count) for (statement, speaker, count) in speech.query_statements("pending", event.id) if not statement.executed ] + ls = speech.query_statements(event.mode, event.id) no_speaker = Speaker("No Speaker", event) no_statement = Statement(no_speaker, event) meta.append((ls[0] if len(ls) > 0 else (no_statement, no_speaker, ()), event)) @@ -59,7 +59,7 @@ 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=target_url) + return render_layout("update.js", update_interval=update_interval, div=div, target_url=target_url, prefix="index_") @app.route("/update_time") def update_time(): @@ -70,7 +70,7 @@ 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) + return render_layout("update.js", update_interval=update_interval, div=div, target_url=target_url, prefix="time_") @app.route("/login", methods=["GET", "POST"]) def login(): diff --git a/templates/admin_event_index.html b/templates/admin_event_index.html index 63e5887..0bdd1d5 100644 --- a/templates/admin_event_index.html +++ b/templates/admin_event_index.html @@ -7,7 +7,7 @@ <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">Mode</th> <th class="mdl-data-table__cell--non-numeric">Delete</th> </tr> </thead> @@ -15,7 +15,7 @@ {% 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">{{ event.mode }}</td> <td class="mdl-data-table__cell--non-numeric"> <a href="{{ url_for('.event_delete', id=event.id) }}"> <i class="material-icons">delete</i> diff --git a/templates/admin_index.html b/templates/admin_index.html index 138ddc2..3c32164 100644 --- a/templates/admin_index.html +++ b/templates/admin_index.html @@ -32,14 +32,14 @@ <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">Mode</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">{{ event.mode }}</td> </tr> {% endfor %} </tbody> diff --git a/templates/content_index.html b/templates/content_index.html index fe78097..b076ce5 100644 --- a/templates/content_index.html +++ b/templates/content_index.html @@ -5,27 +5,17 @@ </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") }}"> + <a href="{{ url_for("speech.index", event=event.id) }}"> <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") }}"> + <a href="{{ url_for("speech.show", event=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> - <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/layout.html b/templates/layout.html index ddb82e4..6836e6a 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -78,11 +78,9 @@ </header> <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", mode="pending") }}"><i class="mdl-color-text--blue-grey-400 material-icons" role="presentation">build</i>Handle 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", mode="pending") }}"><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.show", mode="all") }}"><i class="mdl-color-text--blue-grey-400 material-icons" role="presentation">list</i>All speakers</a> - <a class="mdl-navigation__link" href="{{ url_for("speech.show", mode="past") }}"><i class="mdl-color-text--blue-grey-400 material-icons" role="presentation">schedule</i>Past speakers</a> + <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 %} <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> {% endif %} diff --git a/templates/speech_content_show.html b/templates/speech_content_show.html index 6eb69c8..94c8a61 100644 --- a/templates/speech_content_show.html +++ b/templates/speech_content_show.html @@ -4,40 +4,18 @@ <thead> <tr> <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> </thead> <tbody> - {% if mode == "all" or mode == "past" %} - {% for statement, speaker in statements %} + {% for statement, speaker, count in statements %} + {% if not statement.executed %} <tr> <td class="mdl-data-table__cell--non-numeric"> - {{ speaker.name }} + <h5>{{ speaker.name }}</h5> </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> - {% 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 %} + {% endif %} + {% endfor %} </tbody> </table> {% endfor %} diff --git a/templates/speech_index.html b/templates/speech_index.html index ebd02b7..ad81430 100644 --- a/templates/speech_index.html +++ b/templates/speech_index.html @@ -8,7 +8,9 @@ <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 event.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> @@ -17,14 +19,15 @@ </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> + {% if (mode is not none and mode == "balanced") or (mode is none and event.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", event=event_id) }}"> @@ -42,7 +45,6 @@ </td> {% endif %} </tr> - {% endif %} {% endfor %} </tbody> </table> diff --git a/templates/update.js b/templates/update.js index c6634de..6246d0f 100644 --- a/templates/update.js +++ b/templates/update.js @@ -1,29 +1,31 @@ -var returned = true; -var last_content = ""; -function request() { - if (!returned) +var {{ prefix }}returned = true; +var {{ prefix }}last_content = ""; +function {{ prefix }}request() { + if (!{{ prefix }}returned) return; - returned = false; - var xmlhttp = new XMLHttpRequest(); - xmlhttp.onreadystatechange=function() { - if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { - returned = true; - update(xmlhttp.responseText); + {{ prefix }}returned = false; + var {{ prefix }}xmlhttp = new XMLHttpRequest(); + {{ prefix }}xmlhttp.onreadystatechange=function() { + if ({{ prefix }}xmlhttp.readyState == 4 && {{ prefix }}xmlhttp.status == 200) { + {{ prefix }}returned = true; + {{ prefix }}update({{ prefix }}xmlhttp.responseText); } }; - var target = "{{ target_url }}"; - xmlhttp.open("GET", target, true); - xmlhttp.send(); + var {{ prefix }}target = "{{ target_url }}"; + {{ prefix }}xmlhttp.open("GET", {{ prefix }}target, true); + {{ prefix }}xmlhttp.send(); } -function update(data) { - if (data != last_content) { - document.getElementById("{{ div }}").innerHTML = data; - last_content = data; +function {{ prefix }}update({{ prefix }}data) { + if ({{ prefix }}data != {{ prefix }}last_content) { + document.getElementById("{{ div }}").innerHTML = {{ prefix }}data; + {{ prefix }}last_content = {{ prefix }}data; } } +var {{ prefix }}f = window.onload; window.onload=function() { - window.setInterval(request, 1000 * {{ update_interval }}); + {{ prefix }}f(); + window.setInterval({{ prefix }}request, 1000 * {{ update_interval }}); } -- GitLab