Source code for beat.web.common.utils

#!/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/.           #
#                                                                             #
###############################################################################

"""
Reusable help functions
"""
from django.core.exceptions import ValidationError
from django.utils.encoding import force_text
from django.utils import six

from ..ui.templatetags.markup import restructuredtext

[docs]def validate_restructuredtext(value): """Validates a piece of restructuredtext for strict conformance""" try: from docutils import utils from docutils.nodes import Element from docutils.core import Publisher except ImportError: raise forms.ValidationError("Error in 'reStructuredText' validator: The Python docutils package isn't installed.") # Generate a new parser (copying `rst2html.py` flow) pub = Publisher(None, None, None, settings=None) pub.set_components('standalone', 'restructuredtext', 'pseudoxml') # Configure publisher settings = pub.get_settings(halt_level=5) pub.set_io() # Prepare a document to parse reader = pub.reader document = utils.new_document(None, settings) # Disable stdout # TODO: Find a proper way to do this # TODO: We might exit the program if a certain error level is reached document.reporter.stream = None # Collect errors via an observer errors = [] def error_collector(data): # Mutate the data since it was just generated data.line = data['line'] data.source = data['source'] data.level = data['level'] data.type = data['type'] data.message = Element.astext(data.children[0]) data.full_message = Element.astext(data) # Save the error errors.append(data) document.reporter.attach_observer(error_collector) # Parse the content (and collect errors) reader.parser.parse(force_text(value), document) # Apply transforms (and more collect errors) document.transformer.populate_from_components( (pub.source, pub.reader, pub.reader.parser, pub.writer, pub.destination)) transformer = document.transformer while transformer.transforms: if not transformer.sorted: # Unsorted initially, and whenever a transform is added. transformer.transforms.sort() transformer.transforms.reverse() transformer.sorted = 1 priority, transform_class, pending, kwargs = transformer.transforms.pop() transform = transform_class(transformer.document, startnode=pending) transform.apply(**kwargs) transformer.applied.append((priority, transform_class, pending, kwargs)) # errors should be ready if errors: validation_list = [] msg = 'Line %(line)d (severity %(level)d): %(message)s' for error in errors: #from docutils.parsers.rst module: #debug(0), info(1), warning(2), error(3), severe(4) if error.level > 1: validation_list.append(ValidationError( msg, code=error.type.lower(), params=dict(line=error.line, level=error.level, message=error.message))) if validation_list: raise ValidationError(validation_list)
[docs]def ensure_html(text): try: validate_restructuredtext(text) except ValidationError as e: return '<pre>{}</pre>'.format(text) else: return restructuredtext(text)
[docs]def ensure_string(data): """ Ensure that we have a str object from data which can be either a str in python 2 or a bytes in python 3 """ if data is not None: if isinstance(data, six.binary_type): return data.decode('utf-8') return data return ''