add admin button for sync

This commit is contained in:
Christoph J. Scherr 2023-09-30 19:03:46 +02:00
parent 2c8b562601
commit a687700c85
3 changed files with 57 additions and 5 deletions

View File

@ -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("../")

View File

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

View File

@ -0,0 +1,9 @@
{% extends 'admin/change_list.html' %}
{% block object-tools %}
<form action="sync" method="POST">
{% csrf_token %}
<button type="submit">Sync with FS</button>
</form>
{{ block.super }}
{% endblock %}