Files
PyRIGS/versioning/views.py
FreneticScribbler ce5a92dfa8 Add revision history to invoices/payments.
Also patches previously introduced reversion permissions hole.

Supersedes and closes #337.
2020-09-16 11:37:56 +01:00

110 lines
4.1 KiB
Python

import datetime
import logging
from diff_match_patch import diff_match_patch
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import EmailField, IntegerField, TextField
from django.shortcuts import get_object_or_404
from django.utils.functional import cached_property
from django.views import generic
from reversion.models import Version, VersionQuerySet
from RIGS import models
from assets import models as asset_models
from django.apps import apps
from reversion import revisions as reversion
from versioning.versioning import RIGSVersion
from django.views.decorators.cache import never_cache
from django.utils.decorators import method_decorator
class VersionHistory(generic.ListView):
model = RIGSVersion
template_name = "version_history.html"
paginate_by = 25
def get_queryset(self, **kwargs):
return RIGSVersion.objects.get_for_object(self.get_object()).select_related("revision",
"revision__user").all().order_by(
"-revision__date_created")
def get_object(self, **kwargs):
# Goddamit, almost got away without specific hacks
if self.kwargs['model'].__name__ == 'Asset':
return get_object_or_404(self.kwargs['model'], asset_id=self.kwargs['pk'])
else:
return get_object_or_404(self.kwargs['model'], pk=self.kwargs['pk'])
def get_context_data(self, **kwargs):
context = super(VersionHistory, self).get_context_data(**kwargs)
context['object'] = self.get_object()
if self.kwargs['app'] != 'rigboard':
context['override'] = 'base_{}.html'.format(self.kwargs['app'])
return context
def get_models(app=None):
models = filter(lambda item: not hasattr(item, 'reversion_hide'), reversion.get_registered_models())
if app is not None:
models = filter(lambda item: item in apps.get_app_config(app).get_models(), models)
return models
# TODO Default filter of having permission to view associated object
def filter_models(models, user):
if user is not None:
models = filter(lambda model: not hasattr(model, 'reversion_perm') or user.has_perm(model.reversion_perm), models)
return models
class ActivityTable(generic.ListView):
model = RIGSVersion
template_name = "activity_table.html"
paginate_by = 25
def get_queryset(self):
versions = RIGSVersion.objects.get_for_multiple_models(filter_models(self.kwargs['models'], self.request.user))
return versions.order_by("-revision__date_created")
def get_context_data(self, **kwargs):
context = super(ActivityTable, self).get_context_data(**kwargs)
context['title'] = self.kwargs['app']
if self.kwargs['app'] != 'rigboard':
context['override'] = 'base_{}.html'.format(self.kwargs['app'])
return context
@method_decorator(never_cache, name='dispatch') # Disable browser based caching
class ActivityFeed(generic.ListView): # Appears on homepage
model = RIGSVersion
template_name = "activity_feed_data.html"
paginate_by = 25
def get_queryset(self):
versions = RIGSVersion.objects.get_for_multiple_models(filter_models(get_models(), self.request.user))
return versions.order_by("-revision__date_created")
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(ActivityFeed, self).get_context_data(**kwargs)
maxTimeDelta = datetime.timedelta(hours=1)
items = []
for thisVersion in context['object_list']:
thisVersion.withPrevious = False
if len(items) >= 1:
timeDiff = items[-1].revision.date_created - thisVersion.revision.date_created
timeTogether = timeDiff < maxTimeDelta
sameUser = thisVersion.revision.user_id == items[-1].revision.user_id
thisVersion.withPrevious = timeTogether & sameUser
items.append(thisVersion)
return context