src/p4l/mapping/serializers.py
author ymh <ymh.work@gmail.com>
Mon, 16 Dec 2013 12:40:05 +0100
changeset 164 4f77196ffde1
parent 142 c365a6e23a56
permissions -rw-r--r--
Added tag V00.06 for changeset c875b5418740
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
101
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
# -*- coding: utf-8 -*-
126
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
     2
#
131
f1854630734f change copyright notice
ymh <ymh.work@gmail.com>
parents: 126
diff changeset
     3
# Copyright IRI (c) 2013
126
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
     4
#
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
     5
# contact@iri.centrepompidou.fr
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
     6
#
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
     7
# This software is governed by the CeCILL-B license under French law and
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
     8
# abiding by the rules of distribution of free software.  You can  use, 
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
     9
# modify and/ or redistribute the software under the terms of the CeCILL-B
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    10
# license as circulated by CEA, CNRS and INRIA at the following URL
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    11
# "http://www.cecill.info". 
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    12
#
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    13
# As a counterpart to the access to the source code and  rights to copy,
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    14
# modify and redistribute granted by the license, users are provided only
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    15
# with a limited warranty  and the software's author,  the holder of the
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    16
# economic rights,  and the successive licensors  have only  limited
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    17
# liability. 
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    18
#
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    19
# In this respect, the user's attention is drawn to the risks associated
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    20
# with loading,  using,  modifying and/or developing or reproducing the
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    21
# software by the user in light of its specific status of free software,
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    22
# that may mean  that it is complicated to manipulate,  and  that  also
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    23
# therefore means  that it is reserved for developers  and  experienced
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    24
# professionals having in-depth computer knowledge. Users are therefore
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    25
# encouraged to load and test the software's suitability as regards their
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    26
# requirements in conditions enabling the security of their systems and/or 
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    27
# data to be ensured and,  more generally, to use and operate it in the 
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    28
# same conditions as regards security. 
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    29
#
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    30
# The fact that you are presently reading this means that you have had
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    31
# knowledge of the CeCILL-B license and that you accept its terms.
a345f1a67bf1 Python licence headers
ymh <ymh.work@gmail.com>
parents: 101
diff changeset
    32
#
101
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
142
c365a6e23a56 Correct dump_record, ensure that ref fields are exported as resources. Correct bug https://github.com/IRI-Research/plan4learning/issues/1
ymh <ymh.work@gmail.com>
parents: 131
diff changeset
    34
from collections import OrderedDict
101
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
import logging
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
from rdflib.namespace import RDF
142
c365a6e23a56 Correct dump_record, ensure that ref fields are exported as resources. Correct bug https://github.com/IRI-Research/plan4learning/issues/1
ymh <ymh.work@gmail.com>
parents: 131
diff changeset
    38
from rdflib.term import URIRef, Literal, BNode, Identifier
101
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
logger = logging.getLogger(__name__)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
class BaseSerializer(object):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
    
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
    creation_counter = 0
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
    
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
    def __init__(self, predicate=None, many=False):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
        self.predicate = predicate
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
        self.creation_counter = BaseSerializer.creation_counter
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
        self.many = many
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
        BaseSerializer.creation_counter += 1
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
        if self.predicate and not isinstance(self.predicate, URIRef):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
            self.predicate = URIRef(predicate)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
    
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
class FieldSerializer(BaseSerializer):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
        
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
    def __init__(self, predicate=None, convert=None, source=None, many=False):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
        super(FieldSerializer, self).__init__(predicate=predicate, many=many)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
        self.convert = convert or (lambda x: Literal(unicode(x)) if x else None)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
        self.source = source
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
    def get_rdf_object(self, obj, fieldname):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
        raise NotImplemented()
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
        
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
    def to_graph(self, subject, obj, fieldname, graph):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
        o = self.get_rdf_object(obj, fieldname)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
        if o:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
            graph.add((subject, self.predicate, o))
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
        
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
class SimpleFieldSerializer(FieldSerializer):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
    
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
    def __init__(self, predicate=None, convert=None, source=None, lang_field=None):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
        super(SimpleFieldSerializer, self).__init__(predicate=predicate, convert=convert, source=source, many=False)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
        self.lang_field = lang_field
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
    
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
    def get_rdf_object(self, obj, fieldname):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
        res = self.convert(getattr(obj, self.source or fieldname))
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
        if res is None:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
            return
142
c365a6e23a56 Correct dump_record, ensure that ref fields are exported as resources. Correct bug https://github.com/IRI-Research/plan4learning/issues/1
ymh <ymh.work@gmail.com>
parents: 131
diff changeset
    83
        if not isinstance(res, Identifier):
101
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
            res = Literal(unicode(res))        
142
c365a6e23a56 Correct dump_record, ensure that ref fields are exported as resources. Correct bug https://github.com/IRI-Research/plan4learning/issues/1
ymh <ymh.work@gmail.com>
parents: 131
diff changeset
    85
        
