Completed
Push — master ( c9822b...003a96 )
by Koen
01:25
created

collection_adapter()   A

Complexity

Conditions 2

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 2
c 5
b 0
f 0
dl 0
loc 23
rs 9.0856
1
# -*- coding: utf8 -*-
2
'''
3
This module contains a few utility functions.
4
'''
5
6
import re
7
8
import logging
9
log = logging.getLogger(__name__)
10
11
from pyramid.renderers import JSON
12
13
from skosprovider.skos import (
14
    Concept,
15
    Collection,
16
    Label,
17
    Note,
18
    Source
19
)
20
21
22
def parse_range_header(range):
23
    '''
24
    Parse a range header as used by the dojo Json Rest store.
25
26
    :param str range: The content of the range header to be parsed.
27
        eg. `items=0-9`
28
    :returns: A dict with keys start, finish and number or `False` if the
29
        range is invalid.
30
    '''
31
    match = re.match('^items=([0-9]+)-([0-9]+)$', range)
32
    if match:
33
        start = int(match.group(1))
34
        finish = int(match.group(2))
35
        if finish < start:
36
            finish = start
37
        return {
38
            'start': start,
39
            'finish': finish,
40
            'number': finish - start + 1
41
        }
42
    else:
43
        return False
44
45
json_renderer = JSON()
46
47
48
def concept_adapter(obj, request):
49
    '''
50
    Adapter for rendering a :class:`skosprovider.skos.Concept` to json.
51
52
    :param skosprovider.skos.Concept obj: The concept to be rendered.
53
    :rtype: :class:`dict`
54
    '''
55
    p = request.skos_registry.get_provider(obj.concept_scheme.uri)
56
    return {
57
        'id': obj.id,
58
        'type': 'concept',
59
        'uri': obj.uri,
60
        'label': obj.label().label if obj.label() else None,
61
        'concept_scheme': {
62
            'uri': obj.concept_scheme.uri,
63
            'labels': obj.concept_scheme.labels
64
        },
65
        'labels': obj.labels,
66
        'notes': obj.notes,
67
        'sources': obj.sources,
68
        'narrower': _map_relations(obj.narrower, p),
69
        'broader': _map_relations(obj.broader, p),
70
        'related': _map_relations(obj.related, p),
71
        'member_of': _map_relations(obj.member_of, p),
72
        'subordinate_arrays':  _map_relations(obj.subordinate_arrays, p),
73
        'matches': obj.matches
74
    }
75
76
77
def collection_adapter(obj, request):
78
    '''
79
    Adapter for rendering a :class:`skosprovider.skos.Collection` to json.
80
81
    :param skosprovider.skos.Collection obj: The collection to be rendered.
82
    :rtype: :class:`dict`
83
    '''
84
    p = request.skos_registry.get_provider(obj.concept_scheme.uri)
85
    return {
86
        'id': obj.id,
87
        'type': 'collection',
88
        'uri': obj.uri,
89
        'label': obj.label().label if obj.label() else None,
90
        'concept_scheme': {
91
            'uri': obj.concept_scheme.uri,
92
            'labels': obj.concept_scheme.labels
93
        },
94
        'labels': obj.labels,
95
        'notes': obj.notes,
96
        'sources': obj.sources,
97
        'members': _map_relations(obj.members, p),
98
        'member_of': _map_relations(obj.member_of, p),
99
        'superordinates':  _map_relations(obj.superordinates, p),
100
    }
101
102
def _map_relations(relations, p):
103
    '''
104
    :param: :class:`list` relations: Relations to be mapped. These are concept or collection id's.
105
    :param: :class:`skosprovider.providers.VocabularyProvider` p: Provider to look up id's.
106
    :rtype: :class:`list`
107
    '''
108
    ret = []
109
    for r in relations:
110
        c = p.get_by_id(r)
111
        if c:
112
            ret.append(_map_relation(c))
113
        else:
114
            log.warning(
115
                'A relation references a concept or collection %d in provider %s that can not be found. Please check the integrity of your data.' % 
116
                (r, p.get_vocabulary_id())
117
            )
118
    return ret
119
120
def _map_relation(c):
121
    """
122
    Map related concept or collection, leaving out the relations (to avoid circular dependencies)
123
124
    :param c: the concept or collection to map
125
    :rtype: :class:`dict`
126
    """
127
    return {
128
        'id': c.id,
129
        'type': c.type,
130
        'uri': c.uri,
131
        'label': c.label().label if c.label() else None
132
    }
133
134
135
def label_adapter(obj, request):
136
    '''
137
    Adapter for rendering a :class:`skosprovider.skos.Label` to json.
138
139
    :param skosprovider.skos.Label obj: The label to be rendered.
140
    :rtype: :class:`dict`
141
    '''
142
    return {
143
        'label': obj.label,
144
        'type': obj.type,
145
        'language': obj.language
146
    }
147
148
149
def note_adapter(obj, request):
150
    '''
151
    Adapter for rendering a :class:`skosprovider.skos.Note` to json.
152
153
    :param skosprovider.skos.Note obj: The note to be rendered.
154
    :rtype: :class:`dict`
155
    '''
156
    return {
157
        'note': obj.note,
158
        'type': obj.type,
159
        'language': obj.language,
160
        'markup': obj.markup
161
    }
162
163
164
def source_adapter(obj, request):
165
    '''
166
    Adapter for rendering a :class:`skosprovider.skos.Source` to json.
167
168
    :param skosprovider.skos.Source obj: The source to be rendered.
169
    :rtype: :class:`dict`
170
    '''
171
    return {
172
        'citation': obj.citation
173
    }
174
175
176
json_renderer.add_adapter(Concept, concept_adapter)
177
json_renderer.add_adapter(Collection, collection_adapter)
178
json_renderer.add_adapter(Label, label_adapter)
179
json_renderer.add_adapter(Note, note_adapter)
180
json_renderer.add_adapter(Source, source_adapter)
181