Completed
Push — master ( 6e8b4b...cccc5b )
by Gus
01:08
created

Mention.__eq__()   A

Complexity

Conditions 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
dl 0
loc 5
rs 9.4285
c 1
b 0
f 0
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
from __future__ import unicode_literals
4
from .utils import post_json
5
from .ds import Document
6
import re
7
import json
8
9
10
class OdinAPI(object):
11
    """
12
    API for performing sentiment analysis
13
    """
14
15
    validator = re.compile("^(https?|ftp):.+?\.?ya?ml$")
16
17
    def __init__(self, address):
18
        self._service = "{}/odin/extract".format(address)
19
20
    def _extract(self, json_data):
21
        try:
22
            mentions = [Mention.load_from_JSON(m) for m in post_json(self._service, json_data)]
23
            return mentions
24
        except Exception as e:
25
            print(e)
26
            return None
27
28
    @staticmethod
29
    def valid_rule_url(url):
30
        return True if OdinAPI.validator.match(url) else False
31
32
    def extract_from_text(self, text, rules):
33
        """
34
        Sends text to the server with rules for IE
35
        Returns a list of Mentions on None
36
        """
37
        if OdinAPI.valid_rule_url(rules):
38
            # this is actually a URL to a yaml file
39
            url = rules
40
            container = TextWithURL(text, url)
41
        else:
42
            container = TextWithRules(text, rules)
43
        return self._extract(container.to_JSON())
44
45
    def extract_from_document(self, doc, rules):
46
        """
47
        Sends a Document to the server with rules for IE
48
        Returns a list of Mentions or None
49
        """
50
        if OdinAPI.valid_rule_url(rules):
51
            # this is actually a URL to a yaml file
52
            url = rules
53
            container = DocumentWithURL(doc, rules)
54
        else:
55
            container = DocumentWithRules(doc, rules)
56
        return self._extract(container.to_JSON())
57
58
59
class TextWithRules(object):
60
61
    def __init__(self, text, rules):
62
        self.text = text
63
        self.rules = rules
64
65
    def to_JSON_dict(self):
66
        jdict = dict()
67
        jdict["text"] = self.text
68
        jdict["rules"] = self.rules
69
        return jdict
70
71
    def to_JSON(self):
72
        return json.dumps(self.to_JSON_dict(), sort_keys=True, indent=4)
73
74
class TextWithURL(object):
75
76
    def __init__(self, text, url):
77
        self.text = text
78
        # TODO: throw exception if url is invalid
79
        self.url = url
80
81
    def to_JSON_dict(self):
82
        jdict = dict()
83
        jdict["text"] = self.text
84
        jdict["url"] = self.url
85
        return jdict
86
87
    def to_JSON(self):
88
        return json.dumps(self.to_JSON_dict(), sort_keys=True, indent=4)
89 View Code Duplication
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
90
class DocumentWithRules(object):
91
92
    def __init__(self, document, rules):
93
        # TODO: throw exception if isinstance(document, Document) is False
94
        self.document = document
95
        self.rules = rules
96
97
    def to_JSON_dict(self):
98
        jdict = dict()
99
        jdict["document"] = self.document.to_JSON_dict()
100
        jdict["rules"] = self.rules
101
        return jdict
102
103
    def to_JSON(self):
104
        return json.dumps(self.to_JSON_dict(), sort_keys=True, indent=4)
105 View Code Duplication
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
106
class DocumentWithURL(object):
107
108
    def __init__(self, document, url):
109
        # TODO: throw exception if isinstance(document, Document) is False
110
        self.document = document
111
        # TODO: throw exception if url is invalid
112
        self.url = url
113
114
    def to_JSON_dict(self):
115
        jdict = dict()
116
        jdict["document"] = self.document.to_JSON_dict()
117
        jdict["url"] = self.url
118
        return jdict
119
120
    def to_JSON(self):
121
        return json.dumps(self.to_JSON_dict(), sort_keys=True, indent=4)
122
123
class Mention(object):
124
125
    def __init__(self,
126
                label,
127
                start,
128
                end,
129
                sentence,
130
                document,
131
                foundBy,
132
                labels=None,
133
                trigger=None,
134
                arguments=None,
135
                keep=True):
136
137
        self.label = label
138
        self.labels = labels if labels else [self.label]
139
        self.start = start
140
        self.end = end
141
        self.sentence = sentence
142
        self.document = document
143
        self.trigger = trigger
144
        # unpack args
145
        self.arguments = {role:[Mention.load_from_JSON(a) for a in args] for role, args in arguments.items()}
146
        self.keep = keep
147
        self.foundBy = foundBy
148
        # other
149
        self.sentenceObj = self.document.sentences[self.sentence]
150
        self.text = " ".join(self.sentenceObj.words[self.start:self.end])
151
152
    def __eq__(self, other):
153
        if isinstance(other, self.__class__):
154
            return self.__dict__ == other.__dict__
155
        else:
156
            return False
157
158
    def __ne__(self, other):
159
        return not self.__eq__(other)
160
161
    def __str__(self):
162
        return self.text
163
164
    def to_JSON_dict(self):
165
        m = dict()
166
        m["label"] = self.label
167
        m["labels"] = self.labels
168
        m["start"] = self.start
169
        m["end"] = self.label
170
        m["sentence"] = self.sentence
171
        m["document"] = self.document.to_JSON_dict()
172
        # do we have a trigger?
173
        if self.trigger:
174
             m["trigger"] = self.trigger
175
        m["arguments"] = self.arguments_to_JSON_dict()
176
        m["keep"] = self.keep
177
        m["foundBy"] = self.foundBy
178
        return m
179
180
    def to_JSON(self):
181
        return json.dumps(self.to_JSON_dict(), sort_keys=True, indent=4)
182
183
    def arguments_to_JSON_dict(self):
184
        return dict((role, [a.to_JSON_dict() for a in args]) for (role, args) in self.arguments)
185
186
    @staticmethod
187
    def load_from_JSON(jdict):
188
        sentences = []
189
        kwargs = {
190
            "label": jdict["label"],
191
            "labels": jdict["labels"],
192
            "start": jdict["start"],
193
            "end": jdict["end"],
194
            "sentence": jdict["sentence"],
195
            "document": Document.load_from_JSON(jdict["document"]),
196
            "trigger": jdict.get("trigger", None),
197
            "arguments": jdict.get("arguments", dict()),
198
            "keep": jdict.get("keep", True),
199
            "foundBy": jdict["foundBy"]
200
        }
201
        return Mention(**kwargs)
202