src/notes/api/views/sync.py
author salimr <riwad.salim@yahoo.fr>
Tue, 14 Aug 2018 20:39:55 +0200
changeset 144 8b950885ddae
parent 132 906a6c7c7943
permissions -rw-r--r--
Add local font and assets. Override Bootstrap css varriables. Add specific css files

import datetime
import logging

from auditlog.models import LogEntry
from django.utils import timezone
from notes.models import Note, Session
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework.views import APIView

logger = logging.getLogger(__name__)

class ListLogsView(APIView):
    """
    View to list tle log of changes on Note and Sessions.

    * Only registered users are able to access this view.
    * the results are filtered by connected user
    """
    permission_classes = (permissions.IsAuthenticated,)

    def __filter_object(self, model, user, modified_since, client_id):
        """
        Log entries are filtered by model, actor and timestamp.
        If a client id is given, log entries from this client are ignored.
        """
        log_entries = LogEntry.objects.get_for_model(model).filter(actor=user)
        if modified_since:
            log_entries = log_entries.filter(timestamp__gte=modified_since)
        if client_id:
            log_entries = log_entries.exclude(client=client_id)
        return log_entries.order_by('timestamp')

    def __process_log_entries(self, model, user, modified_since, client_id):
        '''
        Process log entries
        '''
        log_entries = self.__filter_object(model, user, modified_since, client_id)

        res = {}
        for log_entry in log_entries:
            ext_id = log_entry.additional_data.get('ext_id')
            if not ext_id:
                continue
            sync_entry = res.get(ext_id, {})
            new_action = {
                (None                  , LogEntry.Action.CREATE): LogEntry.Action.CREATE,
                (LogEntry.Action.CREATE, LogEntry.Action.CREATE): LogEntry.Action.CREATE,
                (LogEntry.Action.UPDATE, LogEntry.Action.CREATE): LogEntry.Action.UPDATE,
                (LogEntry.Action.DELETE, LogEntry.Action.CREATE): LogEntry.Action.UPDATE,

                (None                  , LogEntry.Action.UPDATE): LogEntry.Action.UPDATE,
                (LogEntry.Action.CREATE, LogEntry.Action.UPDATE): LogEntry.Action.CREATE,
                (LogEntry.Action.UPDATE, LogEntry.Action.UPDATE): LogEntry.Action.UPDATE,
                (LogEntry.Action.DELETE, LogEntry.Action.UPDATE): LogEntry.Action.DELETE,

                (None                  , LogEntry.Action.DELETE): LogEntry.Action.DELETE,
                (LogEntry.Action.CREATE, LogEntry.Action.DELETE): None,
                (LogEntry.Action.UPDATE, LogEntry.Action.DELETE): LogEntry.Action.DELETE,
                (LogEntry.Action.DELETE, LogEntry.Action.DELETE): LogEntry.Action.DELETE,

            } [(sync_entry.get('action'), log_entry.action)]
            if new_action is None:
                del res[ext_id]
            else:
                res[ext_id] = {
                    'type': log_entry.content_type.model,
                    'ext_id': ext_id,
                    'action': new_action,
                    'timestamp': log_entry.timestamp
                }
        return res

    def get(self, request, format=None):
        """
        Return an aggregations of all changes.
        """
        modified_since_str = request.query_params.get('modified_since', None)
        modified_since = None
        if modified_since_str is not None:
            modified_since = datetime.datetime.fromtimestamp(
                float(modified_since_str),
                timezone.utc
            )

        user = request.user
        client_id = request.META.get('HTTP_AUDITLOG_CLIENT', None)
        res_sessions = self.__process_log_entries(Session, user, modified_since, client_id)
        res_notes = self.__process_log_entries(Note, user, modified_since, client_id)

        return Response({
            'sessions': res_sessions.values(),
            'notes': res_notes.values()
        })