mirror of
https://github.com/daniviga/django-ram.git
synced 2025-08-05 05:37:50 +02:00
Replace ckeditor with tinymce (#30)
* Replace ckeditor with tinymce due to deprecation * Remove any ckeditor dependency from old migrations Disable alters, replace create with plain models.TextField * Reformat files * Add more hardening in image_upload
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
from ram.utils import git_suffix
|
||||
|
||||
__version__ = "0.9.6"
|
||||
__version__ = "0.10.0"
|
||||
__version__ += git_suffix(__file__)
|
||||
|
@@ -44,8 +44,7 @@ INSTALLED_APPS = [
|
||||
"adminsortable2",
|
||||
"django_countries",
|
||||
"solo",
|
||||
"ckeditor",
|
||||
"ckeditor_uploader",
|
||||
"tinymce",
|
||||
"rest_framework",
|
||||
"ram",
|
||||
"portal",
|
||||
@@ -60,7 +59,7 @@ MIDDLEWARE = [
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
@@ -142,7 +141,23 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
||||
|
||||
MEDIA_URL = "media/"
|
||||
MEDIA_ROOT = STORAGE_DIR / "media"
|
||||
CKEDITOR_UPLOAD_PATH = "uploads/"
|
||||
|
||||
TINYMCE_DEFAULT_CONFIG = {
|
||||
"height": "500px",
|
||||
"menubar": False,
|
||||
"plugins": "autolink lists link image charmap preview anchor "
|
||||
"searchreplace visualblocks code fullscreen insertdatetime media "
|
||||
"table paste code",
|
||||
"toolbar": "undo redo | "
|
||||
"bold italic underline strikethrough removeformat | "
|
||||
"fontsizeselect formatselect | "
|
||||
"alignleft aligncenter alignright alignjustify | "
|
||||
"outdent indent numlist bullist | "
|
||||
"insertfile image media pageembed template link anchor codesample | "
|
||||
"charmap | "
|
||||
"fullscreen preview code",
|
||||
"images_upload_url": "/tinymce/upload_image",
|
||||
}
|
||||
|
||||
COUNTRIES_OVERRIDE = {
|
||||
"EU": "Europe",
|
||||
|
@@ -13,6 +13,7 @@ Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
from django.shortcuts import redirect
|
||||
@@ -20,9 +21,12 @@ from django.conf.urls.static import static
|
||||
from django.contrib import admin
|
||||
from django.urls import include, path
|
||||
|
||||
from ram.views import UploadImage
|
||||
|
||||
urlpatterns = [
|
||||
path("", lambda r: redirect("portal/")),
|
||||
path("ckeditor/", include("ckeditor_uploader.urls")),
|
||||
path("tinymce/", include("tinymce.urls")),
|
||||
path("tinymce/upload_image", UploadImage.as_view(), name="upload_image"),
|
||||
path("portal/", include("portal.urls")),
|
||||
path("admin/", admin.site.urls),
|
||||
path("api/v1/consist/", include("consist.urls")),
|
||||
|
62
ram/ram/views.py
Normal file
62
ram/ram/views.py
Normal file
@@ -0,0 +1,62 @@
|
||||
import os
|
||||
import datetime
|
||||
import posixpath
|
||||
|
||||
from pathlib import Path
|
||||
from PIL import Image, UnidentifiedImageError
|
||||
|
||||
from django.views import View
|
||||
from django.conf import settings
|
||||
from django.http import (
|
||||
HttpResponseBadRequest,
|
||||
HttpResponseForbidden,
|
||||
JsonResponse,
|
||||
)
|
||||
from django.utils.text import slugify as slugify
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
|
||||
@method_decorator(csrf_exempt, name="dispatch")
|
||||
class UploadImage(View):
|
||||
def post(self, request, application=None, model=None):
|
||||
if not request.user.is_authenticated:
|
||||
raise HttpResponseForbidden()
|
||||
|
||||
file_obj = request.FILES["file"]
|
||||
file_name, file_extension = os.path.splitext(file_obj.name)
|
||||
file_name = slugify(file_name) + file_extension
|
||||
|
||||
try:
|
||||
Image.open(file_obj)
|
||||
except UnidentifiedImageError:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
today = datetime.date.today()
|
||||
container = (
|
||||
"uploads",
|
||||
today.strftime("%Y"),
|
||||
today.strftime("%m"),
|
||||
today.strftime("%d"),
|
||||
)
|
||||
|
||||
dir_path = os.path.join(settings.MEDIA_ROOT, *(p for p in container))
|
||||
file_path = os.path.normpath(os.path.join(dir_path, file_name))
|
||||
# even if we apply slugify to the file name, add more hardening
|
||||
# to avoid any path transversal risk
|
||||
if not file_path.startswith(str(settings.MEDIA_ROOT)):
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
Path(dir_path).mkdir(parents=True, exist_ok=True)
|
||||
with open(file_path, "wb+") as f:
|
||||
for chunk in file_obj.chunks():
|
||||
f.write(chunk)
|
||||
|
||||
return JsonResponse(
|
||||
{
|
||||
"message": "Image uploaded successfully",
|
||||
"location": posixpath.join(
|
||||
settings.MEDIA_URL, *(p for p in container), file_name
|
||||
),
|
||||
}
|
||||
)
|
Reference in New Issue
Block a user