src/notes/api/views/sync.py
author ymh <ymh.work@gmail.com>
Fri, 30 Nov 2018 10:53:15 +0100
changeset 183 f8f3af9e5c83
parent 132 906a6c7c7943
permissions -rw-r--r--
Change the settings to avoid using Session authentication for rest framework as it raise exceptions in case client and backend are on the same domain On the filter, adapt to take into account new version of django_filters
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
126
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
import datetime
128
34a75bd8d0b9 add filter on session and node list to recover specific objects
ymh <ymh.work@gmail.com>
parents: 126
diff changeset
     2
import logging
126
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
from auditlog.models import LogEntry
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
from django.utils import timezone
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
from notes.models import Note, Session
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
from rest_framework import permissions
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
from rest_framework.response import Response
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
from rest_framework.views import APIView
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
128
34a75bd8d0b9 add filter on session and node list to recover specific objects
ymh <ymh.work@gmail.com>
parents: 126
diff changeset
    11
logger = logging.getLogger(__name__)
126
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
class ListLogsView(APIView):
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
    """
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
    View to list tle log of changes on Note and Sessions.
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
    * Only registered users are able to access this view.
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
    * the results are filtered by connected user
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
    """
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
    permission_classes = (permissions.IsAuthenticated,)
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
129
d48946d164c6 Add a first version of synchronisation
ymh <ymh.work@gmail.com>
parents: 128
diff changeset
    22
    def __filter_object(self, model, user, modified_since, client_id):
d48946d164c6 Add a first version of synchronisation
ymh <ymh.work@gmail.com>
parents: 128
diff changeset
    23
        """
d48946d164c6 Add a first version of synchronisation
ymh <ymh.work@gmail.com>
parents: 128
diff changeset
    24
        Log entries are filtered by model, actor and timestamp.
d48946d164c6 Add a first version of synchronisation
ymh <ymh.work@gmail.com>
parents: 128
diff changeset
    25
        If a client id is given, log entries from this client are ignored.
d48946d164c6 Add a first version of synchronisation
ymh <ymh.work@gmail.com>
parents: 128
diff changeset
    26
        """
128
34a75bd8d0b9 add filter on session and node list to recover specific objects
ymh <ymh.work@gmail.com>
parents: 126
diff changeset
    27
        log_entries = LogEntry.objects.get_for_model(model).filter(actor=user)
126
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
        if modified_since:
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
            log_entries = log_entries.filter(timestamp__gte=modified_since)
129
d48946d164c6 Add a first version of synchronisation
ymh <ymh.work@gmail.com>
parents: 128
diff changeset
    30
        if client_id:
d48946d164c6 Add a first version of synchronisation
ymh <ymh.work@gmail.com>
parents: 128
diff changeset
    31
            log_entries = log_entries.exclude(client=client_id)
128
34a75bd8d0b9 add filter on session and node list to recover specific objects
ymh <ymh.work@gmail.com>
parents: 126
diff changeset
    32
        return log_entries.order_by('timestamp')
126
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
129
d48946d164c6 Add a first version of synchronisation
ymh <ymh.work@gmail.com>
parents: 128
diff changeset
    34
    def __process_log_entries(self, model, user, modified_since, client_id):
126
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
        '''
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
        Process log entries
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
        '''
129
d48946d164c6 Add a first version of synchronisation
ymh <ymh.work@gmail.com>
parents: 128
diff changeset
    38
        log_entries = self.__filter_object(model, user, modified_since, client_id)
126
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
        res = {}
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
        for log_entry in log_entries:
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
            ext_id = log_entry.additional_data.get('ext_id')
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
            if not ext_id:
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
                continue
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
            sync_entry = res.get(ext_id, {})
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
            new_action = {
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
                (None                  , LogEntry.Action.CREATE): LogEntry.Action.CREATE,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
                (LogEntry.Action.CREATE, LogEntry.Action.CREATE): LogEntry.Action.CREATE,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
                (LogEntry.Action.UPDATE, LogEntry.Action.CREATE): LogEntry.Action.UPDATE,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
                (LogEntry.Action.DELETE, LogEntry.Action.CREATE): LogEntry.Action.UPDATE,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
                (None                  , LogEntry.Action.UPDATE): LogEntry.Action.UPDATE,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
                (LogEntry.Action.CREATE, LogEntry.Action.UPDATE): LogEntry.Action.CREATE,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
                (LogEntry.Action.UPDATE, LogEntry.Action.UPDATE): LogEntry.Action.UPDATE,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
                (LogEntry.Action.DELETE, LogEntry.Action.UPDATE): LogEntry.Action.DELETE,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
                (None                  , LogEntry.Action.DELETE): LogEntry.Action.DELETE,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
                (LogEntry.Action.CREATE, LogEntry.Action.DELETE): None,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
                (LogEntry.Action.UPDATE, LogEntry.Action.DELETE): LogEntry.Action.DELETE,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
                (LogEntry.Action.DELETE, LogEntry.Action.DELETE): LogEntry.Action.DELETE,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
            } [(sync_entry.get('action'), log_entry.action)]
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
            if new_action is None:
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
                del res[ext_id]
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
            else:
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
                res[ext_id] = {
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
                    'type': log_entry.content_type.model,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
                    'ext_id': ext_id,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
                    'action': new_action,
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
                    'timestamp': log_entry.timestamp
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
                }
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
        return res
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
    def get(self, request, format=None):
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
        """
129
d48946d164c6 Add a first version of synchronisation
ymh <ymh.work@gmail.com>
parents: 128
diff changeset
    76
        Return an aggregations of all changes.
126
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
        """
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
        modified_since_str = request.query_params.get('modified_since', None)
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
        modified_since = None
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
        if modified_since_str is not None:
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
            modified_since = datetime.datetime.fromtimestamp(
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
                float(modified_since_str),
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
                timezone.utc
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
            )
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
        user = request.user
129
d48946d164c6 Add a first version of synchronisation
ymh <ymh.work@gmail.com>
parents: 128
diff changeset
    87
        client_id = request.META.get('HTTP_AUDITLOG_CLIENT', None)
d48946d164c6 Add a first version of synchronisation
ymh <ymh.work@gmail.com>
parents: 128
diff changeset
    88
        res_sessions = self.__process_log_entries(Session, user, modified_since, client_id)
d48946d164c6 Add a first version of synchronisation
ymh <ymh.work@gmail.com>
parents: 128
diff changeset
    89
        res_notes = self.__process_log_entries(Note, user, modified_since, client_id)
126
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
        return Response({
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
            'sessions': res_sessions.values(),
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
            'notes': res_notes.values()
ba8bc0199464 add log api for syncing
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
        })