Use a markdown editor

This commit is contained in:
2022-08-22 18:16:59 +02:00
parent 0fe0644d1b
commit 7cc917d9f7
7 changed files with 95 additions and 3 deletions

View File

@@ -1,5 +1,7 @@
from django.db import models
from django.contrib import admin from django.contrib import admin
from solo.admin import SingletonModelAdmin from solo.admin import SingletonModelAdmin
from martor.widgets import AdminMartorWidget
from portal.models import SiteConfiguration, Flatpage from portal.models import SiteConfiguration, Flatpage
@@ -12,6 +14,10 @@ class FlatpageAdmin(admin.ModelAdmin):
list_display = ("name", "path") list_display = ("name", "path")
search_fields = ("name",) search_fields = ("name",)
formfield_overrides = {
models.TextField: {'widget': AdminMartorWidget},
}
fieldsets = ( fieldsets = (
( (
None, None,

View File

@@ -3,6 +3,7 @@ from django.db import models
from django.urls import reverse from django.urls import reverse
from django.dispatch.dispatcher import receiver from django.dispatch.dispatcher import receiver
from solo.models import SingletonModel from solo.models import SingletonModel
from martor.models import MartorField
from ram import __version__ as app_version from ram import __version__ as app_version
from ram.utils import slugify from ram.utils import slugify
@@ -49,7 +50,7 @@ class Flatpage(models.Model):
name = models.CharField(max_length=256, unique=True) name = models.CharField(max_length=256, unique=True)
path = models.CharField(max_length=256, unique=True) path = models.CharField(max_length=256, unique=True)
draft = models.BooleanField(default=True) draft = models.BooleanField(default=True)
content = models.TextField(blank=True) content = MartorField()
creation_time = models.DateTimeField(auto_now_add=True) creation_time = models.DateTimeField(auto_now_add=True)
updated_time = models.DateTimeField(auto_now=True) updated_time = models.DateTimeField(auto_now=True)

View File

@@ -4,6 +4,7 @@ from portal.views import (
GetHome, GetHome,
GetHomeFiltered, GetHomeFiltered,
GetFlatpage, GetFlatpage,
MDUploader,
GetRollingStock, GetRollingStock,
GetConsist, GetConsist,
Consists, Consists,
@@ -13,6 +14,7 @@ from portal.views import (
urlpatterns = [ urlpatterns = [
path("", GetHome.as_view(), name="index"), path("", GetHome.as_view(), name="index"),
path("uploader/", MDUploader.as_view(), name="markdown_uploader"),
path("<int:page>", GetHome.as_view(), name="index_pagination"), path("<int:page>", GetHome.as_view(), name="index_pagination"),
path( path(
"page/<str:flatpage>", "page/<str:flatpage>",

View File

@@ -1,4 +1,72 @@
import os
import json
import uuid
from django.apps import apps from django.apps import apps
from django.conf import settings
from django.http import HttpResponse
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.decorators import login_required
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from martor.utils import LazyEncoder
@login_required
def markdown_uploader(request):
"""
Makdown image upload for locale storage
and represent as json to markdown editor.
"""
if request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest":
if "markdown-image-upload" in request.FILES:
image = request.FILES["markdown-image-upload"]
image_types = [
"image/png",
"image/jpg",
"image/jpeg",
"image/pjpeg",
"image/gif",
]
if image.content_type not in image_types:
data = json.dumps(
{"status": 405, "error": _("Bad image format.")},
cls=LazyEncoder,
)
return HttpResponse(
data, content_type="application/json", status=405
)
if image.size > settings.MAX_IMAGE_UPLOAD_SIZE:
to_MB = settings.MAX_IMAGE_UPLOAD_SIZE / (1024 * 1024)
data = json.dumps(
{
"status": 405,
"error": _("Maximum image file is %(size)s MB.")
% {"size": to_MB},
},
cls=LazyEncoder,
)
return HttpResponse(
data, content_type="application/json", status=405
)
img_uuid = "{0}-{1}".format(
uuid.uuid4().hex[:10], image.name.replace(" ", "-")
)
tmp_file = os.path.join(settings.MARTOR_UPLOAD_PATH, img_uuid)
def_path = default_storage.save(
tmp_file, ContentFile(image.read())
)
img_url = os.path.join(settings.MEDIA_URL, def_path)
data = json.dumps(
{"status": 200, "link": img_url, "name": image.name}
)
return HttpResponse(data, content_type="application/json")
return HttpResponse(_("Invalid request!"))
return HttpResponse(_("Invalid request!"))
def get_site_conf(): def get_site_conf():

View File

@@ -8,7 +8,7 @@ from django.shortcuts import render
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.core.paginator import Paginator, PageNotAnInteger from django.core.paginator import Paginator, PageNotAnInteger
from portal.utils import get_site_conf from portal.utils import get_site_conf, markdown_uploader
from portal.models import Flatpage from portal.models import Flatpage
from roster.models import RollingStock from roster.models import RollingStock
from consist.models import Consist from consist.models import Consist
@@ -248,7 +248,9 @@ class Scales(View):
class GetFlatpage(View): class GetFlatpage(View):
def get(self, request, flatpage): def get(self, request, flatpage):
try: try:
flatpage = Flatpage.objects.get(path=flatpage) flatpage = Flatpage.objects.get(
Q(Q(path=flatpage) & Q(draft=False))
)
except ObjectDoesNotExist: except ObjectDoesNotExist:
raise Http404 raise Http404
@@ -257,3 +259,8 @@ class GetFlatpage(View):
"flatpage.html", "flatpage.html",
{"flatpage": flatpage}, {"flatpage": flatpage},
) )
class MDUploader(View):
def post(self, request):
return markdown_uploader(request)

View File

@@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/4.0/ref/settings/
""" """
import os import os
import time
from pathlib import Path from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
@@ -45,6 +46,7 @@ INSTALLED_APPS = [
"adminsortable2", "adminsortable2",
"django_countries", "django_countries",
"solo", "solo",
"martor",
"rest_framework", "rest_framework",
"ram", "ram",
"portal", "portal",
@@ -140,6 +142,11 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
MEDIA_URL = "media/" MEDIA_URL = "media/"
MEDIA_ROOT = STORAGE_DIR / "media" MEDIA_ROOT = STORAGE_DIR / "media"
MARTOR_UPLOAD_PATH = "images/uploads/{}".format(time.strftime("%Y/%m/%d/"))
MARTOR_UPLOAD_URL = "/portal/uploader/"
MAX_IMAGE_UPLOAD_SIZE = 5242880 # 5MB
COUNTRIES_OVERRIDE = { COUNTRIES_OVERRIDE = {
"ZZ": "Freelance", "ZZ": "Freelance",
} }

View File

@@ -21,6 +21,7 @@ from django.urls import include, path
urlpatterns = [ urlpatterns = [
path("", lambda r: redirect("portal/")), path("", lambda r: redirect("portal/")),
path('martor/', include('martor.urls')),
path("portal/", include("portal.urls")), path("portal/", include("portal.urls")),
path("ht/", include("health_check.urls")), path("ht/", include("health_check.urls")),
path("admin/", admin.site.urls), path("admin/", admin.site.urls),