From a0916afe7c30b3c91f91111842c5af11ef026bfc Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sat, 4 Jul 2015 03:59:38 -0400 Subject: [PATCH] Update converter transformation arguments to be YAML based. --- mayan/apps/converter/managers.py | 9 +++-- .../apps/converter/migrations/0001_initial.py | 2 +- .../migrations/0003_auto_20150704_0731.py | 33 +++++++++++++++++++ .../migrations/0004_auto_20150704_0753.py | 21 ++++++++++++ mayan/apps/converter/models.py | 17 ++-------- mayan/apps/converter/validators.py | 21 ++++++++++++ 6 files changed, 85 insertions(+), 18 deletions(-) create mode 100644 mayan/apps/converter/migrations/0003_auto_20150704_0731.py create mode 100644 mayan/apps/converter/migrations/0004_auto_20150704_0753.py create mode 100644 mayan/apps/converter/validators.py diff --git a/mayan/apps/converter/managers.py b/mayan/apps/converter/managers.py index ef03cc4eae..c39db9e1a6 100644 --- a/mayan/apps/converter/managers.py +++ b/mayan/apps/converter/managers.py @@ -1,8 +1,9 @@ from __future__ import unicode_literals -from ast import literal_eval import logging +import yaml + from django.contrib.contenttypes.models import ContentType from django.db import models @@ -60,8 +61,10 @@ class TransformationManager(models.Manager): # Non existant transformation, but we don't raise an error logger.error('Non existant transformation: %s for %s', transformation.name, obj) else: - # TODO: what to do if literal_eval fails? - result.append(transformation_class(**literal_eval(transformation.arguments))) + try: + result.append(transformation_class(**yaml.safe_load(transformation.arguments))) + except Exception as exception: + logger.error('Error while parsing transformation "%s", arguments "%s", for object "%s"; %s', transformation, transformation.arguments, obj, exception) return result else: diff --git a/mayan/apps/converter/migrations/0001_initial.py b/mayan/apps/converter/migrations/0001_initial.py index 8332770f5a..ed818e3428 100644 --- a/mayan/apps/converter/migrations/0001_initial.py +++ b/mayan/apps/converter/migrations/0001_initial.py @@ -19,7 +19,7 @@ class Migration(migrations.Migration): ('object_id', models.PositiveIntegerField()), ('order', models.PositiveIntegerField(default=0, null=True, verbose_name='Order', db_index=True, blank=True)), ('transformation', models.CharField(max_length=128, verbose_name='Transformation', choices=[('rotate', 'Rotate'), ('zoom', 'Zoom'), ('resize', 'Resize')])), - ('arguments', models.TextField(blank=True, null=True, verbose_name='Arguments', validators=[converter.models.argument_validator])), + ('arguments', models.TextField(blank=True, null=True, verbose_name='Arguments', validators=[converter.validators.YAMLValidator])), ('content_type', models.ForeignKey(to='contenttypes.ContentType')), ], options={ diff --git a/mayan/apps/converter/migrations/0003_auto_20150704_0731.py b/mayan/apps/converter/migrations/0003_auto_20150704_0731.py new file mode 100644 index 0000000000..cfa1990fa2 --- /dev/null +++ b/mayan/apps/converter/migrations/0003_auto_20150704_0731.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import converter.validators + + +class Migration(migrations.Migration): + + dependencies = [ + ('converter', '0002_auto_20150608_1943'), + ] + + operations = [ + migrations.AlterField( + model_name='transformation', + name='arguments', + field=models.TextField(default='', help_text='Enter the arguments for the transformation as a YAML dictionary. ie: {"degrees": 180}', blank=True, verbose_name='Arguments', validators=[converter.validators.YAMLValidator]), + preserve_default=False, + ), + migrations.AlterField( + model_name='transformation', + name='name', + field=models.CharField(max_length=128, verbose_name='Name', choices=[('rotate', 'Rotate '), ('zoom', 'Zoom '), ('resize', 'Resize ')]), + preserve_default=True, + ), + migrations.AlterField( + model_name='transformation', + name='order', + field=models.PositiveIntegerField(default=0, blank=True, help_text='Order in which the transformations will be executed.', null=True, verbose_name='Order', db_index=True), + preserve_default=True, + ), + ] diff --git a/mayan/apps/converter/migrations/0004_auto_20150704_0753.py b/mayan/apps/converter/migrations/0004_auto_20150704_0753.py new file mode 100644 index 0000000000..892db29185 --- /dev/null +++ b/mayan/apps/converter/migrations/0004_auto_20150704_0753.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import converter.validators + + +class Migration(migrations.Migration): + + dependencies = [ + ('converter', '0003_auto_20150704_0731'), + ] + + operations = [ + migrations.AlterField( + model_name='transformation', + name='arguments', + field=models.TextField(help_text='Enter the arguments for the transformation as a YAML dictionary. ie: {"degrees": 180}', blank=True, verbose_name='Arguments', validators=[converter.validators.YAMLValidator()]), + preserve_default=True, + ), + ] diff --git a/mayan/apps/converter/models.py b/mayan/apps/converter/models.py index 53f0a6403e..fa71e1f67c 100644 --- a/mayan/apps/converter/models.py +++ b/mayan/apps/converter/models.py @@ -1,6 +1,5 @@ from __future__ import unicode_literals -from ast import literal_eval import logging from django.contrib.contenttypes import generic @@ -12,21 +11,11 @@ from django.utils.translation import ugettext_lazy as _ from .classes import BaseTransformation from .managers import TransformationManager +from .validators import YAMLValidator logger = logging.getLogger(__name__) -def argument_validator(value): - """ - Validates that the input evaluates correctly. - """ - value = value.strip() - try: - literal_eval(value) - except (ValueError, SyntaxError): - raise ValidationError(_('Enter a valid value.'), code='invalid') - - @python_2_unicode_compatible class Transformation(models.Model): """ @@ -38,9 +27,9 @@ class Transformation(models.Model): object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id') - order = models.PositiveIntegerField(default=0, blank=True, help_text=_('Order in which the transformations will be executed.'), null=True, verbose_name=_('Order'), db_index=True) + order = models.PositiveIntegerField(blank=True, db_index=True, default=0, help_text=_('Order in which the transformations will be executed.'), null=True, verbose_name=_('Order')) name = models.CharField(choices=BaseTransformation.get_transformation_choices(), max_length=128, verbose_name=_('Name')) - arguments = models.TextField(blank=True, help_text=_('Enter the arguments for the transformation as a Python dictionary. ie: {"degrees": 180}'), verbose_name=_('Arguments'), validators=[argument_validator]) + arguments = models.TextField(blank=True, help_text=_('Enter the arguments for the transformation as a YAML dictionary. ie: {"degrees": 180}'), validators=[YAMLValidator()], verbose_name=_('Arguments')) objects = TransformationManager() diff --git a/mayan/apps/converter/validators.py b/mayan/apps/converter/validators.py new file mode 100644 index 0000000000..1b0ab73e84 --- /dev/null +++ b/mayan/apps/converter/validators.py @@ -0,0 +1,21 @@ +from __future__ import unicode_literals + +import yaml + +from django.core.exceptions import ValidationError +from django.utils.translation import ugettext_lazy as _ +from django.utils.deconstruct import deconstructible + + +@deconstructible +class YAMLValidator(object): + """ + Validates that the input is YAML compliant. + """ + + def __call__(self, value): + value = value.strip() + try: + yaml.safe_load(value) + except yaml.error.YAMLError: + raise ValidationError(_('Enter a valid YAML value.'), code='invalid')