rework posts models and ep api

This commit is contained in:
opruffy
2024-08-06 01:30:39 +02:00
parent baa0845344
commit 3419f8b044
4 changed files with 87 additions and 88 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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">

View File

@@ -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):