Source code for shuup.api.fields

# -*- coding: utf-8 -*-
# This file is part of Shuup.
#
# Copyright (c) 2012-2017, Shoop Commerce Ltd. All rights reserved.
#
# This source code is licensed under the OSL-3.0 license found in the
# LICENSE file in the root directory of this source tree.

import base64
import binascii
import mimetypes
import uuid

import six
from django.core.exceptions import ValidationError
from django.core.files.base import ContentFile
from rest_framework import serializers


[docs]class EnumField(serializers.ChoiceField): """ A field which accepts django-enumfields types """ def __init__(self, enum, **kwargs): self.enum = enum kwargs['choices'] = enum.choices() super(EnumField, self).__init__(**kwargs)
[docs] def to_representation(self, obj): return obj.value
[docs] def to_internal_value(self, data): return self.enum(data)
[docs]class TypedContentFile(ContentFile): def __init__(self, content, content_type, name=None): self.content_type = content_type super(TypedContentFile, self).__init__(content, name)
[docs]class Base64FileField(serializers.FileField): """ Inspired in https://github.com/Hipo/drf-extra-fields/blob/master/drf_extra_fields/fields.py But here we use the media type from the header to guess the file type """
[docs] def to_internal_value(self, base64_data): if not isinstance(base64_data, six.string_types): raise ValidationError("This is not a base64 string") elif ';base64,' not in base64_data: raise ValidationError("base64 files must have media type defined.") header, base64_data = base64_data.split(';base64,') try: decoded_file = base64.b64decode(base64_data) except (TypeError, binascii.Error): raise ValidationError("Invalid file.") media_type = header[len("data:"):] # remove data: from the start of the string extension = mimetypes.guess_extension(media_type, strict=False) if not extension: raise ValidationError("Media type not recognized.") file_name = "{0}{1}".format(uuid.uuid4(), extension) data = TypedContentFile(decoded_file, media_type, name=file_name) return super(Base64FileField, self).to_internal_value(data)
[docs] def to_representation(self, file): try: mime_type = mimetypes.guess_type(file.path, strict=False) with open(file.path, 'rb') as f: return "data:{0};base64,{1}".format(mime_type, base64.b64encode(f.read()).decode()) except Exception: raise IOError("Error encoding file")