From a1903dbbac332209abf7d8d409002f3bc279a9c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Mali=C5=84ski?= Date: Thu, 16 Oct 2014 00:40:21 +0200 Subject: [PATCH 1/6] [close #135] Allow only POST requests to upload view. --- ckeditor/views.py | 66 ++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/ckeditor/views.py b/ckeditor/views.py index ddabc87..336001b 100644 --- a/ckeditor/views.py +++ b/ckeditor/views.py @@ -4,6 +4,7 @@ import os from django.conf import settings from django.core.files.storage import default_storage from django.views.decorators.csrf import csrf_exempt +from django.views import generic from django.http import HttpResponse from django.shortcuts import render_to_response from django.template import RequestContext @@ -32,42 +33,43 @@ def get_upload_filename(upload_name, user): return default_storage.get_available_name(os.path.join(upload_path, upload_name)) -@csrf_exempt -def upload(request): - """ - Uploads a file and send back its URL to CKEditor. +class ImageUploadView(generic.View): + http_method_names = ['post'] - TODO: - Validate uploads - """ - # Get the uploaded file from request. - upload = request.FILES['upload'] + def post(self, request, **kwargs): + """ + Uploads a file and send back its URL to CKEditor. + """ + # Get the uploaded file from request. + upload = request.FILES['upload'] - #Verify that file is a valid image - backend = image_processing.get_backend() - try: - backend.image_verify(upload) - except utils.NotAnImageException: + #Verify that file is a valid image + backend = image_processing.get_backend() + try: + backend.image_verify(upload) + except utils.NotAnImageException: + return HttpResponse(""" + """.format(request.GET['CKEditorFuncNum'])) + + # Open output file in which to store upload. + upload_filename = get_upload_filename(upload.name, request.user) + saved_path = default_storage.save(upload_filename, upload) + + if backend.should_create_thumbnail(saved_path): + backend.create_thumbnail(saved_path) + + url = utils.get_media_url(saved_path) + + # Respond with Javascript sending ckeditor upload url. return HttpResponse(""" - """.format(request.GET['CKEditorFuncNum'])) + """.format(request.GET['CKEditorFuncNum'], url)) - # Open output file in which to store upload. - upload_filename = get_upload_filename(upload.name, request.user) - saved_path = default_storage.save(upload_filename, upload) - - if backend.should_create_thumbnail(saved_path): - backend.create_thumbnail(saved_path) - - url = utils.get_media_url(saved_path) - - # Respond with Javascript sending ckeditor upload url. - return HttpResponse(""" - """.format(request.GET['CKEditorFuncNum'], url)) +upload = csrf_exempt(ImageUploadView.as_view()) def get_image_files(user=None, path=''): From 365de5ebe59710743113ea48342842c15cf21de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Mali=C5=84ski?= Date: Thu, 16 Oct 2014 00:44:34 +0200 Subject: [PATCH 2/6] [#134] Update readme. --- README.rst | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 077392b..298f882 100644 --- a/README.rst +++ b/README.rst @@ -22,7 +22,7 @@ Installation Required ~~~~~~~~ -#. Install or add django-ckeditor-updated to your python path. Note: You may not have the original django-ckeditor and django-ckeditor-updated installed at the same time. +#. Install or add django-ckeditor to your python path. #. Add ``ckeditor`` to your ``INSTALLED_APPS`` setting. @@ -120,6 +120,17 @@ Alernatively you can use the included ``CKEditorWidget`` as the widget for a for admin.site.register(Post, PostAdmin) + +Note that when using outside of admin panel you will have to make sure all form media is present for the editor to work. You may have to render the media like so:: + +
+ {{ myform.media }} + {{ myform.as_p }} + +
+ + + Managment Commands ~~~~~~~~~~~~~~~~~~ Included is a management command to create thumbnails for images already contained in ``CKEDITOR_UPLOAD_PATH``. This is useful to create thumbnails when starting to use django-ckeditor with existing images. Issue the command as follows:: From bdb904ea080a70f47e1b0f8c7f4feae76c2a6881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Mali=C5=84ski?= Date: Thu, 16 Oct 2014 00:46:05 +0200 Subject: [PATCH 3/6] Fix Readme formatting. --- README.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index 298f882..e5ebecc 100644 --- a/README.rst +++ b/README.rst @@ -48,7 +48,7 @@ Required - ``pillow``: uses PIL or Pillow -#. django-ckeditor uses jQuery in ckeditor-init.js file. You must set ``CKEDITOR_JQUERY_URL`` to a jQuery URL that will be used to load the library. If you have jQuery loaded from a different source just don't set this variable and django-ckeditor will not try to load its own jQuery. Example:: +#. **django-ckeditor uses jQuery in ckeditor-init.js file. You must set ``CKEDITOR_JQUERY_URL`` to a jQuery URL that will be used to load the library**. If you have jQuery loaded from a different source just don't set this variable and django-ckeditor will not try to load its own jQuery. Example:: CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js' @@ -147,13 +147,13 @@ See http://django-storages.readthedocs.org/en/latest/ If you want to use allowedContent ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To allowedContent works, disable **stylesheetparser** plugin. -So included this on your settings.py. +So included this on your settings.py.:: -CKEDITOR_CONFIGS = { - "default": { - "removePlugins": "stylesheetparser", + CKEDITOR_CONFIGS = { + "default": { + "removePlugins": "stylesheetparser", + } } -} Demo / Test application From 253a9d7af64d16a0a6ce092ea88b35f9cea5cf1a Mon Sep 17 00:00:00 2001 From: Simon Fransson Date: Fri, 17 Oct 2014 00:06:25 +0200 Subject: [PATCH 4/6] Made get_image_files() exclude hidden files (leading . in filename). --- ckeditor/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ckeditor/views.py b/ckeditor/views.py index 336001b..3223581 100644 --- a/ckeditor/views.py +++ b/ckeditor/views.py @@ -98,7 +98,7 @@ def get_image_files(user=None, path=''): return for filename in storage_list[STORAGE_FILES]: - if os.path.splitext(filename)[0].endswith('_thumb'): + if os.path.splitext(filename)[0].endswith('_thumb') or os.path.basename(filename).startswith('.'): continue filename = os.path.join(browse_path, filename) yield filename From 0526219288a243b044584415157c740d4d66e487 Mon Sep 17 00:00:00 2001 From: Simon Fransson Date: Fri, 17 Oct 2014 00:08:16 +0200 Subject: [PATCH 5/6] Added never_cache() decorator to browse view, as the it often did not display newly uploaded files after being loaded once. --- ckeditor/urls.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ckeditor/urls.py b/ckeditor/urls.py index a88bb0d..e8a3d70 100644 --- a/ckeditor/urls.py +++ b/ckeditor/urls.py @@ -1,10 +1,11 @@ from django.conf.urls import patterns, url from django.contrib.admin.views.decorators import staff_member_required +from django.views.decorators.cache import never_cache from ckeditor import views urlpatterns = patterns( '', url(r'^upload/', staff_member_required(views.upload), name='ckeditor_upload'), - url(r'^browse/', staff_member_required(views.browse), name='ckeditor_browse'), + url(r'^browse/', never_cache(staff_member_required(views.browse)), name='ckeditor_browse'), ) From a5f6d2fcad7c7ecde09f129a6348b626d399eda4 Mon Sep 17 00:00:00 2001 From: Simon Fransson Date: Wed, 22 Oct 2014 13:49:17 +0200 Subject: [PATCH 6/6] Added lazy JSON encoder in order to support i18n in CKEditor settings A LazyEncoder has been implemented based on Djangos DjangoJSONEncoder, rather than json.JSONEncoder, as described [here](https://docs.djangoproject.com/en/dev/topics/serialization/#serialization-formats-json) This allows us to use `ugettext_lazy` (and other laze functions) in `settings.py` which adds the possibility to localize strings for use in the `CKEDITOR_CONFIGS` settings etc. **Example** from django.utils.translation import ugettext_lazy as _ CKEDITOR_CONFIGS = { 'default': { 'stylesSet': [ { 'name': _('Lead') , 'element': 'p', 'attributes': { 'class': 'lead' } }, ... ] ... } --- ckeditor/widgets.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ckeditor/widgets.py b/ckeditor/widgets.py index c322be8..bf68d59 100644 --- a/ckeditor/widgets.py +++ b/ckeditor/widgets.py @@ -8,10 +8,19 @@ from django.utils.encoding import force_text from django.utils.translation import get_language from django.core.exceptions import ImproperlyConfigured from django.forms.util import flatatt -import json + +from django.utils.functional import Promise +from django.utils.encoding import force_text +from django.core.serializers.json import DjangoJSONEncoder + +class LazyEncoder(DjangoJSONEncoder): + def default(self, obj): + if isinstance(obj, Promise): + return force_text(obj) + return super(LazyEncoder, self).default(obj) -json_encode = json.JSONEncoder().encode +json_encode = LazyEncoder().encode DEFAULT_CONFIG = { 'skin': 'moono',