Subversion Repositories basico

Rev

Rev 354 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
340 t00mlabs 1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
"""
4
# File: srv_annot.py
5
# Author: Tomás Vírseda
6
# License: GPL v3
7
# Description: Annotations service
8
"""
9
 
10
import os
11
import json
12
import uuid
13
import glob
14
from os.path import sep as SEP
15
 
16
from basico.core.mod_env import FILE, LPATH
17
from basico.core.mod_srv import Service
18
 
19
 
20
class Annotation(Service):
21
    def initialize(self):
22
        '''
23
        Setup Annotation Service
24
        '''
25
        self.get_services()
351 t00mlabs 26
        self.__fix_annotations()
340 t00mlabs 27
 
28
 
29
    def get_services(self):
30
        self.srvutl = self.get_service('Utils')
31
 
32
 
351 t00mlabs 33
    def __fix_annotations(self):
34
        """
35
        In Basico 0.4, new field 'created' is introduced.
36
        For annotations created before, created timestamp = updated timestamp.
37
        """
38
 
39
        for filename in self.get_all():
40
            metadata = self.get_metadata_from_file(filename)
41
            try:
42
                ts = metadata['Created']
43
            except Exception as error:
44
                # Fix annotation metadata: add 'Created' field
45
                metadata['Created'] = metadata['Timestamp']
46
                with open(filename, 'w') as fa:
47
                    json.dump(metadata, fa)
48
                    self.log.debug("Fixed annotation with AID: %s", metadata['AID'])
49
 
50
 
340 t00mlabs 51
    def gen_aid(self, sid):
52
        '''
53
        Generate new annotation id
54
        '''
55
        return "%s@%s" % (sid, str(uuid.uuid4()))
56
 
57
 
58
    def create(self, annotation):
59
        ANNOTATION_FILE_METADATA = LPATH['ANNOTATIONS'] + annotation['AID'] + '.json'
60
        ANNOTATION_FILE_CONTENT = LPATH['ANNOTATIONS'] + annotation['AID'] + '.adoc'
61
        annotation['Timestamp'] = self.srvutl.timestamp()
354 t00mlabs 62
        annotation['Created'] = self.srvutl.timestamp()
340 t00mlabs 63
 
64
        # Write annotation content first and delete it
65
        with open(ANNOTATION_FILE_CONTENT, 'w') as fc:
66
            fc.write(annotation['Content'])
67
        del annotation['Content']
68
 
69
        # Write annotation metadata
70
        with open(ANNOTATION_FILE_METADATA, 'w') as fa:
71
            json.dump(annotation, fa)
72
 
73
        title = self.get_title(annotation['AID'])
74
        self.log.info("Annotation '%s' (%s) created" % (title, annotation['AID']))
75
 
76
 
77
    def update(self, annotation):
351 t00mlabs 78
        ANNOTATION_FILE_METADATA = LPATH['ANNOTATIONS'] + annotation['AID'] + '.json'
340 t00mlabs 79
        ANNOTATION_FILE_CONTENT = LPATH['ANNOTATIONS'] + annotation['AID'] + '.adoc'
80
 
81
        annotation['Timestamp'] = self.srvutl.timestamp()
82
        # Write updated annotation first and delete the old one after
83
        with open(ANNOTATION_FILE_CONTENT, 'w') as fc:
84
            fc.write(annotation['Content'])
85
        del annotation['Content']
86
 
87
        # Write annotation metadata
88
        with open(ANNOTATION_FILE_METADATA, 'w') as fa:
89
            json.dump(annotation, fa)
90
 
91
        title = self.get_title(annotation['AID'])
92
        self.log.info("Annotation '%s' (%s) updated" % (title, annotation['AID']))
93
 
94
 
95
    def delete(self, aid):
96
        sid = self.get_sid(aid)
97
        ANNOTATION_FILE_METADATA = LPATH['ANNOTATIONS'] + aid + '.json'
98
        ANNOTATION_FILE_CONTENT = LPATH['ANNOTATIONS'] + aid + '.adoc'
