diff --git a/CHANGES.md b/CHANGES.md index 3e73b8a6f..d2046ace9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,9 +4,18 @@ CHANGELOG 8.5.6+dev (XXXX-XX-XX) ---------------------------- -* Support django 4.2 and python 3.11 -* Drop django 3.1 support -* Ease quickstart for developers +**Feature** + +- Allow the user to upload file from TinyMCE editor to insert local images directly into the text area + +**Maintenance** + +- Support django 4.2 and python 3.11 +- Drop django 3.1 support + +**Documentation** + +- Ease quickstart for developers 8.5.6 (2023-09-04) diff --git a/mapentity/settings.py b/mapentity/settings.py index 9b4365f9f..2963cd9e1 100644 --- a/mapentity/settings.py +++ b/mapentity/settings.py @@ -74,7 +74,13 @@ 'img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],' 'p,em/i,strong/b,div[align],br,ul,li,ol,span[style],' 'iframe[src|frameborder=0|alt|title|width|height|align|name]'), - 'setup': 'tinyMceInit' + 'setup': 'tinyMceInit', + 'image_title': True, + 'image_caption': True, + 'automatic_uploads': True, + 'convert_urls': False, + 'file_picker_types': 'image media', + 'images_upload_url': '/tinymce/upload/', } TINYMCE_DEFAULT_CONFIG.update(getattr(settings, 'TINYMCE_DEFAULT_CONFIG', {})) setattr(settings, 'TINYMCE_DEFAULT_CONFIG', TINYMCE_DEFAULT_CONFIG) diff --git a/mapentity/urls.py b/mapentity/urls.py index 122c23b28..f0c28b9e6 100644 --- a/mapentity/urls.py +++ b/mapentity/urls.py @@ -3,7 +3,7 @@ from .registry import registry from .settings import app_settings -from .views import (map_screenshot, history_delete, +from .views import (map_screenshot, history_delete, tinymce_upload, ServeAttachment, JSSettings, Convert) if app_settings['ACTION_HISTORY_ENABLED']: @@ -23,6 +23,7 @@ path('convert/', Convert.as_view(), name='convert'), path('history/delete/', history_delete, name='history_delete'), path('api/auth/', include('rest_framework.urls')), + path('tinymce/upload/', tinymce_upload, name='tinymce_upload'), # See default value in app_settings.JS_SETTINGS. # Will be overriden, most probably. path('api/settings.json', JSSettings.as_view(), name='js_settings'), diff --git a/mapentity/views/__init__.py b/mapentity/views/__init__.py index 9c5ddf16c..4d63d7e7b 100644 --- a/mapentity/views/__init__.py +++ b/mapentity/views/__init__.py @@ -6,6 +6,7 @@ JSSettings, map_screenshot, history_delete, + tinymce_upload, ) from .generic import ( Convert, diff --git a/mapentity/views/base.py b/mapentity/views/base.py index 65c332580..61c9b587b 100644 --- a/mapentity/views/base.py +++ b/mapentity/views/base.py @@ -6,12 +6,13 @@ from datetime import datetime from io import BytesIO from urllib.parse import quote +from uuid import uuid4 from django.conf import settings from django.contrib.auth.decorators import login_required from django.contrib.gis.db.models import GeometryField from django.core.exceptions import PermissionDenied -from django.http import (HttpResponse, HttpResponseBadRequest, Http404) +from django.http import (HttpResponse, HttpResponseBadRequest, Http404, JsonResponse) from django.shortcuts import get_object_or_404 from django.urls import reverse from django.views import static, View @@ -187,3 +188,17 @@ def history_delete(request, path=None): history = [h for h in history if h['path'] != path] request.session['history'] = history return HttpResponse() + + +@require_http_methods(["POST"]) +@csrf_exempt +@login_required +def tinymce_upload(request): + file = request.FILES.get('file') + filename = f"tinymce/{uuid4()}/{str(file)}" + path = f"{settings.MEDIA_URL}{filename}" + location = f"{settings.MEDIA_ROOT}/{filename}" + os.makedirs(os.path.dirname(location), exist_ok=True) + with open(location, "wb+") as destination: + destination.write(file.read()) + return JsonResponse({"location": request.build_absolute_uri(path)})