101
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
        lang = getattr(obj, self.lang_field, None) if self.lang_field else None
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
        
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
        return Literal(res.value, lang) if lang else res
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
class BooleanFieldSerializer(SimpleFieldSerializer):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
    def bool_convert(self, value):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
        return (Literal('TRUE') if value else Literal('FALSE')) if value is not None else None
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
    def __init__(self, predicate=None, convert=None, source=None, lang_field=None):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
        super(BooleanFieldSerializer, self).__init__( predicate, convert=convert, source=source, lang_field=lang_field)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
        self.convert = lambda x: self.bool_convert(x)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
class RelatedFieldSerializer(SimpleFieldSerializer):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
        
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
    def __init__(self, value_field, predicate=None, convert=None, source=None, many=False, lang_field=None):
142
c365a6e23a56 Correct dump_record, ensure that ref fields are exported as resources. Correct bug https://github.com/IRI-Research/plan4learning/issues/1
ymh <ymh.work@gmail.com>
parents: 131
diff changeset
   103
        super(RelatedFieldSerializer, self).__init__(predicate=predicate, convert=convert, source=source, lang_field=lang_field)
101
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
        self.many = many
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
        self.value_field = value_field
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
    def to_graph(self, subject, obj, fieldname, graph):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
        value = getattr(obj, fieldname, None)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
        if not value:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
            return
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
        
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
        values_to_add = []
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
        if self.many:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
            for related_obj in value.all():
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
                values_to_add.append(self.get_rdf_object(related_obj, self.value_field))
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
        else:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
            values_to_add.append(self.get_rdf_object(value, self.value_field))
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
        for o in values_to_add:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
            if o:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
                graph.add((subject, self.predicate, o))
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
    
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
# Directly adapted from serializers in rest_framework 
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
def _get_declared_fields(bases, attrs):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
    """
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
    Create a list of serializer field instances from the passed in 'attrs',
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
    plus any fields on the base classes (in 'bases').
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
    Note that all fields from the base classes are used.
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   131
    """
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   132
    fields = [(field_name, attrs.pop(field_name))
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   133
              for field_name, obj in list(attrs.iteritems())
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   134
              if isinstance(obj, BaseSerializer)]
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   135
    fields.sort(key=lambda x: x[1].creation_counter)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   137
    # If this class is subclassing another Serializer, add that Serializer's
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   138
    # fields.  Note that we loop over the bases in *reverse*. This is necessary
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   139
    # in order to maintain the correct order of fields.
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   140
    for base in bases[::-1]:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   141
        if hasattr(base, 'base_serializers'):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   142
            fields = list(base.base_serializers.items()) + fields
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   143
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   144
    return OrderedDict(fields)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   145
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   146
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   147
class SerializerMetaclass(type):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   148
    def __new__(cls, name, bases, attrs):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   149
        attrs['base_serializers'] = _get_declared_fields(bases, attrs)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   150
        return super(SerializerMetaclass, cls).__new__(cls, name, bases, attrs)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   151
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   152
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   153
class ModelSerializerOptions(object):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   154
    
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   155
    def __init__(self, meta):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   156
        self.type = getattr(meta, 'type', None)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   157
        if self.type and not isinstance(self.type, URIRef):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   158
            self.type = URIRef(self.type)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   159
        self.uri_fieldname = getattr(meta, 'uri_fieldname', None)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   160
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   161
class ModelSerializer(BaseSerializer):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   162
    
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   163
    __metaclass__ =  SerializerMetaclass
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   164
      
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   165
    class Meta(object):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   166
        pass
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   167
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   168
    def get_serializers(self):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   169
        return []
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   170
        
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   171
    def get_uri(self, obj):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   172
        uri = None
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   173
        if self.opts.uri_fieldname:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   174
            uri = getattr(obj, self.opts.uri_fieldname, None)            
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   175
        return URIRef(uri) if uri else None
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   176
    
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   177
    def object_to_graph(self, subject, uri, obj, graph):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   178
        
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   179
        if self.predicate:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   180
            graph.add((subject, self.predicate, uri))
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   181
        
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   182
        for serializer_fieldname, field_serializer in self.base_serializers.iteritems():
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   183
            field_serializer.to_graph(uri, obj, serializer_fieldname, graph)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   184
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   185
    
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   186
    def to_graph(self, subject, obj, fieldname, graph):        
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   187
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   188
        uri = self.get_uri(obj)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   189
        if self.opts.type:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   190
            graph.add((uri, RDF.type, self.opts.type))
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   191
            
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   192
        obj_to_add = []
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   193
        if fieldname:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   194
            field_value = getattr(obj, fieldname, None)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   195
            if field_value:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   196
                if self.many:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   197
                    obj_to_add = [(nested_obj, BNode()) for nested_obj in field_value.all()]
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   198
                else:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   199
                    obj_to_add = [(field_value, BNode())]
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   200
        else:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   201
            obj_to_add = [(obj, uri)]
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   202
        
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   203
        for nested_obj, nested_uri in obj_to_add:
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   204
            self.object_to_graph( subject, nested_uri, nested_obj, graph)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   205
            
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   206
    
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   207
    def __init__(self, predicate=None, many=False):
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   208
        BaseSerializer.__init__(self, predicate=predicate, many=many)
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   209
        self.opts = ModelSerializerOptions(self.Meta)        
71532a54d1c4 update virtualenv + implement record serialization
ymh <ymh.work@gmail.com>
parents:
diff changeset
   210