From ff231dfbc112da4b568b2beed294fa55b3382855 Mon Sep 17 00:00:00 2001 From: PlexSheep Date: Wed, 27 Sep 2023 22:23:13 +0200 Subject: [PATCH] basic markdown loading --- docker-compose.yml | 26 ++++----- docker/main/requirements.txt | 3 +- gawa/blog/data/articles/en-test.md | 86 ++++++++++++++++++++++++++++++ gawa/blog/models.py | 79 ++++++++++++++++++++++++++- requirements.txt | 10 ++++ 5 files changed, 189 insertions(+), 15 deletions(-) create mode 100644 gawa/blog/data/articles/en-test.md create mode 100644 requirements.txt diff --git a/docker-compose.yml b/docker-compose.yml index 54def0d..60d96f8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,7 +17,7 @@ services: command: bash -c " python manage.py migrate && python manage.py collectstatic --noinput - && python manage.py runserver 0.0.0.0:8000 + && python manage.py runserver 0.0.0.0:80 " volumes: - ./gawa:/app @@ -44,18 +44,18 @@ services: - ./gawa/media:/srv/media - blog: - image: ghost - environment: - database__client: mysql - database__connection__host: db - database__connection__user: blog - database__connection__password: blogpass - database__connection__database: blog - url: http://localhost:8081 - NODE_ENV: development - depends_on: - - db + # blog: + # image: ghost + # environment: + # database__client: mysql + # database__connection__host: db + # database__connection__user: blog + # database__connection__password: blogpass + # database__connection__database: blog + # url: http://localhost:8081 + # NODE_ENV: development + # depends_on: + # - db db-admin: diff --git a/docker/main/requirements.txt b/docker/main/requirements.txt index 1a9a9ae..082b81c 100644 --- a/docker/main/requirements.txt +++ b/docker/main/requirements.txt @@ -6,4 +6,5 @@ django-libsass>=0.7 pillow>=9.0.0 colorlog>=6.7.0 favicon>=0.7.0 -libpt>=0.1.5 +markdown>=3.4.4 +Pygments>=2.16.1 diff --git a/gawa/blog/data/articles/en-test.md b/gawa/blog/data/articles/en-test.md new file mode 100644 index 0000000..daaacfc --- /dev/null +++ b/gawa/blog/data/articles/en-test.md @@ -0,0 +1,86 @@ +--- +Title: test +Subtitle: sub +Desc: brief desc +Date: 2023-09-27 +Keywords: main + foo + bar + qux +Category: Test +Featured: True +Public: True +--- + +# Test article +---------------------------------------- +This is a crazy testy + +### toc? +[TOC] + +## foo + +HTML + +lipsum[^1] + +
INLINE DIVbold
+ +### bar bar + +| important | table | +|-----------|-------| +| value | 2 | +| 3 | 4 | +| 5 | 2 | + +## foo + +#### big code + +```py +from django.db import models +from django.utils.translation import gettext as _ +from start.models import Searchable + +import logging +logger = logging.getLogger(__name__) + +import markdown +ARTICLE_DIR = "/app/blog/data/articles" +EXTENSIONS = [ + "extra", + "admonition", + "codehilite", + "toc" +] + +class Category(models.Model): + """ + A category of blog posts + + Name not translated because it would make i18n in urls and Searchables specifically a pain. + Maybe some day it would be cool if these were Searchable + """ + name= models.CharField(max_length=50) + slug = models.SlugField() + + class Meta: + verbose_name = _("Category") + verbose_name_plural = _("Categories") + + def __str__(self): + return f"{{<{self.__class__.__name__}>\"{self.name}\"}}" +``` + +### a +bar +#### a +qux +###### a +baau + +*[HTML]: Hyper Text Markup Language + +[^1]: foooootnote diff --git a/gawa/blog/models.py b/gawa/blog/models.py index 7e4ba13..eaae681 100644 --- a/gawa/blog/models.py +++ b/gawa/blog/models.py @@ -5,6 +5,17 @@ from start.models import Searchable import logging logger = logging.getLogger(__name__) +import markdown +ARTICLE_DIR = "/app/blog/data/articles" +EXTENSIONS = [ + "extra", + "admonition", + "codehilite", + "meta", + "toc" +] +MD = markdown.Markdown(extensions=EXTENSIONS) + class Category(models.Model): """ A category of blog posts @@ -31,7 +42,6 @@ class BlogPost(Searchable): category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True) thumbnail = models.ImageField(blank=True, upload_to="img/thumbnails") featured = models.BooleanField(default=False) - markdown = models.BooleanField(default=False) slug = models.SlugField() @@ -42,9 +52,76 @@ class BlogPost(Searchable): Implements the abstract method of Searchable """ logger.info(f"regenerating {self.__class__.__name__} object: {self}") + # url stuff self.suburl = f"/blog/{self.category.name}/{self.slug}" + + # load from markdown + self.regenerate_markdown() + self.save() + def regenerate_markdown(self): + """ + generate an article fromm it's original markdown file + """ + logger.info(f"regenerating article from markdown for: {self}") + try: + f_en = open(f"{ARTICLE_DIR}/en-{self.slug}.md") + + body_en: str = f_en.read() + + html_en: str = MD.convert(body_en) + try: + meta_en = MD.Meta + self.title_en = meta_en["title"][0] + self.subtitle_en = meta_en["subtitle"][0] + self.desc_en = meta_en["desc"][0] + # TODO: parse date from markdown + self.featured = meta_en["featured"][0] == "True" + self.public = meta_en["public"][0] == "True" + # TODO: parse keywords from markdown + # TODO: parse category from markdown + + # if keyword or category do not exist, create them + # I suppose + except Exception as e: + logger.warning(f"could not generate metadata {self.slug} from markdown: {e}") + + self.body_en = html_en + except FileNotFoundError as e: + # TODO: mark as untranslated + pass + except Exception as e: + logger.warning(f"could not generate article {self.slug} from markdown: {e}") + try: + f_de = open(f"{ARTICLE_DIR}/de-{self.slug}.md") + + body_de: str = f_de.read() + + html_de: str = MD.convert(body_de) + try: + meta_de = MD.Meta + self.title_de = meta_de["title"][0] + self.subtitle_de = meta_de["subtitle"][0] + self.desc_de = meta_de["desc"][0] + # TODO: parse date from markdown + self.featured = meta_de["featured"][0] == "True" + self.public = meta_de["public"][0] == "True" + # TODO: parse keywords from markdown + # TODO: parse category from markdown + + # if keyword or category do not exist, create them + # I suppose + except Exception as e: + logger.warning(f"could not generate metadata {self.slug} from markdown: {e}") + + self.body_de = html_de + except FileNotFoundError as e: + # TODO: mark as untranslated + pass + except Exception as e: + logger.warning(f"could not generate article {self.slug} from markdown: {e}") + class Meta: verbose_name = _("blog post") verbose_name_plural = _("blog posts") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..082b81c --- /dev/null +++ b/requirements.txt @@ -0,0 +1,10 @@ +Django>=3.0,<4.0 +psycopg2>=2.8 +mysqlclient>=1.4.3 +django_compressor>=2.2 +django-libsass>=0.7 +pillow>=9.0.0 +colorlog>=6.7.0 +favicon>=0.7.0 +markdown>=3.4.4 +Pygments>=2.16.1