src/notes/api/views/sync.py
author ymh <ymh.work@gmail.com>
Tue, 01 Aug 2017 12:20:14 +0200
changeset 132 906a6c7c7943
parent 129 d48946d164c6
permissions -rw-r--r--
add group to sync + create groups + various component cleaning
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
        })