guneysus
3/11/2016 - 4:05 PM

Multipart file upload aware custom JSON serializer for Restless using Tornado utils

Multipart file upload aware custom JSON serializer for Restless using Tornado utils

#!/usr/bin/env python
# coding:utf-8
import StringIO
import os
import uuid

import restless.exceptions
import restless.serializers
import restless.tnd
import tornado.httputil


class SnippetUploaderSerializer(restless.serializers.Serializer):
    # Usage
    # class SnippetResource(restless.tnd.TornadoResource):
    #   serializer = helpers.SnippetUploaderSerializer()


    def deserialize(self, body):
        args = dict()
        post_data_multipart_files = dict()

        # We need the boundary string 8d1e7a823982469d82c0358769ccba4c from body
        """--8d1e7a823982469d82c0358769ccba4c
        Content-Disposition: form-data; name="file"; filename="test.txt"

        Test.txt content

        --8d1e7a823982469d82c0358769ccba4c--
        """

        boundary_string = StringIO.StringIO(body).readline()[2:].strip()
        tornado.httputil.parse_multipart_form_data(
            boundary=boundary_string, data=body,
            arguments=args, files=post_data_multipart_files)

        # Parse args
        for multipartfile in post_data_multipart_files.get('file') or []:
            if multipartfile:

                body, content_type, filename = multipartfile.values()
                unique_file_name = "%s" % uuid.uuid4()
                fullpath = os.path.abspath('uploads/%s' % unique_file_name)

                if content_type in ['application/unknown']:
                    content_type = 'text/plain'

                # Write `body` to a file, upload to S3 or GridFS etc.
                # You can use content_type comes from multi_part file also.

                # Upload file to file physical file system
                with open(fullpath, 'wb') as f:
                    f.write(body)
        # You can return uploaded urls, GridFS ObjectIDs, filenames, or any dictionary data that
        # would be used if Restless
        # I use MongoEngine ORM and returning GridFS metadatas for file uploads.

        # {
        #     'id': snippet.id.__str__(),
        #     'grid_id': snippet.file.grid_id.__str__(),
        #     'collection': snippet.file.collection_name,
        #     'file': {
        #         'id': snippet.file.gridout._id.__str__(),
        #         'content_type': snippet.file.gridout.content_type,
        #         'filename': snippet.file.gridout.filename,
        #         'length': snippet.file.gridout.length,
        #         'md5': snippet.file.gridout.md5,
        #         'metadata': snippet.file.gridout.metadata,
        #         'name': snippet.file.gridout.name,
        #         'upload_date': snippet.file.gridout.upload_date.__str__()
        #     }
        # }

        return []