Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
protokollsystem
proto3
Commits
dabb0158
Commit
dabb0158
authored
Feb 24, 2017
by
Robin Sonnabend
Browse files
Upload source
parent
b4e667c7
Changes
8
Hide whitespace changes
Inline
Side-by-side
migrations/versions/aebae2c4523d_.py
0 → 100644
View file @
dabb0158
"""empty message
Revision ID: aebae2c4523d
Revises: b114754024fb
Create Date: 2017-02-24 05:58:37.240601
"""
from
alembic
import
op
import
sqlalchemy
as
sa
# revision identifiers, used by Alembic.
revision
=
'aebae2c4523d'
down_revision
=
'b114754024fb'
branch_labels
=
None
depends_on
=
None
def
upgrade
():
# ### commands auto generated by Alembic - please adjust! ###
op
.
drop_constraint
(
'documents_filename_key'
,
'documents'
,
type_
=
'unique'
)
# ### end Alembic commands ###
def
downgrade
():
# ### commands auto generated by Alembic - please adjust! ###
op
.
create_unique_constraint
(
'documents_filename_key'
,
'documents'
,
[
'filename'
])
# ### end Alembic commands ###
models/database.py
View file @
dabb0158
...
...
@@ -103,8 +103,11 @@ class Protocol(db.Model):
def
fill_from_remarks
(
self
,
remarks
):
new_date
=
datetime
.
strptime
(
remarks
[
"Datum"
].
value
,
"%d.%m.%Y"
).
date
()
if
new_date
!=
self
.
date
:
raise
DateNotMatchingException
(
original_date
=
self
.
date
,
protocol_date
=
new_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
...
...
@@ -115,11 +118,16 @@ class Protocol(db.Model):
return
self
.
done
def
get_identifier
(
self
):
if
self
.
date
is
None
:
return
None
return
"{}-{}"
.
format
(
self
.
protocoltype
.
short_name
.
lower
(),
self
.
date
.
strftime
(
"%y-%m-%d"
))
def
get_etherpad_link
(
self
):
identifier
=
self
.
get_identifier
()
if
identifier
is
None
:
return
""
return
config
.
ETHERPAD_URL
+
self
.
get_identifier
()
def
get_etherpad_source_link
(
self
):
...
...
@@ -131,6 +139,28 @@ class Protocol(db.Model):
def
get_originating_todos
(
self
):
return
[
todo
for
todo
in
self
.
todos
if
self
==
todo
.
get_first_protocol
()]
def
has_compiled_document
(
self
):
candidates
=
[
document
for
document
in
self
.
documents
if
document
.
is_compiled
]
return
len
(
candidates
)
>
0
def
get_compiled_document
(
self
,
private
=
None
):
candidates
=
[
document
for
document
in
self
.
documents
if
document
.
is_compiled
and
(
private
is
None
or
document
.
is_private
==
private
)
]
print
(
candidates
)
private_candidates
=
[
document
for
document
in
candidates
if
document
.
is_private
]
public_candidates
=
[
document
for
document
in
candidates
if
not
document
.
is_private
]
if
len
(
private_candidates
)
>
0
:
return
private_candidates
[
0
]
elif
len
(
public_candidates
)
>
0
:
return
public_candidates
[
0
]
return
None
def
delete_orphan_todos
(
self
):
orphan_todos
=
[
todo
for
todo
in
self
.
todos
...
...
@@ -187,7 +217,7 @@ class Document(db.Model):
id
=
db
.
Column
(
db
.
Integer
,
primary_key
=
True
)
protocol_id
=
db
.
Column
(
db
.
Integer
,
db
.
ForeignKey
(
"protocols.id"
))
name
=
db
.
Column
(
db
.
String
)
filename
=
db
.
Column
(
db
.
String
,
unique
=
True
)
filename
=
db
.
Column
(
db
.
String
)
is_compiled
=
db
.
Column
(
db
.
Boolean
)
is_private
=
db
.
Column
(
db
.
Boolean
)
...
...
server.py
View file @
dabb0158
...
...
@@ -17,7 +17,7 @@ import config
from
shared
import
db
,
date_filter
,
datetime_filter
,
date_filter_long
,
time_filter
,
ldap_manager
,
security_manager
,
current_user
,
check_login
,
login_required
,
group_required
from
utils
import
is_past
,
mail_manager
,
url_manager
from
models.database
import
ProtocolType
,
Protocol
,
DefaultTOP
,
TOP
,
Document
,
Todo
,
Decision
,
MeetingReminder
,
Error
from
views.forms
import
LoginForm
,
ProtocolTypeForm
,
DefaultTopForm
,
MeetingReminderForm
,
NewProtocolForm
,
DocumentUploadForm
from
views.forms
import
LoginForm
,
ProtocolTypeForm
,
DefaultTopForm
,
MeetingReminderForm
,
NewProtocolForm
,
DocumentUploadForm
,
KnownProtocolSourceUploadForm
,
NewProtocolSourceUploadForm
from
views.tables
import
ProtocolsTable
,
ProtocolTypesTable
,
ProtocolTypeTable
,
DefaultTOPsTable
,
MeetingRemindersTable
,
ErrorsTable
,
TodosTable
,
DocumentsTable
app
=
Flask
(
__name__
)
...
...
@@ -293,6 +293,7 @@ def new_protocol():
if
protocoltype
.
has_modify_right
(
user
)
]
form
=
NewProtocolForm
(
protocoltypes
)
upload_form
=
NewProtocolSourceUploadForm
(
protocoltypes
)
if
form
.
validate_on_submit
():
protocoltype
=
ProtocolType
.
query
.
filter_by
(
id
=
form
.
protocoltype
.
data
).
first
()
if
protocoltype
is
None
or
not
protocoltype
.
has_modify_right
(
user
):
...
...
@@ -305,7 +306,7 @@ def new_protocol():
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
,
protocoltypes
=
protocoltypes
)
return
render_template
(
"protocol-new.html"
,
form
=
form
,
upload_form
=
upload_form
,
protocoltypes
=
protocoltypes
)
@
app
.
route
(
"/protocol/show/<int:protocol_id>"
)
def
show_protocol
(
protocol_id
):
...
...
@@ -322,7 +323,8 @@ def show_protocol(protocol_id):
]
documents_table
=
DocumentsTable
(
visible_documents
)
document_upload_form
=
DocumentUploadForm
()
return
render_template
(
"protocol-show.html"
,
protocol
=
protocol
,
errors_table
=
errors_table
,
documents_table
=
documents_table
,
document_upload_form
=
document_upload_form
)
source_upload_form
=
KnownProtocolSourceUploadForm
()
return
render_template
(
"protocol-show.html"
,
protocol
=
protocol
,
errors_table
=
errors_table
,
documents_table
=
documents_table
,
document_upload_form
=
document_upload_form
,
source_upload_form
=
source_upload_form
)
@
app
.
route
(
"/protocol/delete/<int:protocol_id>"
)
@
login_required
...
...
@@ -339,6 +341,7 @@ def delete_protocol(protocol_id):
return
redirect
(
request
.
args
.
get
(
"next"
)
or
url_for
(
"list_protocols"
))
@
app
.
route
(
"/protocol/etherpull/<int:protocol_id>"
)
@
login_required
def
etherpull_protocol
(
protocol_id
):
user
=
current_user
()
protocol
=
Protocol
.
query
.
filter_by
(
id
=
protocol_id
).
first
()
...
...
@@ -353,6 +356,64 @@ def etherpull_protocol(protocol_id):
flash
(
"Das Protokoll wird kompiliert."
,
"alert-success"
)
return
redirect
(
request
.
args
.
get
(
"next"
)
or
url_for
(
"show_protocol"
,
protocol_id
=
protocol
.
id
))
@
app
.
route
(
"/protocol/upload/known/<int:protocol_id>"
,
methods
=
[
"POST"
])
@
login_required
def
upload_source_to_known_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 keine Berechtigung."
,
"alert-error"
)
return
redirect
(
request
.
args
.
get
(
"next"
)
or
url_for
(
"index"
))
form
=
KnownProtocolSourceUploadForm
()
if
form
.
validate_on_submit
():
if
form
.
source
.
data
is
None
:
flash
(
"Es wurde keine Datei ausgewählt."
,
"alert-error"
)
else
:
file
=
form
.
source
.
data
if
file
.
filename
==
""
:
flash
(
"Es wurde keine Datei ausgewählt."
,
"alert-error"
)
else
:
# todo: Prüfen, ob es Text ist?
source
=
file
.
stream
.
read
().
decode
(
"utf-8"
)
protocol
.
source
=
source
db
.
session
.
commit
()
tasks
.
parse_protocol
(
protocol
)
flash
(
"Das Protokoll wird kompiliert."
,
"alert-success"
)
return
redirect
(
request
.
args
.
get
(
"next"
)
or
url_for
(
"show_protocol"
,
protocol_id
=
protocol
.
id
))
@
app
.
route
(
"/protocol/upload/new/"
,
methods
=
[
"POST"
])
@
login_required
def
upload_new_protocol
():
user
=
current_user
()
available_types
=
[
protocoltype
for
protocoltype
in
ProtocolType
.
query
.
all
()
if
protocoltype
.
has_modify_right
(
user
)
]
form
=
NewProtocolSourceUploadForm
(
protocoltypes
=
available_types
)
if
form
.
validate_on_submit
():
if
form
.
source
.
data
is
None
:
flash
(
"Es wurde keine Datei ausgewählt."
,
"alert-error"
)
else
:
print
(
form
.
source
.
data
)
file
=
form
.
source
.
data
if
file
.
filename
==
""
:
flash
(
"Es wurde keine Datei ausgewählt."
,
"alert-error"
)
else
:
source
=
file
.
stream
.
read
().
decode
(
"utf-8"
)
protocoltype
=
ProtocolType
.
query
.
filter_by
(
id
=
form
.
protocoltype
.
data
).
first
()
if
protocoltype
is
None
or
not
protocoltype
.
has_modify_right
(
user
):
flash
(
"Invalider Protokolltyp oder keine Rechte."
,
"alert-error"
)
else
:
protocol
=
Protocol
(
protocoltype
.
id
,
None
,
source
)
db
.
session
.
add
(
protocol
)
db
.
session
.
commit
()
tasks
.
parse_protocol
(
protocol
)
return
redirect
(
request
.
args
.
get
(
"next"
)
or
url_for
(
"show_protocol"
,
protocol_id
=
protocol
.
id
))
return
redirect
(
request
.
args
.
get
(
"fail"
)
or
url_for
(
"new_protocol"
))
@
app
.
route
(
"/protocol/source/<int:protocol_id>"
)
@
login_required
def
get_protocol_source
(
protocol_id
):
...
...
@@ -372,8 +433,8 @@ def update_protocol(protocol_id):
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"
))
# TODO: render form to upload a new version
upload_form
=
KnownProtocolSourceUploadForm
()
return
render_template
(
"protocol-update.html"
,
upload_form
=
upload_form
,
protocol
=
protocol
)
@
app
.
route
(
"/todos/list"
)
def
list_todos
():
...
...
tasks.py
View file @
dabb0158
...
...
@@ -172,9 +172,12 @@ def parse_protocol_async(protocol_id, encoded_kwargs):
db
.
session
.
add
(
top
)
db
.
session
.
commit
()
for
show_private
in
[
True
,
False
]:
latex_source
=
texenv
.
get_template
(
"protocol.tex"
).
render
(
protocol
=
protocol
,
tree
=
tree
,
show_private
=
show_private
)
compile
(
latex_source
,
protocol
,
show_private
=
show_private
)
latex_source_private
=
texenv
.
get_template
(
"protocol.tex"
).
render
(
protocol
=
protocol
,
tree
=
tree
,
show_private
=
True
)
latex_source_public
=
texenv
.
get_template
(
"protocol.tex"
).
render
(
protocol
=
protocol
,
tree
=
tree
,
show_private
=
False
)
compile
(
latex_source_public
,
protocol
,
show_private
=
False
)
if
latex_source_private
!=
latex_source_public
:
compile
(
latex_source_private
,
protocol
,
show_private
=
True
)
# TODO compare something that may actually be equal
protocol
.
done
=
True
db
.
session
.
commit
()
...
...
templates/protocol-new.html
View file @
dabb0158
...
...
@@ -4,6 +4,15 @@
{% block content %}
<div
class=
"container"
>
{{render_form(form, action_url=url_for("new_protocol"), action_text="Anlegen")}}
<div
class=
"row"
>
<div
id=
"left-column"
class=
"col-lg-6"
>
<h3>
Neues Protokoll
</h3>
{{render_form(form, action_url=url_for("new_protocol"), action_text="Anlegen")}}
</div>
<div
id=
"left-column"
class=
"col-lg-6"
>
<h3>
Neues Protokoll hochladen
</h3>
{{render_form(upload_form, action_url=url_for("upload_new_protocol", fail=url_for("new_protocol")), action_text="Hochladen", enctype="multipart/form-data")}}
</div>
</div>
</div>
{% endblock %}
templates/protocol-show.html
View file @
dabb0158
...
...
@@ -5,25 +5,38 @@
{% block content %}
<div
class=
"container"
>
<div
class=
"btn-group"
>
<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>
{% 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 %}
{% if protocol.is_done() %}
<a
class=
"btn btn-success"
href=
"{{url_for("
update_protocol
",
protocol_id=
protocol.id)}}"
>
Protokoll editieren
</a>
{% if protocol.protocoltype.has_modify_right(current_user()) %}
<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>
{% 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 %}
{% if protocol.is_done() %}
<a
class=
"btn btn-success"
href=
"{{url_for("
update_protocol
",
protocol_id=
protocol.id)}}"
>
Protokoll editieren
</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>
{% 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>
</div>
<div
class=
"row"
>
<div
id=
"left-column"
class=
"col-lg-6"
>
<h2>
Protokoll: {{protocol.protocoltype.name}} vom {{protocol.date|datify}}
</h2>
{% if protocol.is_done() %}
<p><strong>
Datum:
</strong>
{{protocol.date|datify_long}}
</p>
<p><strong>
Zeit:
</strong>
von {{protocol.start_time|timify}} bis {{protocol.end_time|timify}}
</p>
<p><strong>
Ort:
</strong>
{{protocol.location}}
</p>
<p><strong>
Protokollant:
</strong>
{{protocol.author}}
</p>
<p><strong>
Anwesende:
</strong>
{{protocol.participants}}
</p>
{% if protocol.date is not none %}
<p><strong>
Datum:
</strong>
{{protocol.date|datify_long}}
</p>
{% endif %}
{% if protocol.start_time is not none and protocol.end_time is not none %}
<p><strong>
Zeit:
</strong>
von {{protocol.start_time|timify}} bis {{protocol.end_time|timify}}
</p>
{% endif %}
{% if protocol.location is not none %}
<p><strong>
Ort:
</strong>
{{protocol.location}}
</p>
{% endif %}
{% if protocol.author is not none %}
<p><strong>
Protokollant:
</strong>
{{protocol.author}}
</p>
{% endif %}
{% if protocol.participants is not none %}
<p><strong>
Anwesende:
</strong>
{{protocol.participants}}
</p>
{% endif %}
{% else %}
<p><strong>
Geplant:
</strong>
{{protocol.date|datify_long}}
</p>
{% endif %}
...
...
@@ -60,25 +73,30 @@
</div>
<div
id=
"right-column"
class=
"col-lg-6"
>
{% if protocol.is_done() %}
<h3>
Todos dieser Sitzung
<a
href=
"{{url_for("
list_todos
")}}"
>
Aktuelle Todos
</a></h3>
<ul>
{% if protocol.get_originating_todos()|length > 0 %}
{% for todo in protocol.get_originating_todos() %}
<li>
{{todo.render_html()|safe}}
</li>
{% endfor %}
{% else %}
<li>
Keine Todos
</li>
{% endif %}
</ul>
<h3>
Todos dieser Sitzung
<a
href=
"{{url_for("
list_todos
")}}"
>
Aktuelle Todos
</a></h3>
<ul>
{% if protocol.get_originating_todos()|length > 0 %}
{% for todo in protocol.get_originating_todos() %}
<li>
{{todo.render_html()|safe}}
</li>
{% endfor %}
{% else %}
<li>
Keine Todos
</li>
{% endif %}
</ul>
{% endif %}
{% if protocol.errors|length > 0 %}
{{render_table(errors_table)}}
{% if protocol.protocoltype.has_modify_right(current_user()) %}
{% if protocol.errors|length > 0 %}
{{render_table(errors_table)}}
{% endif %}
{% endif %}
{% if protocol.documents|length > 0 %}
{{render_table(documents_table)}}
{% else %}
<h3>
Hochladen
</h3>
{% endif %}
{% if protocol.is_done() %}
{{render_form(document_upload_form, action_url=url_for("upload_document", protocol_id=protocol.id, next=url_for("show_protocol", protocol_id=protocol.id)), action_text="Hochladen", enctype="multipart/form-data")}}
{% if protocol.protocoltype.has_modify_right(current_user()) %}
{{render_form(source_upload_form, action_url=url_for("upload_source_to_known_protocol", protocol_id=protocol.id, next=url_for("show_protocol", protocol_id=protocol.id)), action_text="Hochladen", enctype="multipart/form-data")}}
{{render_form(document_upload_form, action_url=url_for("upload_document", protocol_id=protocol.id, next=url_for("show_protocol", protocol_id=protocol.id)), action_text="Hochladen", enctype="multipart/form-data")}}
{% endif %}
</div>
</div>
...
...
templates/protocol-update.html
0 → 100644
View file @
dabb0158
{% extends "layout.html" %}
{% from "macros.html" import render_form %}
{% block title %}Protokoll ändern{% endblock %}
{% block content %}
<div
class=
"container"
>
<div
class=
"row"
>
<div
id=
"left-column"
class=
"col-lg-6"
>
<h3>
Protokoll herunterladen
</h3>
<div
class=
"btn-group"
>
{% 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 btn-default"
href=
"{{url_for("
show_protocol
",
protocol_id=
protocol.id)}}"
>
Zurück
</a>
{% if protocol.has_compiled_document() %}
<a
class=
"btn btn-success"
href=
"{{url_for("
download_document
",
document_id=
protocol.get_compiled_document().id)}}"
>
Download PDF
</a>
{% endif %}
</div>
</div>
<div
id=
"right-column"
class=
"col-lg-6"
>
<h3>
Neue Version hochladen
</h3>
{{render_form(upload_form, action_url=url_for("upload_source_to_known_protocol", protocol_id=protocol.id), action_text="Hochladen", enctype="multipart/form-data")}}
</div>
</div>
</div>
{% endblock %}
views/forms.py
View file @
dabb0158
...
...
@@ -34,5 +34,16 @@ class NewProtocolForm(FlaskForm):
self
.
protocoltype
.
choices
=
[(
protocoltype
.
id
,
protocoltype
.
short_name
)
for
protocoltype
in
protocoltypes
]
class
DocumentUploadForm
(
FlaskForm
):
document
=
FileField
(
"Datei"
,
validators
=
[
InputRequired
(
"Du musst eine Datei angeben."
)]
)
document
=
FileField
(
"Datei"
)
private
=
BooleanField
(
"Intern"
)
class
KnownProtocolSourceUploadForm
(
FlaskForm
):
source
=
FileField
(
"Quellcode"
)
class
NewProtocolSourceUploadForm
(
FlaskForm
):
source
=
FileField
(
"Quellcode"
)
protocoltype
=
SelectField
(
"Typ"
,
choices
=
[],
coerce
=
int
)
def
__init__
(
self
,
protocoltypes
,
**
kwargs
):
super
().
__init__
(
**
kwargs
)
self
.
protocoltype
.
choices
=
[(
protocoltype
.
id
,
protocoltype
.
short_name
)
for
protocoltype
in
protocoltypes
]
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment