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"
LDAP_BASE = "dc=example,dc=example,dc=com"
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"
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):
use_wiki = db.Column(db.Boolean)
wiki_category = db.Column(db.String)
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")
default_tops = relationship("DefaultTOP", backref=backref("protocoltype"), cascade="all, delete-orphan", order_by="DefaultTOP.number")
......@@ -37,7 +38,7 @@ class ProtocolType(db.Model):
def __init__(self, name, short_name, organization,
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.short_name = short_name
self.organization = organization
......@@ -49,16 +50,17 @@ class ProtocolType(db.Model):
self.use_wiki = use_wiki
self.wiki_category = wiki_category
self.wiki_only_public = wiki_only_public
self.printer = printer
def __repr__(self):
return ("<ProtocolType(id={}, short_name={}, name={}, "
"organization={}, is_public={}, private_group={}, "
"public_group={}, use_wiki={}, wiki_category='{}', "
"wiki_only_public={})>".format(
"wiki_only_public={}, printer={})>".format(
self.id, self.short_name, self.name,
self.organization, self.is_public, self.private_group,
self.public_group, self.use_wiki, self.wiki_category,
self.wiki_only_public))
self.wiki_only_public, self.printer))
def get_latest_protocol(self):
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():
form.private_group.data, form.public_group.data,
form.private_mail.data, form.public_mail.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.commit()
flash("Der Protokolltyp {} wurde angelegt.".format(protocoltype.name), "alert-success")
......@@ -688,6 +688,17 @@ def delete_document(document_id):
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))
@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"])
def login():
......
......@@ -281,6 +281,33 @@ def compile_async(content, protocol_id, show_private):
finally:
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):
send_mail_async.delay(mail.id)
......
......@@ -124,4 +124,3 @@ def set_etherpad_text(pad, text, only_if_default=True):
req = requests.post(get_etherpad_import_url(pad), files=files)
return req.status_code == 200
......@@ -2,6 +2,8 @@ from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, DateField, HiddenField, IntegerField, SelectField, FileField, DateTimeField
from wtforms.validators import InputRequired, Optional
import config
class LoginForm(FlaskForm):
username = StringField("Benutzer", validators=[InputRequired("Bitte gib deinen Benutzernamen ein.")])
password = PasswordField("Passwort", validators=[InputRequired("Bitte gib dein Passwort ein.")])
......@@ -18,6 +20,7 @@ class ProtocolTypeForm(FlaskForm):
wiki_category = StringField("Wiki-Kategorie")
use_wiki = BooleanField("Wiki benutzen")
wiki_only_public = BooleanField("Wiki ist öffentlich")
printer = SelectField("Drucker", choices=list(zip(config.PRINTING_PRINTERS, config.PRINTING_PRINTERS)))
class DefaultTopForm(FlaskForm):
name = StringField("Name", validators=[InputRequired("Du musst einen Namen angeben.")])
......
......@@ -98,7 +98,7 @@ class ProtocolTypeTable(SingleValueTable):
headers = ["Name", "Abkürzung", "Organisation", "Öffentlich",
"Interne Gruppe", "Öffentliche Gruppe",
"Interner Verteiler", "Öffentlicher Verteiler",
"Wiki"]
"Drucker", "Wiki"]
if self.value.use_wiki:
headers.append("Wiki-Kategorie")
return headers
......@@ -113,7 +113,8 @@ class ProtocolTypeTable(SingleValueTable):
self.value.public_group,
self.value.private_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:
row.append(self.value.wiki_category)
......@@ -221,7 +222,10 @@ class DocumentsTable(Table):
return [
document.id,
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))
if document.protocol.protocoltype.has_modify_right(user)
else "")
Table.concat([
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.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