#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
###############################################################################
# #
# Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ #
# Contact: beat.support@idiap.ch #
# #
# This file is part of the beat.web module of the BEAT platform. #
# #
# Commercial License Usage #
# Licensees holding valid commercial BEAT licenses may use this file in #
# accordance with the terms contained in a written agreement between you #
# and Idiap. For further information contact tto@idiap.ch #
# #
# Alternatively, this file may be used under the terms of the GNU Affero #
# Public License version 3 as published by the Free Software and appearing #
# in the file LICENSE.AGPL included in the packaging of this file. #
# The BEAT platform is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY #
# or FITNESS FOR A PARTICULAR PURPOSE. #
# #
# You should have received a copy of the GNU Affero Public License along #
# with the BEAT platform. If not, see http://www.gnu.org/licenses/. #
# #
###############################################################################
# Code copied on 24.09.2014 (and customised) from:
# https://github.com/lambdalisue/django-codemirror-widget
# (originally BSD-Licensed)
from django import forms
from django.core.files.base import ContentFile
from .widgets import CodeMirrorFileWidget, CodeMirrorTextarea
from ..common.models import Contribution
from ..common.utils import validate_restructuredtext
[docs]class NameField(forms.CharField):
"""A specialization of the CharField that runs algo name validation"""
def __init__(self, *args, **kwargs):
super(NameField, self).__init__(*args, **kwargs)
[docs] def to_python(self, value):
"""Converts the name to a valid python value"""
if not value:
raise forms.ValidationError(u'A non-blank name is required.')
return Contribution.sanitize_name(value)
#-----------------------------------------------------------------------------
[docs]class CodeMirrorCharField(forms.CharField):
"""Allows editing a text field with a source code editor"""
def __init__(self, codemirror_kwargs={}, *args, **kwargs):
codemirror_kwargs = dict(codemirror_kwargs)
# handles the readonly attribute gracefully
if 'readonly' in kwargs:
if kwargs['readonly']:
config = codemirror_kwargs.get('config', {})
config['readOnly'] = True
codemirror_kwargs['config'] = config
del kwargs['readonly']
kwargs.update({'widget': CodeMirrorTextarea(**codemirror_kwargs)})
super(CodeMirrorCharField, self).__init__(*args, **kwargs)
[docs] def to_python(self, data):
clean_data = data.replace('\r', '') if data else ''
return super(CodeMirrorCharField, self).to_python(clean_data)
[docs]class CodeMirrorRSTCharField(CodeMirrorCharField):
"""Allows editing a text field with a source code editor"""
def __init__(self, codemirror_kwargs={}, *args, **kwargs):
codemirror_kwargs = dict(codemirror_kwargs)
addon_js = list(codemirror_kwargs.get('addon_js', []))
addon_js += [
"display/rulers",
]
codemirror_kwargs['addon_js'] = addon_js
codemirror_kwargs['mode'] = 'rst'
config = codemirror_kwargs.get('config', {})
config['foldGutter'] = False
config['gutters'] = ["CodeMirror-linenumbers"]
codemirror_kwargs['config'] = config
super(CodeMirrorRSTCharField, self).__init__(codemirror_kwargs, *args, **kwargs)
[docs] def to_python(self, data):
validate_restructuredtext(data)
return super(CodeMirrorRSTCharField, self).to_python(data)
[docs]class CodeMirrorPythonCharField(CodeMirrorCharField):
"""Allows editing a file instead of a plain content"""
def __init__(self, codemirror_kwargs={}, *args, **kwargs):
codemirror_kwargs = dict(codemirror_kwargs)
addon_js = list(codemirror_kwargs.get('addon_js', []))
addon_js += [
"fold/indent-fold",
"display/rulers",
]
codemirror_kwargs['addon_js'] = addon_js
codemirror_kwargs['mode'] = 'python'
super(CodeMirrorPythonCharField, self).__init__(codemirror_kwargs, *args, **kwargs)
[docs]class CodeMirrorJSONCharField(CodeMirrorCharField):
"""Allows editing a file instead of a plain content"""
def __init__(self, codemirror_kwargs={}, *args, **kwargs):
codemirror_kwargs = dict(codemirror_kwargs)
addon_js = list(codemirror_kwargs.get('addon_js', []))
addon_js += [
"fold/brace-fold",
"display/rulers",
]
codemirror_kwargs['addon_js'] = addon_js
codemirror_kwargs['mode'] = {'name': 'javascript', 'json': True}
super(CodeMirrorJSONCharField, self).__init__(codemirror_kwargs, *args, **kwargs)
#-----------------------------------------------------------------------------
[docs]class CodeMirrorFileField(forms.FileField):
"""Allows editing a file instead of a plain content"""
def __init__(self, codemirror_kwargs={}, *args, **kwargs):
codemirror_kwargs = dict(codemirror_kwargs)
# handles the readonly attribute gracefully
if 'readonly' in kwargs:
if kwargs['readonly']:
config = codemirror_kwargs.get('config', {})
config['readOnly'] = True
codemirror_kwargs['config'] = config
del kwargs['readonly']
kwargs.update({'widget': CodeMirrorFileWidget(**codemirror_kwargs)})
super(CodeMirrorFileField, self).__init__(*args, **kwargs)
[docs] def to_python(self, data):
data = ContentFile(data.replace('\r',''))
data.name = '__ignore__'
return super(CodeMirrorFileField, self).to_python(data)
[docs]class CodeMirrorRSTFileField(CodeMirrorFileField):
"""Allows editing a text field with a source code editor"""
def __init__(self, codemirror_kwargs={}, *args, **kwargs):
codemirror_kwargs = dict(codemirror_kwargs)
addon_js = list(codemirror_kwargs.get('addon_js', []))
addon_js += [
"display/rulers",
]
codemirror_kwargs['addon_js'] = addon_js
codemirror_kwargs['mode'] = 'rst'
config = codemirror_kwargs.get('config', {})
config['foldGutter'] = False
config['gutters'] = ["CodeMirror-linenumbers"]
codemirror_kwargs['config'] = config
super(CodeMirrorRSTFileField, self).__init__(codemirror_kwargs, *args, **kwargs)
[docs] def to_python(self, data):
validate_restructuredtext(data)
return super(CodeMirrorRSTFileField, self).to_python(data)
[docs]class CodeMirrorPythonFileField(CodeMirrorFileField):
"""Allows editing a file instead of a plain content"""
def __init__(self, codemirror_kwargs={}, *args, **kwargs):
codemirror_kwargs = dict(codemirror_kwargs)
addon_js = list(codemirror_kwargs.get('addon_js', []))
addon_js += [
"fold/indent-fold",
"display/rulers",
]
codemirror_kwargs['addon_js'] = addon_js
codemirror_kwargs['mode'] = 'python'
super(CodeMirrorPythonFileField, self).__init__(codemirror_kwargs, *args, **kwargs)
[docs]class CodeMirrorJSONFileField(CodeMirrorFileField):
"""Allows editing a file instead of a plain content"""
def __init__(self, codemirror_kwargs={}, *args, **kwargs):
codemirror_kwargs = dict(codemirror_kwargs)
addon_js = list(codemirror_kwargs.get('addon_js', []))
addon_js += [
"fold/brace-fold",
"display/rulers",
]
codemirror_kwargs['addon_js'] = addon_js
codemirror_kwargs['mode'] = {'name': 'javascript', 'json': True}
super(CodeMirrorJSONFileField, self).__init__(codemirror_kwargs, *args, **kwargs)