Commit 99c15899 authored by Robin Sonnabend's avatar Robin Sonnabend
Browse files

Implemented printing

parent b3f71d25
...@@ -25,6 +25,14 @@ LDAP_PROVIDER_URL = "ldaps://auth.example.com:389" ...@@ -25,6 +25,14 @@ LDAP_PROVIDER_URL = "ldaps://auth.example.com:389"
LDAP_BASE = "dc=example,dc=example,dc=com" LDAP_BASE = "dc=example,dc=example,dc=com"
LDAP_PROTOCOL_VERSION = 3 # do not change LDAP_PROTOCOL_VERSION = 3 # do not change
PRINTING_ACTIVE = True
PRINTING_SERVER = "printsrv.example.com:631"
PRINTING_USER = "protocols"
PRINTING_PRINTERS = [
"example_printer": ["Duplex=DuplexNoTumble", "option2=value"],
"other_printer": ["list", "of", "options"]
]
ETHERPAD_URL = "https://fachschaften.rwth-aachen.de/etherpad" ETHERPAD_URL = "https://fachschaften.rwth-aachen.de/etherpad"
EMPTY_ETHERPAD = """Welcome to Etherpad! EMPTY_ETHERPAD = """Welcome to Etherpad!
......
"""empty message
Revision ID: f91d760158dc
Revises: d8c0c74b88bd
Create Date: 2017-02-25 21:52:07.654276
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'f91d760158dc'
down_revision = 'd8c0c74b88bd'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('protocoltypes', sa.Column('printer', sa.String(), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('protocoltypes', 'printer')
# ### end Alembic commands ###
...@@ -29,6 +29,7 @@ class ProtocolType(db.Model): ...@@ -29,6 +29,7 @@ class ProtocolType(db.Model):
use_wiki = db.Column(db.Boolean) use_wiki = db.Column(db.Boolean)
wiki_category = db.Column(db.String) wiki_category = db.Column(db.String)
wiki_only_public = db.Column(db.Boolean) wiki_only_public = db.Column(db.Boolean)
printer = db.Column(db.String)
protocols = relationship("Protocol", backref=backref("protocoltype"), cascade="all, delete-orphan", order_by="Protocol.id") protocols = relationship("Protocol", backref=backref("protocoltype"), cascade="all, delete-orphan", order_by="Protocol.id")
default_tops = relationship("DefaultTOP", backref=backref("protocoltype"), cascade="all, delete-orphan", order_by="DefaultTOP.number") default_tops = relationship("DefaultTOP", backref=backref("protocoltype"), cascade="all, delete-orphan", order_by="DefaultTOP.number")
...@@ -37,7 +38,7 @@ class ProtocolType(db.Model): ...@@ -37,7 +38,7 @@ class ProtocolType(db.Model):
def __init__(self, name, short_name, organization, def __init__(self, name, short_name, organization,
is_public, private_group, public_group, private_mail, public_mail, is_public, private_group, public_group, private_mail, public_mail,
use_wiki, wiki_category, wiki_only_public): use_wiki, wiki_category, wiki_only_public, printer):
self.name = name self.name = name
self.short_name = short_name self.short_name = short_name
self.organization = organization self.organization = organization
...@@ -49,16 +50,17 @@ class ProtocolType(db.Model): ...@@ -49,16 +50,17 @@ class ProtocolType(db.Model):
self.use_wiki = use_wiki self.use_wiki = use_wiki
self.wiki_category = wiki_category self.wiki_category = wiki_category
self.wiki_only_public = wiki_only_public self.wiki_only_public = wiki_only_public
self.printer = printer
def __repr__(self): def __repr__(self):
return ("<ProtocolType(id={}, short_name={}, name={}, " return ("<ProtocolType(id={}, short_name={}, name={}, "
"organization={}, is_public={}, private_group={}, " "organization={}, is_public={}, private_group={}, "
"public_group={}, use_wiki={}, wiki_category='{}', " "public_group={}, use_wiki={}, wiki_category='{}', "
"wiki_only_public={})>".format( "wiki_only_public={}, printer={})>".format(
self.id, self.short_name, self.name, self.id, self.short_name, self.name,
self.organization, self.is_public, self.private_group, self.organization, self.is_public, self.private_group,
self.public_group, self.use_wiki, self.wiki_category, self.public_group, self.use_wiki, self.wiki_category,
self.wiki_only_public)) self.wiki_only_public, self.printer))
def get_latest_protocol(self): def get_latest_protocol(self):
candidates = sorted([protocol for protocol in self.protocols if protocol.is_done()], key=lambda p: p.date, reverse=True) candidates = sorted([protocol for protocol in self.protocols if protocol.is_done()], key=lambda p: p.date, reverse=True)
......
...@@ -90,7 +90,7 @@ def new_type(): ...@@ -90,7 +90,7 @@ def new_type():
form.private_group.data, form.public_group.data, form.private_group.data, form.public_group.data,
form.private_mail.data, form.public_mail.data, form.private_mail.data, form.public_mail.data,
form.use_wiki.data, form.wiki_category.data, form.use_wiki.data, form.wiki_category.data,
form.wiki_only_public.data) form.wiki_only_public.data, form.printer.data)
db.session.add(protocoltype) db.session.add(protocoltype)
db.session.commit() db.session.commit()
flash("Der Protokolltyp {} wurde angelegt.".format(protocoltype.name), "alert-success") flash("Der Protokolltyp {} wurde angelegt.".format(protocoltype.name), "alert-success")
...@@ -688,6 +688,17 @@ def delete_document(document_id): ...@@ -688,6 +688,17 @@ def delete_document(document_id):
flash("Das Dokument {} wurde gelöscht.".format(name), "alert-success") flash("Das Dokument {} wurde gelöscht.".format(name), "alert-success")
return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id)) return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id))
@app.route("/document/print/<int:document_id>")
@login_required
def print_document(document_id):
user = current_user()
document = Document.query.filter_by(id=document_id).first()
if document is None or not document.protocol.protocoltype.has_modify_right(user):
flash("Invalides Protokoll oder keine Berechtigung.", "alert-error")
return redirect(request.args.get("next") or url_for("index"))
tasks.print_file(document.get_filename(), document.protocol)
flash("Das Dokument {} wird gedruckt.".format(document.name), "alert-success")
return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=document.protocol.id))
@app.route("/login", methods=["GET", "POST"]) @app.route("/login", methods=["GET", "POST"])
def login(): def login():
......
...@@ -281,6 +281,33 @@ def compile_async(content, protocol_id, show_private): ...@@ -281,6 +281,33 @@ def compile_async(content, protocol_id, show_private):
finally: finally:
os.chdir(current) os.chdir(current)
def print_file(filename, protocol):
if config.PRINTING_ACTIVE:
print_file_async.delay(filename, protocol.id)
@celery.task
def print_file_async(filename, protocol_id):
with app.app_context():
protocol = Protocol.query.filter_by(id=protocol_id).first()
if protocol.protocoltype.printer is None:
error = protocol.create_error("Printing", "No printer configured.", "You don't have any printer configured for the protocoltype {}. Please do so before printing a protocol.".format(protocol.protocoltype.name))
try:
command = [
"/usr/bin/lpr",
"-H", config.PRINTING_SERVER,
"-P", protocol.protocoltype.printer,
"-U", config.PRINTING_USER,
"-T", protocol.get_identifier(),
]
for option in config.PRINTING_PRINTERS[protocol.protocoltype.printer]:
command.extend(["-o", '"{}"'.format(option) if " " in option else option])
command.append(filename)
subprocess.check_call(command, universal_newlines=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
except subprocess.SubprocessError:
error = protocol.create_error("Printing", "Printing {} failed.".format(protocol.get_identifier()), "")
db.session.add(error)
db.session.commit()
def send_mail(mail): def send_mail(mail):
send_mail_async.delay(mail.id) send_mail_async.delay(mail.id)
......
...@@ -124,4 +124,3 @@ def set_etherpad_text(pad, text, only_if_default=True): ...@@ -124,4 +124,3 @@ def set_etherpad_text(pad, text, only_if_default=True):
req = requests.post(get_etherpad_import_url(pad), files=files) req = requests.post(get_etherpad_import_url(pad), files=files)
return req.status_code == 200 return req.status_code == 200
...@@ -2,6 +2,8 @@ from flask_wtf import FlaskForm ...@@ -2,6 +2,8 @@ from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, DateField, HiddenField, IntegerField, SelectField, FileField, DateTimeField from wtforms import StringField, PasswordField, BooleanField, DateField, HiddenField, IntegerField, SelectField, FileField, DateTimeField
from wtforms.validators import InputRequired, Optional from wtforms.validators import InputRequired, Optional
import config
class LoginForm(FlaskForm): class LoginForm(FlaskForm):
username = StringField("Benutzer", validators=[InputRequired("Bitte gib deinen Benutzernamen ein.")]) username = StringField("Benutzer", validators=[InputRequired("Bitte gib deinen Benutzernamen ein.")])
password = PasswordField("Passwort", validators=[InputRequired("Bitte gib dein Passwort ein.")]) password = PasswordField("Passwort", validators=[InputRequired("Bitte gib dein Passwort ein.")])
...@@ -18,6 +20,7 @@ class ProtocolTypeForm(FlaskForm): ...@@ -18,6 +20,7 @@ class ProtocolTypeForm(FlaskForm):
wiki_category = StringField("Wiki-Kategorie") wiki_category = StringField("Wiki-Kategorie")
use_wiki = BooleanField("Wiki benutzen") use_wiki = BooleanField("Wiki benutzen")
wiki_only_public = BooleanField("Wiki ist öffentlich") wiki_only_public = BooleanField("Wiki ist öffentlich")
printer = SelectField("Drucker", choices=list(zip(config.PRINTING_PRINTERS, config.PRINTING_PRINTERS)))
class DefaultTopForm(FlaskForm): class DefaultTopForm(FlaskForm):
name = StringField("Name", validators=[InputRequired("Du musst einen Namen angeben.")]) name = StringField("Name", validators=[InputRequired("Du musst einen Namen angeben.")])
......
...@@ -98,7 +98,7 @@ class ProtocolTypeTable(SingleValueTable): ...@@ -98,7 +98,7 @@ class ProtocolTypeTable(SingleValueTable):
headers = ["Name", "Abkürzung", "Organisation", "Öffentlich", headers = ["Name", "Abkürzung", "Organisation", "Öffentlich",
"Interne Gruppe", "Öffentliche Gruppe", "Interne Gruppe", "Öffentliche Gruppe",
"Interner Verteiler", "Öffentlicher Verteiler", "Interner Verteiler", "Öffentlicher Verteiler",
"Wiki"] "Drucker", "Wiki"]
if self.value.use_wiki: if self.value.use_wiki:
headers.append("Wiki-Kategorie") headers.append("Wiki-Kategorie")
return headers return headers
...@@ -113,7 +113,8 @@ class ProtocolTypeTable(SingleValueTable): ...@@ -113,7 +113,8 @@ class ProtocolTypeTable(SingleValueTable):
self.value.public_group, self.value.public_group,
self.value.private_mail, self.value.private_mail,
self.value.public_mail, self.value.public_mail,
Table.bool(self.value.use_wiki) + (", " + ("Öffentlich" if self.value.wiki_only_public else "Intern")) if self.value.use_wiki else "" self.value.printer,
(Table.bool(self.value.use_wiki) + ((", " + ("Öffentlich" if self.value.wiki_only_public else "Intern")) if self.value.use_wiki else ""))
] ]
if self.value.use_wiki: if self.value.use_wiki:
row.append(self.value.wiki_category) row.append(self.value.wiki_category)
...@@ -221,7 +222,10 @@ class DocumentsTable(Table): ...@@ -221,7 +222,10 @@ class DocumentsTable(Table):
return [ return [
document.id, document.id,
Table.link(url_for("download_document", document_id=document.id), document.name), Table.link(url_for("download_document", document_id=document.id), document.name),
(Table.link(url_for("delete_document", document_id=document.id), "Löschen", confirm="Bist du dir sicher, dass du das Dokument {} löschen willst?".format(document.name)) Table.concat([
if document.protocol.protocoltype.has_modify_right(user) Table.link(url_for("delete_document", document_id=document.id), "Löschen", confirm="Bist du dir sicher, dass du das Dokument {} löschen willst?".format(document.name)),
else "") Table.link(url_for("print_document", document_id=document.id), "Drucken")
])
if document.protocol.protocoltype.has_modify_right(user)
else ""
] ]
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