models.py 7.08 KB
Newer Older
1
2
3
import json
import os
from collections import defaultdict
4
from pyld import jsonld
5

J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
6

7

8
9
10
11
12
13
14
15
16
17
18
19
20
class Leaf(dict):
    _prefix = None
    _frame = {}
    _context = {}

    def __init__(self,
                 id=None,
                 context=None,
                 vocab=None,
                 prefix=None,
                 frame=None):
        super(Leaf, self).__init__()
        if context is not None:
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
21
            self.context = context
22
23
24
25
26
27
        elif self._context:
            self.context = self._context
        else:
            self.context = {}
        if frame is not None:
            self._frame = frame
28
        self._prefix = prefix
29
        self.id = id
30
31

    def __getattr__(self, key):
32
33
34
35
36
37
38
        try:
            return object.__getattr__(self, key)
        except AttributeError:
            try:
                return super(Leaf, self).__getitem__(self._get_key(key))
            except KeyError:
                raise AttributeError()
39

40
41
42
43
44
45
    def __setattr__(self, key, value):
        try:
            object.__getattr__(self, key)
            object.__setattr__(self, key, value)
        except AttributeError:
            key = self._get_key(key)
46
47
48
49
            if key == "@context":
                value = self.get_context(value)
            elif key == "@id":
                value = self.get_id(value)
50
51
52
            if key[0] == "_":
                object.__setattr__(self, key, value)
            else:
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
                if value is None:
                    try:
                        super(Leaf, self).__delitem__(key)
                    except KeyError:
                        pass
                else:
                    super(Leaf, self).__setitem__(key, value)

    def get_id(self, id):
        """
        This is not the most elegant solution to change the @id attribute, but it
        is the quickest way to have it included in the dictionary without extra
        boilerplate.
        """
        if id and self._prefix and ":" not in id:
            return "{}{}".format(self._prefix, id)
        else:
            return id
71

72
73
    def __delattr__(self, key):
        return super(Leaf, self).__delitem__(self._get_key(key))
74

75
    def _get_key(self, key):
76
77
78
        if key[0] == "_":
            return key
        elif key in ["context", "id"]:
79
            return "@{}".format(key)
80
81
        else:
            return key
82

J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    @staticmethod
    def get_context(context):
        if isinstance(context, list):
            contexts = []
            for c in context:
                contexts.append(Response.get_context(c))
            return contexts
        elif isinstance(context, dict):
            return context
        elif isinstance(context, basestring):
            try:
                with open(context) as f:
                    return json.loads(f.read())
            except IOError:
                return context

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
    def compact(self):
        return jsonld.compact(self, self.context)

    def frame(self, frame=None, options=None):
        if frame is None:
            frame = self._frame
        if options is None:
            options = {}
        return jsonld.frame(self, frame, options)

    def jsonable(self, parameters=False, frame=None, options=None, context=None):
        if frame is None:
            frame = self._frame
        if options is None:
            options = {}
        if context is None:
            context = self._context
        return jsonld.compact(jsonld.frame(self, frame, options), context)
        #if parameters:
            #resp["parameters"] = self.params
        #elif self.extra_params:
            #resp["extra_parameters"] = self.extra_params
        #return resp


    def to_JSON(self):
        return json.dumps(self,
                          default=lambda o: o.__dict__,
                          sort_keys=True, indent=4)


J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
130

131
class Response(Leaf):
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
    _frame =  { "@context": {
                    "analysis": {
                        "@container": "@set",
                        "@id": "prov:wasInformedBy"
                    },
                    "date": {
                        "@id": "dc:date",
                        "@type": "xsd:dateTime"
                    },
                    "dc": "http://purl.org/dc/terms/",
                    "dc:subject": {
                        "@type": "@id"
                    },
                    "emotions": {
                        "@container": "@set",
                        "@id": "onyx:hasEmotionSet"
                    },
                    "entries": {
                        "@container": "@set",
                        "@id": "prov:generated"
                    },
                    "marl": "http://www.gsi.dit.upm.es/ontologies/marl/ns#",
                    "nif": "http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#",
                    "onyx": "http://www.gsi.dit.upm.es/ontologies/onyx/ns#",
                    "opinions": {
                        "@container": "@set",
                        "@id": "marl:hasOpinion"
                    },
                    "prov": "http://www.w3.org/ns/prov#",
                    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
                    "strings": {
                        "@container": "@set",
                        "@reverse": "nif:hasContext"
                    },
                    "wnaffect": "http://www.gsi.dit.upm.es/ontologies/wnaffect#",
                    "xsd": "http://www.w3.org/2001/XMLSchema#"
                },
                "analysis": {},
                "entries": {}
    }

    def __init__(self, context=None, *args, **kwargs):
174
175
        if context is None:
            context = "{}/context.jsonld".format(os.path.dirname(
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
176
                os.path.realpath(__file__)))
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
177
        super(Response, self).__init__(*args, context=context, **kwargs)
178
179
        self.analysis = []
        self.entries = []
180
181
182


class Entry(Leaf):
183
184
185
186
    _context = {
        "@vocab": "http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#"

    }
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
187
    def __init__(self, text=None, emotion_sets=None, opinions=None, **kwargs):
188
189
190
        super(Entry, self).__init__(**kwargs)
        if text:
            self.text = text
191
192
        self.emotionSets = emotion_sets if emotion_sets else []
        self.opinions = opinions if opinions else []
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
193

194
class Opinion(Leaf):
195
196
197
    _context = {
        "@vocab": "http://www.gsi.dit.upm.es/ontologies/marl/ns#"
    }
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
198
    def __init__(self, polarityValue=None, hasPolarity=None, *args, **kwargs):
199
        super(Opinion, self).__init__(*args,
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
200
201
                                      **kwargs)
        if polarityValue is not None:
202
            self.hasPolarityValue = polarityValue
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
203
204
        if hasPolarity is not None:
            self.hasPolarity = hasPolarity
205
206
207


class EmotionSet(Leaf):
208
    _context = {}
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
209
    def __init__(self, emotions=None, *args, **kwargs):
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
210
211
        if not emotions:
            emotions = []
212
        super(EmotionSet, self).__init__(context=EmotionSet._context,
J. Fernando Sánchez's avatar
J. Fernando Sánchez committed
213
214
                                         *args,
                                         **kwargs)
215
        self.emotions = emotions or []
216
217

class Emotion(Leaf):
218
219
220
221
222
223
    _context = {}

class Error(Leaf):
    def __init__(self, *args, **kwargs):
        super(Error, self).__init__(*args)
        self.update(kwargs)