From f0e5ac861d8d1a750530d0bb674a7c7c8420592b Mon Sep 17 00:00:00 2001 From: Pouria Hadjibagheri Date: Sun, 19 Mar 2017 17:19:28 +0000 Subject: [PATCH] Updates - mostly to do with docs and front-end settings. --- markdownx/__init__.py | 7 +++-- markdownx/admin.py | 3 -- markdownx/exceptions.py | 14 ++++----- markdownx/fields.py | 15 +++++++--- markdownx/forms.py | 2 +- markdownx/models.py | 1 - markdownx/settings.py | 7 +++++ markdownx/tests/models.py | 4 +++ markdownx/views.py | 61 +++++++++++++++++++++++++++++++++----- markdownx/widgets.py | 62 ++++++++++++++++++++++++++++++++------- 10 files changed, 139 insertions(+), 37 deletions(-) diff --git a/markdownx/__init__.py b/markdownx/__init__.py index a0373e6..d54e508 100755 --- a/markdownx/__init__.py +++ b/markdownx/__init__.py @@ -1,6 +1,6 @@ """ -Django MarkdownX is a comprehensive `Markdown `_ editor built for -`Django `_, the renowned high-level Python web framework. +Django MarkdownX is a comprehensive Markdown_ plugin built for Django_, the renowned high-level +Python web framework, with flexibility, extensibility, and ease-of-use at its core. Key features @@ -22,6 +22,9 @@ Key features :target: https://github.com/adi-/django-markdownx :align: center :alt: django-markdownx preview + +.. _Markdown: https://en.wikipedia.org/wiki/Markdown +.. _Django: https://www.djangoproject.com """ # ~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= diff --git a/markdownx/admin.py b/markdownx/admin.py index f5164d5..b8e07e0 100644 --- a/markdownx/admin.py +++ b/markdownx/admin.py @@ -6,9 +6,6 @@ from .models import MarkdownxField class MarkdownxModelAdmin(admin.ModelAdmin): - """ - - """ formfield_overrides = { MarkdownxField: {'widget': AdminMarkdownxWidget} diff --git a/markdownx/exceptions.py b/markdownx/exceptions.py index 67c7bd9..5ef4fee 100644 --- a/markdownx/exceptions.py +++ b/markdownx/exceptions.py @@ -20,8 +20,8 @@ class MarkdownxImageUploadError(ValidationError): @staticmethod def unsupported_format(): """ - The file is of a format not defined in `settings.py` - or if default, in `markdownx/settings.py`. + The file is of a format not defined in :guilabel:`settings.py` + or if default, in :guilabel:`markdownx/settings.py`. :return: :rtype: @@ -31,7 +31,7 @@ class MarkdownxImageUploadError(ValidationError): @staticmethod def invalid_size(current, expected): """ - The file is larger in size that the maximum allow in `settings.py` (or the default). + The file is larger in size that the maximum allow in :guilabel:`settings.py` (or the default). :param current: :type current: @@ -43,8 +43,8 @@ class MarkdownxImageUploadError(ValidationError): from django.template.defaultfilters import filesizeformat return MarkdownxImageUploadError( - _('Please keep file size under {max}. Current file size {current}').format( - max=filesizeformat(expected), - current=filesizeformat(current) - ) + _('Please keep file size under %(max)s. Current file size: %(current)s.') % { + 'max': filesizeformat(expected), + 'current': filesizeformat(current) + } ) diff --git a/markdownx/fields.py b/markdownx/fields.py index b97c6b0..ca59bd8 100644 --- a/markdownx/fields.py +++ b/markdownx/fields.py @@ -1,14 +1,21 @@ from django import forms -from .widgets import ( - MarkdownxWidget, - AdminMarkdownxWidget, -) +from .widgets import MarkdownxWidget, AdminMarkdownxWidget class MarkdownxFormField(forms.CharField): + """ + + """ def __init__(self, *args, **kwargs): + """ + + :param args: + :type args: + :param kwargs: + :type kwargs: + """ super(MarkdownxFormField, self).__init__(*args, **kwargs) if issubclass(self.widget.__class__, forms.widgets.MultiWidget): diff --git a/markdownx/forms.py b/markdownx/forms.py index c371596..5158344 100755 --- a/markdownx/forms.py +++ b/markdownx/forms.py @@ -24,7 +24,7 @@ from .settings import ( class ImageForm(forms.Form): """ - Used for the handling of images uploaded using the editor through AJAX. + Used for the handling of images uploaded using the editor through :guilabel:`AJAX`. """ image = forms.FileField() diff --git a/markdownx/models.py b/markdownx/models.py index 0233cbe..d5bff6c 100644 --- a/markdownx/models.py +++ b/markdownx/models.py @@ -40,7 +40,6 @@ class MarkdownxField(models.TextField): information. .. _documentations: https://docs.djangoproject.com/en/1.10/ref/models/fields/#error-messages - .. _validators: https://docs.djangoproject.com/en/dev/ref/validators/ """ diff --git a/markdownx/settings.py b/markdownx/settings.py index cc96e47..1b3619a 100755 --- a/markdownx/settings.py +++ b/markdownx/settings.py @@ -12,6 +12,7 @@ VALID_CONTENT_TYPES = 'image/jpeg', 'image/png', 'image/svg+xml' NINETY_DPI = 90 IM_WIDTH = 500 IM_HEIGHT = 500 +LATENCY = 500 # ------------------------------------------------------------------ @@ -37,6 +38,8 @@ def _mdx(var, default): # -------------------- MARKDOWNX_MARKDOWNIFY_FUNCTION = _mdx('MARKDOWNIFY_FUNCTION', 'markdownx.utils.markdownify') +MARKDOWNX_SERVER_CALL_LATENCY = _mdx('SERVER_CALL_LATENCY', LATENCY) + # Markdown extensions # -------------------- @@ -85,6 +88,10 @@ try: ( ('en', _('English')), ('pl', _('Polish')), + ('de', _('German')), + ('fr', _('French')), + ('fa', _('Persian')), + ('du', _('Dutch')) ) ) except ImproperlyConfigured: diff --git a/markdownx/tests/models.py b/markdownx/tests/models.py index 9bfdc40..5228699 100644 --- a/markdownx/tests/models.py +++ b/markdownx/tests/models.py @@ -2,7 +2,11 @@ from django.db import models from markdownx.models import MarkdownxField + class MyModel(models.Model): + """ + + """ markdownx_field = MarkdownxField() class Meta: diff --git a/markdownx/views.py b/markdownx/views.py index b407731..4aeccd4 100755 --- a/markdownx/views.py +++ b/markdownx/views.py @@ -1,37 +1,82 @@ from django.http import HttpResponse, JsonResponse from django.utils.module_loading import import_string -from django.views.generic.edit import View, FormView +from django.views.generic.edit import View, FormView, BaseFormView from .forms import ImageForm from .settings import MARKDOWNX_MARKDOWNIFY_FUNCTION class MarkdownifyView(View): + """ + Conversion of Markdown to HTML. + """ def post(self, request, *args, **kwargs): + """ + Handling of the conversion from Markdown to HTML using the conversion + function in settings under ``MARKDOWNX_MARKDOWNIFY_FUNCTION``. + + :param request: HTTP request. + :param args: Default Django POST arguments. + :param kwargs: Default Django POST keyword arguments. + :return: HTTP response + :rtype: django.http.HttpResponse + """ markdownify = import_string(MARKDOWNX_MARKDOWNIFY_FUNCTION) return HttpResponse(markdownify(request.POST['content'])) -class ImageUploadView(FormView): +class ImageUploadView(BaseFormView): + """ + Handling requests for uploading images. + """ - template_name = "dummy.html" + # template_name = "dummy.html" form_class = ImageForm success_url = '/' def form_invalid(self, form): + """ + Handling of invalid form events. + + :param form: Django form instance. + :type form: django.forms.Form + :return: JSON response with the HTTP-400 error message for AJAX requests + and the default response for HTTP requests. + :rtype: django.http.JsonResponse, django.http.HttpResponse + """ response = super(ImageUploadView, self).form_invalid(form) + if self.request.is_ajax(): return JsonResponse(form.errors, status=400) - else: - return response + + return response def form_valid(self, form): - image_path = form.save() + """ + If the form is valid, the contents are saved. + + If the **POST** request is AJAX (image uploads), a JSON response will be + produced containing the Markdown encoded image insertion tag with the URL + using which the uploaded image may be accessed. + + JSON response would be as follows: + + .. code-block:: json + + { image_code: "![](/media/image_directory/123-4e6-ga3.png)" } + + :param form: Django form instance. + :type form: django.forms.Form + :return: JSON encoded Markdown tag for AJAX requests, and an appropriate + response for HTTP requests. + :rtype: django.http.JsonResponse, django.http.HttpResponse + """ response = super(ImageUploadView, self).form_valid(form) if self.request.is_ajax(): + image_path = form.save(commit=True) image_code = '![]({})'.format(image_path) return JsonResponse({'image_code': image_code}) - else: - return response + + return response diff --git a/markdownx/widgets.py b/markdownx/widgets.py index 66bdb2d..a985c64 100755 --- a/markdownx/widgets.py +++ b/markdownx/widgets.py @@ -1,29 +1,53 @@ from django import forms from django.template.loader import get_template from django.contrib.admin import widgets +from django.conf import settings from .settings import ( MARKDOWNX_EDITOR_RESIZABLE, MARKDOWNX_URLS_PATH, MARKDOWNX_UPLOAD_URLS_PATH, + MARKDOWNX_SERVER_CALL_LATENCY ) -class MarkdownxWidget(forms.Textarea): +DEBUG = getattr(settings, 'DEBUG', False) - def render(self, name, value, attrs=None): + +class MarkdownxWidget(forms.Textarea): + """ + + """ + + def render(self, name, value, attrs=None, renderer=None): + """ + + :param name: + :type name: + :param value: + :type value: + :param attrs: + :type attrs: + :param renderer: + :type renderer: + :return: + :rtype: + """ attrs = self.build_attrs(attrs, name=name) if 'class' in attrs: attrs['class'] += ' markdownx-editor' else: - attrs.update({'class':'markdownx-editor'}) + attrs.update({ + 'class': 'markdownx-editor' + }) attrs['data-markdownx-editor-resizable'] = MARKDOWNX_EDITOR_RESIZABLE attrs['data-markdownx-urls-path'] = MARKDOWNX_URLS_PATH attrs['data-markdownx-upload-urls-path'] = MARKDOWNX_UPLOAD_URLS_PATH + attrs['data-markdownx-latency'] = MARKDOWNX_SERVER_CALL_LATENCY - widget = super(MarkdownxWidget, self).render(name, value, attrs) + widget = super(MarkdownxWidget, self).render(name, value, attrs, renderer) template = get_template('markdownx/widget.html') @@ -32,17 +56,33 @@ class MarkdownxWidget(forms.Textarea): }) class Media: - js = ( - 'markdownx/js/markdownx.js', - ) + """ + + """ + + css = { + 'all': {'markdownx/css/markdownx.css', }, + } + + js = { + 'markdownx/js/' + ('markdownx.min.js' if not DEBUG else 'markdownx.js'), + } class AdminMarkdownxWidget(MarkdownxWidget, widgets.AdminTextareaWidget): + """ + + """ class Media: + """ + + """ + css = { - 'all': ('markdownx/admin/css/markdownx.css',) + 'all': {'markdownx/admin/css/markdownx.css', } + } + + js = { + 'markdownx/js/' + ('markdownx.min.js' if not DEBUG else 'markdownx.js'), } - js = ( - 'markdownx/js/markdownx.js', - )