1 Commits

Author SHA1 Message Date
112e31efdc intern mit etherpad 2021-02-08 18:09:48 +00:00
10 changed files with 197 additions and 28 deletions

View File

@@ -1 +1,16 @@
from .api import getPadHTML, setPadHTML, createPadifNotExists
from .api import getPadHTML, setPadHTML, createPadifNotExists, get_pad_link
from .parse import to_key, to_path, parse_html_from_ep
def getInternPadHTML(key):
key = to_key(key)
createPadifNotExists(key, groupName="intern")
html = getPadHTML(to_key(key), groupName="intern")
return parse_html_from_ep(html, key)
def get_int_pad_link(path):
return get_pad_link(to_key(path), groupName="intern")

View File

@@ -2,18 +2,15 @@ from django.conf import settings
import os import os
import urllib.parse import urllib.parse
from etherpad_lite import EtherpadLiteClient, EtherpadException from etherpad_lite import EtherpadLiteClient, EtherpadException
from contextlib import contextmanager from contextlib import contextmanager
import logging import logging
from .parse import ToText
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
SERVER_URL = settings.ETHERPAD_CLIENT["exturl"] SERVER_URL = settings.ETHERPAD_CLIENT["exturl"]
@contextmanager @contextmanager
def ignore_ep_exception(msg="", *exceptions): def ignore_ep_exception(msg="", *exceptions):
try: try:
@@ -29,8 +26,7 @@ def get_ep_client(groupName="fet"):
with ignore_ep_exception("Error connecting to Etherpad", Exception): with ignore_ep_exception("Error connecting to Etherpad", Exception):
with open(os.path.abspath(settings.ETHERPAD_CLIENT["apikey"]), "r") as f: with open(os.path.abspath(settings.ETHERPAD_CLIENT["apikey"]), "r") as f:
apikey = f.read() apikey = f.read().rstrip()
apikey = apikey.rstrip()
epc = EtherpadLiteClient( epc = EtherpadLiteClient(
base_params={ base_params={
"apikey": apikey, "apikey": apikey,
@@ -42,6 +38,7 @@ def get_ep_client(groupName="fet"):
return epc, group return epc, group
@contextmanager @contextmanager
def ep_client(groupName="fet"): def ep_client(groupName="fet"):
epc, group = get_ep_client(groupName) epc, group = get_ep_client(groupName)
@@ -52,11 +49,11 @@ def ep_client(groupName="fet"):
yield epc, group yield epc, group
def __checkPadExists(padID=None): def __checkPadExists(padID=None, groupName="fet"):
if not padID: if not padID:
return False return False
with ep_client() as (epc, group): with ep_client(groupName) as (epc, group):
if not epc or not group: if not epc or not group:
return None return None
lists = epc.listPads(groupID = group["groupID"]) lists = epc.listPads(groupID = group["groupID"])
@@ -66,9 +63,29 @@ def __checkPadExists(padID=None):
return False return False
def createPadifNotExists(padID): def list_pads(groupName="fet"):
if not __checkPadExists(padID=padID): with ep_client(groupName) as (epc, group):
with ep_client() as (epc, group): return [p.split("$")[1] for p in epc.listPads(groupID = group["groupID"])["padIDs"]]
def list_main_pads(groupName="intern"):
def is_main(s):
return len(s.split("-")) == 1
return list(filter(is_main, list_pads(groupName)))
def clean_up_pads(groupName="intern"):
with ep_client(groupName) as (epc, group):
for pid in epc.listPads(groupID = group["groupID"])["padIDs"]:
print(pid)
html = epc.getHTML(padID=pid)["html"]
if ToText(html) == "":
print(f"Deleting...${pid}")
epc.deletePad(padID = pid)
return
def createPadifNotExists(padID, groupName="fet"):
if not __checkPadExists(padID=padID, groupName=groupName):
with ep_client(groupName) as (epc, group):
if not epc or not group: if not epc or not group:
return None return None
epc.createGroupPad( epc.createGroupPad(
@@ -78,17 +95,17 @@ def createPadifNotExists(padID):
return padID return padID
def getPadHTML(padID): def getPadHTML(padID, groupName="fet"):
text = None text = None
with ep_client() as (epc, group): with ep_client(groupName) as (epc, group):
if not epc or not group: if not epc or not group:
return None return None
text = epc.getHTML(padID = group["groupID"] + "$" + padID)["html"] text = epc.getHTML(padID = group["groupID"] + "$" + padID)["html"]
return text return text
def setPadHTML(padID, html): def setPadHTML(padID, html, groupName="fet"):
epc, group = get_ep_client() epc, group = get_ep_client(groupName)
if not epc or not group: if not epc or not group:
return None return None
@@ -96,12 +113,13 @@ def setPadHTML(padID, html):
return html return html
def get_pad_link(padID): def get_pad_link(padID, groupName="fet"):
if padID is None: if padID is None:
return "#" return "#"
with ep_client() as (epc, group): with ep_client(groupName) as (epc, group):
if not epc or not group: if not epc or not group:
return "#" return "#"
return urllib.parse.urljoin( return urllib.parse.urljoin(
settings.ETHERPAD_CLIENT["exturl"], "p/" + group["groupID"] + "$" + str(padID) settings.ETHERPAD_CLIENT["exturl"],
"p/" + group["groupID"] + "$" + str(padID),
) )

View File

@@ -7,8 +7,8 @@ from authentications.decorators import ep_authenticated_user
@ep_authenticated_user @ep_authenticated_user
def __get_ep_sessionid(request): def __get_ep_sessionid(request, groupName="fet"):
epc, group = get_ep_client() epc, group = get_ep_client(groupName)
if not epc or not group: if not epc or not group:
return None, None return None, None
@@ -30,8 +30,8 @@ def __get_ep_sessionid(request):
return result["sessionID"], expires return result["sessionID"], expires
def add_ep_cookie(request, response): def add_ep_cookie(request, response, groupName="fet"):
ep_sessid, expires = __get_ep_sessionid(request) ep_sessid, expires = __get_ep_sessionid(request, groupName=groupName)
if ep_sessid: if ep_sessid:
response.set_cookie( response.set_cookie(

View File

@@ -0,0 +1,50 @@
from slugify import slugify
import re
from bs4 import BeautifulSoup
from django.urls import reverse
from os.path import join
from functools import partial
def clean_string(s):
s = re.sub("[^\w\d\_/-]", "_", s).replace("/", "-")
while s[-1]=="-":
s=s[0:-1]
return s
def to_key(s):
return (clean_string(s).replace("/", "-"))
def to_path(s):
return clean_string(s).replace("-","/")
def create_a_link_for(v, path):
v = v.group(1)
v = clean_string(v).replace("-", "/")
if path[0] != "/":
path = join(path, v)
while path[0]=="/":
path = path[1:]
u = reverse("int", kwargs={"path": path})
return "<a href=\"%s\">%s</a>" % (u, v)
def ToText(html):
s = BeautifulSoup(html, "html.parser").find("body")
return s.get_text().strip()
def parse_html_from_ep(html, key):
path = to_path(key)
soup = BeautifulSoup(html, "html.parser")
soup = soup.find("body")
textNodes = soup.findAll(text=True)
for node in textNodes:
text = str(node)
text = re.sub(r'^##(.+)$', r'<h2>\1</h2>', text, 0, re.M)
text = re.sub(r'\[\[([\w\d\_/-]+)\]\]', partial(create_a_link_for, path=path), text)
node.replaceWith(BeautifulSoup(text, 'html.parser'))
return str(soup)

View File

@@ -0,0 +1,40 @@
from . import getInternPadHTML, get_int_pad_link
from authentications.decorators import authenticated_user
from django.urls import path
from django.shortcuts import render, reverse
from .etherpadlib import add_ep_cookie
from django.http import HttpResponse
from django.shortcuts import redirect
from .parse import to_path
from .api import list_main_pads, clean_up_pads
@authenticated_user
def clean_up_pads_views(request):
clean_up_pads("intern")
return redirect('int', path = "home")
@authenticated_user
def intern_view(request, path=""):
if path != to_path(path):
return redirect('int', path = to_path(path))
context = {
"body": getInternPadHTML(path),
"link": get_int_pad_link(path),
"main_pads": list_main_pads("intern"),
"path": path}
response = render(request, "documents/intern.html", context)
response = add_ep_cookie(request, response, "intern")
return response
@authenticated_user
def intern_api_view(request, path=""):
return HttpResponse(getInternPadHTML(path))
urlpatterns = [
path("cleanup", clean_up_pads_views),
path("api/<path:path>", intern_api_view, name="apiint"),
path("<path:path>", intern_view, name="int")
]

View File

@@ -38,6 +38,7 @@ urlpatterns = [
path("member/", include(member_urlpatterns), name="member"), path("member/", include(member_urlpatterns), name="member"),
path("blackboard/", include("blackboard.urls"), name="blackboard"), path("blackboard/", include("blackboard.urls"), name="blackboard"),
path("tasks/", include("tasks.urls"), name="tasks"), path("tasks/", include("tasks.urls"), name="tasks"),
path("int/", include("documents.view_url"), name="int"),
path( path(
"sitemap.xml", "sitemap.xml",
sitemap, sitemap,

View File

@@ -14,3 +14,4 @@ etherpad-lite==0.5
ghostscript==0.6 ghostscript==0.6
ldap3==2.8.1 ldap3==2.8.1
mysqlclient==2.0.1 mysqlclient==2.0.1
python-slugify

View File

@@ -25,3 +25,11 @@ a.thumbnail img {
height: 150px; height: 150px;
} }
div.document {
background: white;
}
div.document ul.indent li {
list-style-type: none;
}
iframe.int {
height: 95%; width: 100%; min-height: 500px; display: block}

View File

@@ -0,0 +1,35 @@
{% extends 'layout.html' %}
{% block extraheader %}
<script>
document.addEventListener('DOMContentLoaded', function() {
setInterval(function(){
jQuery.ajax({
url: "{% url 'apiint' path %}",
success: function (res, status) {
jQuery("div.document")[0].innerHTML=res;
}}
);
},4000)
}, false);
</script>
{% endblock %}
{% block content %}
<div class="grid-container">
<div class="grid-x">
<div class="medium-8 cell">
<a href="{{link}}">Edit</a>
{% for p in main_pads %}
<a href="{% url 'int' p %}" class="button" >{{p}}</a>
{% endfor %}
<div class="document padding-1">
{{body | safe}}
</div>
</div>
<div class="medium-4 cell">
<iframe class="int" src="{{link}}?"></iframe>
</div>
</div>
</div>
{% endblock %}

View File

@@ -1,12 +1,13 @@
# pylint: skip-file # pylint: skip-file
import pytest import pytest
from posts.models import News, Post, Event, FetMeeting
from django.urls import reverse from django.urls import reverse
from django.core.validators import ValidationError from django.core.validators import ValidationError
import datetime import datetime
from urllib.request import URLError from urllib.request import URLError
import random import random
import string import string
from posts.models import News, Post, Event, FetMeeting
def get_random_string(size): def get_random_string(size):
chars = string.ascii_lowercase+string.ascii_uppercase+string.digits chars = string.ascii_lowercase+string.ascii_uppercase+string.digits