Source code for beat.web.utils.activity_stream_serializer

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

from django.core.serializers.base import DeserializationError
from django.core.serializers.python import Deserializer as PythonDeserializer, _get_model
from django.core.serializers.json import Serializer as JSONSerializer
from django.utils.encoding import force_text
from django.contrib.contenttypes.models import ContentType

from django.utils import six

from actstream.models import Action

import sys
import json

elements_to_convert = [('actor_object_id', 'actor_content_type'),
                       ('action_object_object_id', 'action_object_content_type'),
                       ('target_object_id', 'target_content_type')]


[docs]class Serializer(JSONSerializer): """ Custom JSON serializer that replaces the actstream Action model ids by their natural key counterpart. """
[docs] def get_dump_object(self, obj): data = { "model": force_text(obj._meta), "fields": self._current, } if not self.use_natural_primary_keys or not hasattr(obj, 'natural_key'): data["pk"] = force_text(obj._get_pk_val(), strings_only=True) if self.use_natural_primary_keys and isinstance(obj, Action): for element in elements_to_convert: element_object_id = element[0] element_content_type = element[1] element_info = data['fields'][element_content_type] if element_info: element_app = element_info[0] element_model = element_info[1] element_type = ContentType.objects.get(app_label=element_app, model=element_model) element_id = data['fields'][element_object_id] element_object = element_type.get_object_for_this_type(id=int(element_id)) data['fields'][element_object_id] = element_object.natural_key() return data
[docs]def Deserializer(stream_or_string, **options): """ Custom JSON deserializer that will replace the natural keys generated by the serializer to their id counterpart. """ if not isinstance(stream_or_string, (bytes, six.string_types)): stream_or_string = stream_or_string.read() if isinstance(stream_or_string, bytes): stream_or_string = stream_or_string.decode('utf-8') try: objects = json.loads(stream_or_string) for d in objects: # Look up the model and starting build a dict of data for it. Model = _get_model(d["model"]) if Model == Action: for element in elements_to_convert: element_object_id = element[0] element_content_type = element[1] element_info = d['fields'][element_content_type] if element_info: element_app = element_info[0] element_model = element_info[1] element_type = ContentType.objects.get(app_label=element_app, model=element_model) element_natural_key = d['fields'][element_object_id] element_object = element_type.model_class().objects.get_by_natural_key(*element_natural_key) d['fields'][element_object_id] = str(element_object.id) for obj in PythonDeserializer(objects, **options): yield obj except GeneratorExit: raise except Exception as e: # Map to deserializer error six.reraise(DeserializationError, DeserializationError(e), sys.exc_info()[2])