atramhasis.audit._origin_from_response()   A
last analyzed

Complexity

Conditions 5

Size

Total Lines 8
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 8
rs 9.3333
c 0
b 0
f 0
cc 5
nop 1
1
import logging
2
3
from pyramid.response import Response
4
5
from atramhasis.data.models import ConceptVisitLog
6
from atramhasis.data.models import ConceptschemeVisitLog
7
8
log = logging.getLogger(__name__)
9
10
11
def _origin_from_request(request):
12
    if '.csv' in request.url:
13
        return 'CSV'
14
    elif 'text/html' in request.accept:
15
        return 'HTML'
16
    elif 'application/json' in request.accept:
17
        return 'REST'
18
    elif 'application/ld+json' in request.accept:
19
        return 'RDF'
20
    else:
21
        return None
22
23
24
def _origin_from_response(response):
25
    if response.content_type == 'application/rdf+xml' \
26
            or response.content_type == 'application/ld+json' \
27
            or response.content_type == 'text/turtle' \
28
            or response.content_type == 'application/x-turtle':
29
        return 'RDF'
30
    else:
31
        return None
32
33
34
def audit(fn):
35
    """
36
    use this decorator to audit an operation and to log the visit
37
    external conceptschemes won't be logged
38
39
    * CSV routes with .csv extensions accept all mime types,
40
      the response is not of the `pyramid.response.Response` type,
41
      the origin is derived from the `pyramid.request.Request.url` extension.
42
    * RDF routes with .rdf, .ttl extensions accept all mime types,
43
      the origin is derived form the response content type.
44
    * REST and HTML the view results are not of the `pyramid.response.Response` type,
45
      the origin is derived from the accept header.
46
    """
47
48
    def advice(parent_object, *args, **kw):
49
        request = parent_object.request
50
        audit_manager = request.data_managers['audit_manager']
51
52
        if 'scheme_id' not in request.matchdict.keys():
53
            log.error('Misuse of the audit decorator. The url must at least contain a {scheme_id} parameter')
54
            return fn(parent_object, *args, **kw)
55
56
        provider = request.skos_registry.get_provider(request.matchdict['scheme_id'])
57
        if not provider or 'external' in provider.get_metadata()['subject']:
58
            return fn(parent_object, *args, **kw)
59
        else:
60
            if 'c_id' in request.matchdict.keys():
61
                visit_log = ConceptVisitLog(
62
                    concept_id=request.matchdict['c_id'],
63
                    conceptscheme_id=request.matchdict['scheme_id']
64
                )
65
            else:
66
                visit_log = ConceptschemeVisitLog(conceptscheme_id=request.matchdict['scheme_id'])
67
            response = fn(parent_object, *args, **kw)
68
69
            if isinstance(response, Response):
70
                visit_log.origin = _origin_from_response(response)
71
            else:
72
                visit_log.origin = _origin_from_request(request)
73
74
            audit_manager.save(visit_log)
75
76
        return response
77
78
    return advice
79