Commit 9762468a authored by Robin Sonnabend's avatar Robin Sonnabend
Browse files

Fixed todos

parent 6ebc35e9
"""empty message
Revision ID: 24bd2198a626
Revises: 2e2682dfac21
Create Date: 2017-02-24 17:20:07.135782
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '24bd2198a626'
down_revision = '2e2682dfac21'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('todos', sa.Column('number', sa.Integer(), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('todos', 'number')
# ### end Alembic commands ###
"""empty message
Revision ID: 2e2682dfac21
Revises: aebae2c4523d
Create Date: 2017-02-24 16:31:01.729972
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '2e2682dfac21'
down_revision = 'aebae2c4523d'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('todos', sa.Column('is_id_fixed', sa.Boolean(), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('todos', 'is_id_fixed')
# ### end Alembic commands ###
......@@ -102,17 +102,17 @@ class Protocol(db.Model):
return Error(self.id, action, name, now, description)
def fill_from_remarks(self, remarks):
new_date = datetime.strptime(remarks["Datum"].value, "%d.%m.%Y").date()
new_date = datetime.strptime(remarks["Datum"].value.strip(), "%d.%m.%Y").date()
if self.date is not None:
if new_date != self.date:
raise DateNotMatchingException(original_date=self.date, protocol_date=new_date)
else:
self.date = new_date
self.start_time = datetime.strptime(remarks["Beginn"].value, "%H:%M").time()
self.end_time = datetime.strptime(remarks["Ende"].value, "%H:%M").time()
self.author = remarks["Autor"].value
self.participants = remarks["Anwesende"].value
self.location = remarks["Ort"].value
self.start_time = datetime.strptime(remarks["Beginn"].value.strip(), "%H:%M").time()
self.end_time = datetime.strptime(remarks["Ende"].value.strip(), "%H:%M").time()
self.author = remarks["Autor"].value.strip()
self.participants = remarks["Anwesende"].value.strip()
self.location = remarks["Ort"].value.strip()
def is_done(self):
return self.done
......@@ -160,6 +160,9 @@ class Protocol(db.Model):
return public_candidates[0]
return None
def get_template(self):
return render_template("protocol-template.txt", protocol=self)
def delete_orphan_todos(self):
orphan_todos = [
todo for todo in self.todos
......@@ -244,22 +247,28 @@ def on_document_delete(mapper, connection, document):
class Todo(db.Model):
__tablename__ = "todos"
id = db.Column(db.Integer, primary_key=True)
number = db.Column(db.Integer)
who = db.Column(db.String)
description = db.Column(db.String)
tags = db.Column(db.String)
done = db.Column(db.Boolean)
is_id_fixed = db.Column(db.Boolean, default=False)
protocols = relationship("Protocol", secondary="todoprotocolassociations", backref="todos")
def __init__(self, who, description, tags, done):
def __init__(self, who, description, tags, done, number=None):
self.who = who
self.description = description
self.tags = tags
self.done = done
self.number = number
def __repr__(self):
return "<Todo(id={}, who={}, description={}, tags={}, done={})>".format(
self.id, self.who, self.description, self.tags, self.done)
return "<Todo(id={}, number={}, who={}, description={}, tags={}, done={})>".format(
self.id, self.number, self.who, self.description, self.tags, self.done)
def get_id(self):
return self.number if self.number is not None else self.id
def get_first_protocol(self):
candidates = sorted(self.protocols, key=lambda p: p.date)
......
......@@ -304,27 +304,12 @@ def new_protocol():
protocol = Protocol(protocoltype.id, form.date.data)
db.session.add(protocol)
db.session.commit()
return redirect(request.args.get("next") or url_for("list_protocols"))
return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id))
type_id = request.args.get("type_id")
if type_id is not None:
form.protocoltype.data = type_id
return render_template("protocol-new.html", form=form, upload_form=upload_form, protocoltypes=protocoltypes)
@app.route("/protocol/edit/<int:protocol_id>", methods=["POST"])
@login_required
def edit_protocol(protocol_id):
user = current_user()
protocol = Protocol.query.filter_by(id=protocol_id).first()
if protocol is None or not protocol.protocoltype.has_modify_right(user):
flash("Invalides Protokoll oder fehlende Zugriffsrechte.", "alert-error")
return redirect(request.args.get("next") or url_for("list_protocols"))
form = ProtocolForm(obj=protocol)
if form.validate_on_submit():
form.populate_obj(protocol)
db.session.commit()
return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id))
return redirect(request.args.get("fail") or url_for("update_protocol", protocol_id=protocol.id))
@app.route("/protocol/show/<int:protocol_id>")
def show_protocol(protocol_id):
user = current_user()
......@@ -439,7 +424,18 @@ def get_protocol_source(protocol_id):
file_like = BytesIO(protocol.source.encode("utf-8"))
return send_file(file_like, cache_timeout=1, as_attachment=True, attachment_filename="{}.txt".format(protocol.get_identifier()))
@app.route("/protocol/update/<int:protocol_id>")
@app.route("/protocol/template/<int:protocol_id>")
@login_required
def get_protocol_template(protocol_id):
user = current_user()
protocol = Protocol.query.filter_by(id=protocol_id).first()
if protocol is None or not protocol.protocoltype.has_modify_right(user):
flash("Invalides Protokoll oder keine Berechtigung.", "alert-error")
return redirect(request.args.get("next") or url_for("index"))
file_like = BytesIO(protocol.get_template().encode("utf-8"))
return send_file(file_like, cache_timeout=1, as_attachment=True, attachment_filename="{}-template.txt".format(protocol.get_identifier()))
@app.route("/protocol/update/<int:protocol_id>", methods=["GET", "POST"])
@login_required
def update_protocol(protocol_id):
user = current_user()
......@@ -449,6 +445,10 @@ def update_protocol(protocol_id):
return redirect(request.args.get("next") or url_for("index"))
upload_form = KnownProtocolSourceUploadForm()
edit_form = ProtocolForm(obj=protocol)
if edit_form.validate_on_submit():
edit_form.populate_obj(protocol)
db.session.commit()
return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id))
return render_template("protocol-update.html", upload_form=upload_form, edit_form=edit_form, protocol=protocol)
@app.route("/protocol/tops/new/<int:protocol_id>", methods=["GET", "POST"])
......
......@@ -121,9 +121,9 @@ def parse_protocol_async(protocol_id, encoded_kwargs):
who = todo_tag.values[0]
what = todo_tag.values[1]
todo = None
field_id = None
for other_field in todo_tag.values[2:]:
if other_field.startswith(ID_FIELD_BEGINNING):
field_id = 0
try:
field_id = int(other_field[len(ID_FIELD_BEGINNING):])
except ValueError:
......@@ -133,10 +133,27 @@ def parse_protocol_async(protocol_id, encoded_kwargs):
db.session.add(error)
db.session.commit()
return
todo = Todo.query.filter_by(id=field_id).first()
todo = Todo.query.filter_by(number=field_id).first()
who = who.strip()
what = what.strip()
if todo is None:
todo = Todo(who=who, description=what, tags="", done=False)
db.session.add(todo)
if field_id is not None:
candidate = Todo.query.filter_by(who=who, description=what, number=None).first()
if candidate is None:
candidate = Todo.query.filter_by(description=what, number=None).first()
if candidate is not None:
candidate.number = field_id
todo = candidate
else:
todo = Todo(who=who, description=what, tags="", done=False)
todo.number = field_id
else:
candidate = Todo.query.filter_by(who=who, description=what).first()
if candidate is not None:
todo = candidate
else:
todo = Todo(who=who, description=what, tags="", done=False)
db.session.add(todo)
todo.protocols.append(protocol)
todo_tags_internal = todo.tags.split(";")
for other_field in todo_tag.values[2:]:
......
......@@ -12,11 +12,14 @@
<div class="container">
<div class="btn-group">
{% if has_modify_right %}
<a class="btn {% if protocol.source is none %}btn-primary{% else %}btn-default{% endif %}" href="{{url_for("etherpull_protocol", protocol_id=protocol.id)}}">From etherpad</a>
<a class="btn {% if protocol.source is none %}btn-primary{% else %}btn-default{% endif %}" href="{{url_for("etherpull_protocol", protocol_id=protocol.id)}}">Aus Etherpad</a>
{% if protocol.source is not none %}
<a class="btn btn-primary" href="{{url_for("get_protocol_source", protocol_id=protocol.id)}}">Download Quelltext</a>
{% endif %}
<a class="btn {% if protocol.is_done() %}btn-success{% else %}btn-default{% endif %}" href="{{url_for("update_protocol", protocol_id=protocol.id)}}">Protokoll editieren</a>
{% if not protocol.is_done() %}
<a class="btn btn-default" href="{{url_for("get_protocol_template", protocol_id=protocol.id)}}">Vorlage herunterladen</a>
{% endif %}
<a class="btn btn-default" href="{{protocol.get_etherpad_link()}}" target="_blank">Etherpad</a>
<a class="btn btn-default" href="{{url_for("show_type", type_id=protocol.protocoltype.id)}}">Typ</a>
<a class="btn btn-danger" href="{{url_for("delete_protocol", protocol_id=protocol.id)}}" onclick="return confirm('Bist du dir sicher, dass du das Protokoll {{protocol.get_identifier()}} löschen möchtest?');">Löschen</a>
......
#Datum;{{protocol.date|datify}}
#Anwesende;
#Beginn;
#Ende;
#Autor;
#Ort;
{% macro render_top(top) %}
{TOP {{top.name}}
{% if top.name == "Todos" %}
{% if protocol.todos|length > 0 %}
{% for todo in protocol.todos %}
[todo;{{todo.who}};{{todo.description}};id {{todo.get_number()}}];
{% endfor %}
{% else %}
{% endif %}
{% else %}
{% endif %}
}
{% endmacro -%}
{% if not protocol.has_nonplanned_tops() %}
{% for default_top in protocol.protocoltype.default_tops %}
{% if not default_top.is_at_end() %}
{{-render_top(default_top)}}
{% endif %}
{% endfor %}
{% endif %}
{% for top in protocol.tops %}
{{-render_top(top)}}
{% endfor %}
{% if not protocol.has_nonplanned_tops() %}
{% for default_top in protocol.protocoltype.default_tops %}
{% if default_top.is_at_end() %}
{{-render_top(default_top)}}
{% endif %}
{% endfor %}
{% endif %}
......@@ -9,10 +9,10 @@
{% for top in protocol.tops %}
<li>
{{top.name}}
{% if has_private_view_right %}
{% if not protocol.is_done() and has_private_view_right %}
({{top.number}})
{% endif %}
{% if has_modify_right %}
{% if not protocol.is_done() and has_modify_right %}
<a href="{{url_for('edit_top', top_id=top.id)}}">Ändern</a>
<a href="{{url_for('move_top', top_id=top.id, diff=1)}}">Runter</a>
<a href="{{url_for('move_top', top_id=top.id, diff=-1)}}">Hoch</a>
......
......@@ -6,7 +6,7 @@
<div class="container">
<div class="row">
<div id="left-column" class="col-lg-6">
{{render_form(edit_form, action_url=url_for("edit_protocol", protocol_id=protocol.id), action_text="Ändern")}}
{{render_form(edit_form, action_url=url_for("update_protocol", protocol_id=protocol.id), action_text="Ändern")}}
</div>
<div id="right-column" class="col-lg-6">
<h3>Protokoll herunterladen</h3>
......
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, DateField, HiddenField, IntegerField, SelectField, FileField, DateTimeField
from wtforms.validators import InputRequired
from wtforms.validators import InputRequired, Optional
class LoginForm(FlaskForm):
username = StringField("Benutzer", validators=[InputRequired("Bitte gib deinen Benutzernamen ein.")])
......@@ -50,8 +50,8 @@ class NewProtocolSourceUploadForm(FlaskForm):
class ProtocolForm(FlaskForm):
date = DateField("Datum", validators=[InputRequired("Bitte gib das Datum des Protkolls an.")], format="%d.%m.%Y")
start_time = DateTimeField("Beginn", format="%H:%M")
end_time = DateTimeField("Ende", format="%H:%M")
start_time = DateTimeField("Beginn", format="%H:%M", validators=[Optional()])
end_time = DateTimeField("Ende", format="%H:%M", validators=[Optional()])
location = StringField("Ort")
author = StringField("Protokollant")
participants = StringField("Anwesende")
......
......@@ -177,11 +177,12 @@ class TodosTable(Table):
super().__init__("Todos", todos)
def headers(self):
return ["Status", "Sitzung", "Name", "Aufgabe"]
return ["ID", "Status", "Sitzung", "Name", "Aufgabe"]
def row(self, todo):
protocol = todo.get_first_protocol()
return [
todo.get_id(),
todo.get_state(),
Table.link(url_for("show_protocol", protocol_id=protocol.id), protocol.get_identifier()) if protocol is not None else "",
todo.who,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment