Compare commits
1 Commits
7b78368eb0
...
etherpadin
| Author | SHA1 | Date | |
|---|---|---|---|
| 112e31efdc |
@@ -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")
|
||||||
@@ -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:
|
||||||
@@ -21,7 +18,7 @@ def ignore_ep_exception(msg="", *exceptions):
|
|||||||
except exceptions as e:
|
except exceptions as e:
|
||||||
logger.error(msg)
|
logger.error(msg)
|
||||||
logger.error("%s", e)
|
logger.error("%s", e)
|
||||||
|
|
||||||
|
|
||||||
def get_ep_client(groupName="fet"):
|
def get_ep_client(groupName="fet"):
|
||||||
epc = None
|
epc = None
|
||||||
@@ -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,43 +49,63 @@ 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"])
|
||||||
if str(padID) in lists["padIDs"]:
|
if str(padID) in lists["padIDs"]:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
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(
|
||||||
groupID = group["groupID"], padName=padID, text="helloworld"
|
groupID=group["groupID"], padName=padID, text="helloworld"
|
||||||
)
|
)
|
||||||
|
|
||||||
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),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
50
fet2020/documents/parse.py
Normal file
50
fet2020/documents/parse.py
Normal 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)
|
||||||
|
|
||||||
40
fet2020/documents/view_url.py
Normal file
40
fet2020/documents/view_url.py
Normal 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")
|
||||||
|
]
|
||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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}
|
||||||
35
fet2020/templates/documents/intern.html
Normal file
35
fet2020/templates/documents/intern.html
Normal 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 %}
|
||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user