diff --git a/gawa/blog/admin.py b/gawa/blog/admin.py index 889b084..845847a 100644 --- a/gawa/blog/admin.py +++ b/gawa/blog/admin.py @@ -1,5 +1,7 @@ from django.contrib import admin +from django.urls import path from django.utils.translation import gettext as _ +from django.http.response import HttpResponseRedirect from .models import * @admin.register(Category) @@ -15,6 +17,7 @@ def regenerate(modeladmin, request, queryset): for obj in queryset: obj.regenerate() + @admin.register(BlogPost) class BlogPostAdmin(admin.ModelAdmin): """ @@ -24,3 +27,16 @@ class BlogPostAdmin(admin.ModelAdmin): date_hierarchy = "date" ordering = ['title_de', 'title_en'] actions = [regenerate] + + change_list_template = "admin/blogpost.html" + + def get_urls(self): + urls = super().get_urls() + my_urls = [ + path('sync/', self.sync_with_fs), + ] + return my_urls + urls + + def sync_with_fs(self, request): + BlogPost.sync_all() + return HttpResponseRedirect("../") diff --git a/gawa/blog/models.py b/gawa/blog/models.py index 130eb51..515bc8a 100644 --- a/gawa/blog/models.py +++ b/gawa/blog/models.py @@ -6,7 +6,6 @@ import logging logger = logging.getLogger(__name__) import markdown -ARTICLE_DIR = "/app/blog/data/articles" EXTENSIONS = [ "extra", "admonition", @@ -23,6 +22,9 @@ EXTENSION_CONFIGS = { MD = markdown.Markdown(extensions=EXTENSIONS, extension_configs=EXTENSION_CONFIGS) +import pathlib +import os + class Category(models.Model): """ A category of blog posts @@ -53,6 +55,8 @@ class BlogPost(Searchable): # TODO autodiscover new blog posts based on markdown files? + DATA_DIR = "/app/blog/data/articles" + def regenerate(self): """ regenerate a object @@ -64,17 +68,18 @@ class BlogPost(Searchable): self.suburl = f"/blog/{self.category.name}/{self.slug}" # load from markdown - self.regenerate_markdown() + self.sync_file() self.save() - def regenerate_markdown(self): + def sync_file(self): """ generate an article fromm it's original markdown file """ logger.info(f"regenerating article from markdown for: {self}") try: - with open(f"{ARTICLE_DIR}/en-{self.slug}.md") as f_en: + MD.reset() + with open(f"{self.DATA_DIR}/en-{self.slug}.md") as f_en: body_en: str = f_en.read() @@ -103,7 +108,8 @@ class BlogPost(Searchable): except Exception as e: logger.warning(f"could not generate article {self.slug} from markdown: {e}") try: - with open(f"{ARTICLE_DIR}/de-{self.slug}.md") as f_de: + MD.reset() + with open(f"{self.DATA_DIR}/de-{self.slug}.md") as f_de: body_de: str = f_de.read() @@ -132,6 +138,27 @@ class BlogPost(Searchable): except Exception as e: logger.warning(f"could not generate article {self.slug} from markdown: {e}") + @classmethod + def sync_all(cls): + """ + Sync all Blog Posts with the filesystem. + + Caution: Will delete all Blog Posts + """ + # delete all existing objects + BlogPost.objects.all().delete() + + # check if the DATA_DIR is OK + data_dir = pathlib.Path(cls.DATA_DIR) + if not data_dir.exists(): + logger.error(f"'{cls.DATA_DIR} does not exist'") + if not data_dir.is_dir(): + logger.error(f"'{cls.DATA_DIR} is not a directory'") + + files = [f for f in os.listdir(data_dir) if os.path.isfile(f)] + logger.debug(f"discovered files: {files}") + + class Meta: verbose_name = _("blog post") verbose_name_plural = _("blog posts") diff --git a/gawa/blog/templates/admin/blogpost.html b/gawa/blog/templates/admin/blogpost.html new file mode 100644 index 0000000..e1f2936 --- /dev/null +++ b/gawa/blog/templates/admin/blogpost.html @@ -0,0 +1,9 @@ +{% extends 'admin/change_list.html' %} + +{% block object-tools %} +
+ {% csrf_token %} + +
+ {{ block.super }} +{% endblock %}