rework posts models and ep api
This commit is contained in:
@@ -10,14 +10,20 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
def get_ep_client():
|
def get_ep_client():
|
||||||
api_key = ""
|
api_key = ""
|
||||||
|
api_key_path = settings.ETHERPAD_CLIENT["apikey"]
|
||||||
ep_c = None
|
ep_c = None
|
||||||
|
|
||||||
# Get api key from settings
|
# Get api key from settings
|
||||||
with open(os.path.abspath(settings.ETHERPAD_CLIENT["apikey"]), "r") as f:
|
if not os.path.isfile(api_key_path):
|
||||||
|
logger.info(f"API Key file is missing. Path: {api_key_path}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
with open(os.path.abspath(api_key_path), "r") as f:
|
||||||
api_key = f.read()
|
api_key = f.read()
|
||||||
api_key = api_key.rstrip()
|
api_key = api_key.rstrip()
|
||||||
|
|
||||||
if api_key == "":
|
if api_key == "":
|
||||||
|
logger.info(f"API Key is missing. Path: {api_key_path}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Connection to Etherpad Client
|
# Connection to Etherpad Client
|
||||||
@@ -30,13 +36,13 @@ def get_ep_client():
|
|||||||
api_version="1.2.14",
|
api_version="1.2.14",
|
||||||
)
|
)
|
||||||
except EtherpadException as e:
|
except EtherpadException as e:
|
||||||
logger.info("Connection to Etherpad Client failed. Error: %s", e)
|
logger.info(f"Connection to Etherpad Client failed. Error: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return ep_c
|
return ep_c
|
||||||
|
|
||||||
|
|
||||||
def get_ep_group(ep_group_name="fet"):
|
def get_ep_group(ep_group_name: str = "fet") -> dict[str, str]:
|
||||||
ep_group = None
|
ep_group = None
|
||||||
|
|
||||||
if (ep_c := get_ep_client()) is None:
|
if (ep_c := get_ep_client()) is None:
|
||||||
@@ -50,7 +56,7 @@ def get_ep_group(ep_group_name="fet"):
|
|||||||
return ep_group
|
return ep_group
|
||||||
|
|
||||||
|
|
||||||
def ep_pad_exists(pad_id=None):
|
def ep_pad_exists(pad_id: str | None = None):
|
||||||
if pad_id is None:
|
if pad_id is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -61,15 +67,15 @@ def ep_pad_exists(pad_id=None):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
lists = ep_c.listPads(groupID=ep_group["groupID"])
|
lists = ep_c.listPads(groupID=ep_group["groupID"])
|
||||||
if any(str(pad_id) in s for s in lists["padIDs"]):
|
if any(pad_id in s for s in lists["padIDs"]):
|
||||||
logger.info("Etherpad '%s' existiert.", pad_id)
|
logger.info(f"Etherpad exists. Pad: {pad_id}")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
logger.info("Etherpad '%s' existiert nicht.", pad_id)
|
logger.info(f"Etherpad doesn't exist. Pad: {pad_id}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def ep_create_new_pad(pad_id, text="helloworld"):
|
def ep_create_new_pad(pad_id: str | None, text="helloworld"):
|
||||||
"""
|
"""
|
||||||
Create a pad if it doesn't exist.
|
Create a pad if it doesn't exist.
|
||||||
|
|
||||||
@@ -84,15 +90,15 @@ def ep_create_new_pad(pad_id, text="helloworld"):
|
|||||||
if (ep_group := get_ep_group()) is None:
|
if (ep_group := get_ep_group()) is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if ep_pad_exists(pad_id) is False:
|
if ep_pad_exists(pad_id) is True:
|
||||||
ep_c.createGroupPad(groupID=ep_group["groupID"], padName=pad_id, text=text)
|
ep_c.createGroupPad(groupID=ep_group["groupID"], padName=pad_id, text=text)
|
||||||
logger.info("Neues Etherpad '%s' erzeugt.", pad_id)
|
logger.info(f"Create new etherpad. Pad: {pad_id}")
|
||||||
return pad_id
|
return pad_id
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def ep_get_html(pad_id):
|
def ep_get_html(pad_id: str | None) -> (str | None):
|
||||||
if (ep_c := get_ep_client()) is None:
|
if (ep_c := get_ep_client()) is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -105,7 +111,7 @@ def ep_get_html(pad_id):
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def ep_set_html(pad_id, html):
|
def ep_set_html(pad_id: str | None, html: str):
|
||||||
if (ep_c := get_ep_client()) is None:
|
if (ep_c := get_ep_client()) is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -119,10 +125,7 @@ def ep_set_html(pad_id, html):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def ep_get_url(pad_id):
|
def ep_get_url(pad_id: str | None):
|
||||||
if (ep_c := get_ep_client()) is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
if (ep_group := get_ep_group()) is None:
|
if (ep_group := get_ep_group()) is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@@ -43,11 +43,10 @@ def create_pad_for_post(slug, item="agenda"):
|
|||||||
|
|
||||||
pad_id = slug + "-" + item
|
pad_id = slug + "-" + item
|
||||||
if ep_create_new_pad(pad_id):
|
if ep_create_new_pad(pad_id):
|
||||||
# set template into the newly created pad if it exists
|
# Set template into the newly created pad if it exists.
|
||||||
page = CustomFlatPage.objects.filter(title__iexact=item).first()
|
if page := CustomFlatPage.objects.filter(title__iexact=item).first():
|
||||||
if page:
|
|
||||||
ep_set_html(pad_id, page.content)
|
ep_set_html(pad_id, page.content)
|
||||||
logger.info(f"Template gesetzt von: {page.title}")
|
logger.info(f"Template is set. Template: {page.title}")
|
||||||
|
|
||||||
return pad_id
|
return pad_id
|
||||||
|
|
||||||
@@ -152,126 +151,124 @@ class Post(models.Model):
|
|||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def agenda_html(self):
|
def agenda_html(self) -> (str | None):
|
||||||
"Agenda HTML from Etherpad Pad"
|
"Agenda HTML from Etherpad Pad"
|
||||||
if not self.agenda_key:
|
if self.agenda_key in [None, "#"]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return ep_get_html(self.agenda_key)
|
return ep_get_html(self.agenda_key)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def protocol_html(self):
|
def protocol_html(self) -> (str | None):
|
||||||
"Protocol HTML from Etherpad Pad"
|
"Protocol HTML from Etherpad Pad"
|
||||||
if not self.protocol_key:
|
if self.protocol_key in [None, "#"]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return ep_get_html(self.protocol_key)
|
return ep_get_html(self.protocol_key)
|
||||||
|
|
||||||
@agenda_html.setter
|
@agenda_html.setter
|
||||||
def agenda_html(self, value):
|
def agenda_html(self, value: str) -> (str | None):
|
||||||
if not self.agenda_key:
|
if self.agenda_key is None:
|
||||||
self.agenda_key = self.create_agenda_key()
|
self.create_agenda_key()
|
||||||
if not value or not self.agenda_key:
|
|
||||||
|
if value is None or self.agenda_key in [None, "#"]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
ep_set_html(self.agenda_key, value)
|
ep_set_html(self.agenda_key, value)
|
||||||
|
request_logger.info(f"Set agenda etherpad. Post: {self.slug}. Key: {self.agenda_key}")
|
||||||
request_logger.info("set etherpad for post %s id: %s", self.slug, self.agenda_key)
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
@protocol_html.setter
|
@protocol_html.setter
|
||||||
def protocol_html(self, value):
|
def protocol_html(self, value: str) -> (str | None):
|
||||||
if not self.protocol_key:
|
if self.protocol_key is None:
|
||||||
self.protocol_key = self.create_protocol_key()
|
self.create_protocol_key()
|
||||||
if not value or not self.protocol_key:
|
|
||||||
|
if value is None or self.protocol_key in [None, "#"]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
ep_set_html(self.protocol_key, value)
|
ep_set_html(self.protocol_key, value)
|
||||||
|
request_logger.info(f"Set protocol etherpad. Post: {self.slug}. Key: {self.protocol_key}")
|
||||||
request_logger.info("set etherpad for post %s id: %s", self.slug, self.protocol_key)
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
_agenda_filename = None
|
_agenda_filename = None
|
||||||
_agenda_url = "#"
|
_agenda_url = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def agenda_url(self):
|
def agenda_url(self) -> (str | None):
|
||||||
if self.has_agenda is not True:
|
if self.has_agenda is not True:
|
||||||
self.a_url = "#"
|
self._agenda_url = None
|
||||||
self._agenda_filename = None
|
self._agenda_filename = None
|
||||||
return self.a_url
|
|
||||||
|
|
||||||
if self._agenda_url != "#":
|
|
||||||
return self._agenda_url
|
return self._agenda_url
|
||||||
|
|
||||||
if (url := ep_get_url(self.agenda_key)) != "#":
|
if self._agenda_url is not None:
|
||||||
|
return self._agenda_url
|
||||||
|
|
||||||
|
if (url := ep_get_url(self.agenda_key)) not in [None, "#"]:
|
||||||
self._agenda_url = url
|
self._agenda_url = url
|
||||||
self._agenda_filename = self.slug + "-agenda.pdf"
|
self._agenda_filename = self.slug + "-agenda.pdf"
|
||||||
else:
|
else:
|
||||||
self._agenda_url = "#"
|
self._agenda_url = None
|
||||||
self._agenda_filename = None
|
self._agenda_filename = None
|
||||||
|
|
||||||
return self._agenda_url
|
return self._agenda_url
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def agenda_filename(self):
|
def agenda_filename(self) -> (str | None):
|
||||||
if self._agenda_filename is not None:
|
if self._agenda_filename is not None:
|
||||||
return self._agenda_filename
|
return self._agenda_filename
|
||||||
|
|
||||||
if self.has_agenda and self.agenda_url != "#":
|
if self.has_agenda and self.agenda_url:
|
||||||
return self.slug + "-agenda.pdf"
|
return self.slug + "-agenda.pdf"
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
_protocol_filename = None
|
_protocol_filename = None
|
||||||
_protocol_url = "#"
|
_protocol_url = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def protocol_url(self):
|
def protocol_url(self) -> (str | None):
|
||||||
if self.has_protocol is not True:
|
if self.has_protocol is not True:
|
||||||
self._protocol_url = "#"
|
self._protocol_url = None
|
||||||
self._protocol_filename = None
|
self._protocol_filename = None
|
||||||
return self._protocol_url
|
return self._protocol_url
|
||||||
|
|
||||||
if self._protocol_url != "#":
|
if self._protocol_url is not None:
|
||||||
return self._protocol_url
|
return self._protocol_url
|
||||||
|
|
||||||
if (url := ep_get_url(self.protocol_key)) != "#":
|
if (url := ep_get_url(self.protocol_key)) not in [None, "#"]:
|
||||||
self._protocol_url = url
|
self._protocol_url = url
|
||||||
self._protocol_filename = self.slug + "-agenda.pdf"
|
self._protocol_filename = self.slug + "-protokoll.pdf"
|
||||||
else:
|
else:
|
||||||
self._protocol_url = "#"
|
self._protocol_url = None
|
||||||
self._protocol_filename = None
|
self._protocol_filename = None
|
||||||
|
|
||||||
return self._protocol_url
|
return self._protocol_url
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def protocol_filename(self):
|
def protocol_filename(self) -> (str | None):
|
||||||
if self._protocol_filename is not None:
|
if self._protocol_filename is not None:
|
||||||
return self._protocol_filename
|
return self._protocol_filename
|
||||||
|
|
||||||
if self.has_protocol and self.protocol_url != "#":
|
if self.has_protocol and self.protocol_url:
|
||||||
return self.slug + "-protokoll.pdf"
|
return self.slug + "-protokoll.pdf"
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def create_agenda_key(self):
|
def create_agenda_key(self) -> None:
|
||||||
"""
|
"""
|
||||||
Create a Etherpad Id for the Pad associated to this post.
|
Create a Etherpad Id for the Pad associated to this post.
|
||||||
Create the pad if it doesn't exist.
|
Create the pad if it doesn't exist.
|
||||||
"""
|
"""
|
||||||
if not self.slug:
|
if self.slug:
|
||||||
return None
|
self.agenda_key = create_pad_for_post(self.slug, "agenda")
|
||||||
return create_pad_for_post(self.slug, "agenda")
|
|
||||||
|
|
||||||
def create_protocol_key(self):
|
def create_protocol_key(self) -> None:
|
||||||
"""
|
"""
|
||||||
Create a Etherpad Id for the Pad associated to this post.
|
Create a Etherpad Id for the Pad associated to this post.
|
||||||
Create the pad if it doesn't exist.
|
Create the pad if it doesn't exist.
|
||||||
"""
|
"""
|
||||||
if not self.slug:
|
if self.slug:
|
||||||
return None
|
self.protocol_key = create_pad_for_post(self.slug, "protocol")
|
||||||
return create_pad_for_post(self.slug, "protocol")
|
|
||||||
|
|
||||||
def get_model_name(self):
|
def get_model_name(self):
|
||||||
return self._meta.model_name
|
return self._meta.model_name
|
||||||
@@ -285,7 +282,7 @@ class Post(models.Model):
|
|||||||
return [t for t in self.tags.names()]
|
return [t for t in self.tags.names()]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def imageurl(self):
|
def imageurl(self) -> str:
|
||||||
"""
|
"""
|
||||||
returns the url to the image
|
returns the url to the image
|
||||||
"""
|
"""
|
||||||
@@ -297,9 +294,9 @@ class Post(models.Model):
|
|||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
if self.event_end and self.event_end < self.event_start:
|
if self.event_end and self.event_end < self.event_start:
|
||||||
raise ValidationError(_("Das Ende des Events liegt vor dem Beginn."))
|
raise ValidationError("Das Ende des Events liegt vor dem Beginn.")
|
||||||
if self.event_start and self.post_type not in ["E", "F"]:
|
if self.event_start and self.post_type not in ["E", "F"]:
|
||||||
raise ValidationError(_("Für diesen Post Typ ist kein Event Start zulässig"))
|
raise ValidationError("Für diesen Post Typ ist kein Event Start zulässig.")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def published(self):
|
def published(self):
|
||||||
@@ -350,7 +347,7 @@ class Event(Post):
|
|||||||
def clean(self):
|
def clean(self):
|
||||||
super().clean()
|
super().clean()
|
||||||
if not self.event_start:
|
if not self.event_start:
|
||||||
raise ValidationError(_("Das Datum des Events fehlt."))
|
raise ValidationError("Das Datum des Events fehlt.")
|
||||||
|
|
||||||
|
|
||||||
class FetMeeting(Event):
|
class FetMeeting(Event):
|
||||||
@@ -371,14 +368,15 @@ class FetMeeting(Event):
|
|||||||
if not self.slug:
|
if not self.slug:
|
||||||
self.slug = self.__get_slug()
|
self.slug = self.__get_slug()
|
||||||
|
|
||||||
self.has_agenda = True
|
if ep_pad_exists(self.agenda_key) is not True or self.slug not in self.agenda_key:
|
||||||
self.has_protocol = True
|
self.create_agenda_key()
|
||||||
|
if self.agenda_key not in [None, "#"]:
|
||||||
|
self.has_agenda = True
|
||||||
|
|
||||||
if not ep_pad_exists(self.agenda_key):
|
if ep_pad_exists(self.protocol_key) is not True or self.slug not in self.protocol_key:
|
||||||
self.agenda_key = self.create_agenda_key()
|
self.create_protocol_key()
|
||||||
|
if self.protocol_key not in [None, "#"]:
|
||||||
if not ep_pad_exists(self.protocol_key):
|
self.has_protocol = True
|
||||||
self.protocol_key = self.create_protocol_key()
|
|
||||||
|
|
||||||
if not self.post_type:
|
if not self.post_type:
|
||||||
self.post_type = "F"
|
self.post_type = "F"
|
||||||
@@ -395,12 +393,12 @@ class FetMeeting(Event):
|
|||||||
|
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
def __get_slug(self):
|
def __get_slug(self) -> str:
|
||||||
slug = slugify(self.event_start.date()) + "-" + slugify("Fachschaftssitzung")
|
slug = slugify(self.event_start.date()) + "-" + slugify("Fachschaftssitzung")
|
||||||
|
|
||||||
if Post.objects.filter(slug=slug).exists():
|
if Post.objects.filter(slug=slug).exists():
|
||||||
if Post.objects.get(slug=slug).id != self.id:
|
if Post.objects.get(slug=slug).id != self.id:
|
||||||
raise ValidationError(_("Es existiert bereits eine Sitzung mit demselben Datum."))
|
raise ValidationError("Es existiert bereits eine Sitzung mit demselben Datum.")
|
||||||
|
|
||||||
return slug
|
return slug
|
||||||
|
|
||||||
|
|||||||
@@ -49,12 +49,12 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block post_body %}
|
{% block post_body %}
|
||||||
{% if post.has_agenda %}
|
{% if post.has_agenda and post.agenda_html %}
|
||||||
<h2>Agenda</h2>
|
<h2>Agenda</h2>
|
||||||
{{ post.agenda_html|safe }}
|
{{ post.agenda_html|safe }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if request.user.is_authenticated and post.has_protocol %}
|
{% if request.user.is_authenticated and post.has_protocol and post.protocol_html %}
|
||||||
<hr>
|
<hr>
|
||||||
<h2>Protokoll</h2>
|
<h2>Protokoll</h2>
|
||||||
{{ post.protocol_html|safe }}
|
{{ post.protocol_html|safe }}
|
||||||
@@ -77,12 +77,10 @@
|
|||||||
|
|
||||||
{% block docu_buttons %}
|
{% block docu_buttons %}
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
{% if post.has_agenda or post.has_protocol %}
|
<hr class="-mx-4 border-gray-200 dark:border-gray-800 dark:border my-4">
|
||||||
<hr class="-mx-4 border-gray-200 dark:border-gray-800 dark:border my-4">
|
<h2 class="text-gray-800 dark:text-gray-200 font-medium"><i class="fa-solid fa-inbox mr-2 text-gray-400 dark:text-gray-500"></i>Dokument(e):</h2>
|
||||||
<h2 class="text-gray-800 dark:text-gray-200 font-medium"><i class="fa-solid fa-inbox mr-2 text-gray-400 dark:text-gray-500"></i>Dokument(e):</h2>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if post.has_agenda %}
|
{% if post.has_agenda and post.agenda_key != "#" %}
|
||||||
<div class="w-full my-2 flex items-center gap-4 text-gray-700 dark:text-gray-300" x-data="optionsToggle">
|
<div class="w-full my-2 flex items-center gap-4 text-gray-700 dark:text-gray-300" x-data="optionsToggle">
|
||||||
<span class="flex-1">Agenda</span>
|
<span class="flex-1">Agenda</span>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
@@ -118,7 +116,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if post.has_protocol %}
|
{% if post.has_protocol and post.protocol_key != "#" %}
|
||||||
<div class="w-full my-2 flex items-center gap-4 text-gray-700 dark:text-gray-300" x-data="optionsToggle">
|
<div class="w-full my-2 flex items-center gap-4 text-gray-700 dark:text-gray-300" x-data="optionsToggle">
|
||||||
<span class="flex-1">Protokoll</span>
|
<span class="flex-1">Protokoll</span>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
|
|||||||
@@ -109,15 +109,15 @@ class TestPostEtherpad:
|
|||||||
|
|
||||||
def test_agenda_id(self, post_saved, mock_createpad):
|
def test_agenda_id(self, post_saved, mock_createpad):
|
||||||
mock_createpad.return_value = post_saved.slug + "-agenda"
|
mock_createpad.return_value = post_saved.slug + "-agenda"
|
||||||
k = post_saved.create_agenda_key()
|
post_saved.create_agenda_key()
|
||||||
mock_createpad.assert_called_with(post_saved.slug + "-agenda")
|
mock_createpad.assert_called_with(post_saved.slug + "-agenda")
|
||||||
assert post_saved.slug in str(k)
|
assert post_saved.slug in str(post_saved.agenda_key)
|
||||||
|
|
||||||
def test_protocol_id(self, post_saved, mock_createpad):
|
def test_protocol_id(self, post_saved, mock_createpad):
|
||||||
mock_createpad.return_value = post_saved.slug + "-protocol"
|
mock_createpad.return_value = post_saved.slug + "-protocol"
|
||||||
k = post_saved.create_protocol_key()
|
post_saved.create_protocol_key()
|
||||||
mock_createpad.assert_called_with(post_saved.slug + "-protocol")
|
mock_createpad.assert_called_with(post_saved.slug + "-protocol")
|
||||||
assert post_saved.slug in str(k)
|
assert post_saved.slug in str(post_saved.protocol_key)
|
||||||
|
|
||||||
def test_catch_url_error(self, post_saved, mock_createpad):
|
def test_catch_url_error(self, post_saved, mock_createpad):
|
||||||
def raise_url_error(key):
|
def raise_url_error(key):
|
||||||
|
|||||||
Reference in New Issue
Block a user