99
        title = self.get_title(aid)
100
 
101
        if os.path.exists(ANNOTATION_FILE_METADATA):
102
            os.unlink(ANNOTATION_FILE_METADATA)
103
 
104
        if os.path.exists(ANNOTATION_FILE_CONTENT):
105
            os.unlink(ANNOTATION_FILE_CONTENT)
106
 
107
        self.log.info("Annotation '%s' (%s) deleted" % (title, aid))
108
 
109
 
110
    def get_by_sid(self, sid):
111
        ANNOTATION_FILES = LPATH['ANNOTATIONS'] + '%s*.json' % sid
112
        annotations = glob.glob(ANNOTATION_FILES)
113
        annotations.sort(reverse=True)
114
 
115
        return annotations
116
 
117
 
118
    def get_all(self):
119
        return glob.glob(LPATH['ANNOTATIONS'] + '*.json')
120
 
121
 
122
    def get_total(self):
123
        return len(self.get_all())
124
 
125
 
126
    def get_sid(self, aid):
127
        if '@' in aid:
128
            return aid[:aid.find('@')]
129
        else:
130
            return aid # aid = sid
131
 
132
 
351 t00mlabs 133
    def get_metadata_from_aid(self, aid=None):
340 t00mlabs 134
        if aid is not None:
135
            ANNOTATION_FILE_METADATA = LPATH['ANNOTATIONS'] + aid + '.json'
136
            with open(ANNOTATION_FILE_METADATA, 'r') as fa:
137
                annotation = json.load(fa)
138
            return annotation
139
        else:
140
            return None
141
 
142
 
351 t00mlabs 143
    def get_metadata_from_file(self, filename=None):
144
        if filename is not None:
145
            with open(filename, 'r') as fa:
146
                annotation = json.load(fa)
147
            return annotation
148
        else:
149
            return None
150
 
151
 
340 t00mlabs 152
    def is_valid(self, aid):
153
        ANNOTATION_FILE = LPATH['ANNOTATIONS'] + aid + '.json'
154
        valid = os.path.exists(ANNOTATION_FILE)
155
        if valid is False:
156
            self.log.debug("Annotation %s is not valid or it doesn't exist yet." % aid)
157
 
158
        return valid
159
 
160
    def get_title(self, aid):
161
        ANNOTATION_FILE = LPATH['ANNOTATIONS'] + aid + '.json'
162
        with open(ANNOTATION_FILE, 'r') as fa:
163
            metadata = json.load(fa)
164
            return metadata['Title']
165
 
166
 
167
    def search_term(self, term):
168
        matches = set()
169
        annotations = self.get_all()
170
 
171
        for fname in annotations:
172
            # search only in title
173
            with open(fname, 'r') as fa:
174
                try:
175
                    annotation = json.load(fa)
176
                    text = annotation['Title']
177
                    if term.upper() in text.upper():
178
                        # ~ self.log.debug("Found '%s' in '%s'", term, text)
179
                        matches.add(fname)
180
                except Exception as error:
181
                    self.log.error("%s: %s", fname, error)
182
 
183
            # SEARCH IN ALL PROPERTIES (DISABLED)
184
            # ~ with open(fname, 'r') as fa:
185
                # ~ try:
186
                    # ~ annotation = json.load(fa)
187
                    # ~ text = ''
188
                    # ~ for node in annotation:
189
                        # ~ text += annotation[node]
190
                    # ~ if term.upper() in text.upper():
191
                        # ~ self.log.debug("Found '%s' in '%s'", term, text)
192
                        # ~ matches.add(fname)
193
                # ~ except Exception as error:
194
                    # ~ self.log.error("%s: %s", fname, error)
195
 
196
            # SEARCH IN CONTENT (DISABLED)
197
            # ~ fcontent = fname.replace('.json', '.adoc')
198
            # ~ text = open(fcontent, 'r').read()
199
            # ~ if term.upper() in text.upper():
200
                # ~ matches.add(fname)
201
 
202
        return matches
203
 
204
 
205
    def finalize(self):
206
        pass
207