From 6031524d2eded53c505b07453aa1946c52bf3c31 Mon Sep 17 00:00:00 2001
From: Robin Sonnabend <robin@fsmpi.rwth-aachen.de>
Date: Fri, 24 Feb 2017 19:39:43 +0100
Subject: [PATCH] Pushing to etherpad

---
 models/database.py           |  7 ++-----
 requirements.txt             |  6 ++++++
 server.py                    | 21 ++++++++++++++++-----
 shared.py                    |  5 -----
 templates/protocol-show.html |  3 ++-
 utils.py                     | 24 ++++++++++++++++++++++++
 6 files changed, 50 insertions(+), 16 deletions(-)

diff --git a/models/database.py b/models/database.py
index 582c9ec..2ca9abc 100644
--- a/models/database.py
+++ b/models/database.py
@@ -4,7 +4,7 @@ from datetime import datetime, time, date, timedelta
 import math
 
 from shared import db
-from utils import random_string, url_manager
+from utils import random_string, url_manager, get_etherpad_url
 from models.errors import DateNotMatchingException
 
 import os
@@ -128,10 +128,7 @@ class Protocol(db.Model):
         identifier = self.get_identifier()
         if identifier is None:
             return ""
-        return config.ETHERPAD_URL + self.get_identifier()
-
-    def get_etherpad_source_link(self):
-        return self.get_etherpad_link() + "/export/txt"
+        return get_etherpad_url(self.get_identifier())
 
     def has_nonplanned_tops(self):
         return len([top for top in self.tops if not top.planned]) > 0
diff --git a/requirements.txt b/requirements.txt
index 5b99e67..78fd29d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,15 +3,19 @@ amqp==2.1.4
 appdirs==1.4.0
 argh==0.26.2
 billiard==3.5.0.2
+blessings==1.6
 blinker==1.4
+bpython==0.16
 celery==4.0.2
 click==6.7
+curtsies==0.2.11
 Flask==0.12
 Flask-Migrate==2.0.3
 Flask-Script==2.0.5
 Flask-SocketIO==2.8.4
 Flask-SQLAlchemy==2.1
 Flask-WTF==0.14.2
+greenlet==0.4.12
 itsdangerous==0.24
 Jinja2==2.9.5
 kombu==4.0.2
@@ -20,6 +24,7 @@ MarkupSafe==0.23
 packaging==16.8
 pathtools==0.1.2
 psycopg2==2.6.2
+Pygments==2.2.0
 pyldap==2.4.28
 pyparsing==2.1.10
 python-editor==1.0.3
@@ -34,5 +39,6 @@ six==1.10.0
 SQLAlchemy==1.1.5
 vine==1.1.3
 watchdog==0.8.3
+wcwidth==0.1.7
 Werkzeug==0.11.15
 WTForms==2.1
diff --git a/server.py b/server.py
index a9d1962..befafac 100755
--- a/server.py
+++ b/server.py
@@ -8,14 +8,13 @@ from flask_script import Manager, prompt
 from flask_migrate import Migrate, MigrateCommand
 #from flask_socketio import SocketIO
 from celery import Celery
-import requests
 from io import StringIO, BytesIO
 import os
 from datetime import datetime
 
 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, get_first_unused_int
+from utils import is_past, mail_manager, url_manager, get_first_unused_int, set_etherpad_text, get_etherpad_text
 from models.database import ProtocolType, Protocol, DefaultTOP, TOP, Document, Todo, Decision, MeetingReminder, Error
 from views.forms import LoginForm, ProtocolTypeForm, DefaultTopForm, MeetingReminderForm, NewProtocolForm, DocumentUploadForm, KnownProtocolSourceUploadForm, NewProtocolSourceUploadForm, ProtocolForm, TopForm
 from views.tables import ProtocolsTable, ProtocolTypesTable, ProtocolTypeTable, DefaultTOPsTable, MeetingRemindersTable, ErrorsTable, TodosTable, DocumentsTable
@@ -351,9 +350,7 @@ def etherpull_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"))
-    source_req = requests.get(protocol.get_etherpad_source_link())
-    source = source_req.text
-    protocol.source = source
+    protocol.source = get_etherpad_text(protocol.get_identifier())
     db.session.commit()
     tasks.parse_protocol(protocol)
     flash("Das Protokoll wird kompiliert.", "alert-success")
@@ -435,6 +432,20 @@ def get_protocol_template(protocol_id):
     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/etherpush/<int:protocol_id>")
+@login_required
+def etherpush_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"))
+    if set_etherpad_text(protocol.get_identifier(), protocol.get_template()):
+        flash("Vorlage von {} in Etherpad hochgeladen.".format(protocol.get_identifier()), "alert-success")
+    else:
+        flash("Das Etherpad wurde bereits bearbeitet.", "alert-error")
+    return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id))
+
 @app.route("/protocol/update/<int:protocol_id>", methods=["GET", "POST"])
 @login_required
 def update_protocol(protocol_id):
diff --git a/shared.py b/shared.py
index 9761b10..d7a6b65 100644
--- a/shared.py
+++ b/shared.py
@@ -111,9 +111,4 @@ def group_required(function, group):
             return redirect(request.args.get("next") or url_for("index"))
     return decorated_function
 
-EMPTY_ETHERPAD = """Welcome to Etherpad!
 
-This pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!
-
-Get involved with Etherpad at http://etherpad.org
-"""
diff --git a/templates/protocol-show.html b/templates/protocol-show.html
index 20dd1a6..2f9a02e 100644
--- a/templates/protocol-show.html
+++ b/templates/protocol-show.html
@@ -18,7 +18,8 @@
             {% 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>
+                <a class="btn btn-default" href="{{url_for("get_protocol_template", protocol_id=protocol.id)}}">Vorlage</a>
+                <a class="btn btn-primary" href="{{url_for("etherpush_protocol", protocol_id=protocol.id)}}">In Etherpad</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>
diff --git a/utils.py b/utils.py
index 47738f3..6d818bc 100644
--- a/utils.py
+++ b/utils.py
@@ -7,6 +7,8 @@ import smtplib
 from email.mime.multipart import MIMEMultipart
 from email.mime.text import MIMEText
 from datetime import datetime, date, timedelta
+import requests
+from io import BytesIO
 
 import config
 
@@ -100,3 +102,25 @@ def get_first_unused_int(numbers):
         if linear < given:
             return linear
     return highest + 1
+
+def get_etherpad_url(pad):
+    return "{}/p/{}".format(config.ETHERPAD_URL, pad)
+def get_etherpad_export_url(pad):
+    return "{}/p/{}/export/txt".format(config.ETHERPAD_URL, pad)
+def get_etherpad_import_url(pad):
+    return "{}/p/{}/import".format(config.ETHERPAD_URL, pad)
+
+def get_etherpad_text(pad):
+    req = requests.get("{}/p/{}/export/txt".format(config.ETHERPAD_URL, pad))
+    return req.text
+
+def set_etherpad_text(pad, text, only_if_default=True):
+    if only_if_default:
+        current_text = get_etherpad_text(pad)
+        if current_text != config.EMPTY_ETHERPAD and len(current_text.strip()) > 0:
+            return False
+    file_like = BytesIO(text.encode("utf-8"))
+    files = {"file": file_like}
+    req = requests.post(get_etherpad_import_url(pad), files=files)
+    return req.status_code == 200
+    
-- 
GitLab