add admin button for sync
This commit is contained in:
parent
2c8b562601
commit
a687700c85
|
@ -1,5 +1,7 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from django.urls import path
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
from django.http.response import HttpResponseRedirect
|
||||||
from .models import *
|
from .models import *
|
||||||
|
|
||||||
@admin.register(Category)
|
@admin.register(Category)
|
||||||
|
@ -15,6 +17,7 @@ def regenerate(modeladmin, request, queryset):
|
||||||
for obj in queryset:
|
for obj in queryset:
|
||||||
obj.regenerate()
|
obj.regenerate()
|
||||||
|
|
||||||
|
|
||||||
@admin.register(BlogPost)
|
@admin.register(BlogPost)
|
||||||
class BlogPostAdmin(admin.ModelAdmin):
|
class BlogPostAdmin(admin.ModelAdmin):
|
||||||
"""
|
"""
|
||||||
|
@ -24,3 +27,16 @@ class BlogPostAdmin(admin.ModelAdmin):
|
||||||
date_hierarchy = "date"
|
date_hierarchy = "date"
|
||||||
ordering = ['title_de', 'title_en']
|
ordering = ['title_de', 'title_en']
|
||||||
actions = [regenerate]
|
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("../")
|
||||||
|
|
|
@ -6,7 +6,6 @@ import logging
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
import markdown
|
import markdown
|
||||||
ARTICLE_DIR = "/app/blog/data/articles"
|
|
||||||
EXTENSIONS = [
|
EXTENSIONS = [
|
||||||
"extra",
|
"extra",
|
||||||
"admonition",
|
"admonition",
|
||||||
|
@ -23,6 +22,9 @@ EXTENSION_CONFIGS = {
|
||||||
|
|
||||||
MD = markdown.Markdown(extensions=EXTENSIONS, extension_configs=EXTENSION_CONFIGS)
|
MD = markdown.Markdown(extensions=EXTENSIONS, extension_configs=EXTENSION_CONFIGS)
|
||||||
|
|
||||||
|
import pathlib
|
||||||
|
import os
|
||||||
|
|
||||||
class Category(models.Model):
|
class Category(models.Model):
|
||||||
"""
|
"""
|
||||||
A category of blog posts
|
A category of blog posts
|
||||||
|
@ -53,6 +55,8 @@ class BlogPost(Searchable):
|
||||||
|
|
||||||
# TODO autodiscover new blog posts based on markdown files?
|
# TODO autodiscover new blog posts based on markdown files?
|
||||||
|
|
||||||
|
DATA_DIR = "/app/blog/data/articles"
|
||||||
|
|
||||||
def regenerate(self):
|
def regenerate(self):
|
||||||
"""
|
"""
|
||||||
regenerate a object
|
regenerate a object
|
||||||
|
@ -64,17 +68,18 @@ class BlogPost(Searchable):
|
||||||
self.suburl = f"/blog/{self.category.name}/{self.slug}"
|
self.suburl = f"/blog/{self.category.name}/{self.slug}"
|
||||||
|
|
||||||
# load from markdown
|
# load from markdown
|
||||||
self.regenerate_markdown()
|
self.sync_file()
|
||||||
|
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def regenerate_markdown(self):
|
def sync_file(self):
|
||||||
"""
|
"""
|
||||||
generate an article fromm it's original markdown file
|
generate an article fromm it's original markdown file
|
||||||
"""
|
"""
|
||||||
logger.info(f"regenerating article from markdown for: {self}")
|
logger.info(f"regenerating article from markdown for: {self}")
|
||||||
try:
|
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()
|
body_en: str = f_en.read()
|
||||||
|
|
||||||
|
@ -103,7 +108,8 @@ class BlogPost(Searchable):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"could not generate article {self.slug} from markdown: {e}")
|
logger.warning(f"could not generate article {self.slug} from markdown: {e}")
|
||||||
try:
|
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()
|
body_de: str = f_de.read()
|
||||||
|
|
||||||
|
@ -132,6 +138,27 @@ class BlogPost(Searchable):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"could not generate article {self.slug} from markdown: {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:
|
class Meta:
|
||||||
verbose_name = _("blog post")
|
verbose_name = _("blog post")
|
||||||
verbose_name_plural = _("blog posts")
|
verbose_name_plural = _("blog posts")
|
||||||
|
|
|
@ -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 %}
|
Loading…
Reference in New Issue