diff --git a/PyRIGS/urls.py b/PyRIGS/urls.py index a3e1727e..e4a675e4 100644 --- a/PyRIGS/urls.py +++ b/PyRIGS/urls.py @@ -11,13 +11,17 @@ from registration.backends.default.views import RegistrationView from PyRIGS.decorators import permission_required_with_403 import RIGS import users +import versioning from PyRIGS import views urlpatterns = [ path('', include('users.urls')), + path('', include('versioning.urls')), path('', include('RIGS.urls')), path('assets/', include('assets.urls')), + path('', login_required(views.Index.as_view()), name='index'), + # API path('api//', login_required(views.SecureAPIRequest.as_view()), name="api_secure"), diff --git a/PyRIGS/views.py b/PyRIGS/views.py index e0cf97cd..c4f709d3 100644 --- a/PyRIGS/views.py +++ b/PyRIGS/views.py @@ -20,6 +20,19 @@ from RIGS import models, forms from assets import models as asset_models from functools import reduce +from django.views.decorators.cache import never_cache +from django.utils.decorators import method_decorator + + +# Displays the current rig count along with a few other bits and pieces +@method_decorator(never_cache, name='dispatch') # Disable browser based caching +class Index(generic.TemplateView): + template_name = 'index.html' + + def get_context_data(self, **kwargs): + context = super(Index, self).get_context_data(**kwargs) + context['rig_count'] = models.Event.objects.rig_count() + return context class SecureAPIRequest(generic.View): models = { diff --git a/RIGS/models.py b/RIGS/models.py index a3310bac..1efc6874 100644 --- a/RIGS/models.py +++ b/RIGS/models.py @@ -197,6 +197,8 @@ class VatRate(models.Model, RevisionMixin): objects = VatManager() + reversion_hide = True + @property def as_percent(self): return self.rate * 100 @@ -332,6 +334,10 @@ class Event(models.Model, RevisionMixin): auth_request_at = models.DateTimeField(null=True, blank=True) auth_request_to = models.EmailField(null=True, blank=True) + @property + def display_id(self): + return str("N%05d" % self.pk) + # Calculated values """ EX Vat @@ -467,7 +473,6 @@ class Event(models.Model, RevisionMixin): self.full_clean() super(Event, self).save(*args, **kwargs) - class EventItem(models.Model): event = models.ForeignKey('Event', related_name='items', blank=True, on_delete=models.CASCADE) name = models.CharField(max_length=255) @@ -476,6 +481,8 @@ class EventItem(models.Model): cost = models.DecimalField(max_digits=10, decimal_places=2) order = models.IntegerField() + reversion_hide = True + @property def total_cost(self): return self.cost * self.quantity @@ -673,5 +680,7 @@ class EventChecklistVehicle(models.Model): vehicle = models.CharField(max_length=255) driver = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='drivers', on_delete=models.CASCADE) + reversion_hide = True + def __str__(self): return "{} driven by {}".format(self.vehicle, str(self.driver)) diff --git a/RIGS/signals.py b/RIGS/signals.py index bc424e27..ae243653 100644 --- a/RIGS/signals.py +++ b/RIGS/signals.py @@ -19,7 +19,7 @@ from premailer import Premailer from z3c.rml import rml2pdf from RIGS import models -from versioning.versioning import models_for_feed +from reversion import revisions as reversion def send_eventauthorisation_success_email(instance): @@ -142,11 +142,9 @@ def send_admin_awaiting_approval_email(user, request, **kwargs): user_activated.connect(send_admin_awaiting_approval_email) # TODO Move - - def update_cache(sender, instance, created, **kwargs): cache.clear() -for model in models_for_feed(): +for model in reversion.get_registered_models(): post_save.connect(update_cache, sender=model) diff --git a/RIGS/templates/event_checklist_detail.html b/RIGS/templates/event_checklist_detail.html index 7ba7e23d..8f708878 100644 --- a/RIGS/templates/event_checklist_detail.html +++ b/RIGS/templates/event_checklist_detail.html @@ -80,7 +80,7 @@ class="hidden-xs">Edit
- {% include 'partials/last_edited.html' with target="ec_history" %} + {% include 'partials/last_edited.html' with target="eventchecklist_history" %}
{% endblock %} diff --git a/RIGS/templates/event_table.html b/RIGS/templates/event_table.html index 5fe01a2c..d00207b2 100644 --- a/RIGS/templates/event_table.html +++ b/RIGS/templates/event_table.html @@ -14,7 +14,7 @@ {% for event in events %} - {{ event.pk }} + {{ event.display_id }}
{{ event.start_date|date:"D d/m/Y" }}
diff --git a/RIGS/templates/invoice_list_waiting.html b/RIGS/templates/invoice_list_waiting.html index db3a5e6e..e4843380 100644 --- a/RIGS/templates/invoice_list_waiting.html +++ b/RIGS/templates/invoice_list_waiting.html @@ -33,7 +33,7 @@ {% for event in object_list %} - N{{ event.pk|stringformat:"05d" }}
+ {{ event.display_id }}
{{ event.get_status_display }} {{ event.start_date }} diff --git a/RIGS/templates/risk_assessment_detail.html b/RIGS/templates/risk_assessment_detail.html index 1cfcd065..6d521501 100644 --- a/RIGS/templates/risk_assessment_detail.html +++ b/RIGS/templates/risk_assessment_detail.html @@ -150,7 +150,7 @@ class="hidden-xs">Edit
- {% include 'partials/last_edited.html' with target="ra_history" %} + {% include 'partials/last_edited.html' with target="riskassessment_history" %}
{% endblock %} diff --git a/RIGS/urls.py b/RIGS/urls.py index 439b8cee..1d8789de 100644 --- a/RIGS/urls.py +++ b/RIGS/urls.py @@ -6,12 +6,8 @@ from django.views.generic import RedirectView from PyRIGS.decorators import (api_key_required, has_oembed, permission_required_with_403) from RIGS import finance, ical, models, rigboard, views, hs -from versioning import versioning -from django.views.decorators.cache import cache_page urlpatterns = [ - path('', login_required(views.Index.as_view()), name='index'), - # People path('people/', permission_required_with_403('RIGS.view_person')(views.PersonList.as_view()), name='person_list'), @@ -19,9 +15,6 @@ urlpatterns = [ name='person_create'), path('people//', permission_required_with_403('RIGS.view_person')(views.PersonDetail.as_view()), name='person_detail'), - path('people//history/', - permission_required_with_403('RIGS.view_person')(versioning.VersionHistory.as_view()), - name='person_history', kwargs={'model': models.Person}), path('people//edit/', permission_required_with_403('RIGS.change_person')(views.PersonUpdate.as_view()), name='person_update'), @@ -34,9 +27,6 @@ urlpatterns = [ path('organisations//', permission_required_with_403('RIGS.view_organisation')(views.OrganisationDetail.as_view()), name='organisation_detail'), - path('organisations//history/', - permission_required_with_403('RIGS.view_organisation')(versioning.VersionHistory.as_view()), - name='organisation_history', kwargs={'model': models.Organisation}), path('organisations//edit/', permission_required_with_403('RIGS.change_organisation')(views.OrganisationUpdate.as_view()), name='organisation_update'), @@ -48,9 +38,6 @@ urlpatterns = [ name='venue_create'), path('venues//', permission_required_with_403('RIGS.view_venue')(views.VenueDetail.as_view()), name='venue_detail'), - path('venues//history/', - permission_required_with_403('RIGS.view_venue')(versioning.VersionHistory.as_view()), - name='venue_history', kwargs={'model': models.Venue}), path('venues//edit/', permission_required_with_403('RIGS.change_venue')(views.VenueUpdate.as_view()), name='venue_update'), @@ -63,11 +50,7 @@ urlpatterns = [ url(r'^rigboard/calendar/(?P(month|week|day))/(?P(\d{4}-\d{2}-\d{2}))/$', login_required()(rigboard.WebCalendar.as_view()), name='web_calendar'), path('rigboard/archive/', RedirectView.as_view(permanent=True, pattern_name='event_archive')), - path('rigboard/activity/', permission_required_with_403('RIGS.view_event')(versioning.ActivityTable.as_view()), - name='activity_table'), - path('rigboard/activity/feed/', - cache_page(60 * 10)(permission_required_with_403('RIGS.view_event')(versioning.ActivityFeed.as_view())), - name='activity_feed'), + path('event//', has_oembed(oembed_view="event_oembed")(rigboard.EventDetail.as_view()), name='event_detail'), @@ -86,9 +69,6 @@ urlpatterns = [ name='event_update'), path('event//duplicate/', permission_required_with_403('RIGS.add_event')(rigboard.EventDuplicate.as_view()), name='event_duplicate'), - path('event//history/', - permission_required_with_403('RIGS.view_event')(versioning.VersionHistory.as_view()), - name='event_history', kwargs={'model': models.Event}), # Event H&S path('event/hs/', permission_required_with_403('RIGS.change_event')(hs.HSList.as_view()), name='hs_list'), @@ -99,8 +79,6 @@ urlpatterns = [ name='ra_detail'), path('event/ra//edit/', permission_required_with_403('RIGS.change_event')(hs.EventRiskAssessmentEdit.as_view()), name='ra_edit'), - path('event/ra//history/', permission_required_with_403('RIGS.change_event')(versioning.VersionHistory.as_view()), - name='ra_history', kwargs={'model': models.RiskAssessment}), path('event/ra/list', permission_required_with_403('RIGS.change_event')(hs.EventRiskAssessmentList.as_view()), name='ra_list'), path('event/ra//review/', permission_required_with_403('RIGS.change_event')(hs.EventRiskAssessmentReview.as_view()), name='ra_review'), @@ -111,13 +89,8 @@ urlpatterns = [ name='ec_detail'), path('event/checklist//edit/', permission_required_with_403('RIGS.change_event')(hs.EventChecklistEdit.as_view()), name='ec_edit'), - path('event/checklist//history/', permission_required_with_403('RIGS.change_event')(versioning.VersionHistory.as_view()), - name='ec_history', kwargs={'model': models.EventChecklist}), path('event/checklist/list', permission_required_with_403('RIGS.change_event')(hs.EventChecklistList.as_view()), name='ec_list'), - # TEMPORARY - path('event/vehicle//history/', permission_required_with_403('RIGS.change_event')(versioning.VersionHistory.as_view()), - name='vc_history', kwargs={'model': models.EventChecklistVehicle}), # Finance path('invoice/', permission_required_with_403('RIGS.view_invoice')(finance.InvoiceIndex.as_view()), @@ -141,9 +114,6 @@ urlpatterns = [ path('invoice//delete/', permission_required_with_403('RIGS.change_invoice')(finance.InvoiceDelete.as_view()), name='invoice_delete'), - path('invoice/(/history/', - permission_required_with_403('RIGS.view_invoice')(versioning.VersionHistory.as_view()), - name='invoice_history', kwargs={'model': models.Invoice}), path('payment/create/', permission_required_with_403('RIGS.add_payment')(finance.PaymentCreate.as_view()), name='payment_create'), diff --git a/RIGS/views.py b/RIGS/views.py index 57ba2fbf..e0b96f8a 100644 --- a/RIGS/views.py +++ b/RIGS/views.py @@ -21,25 +21,6 @@ from assets import models as asset_models from functools import reduce from PyRIGS.views import GenericListView -from django.views.decorators.cache import never_cache -from django.utils.decorators import method_decorator - -""" -Displays the current rig count along with a few other bits and pieces -""" - -# Disable browser based caching - - -@method_decorator(never_cache, name='dispatch') -class Index(generic.TemplateView): - template_name = 'index.html' - - def get_context_data(self, **kwargs): - context = super(Index, self).get_context_data(**kwargs) - context['rig_count'] = models.Event.objects.rig_count() - return context - class PersonList(GenericListView): template_name = 'person_list.html' diff --git a/assets/models.py b/assets/models.py index 166d28f9..236ca479 100644 --- a/assets/models.py +++ b/assets/models.py @@ -184,6 +184,10 @@ class Asset(models.Model, RevisionMixin): def activity_feed_string(self): return str(self) + @property + def display_id(self): + return str(self.asset_id) + @receiver(pre_save, sender=Asset) def pre_save_asset(sender, instance, **kwargs): diff --git a/assets/templates/base_assets.html b/assets/templates/base_assets.html index cd5f0cfe..b2f24e15 100644 --- a/assets/templates/base_assets.html +++ b/assets/templates/base_assets.html @@ -34,7 +34,7 @@ {% if perms.assets.view_asset %} - + {% endif %} {% endblock %} diff --git a/assets/templates/supplier_detail.html b/assets/templates/supplier_detail.html index 166dbc5b..678bb4a5 100644 --- a/assets/templates/supplier_detail.html +++ b/assets/templates/supplier_detail.html @@ -1 +1 @@ -{% include 'generic_detail.html' with type='Supplier' history_link='supplier_history' detail_link='supplier_detail' update_link='supplier_update' associated='partials/associated_assets.html' associated2='None' %} +{% include 'generic_detail.html' with type='Supplier' history_link='supplier_history' detail_link='supplier_detail' update_link='supplier_update' associated='partials/associated_assets.html' associated2='' %} diff --git a/assets/urls.py b/assets/urls.py index ffc3dc8d..6e44fcd4 100644 --- a/assets/urls.py +++ b/assets/urls.py @@ -17,10 +17,6 @@ urlpatterns = [ (views.AssetEdit.as_view()), name='asset_update'), path('asset/id//duplicate/', permission_required_with_403('assets.add_asset') (views.AssetDuplicate.as_view()), name='asset_duplicate'), - path('asset/id//history/', permission_required_with_403('assets.view_asset')(views.AssetVersionHistory.as_view()), - name='asset_history', kwargs={'model': models.Asset}), - path('activity', permission_required_with_403('assets.view_asset') - (views.ActivityTable.as_view()), name='asset_activity_table'), path('cabletype/list/', views.CableTypeList.as_view(), name='cable_type_list'), path('cabletype/create/', permission_required_with_403('assets.add_cable_type')(views.CableTypeCreate.as_view()), name='cable_type_create'), @@ -39,14 +35,12 @@ urlpatterns = [ path('asset/audit/', permission_required_with_403('assets.change_asset')(views.AssetAuditList.as_view()), name='asset_audit_list'), path('asset/id//audit/', permission_required_with_403('assets.change_asset')(views.AssetAudit.as_view()), name='asset_audit'), - path('supplier/list', views.SupplierList.as_view(), name='supplier_list'), - path('supplier/', views.SupplierDetail.as_view(), name='supplier_detail'), - path('supplier/create', permission_required_with_403('assets.add_supplier') + path('supplier/list/', views.SupplierList.as_view(), name='supplier_list'), + path('supplier//', views.SupplierDetail.as_view(), name='supplier_detail'), + path('supplier/create/', permission_required_with_403('assets.add_supplier') (views.SupplierCreate.as_view()), name='supplier_create'), - path('supplier//edit', permission_required_with_403('assets.change_supplier') + path('supplier//edit/', permission_required_with_403('assets.change_supplier') (views.SupplierUpdate.as_view()), name='supplier_update'), - path('supplier//history/', views.SupplierVersionHistory.as_view(), - name='supplier_history', kwargs={'model': models.Supplier}), path('supplier/search/', views.SupplierSearch.as_view(), name='supplier_search_json'), ] diff --git a/assets/views.py b/assets/views.py index eff92d02..3d09ad38 100644 --- a/assets/views.py +++ b/assets/views.py @@ -240,43 +240,6 @@ class SupplierUpdate(generic.UpdateView): template_name = 'supplier_update.html' -class SupplierVersionHistory(versioning.VersionHistory): - template_name = "asset_version_history.html" - - -class AssetVersionHistory(versioning.VersionHistory): - template_name = "version_history.html" - - def get_object(self, **kwargs): - return get_object_or_404(models.Asset, asset_id=self.kwargs['pk']) - - def get_context_data(self, **kwargs): - context = super(AssetVersionHistory, self).get_context_data(**kwargs) - context['object'] = self.get_object() - context['id'] = self.get_object().asset_id - context['override'] = 'base_assets.html' - - return context - - -class ActivityTable(versioning.ActivityTable): - model = versioning.RIGSVersion - template_name = "activity_table.html" - paginate_by = 25 - - def get_queryset(self): - versions = versioning.RIGSVersion.objects.get_for_multiple_models( - [models.Asset, models.Supplier]) - return versions - - def get_context_data(self, **kwargs): - context = super(ActivityTable, self).get_context_data(**kwargs) - context['override'] = 'base_assets.html' - context['title'] = 'Asset Database' - - return context - - class CableTypeList(generic.ListView): model = models.CableType template_name = 'cable_type_list.html' diff --git a/RIGS/templates/index.html b/templates/index.html similarity index 100% rename from RIGS/templates/index.html rename to templates/index.html diff --git a/versioning/templates/activity_feed_data.html b/versioning/templates/activity_feed_data.html index 22f5410f..25af3337 100644 --- a/versioning/templates/activity_feed_data.html +++ b/versioning/templates/activity_feed_data.html @@ -22,11 +22,13 @@ + {% else %} + {% endif %}
- {{ version.revision.user.name }} + {{ version.revision.user.name|default:'System' }} {{version.revision.date_created|naturaltime}}
{% endif %} diff --git a/versioning/templates/activity_table.html b/versioning/templates/activity_table.html index bf132ebf..f7f47f99 100644 --- a/versioning/templates/activity_table.html +++ b/versioning/templates/activity_table.html @@ -2,15 +2,15 @@ {% load paginator from filters %} {% load to_class_name from filters %} -{% block title %}{{ title }} Activity Stream{% endblock %} +{% block title %}{{ title|title }} Activity Stream{% endblock %} {% block js %} {% include 'partials/version_scripts.html' %} {% endblock %} {% block content %} -
-

{{ title }} Activity Stream

+
+

{{ title|title }} Activity Stream

{% include 'partials/activity_table_body.html' %} {% paginator %}
diff --git a/versioning/templates/partials/activity_table_body.html b/versioning/templates/partials/activity_table_body.html index 751c7b69..c94c93f2 100644 --- a/versioning/templates/partials/activity_table_body.html +++ b/versioning/templates/partials/activity_table_body.html @@ -14,20 +14,14 @@ {% for version in object_list %} {{ version.revision.date_created }} - {{version.changes.new|to_class_name}} - {% if version.changes.new.asset_id %} - {{ version.changes.new.asset_id }} - {% else %} - {{ version.changes.new.pk|stringformat:"05d" }} - {% endif %} - + {{ version.changes.new.display_id|default:version.changes.new.pk }} | {{version.changes.new|to_class_name}} {{ version.pk }}|{{ version.revision.pk }} {{ version.revision.user.name|default:"System" }} {% if version.changes.old == None %} {{version.changes.new|to_class_name}} Created {% else %} - {% include 'version_changes.html' %} + {% include 'partials/version_changes.html' %} {% endif %} diff --git a/versioning/templates/version_history.html b/versioning/templates/version_history.html index f36d422b..771a623d 100644 --- a/versioning/templates/version_history.html +++ b/versioning/templates/version_history.html @@ -2,7 +2,7 @@ {% load to_class_name from filters %} {% load paginator from filters %} -{% block title %}{{object|to_class_name}} {{ id }} - Revision History{% endblock %} +{% block title %}{{object|to_class_name}} {{ object.display_id|default:object.pk }} - Revision History{% endblock %} {% block js %} {% include 'partials/version_scripts.html' %} @@ -10,7 +10,7 @@ {% block content %}
-

{{object|to_class_name}} {{ id }} - Revision History

+

{{object|to_class_name}} {{ object.display_id|default:object.pk }} - Revision History

{% include 'partials/version_history_table.html' %}
{% paginator %}
diff --git a/versioning/urls.py b/versioning/urls.py new file mode 100644 index 00000000..7392d860 --- /dev/null +++ b/versioning/urls.py @@ -0,0 +1,34 @@ +from django.conf.urls import url +from django.contrib.auth.decorators import login_required +from django.urls import path +from django.views.decorators.clickjacking import xframe_options_exempt +from django.views.generic import RedirectView +from PyRIGS.decorators import (api_key_required, has_oembed, + permission_required_with_403) +from RIGS import finance, ical, models, rigboard, views, hs +from versioning import views +from django.views.decorators.cache import cache_page +from django.apps import apps + +urlpatterns = [ + path('rigboard/activity/feed/', + cache_page(60 * 10)(permission_required_with_403('RIGS.view_event')(views.ActivityFeed.as_view())), + name='activity_feed'), +] + +for app in apps.get_app_configs(): + appname = str(app.label) + # Well except this specific hack for legacy URLs...if only the RIGS app had been named 'rigboard'! + if appname == 'RIGS': + appname = 'rigboard' + urlpatterns += [path(appname + '/activity/', permission_required_with_403('RIGS.view_event')(views.ActivityTable.as_view()), + name='activity_table', kwargs={'app': appname, 'models': views.get_models(app.label)}),] + else: + urlpatterns += [path(appname + '/activity/', permission_required_with_403('RIGS.view_event')(views.ActivityTable.as_view()), + name=appname + '_activity_table', kwargs={'app': appname, 'models': views.get_models(app.label)}),] + for model in views.get_models(app.label): + modelname = model.__name__.lower() + urlpatterns += [ + path(appname + '/' + modelname + '//history/', permission_required_with_403('{}.change_{}'.format(app.label, modelname))(views.VersionHistory.as_view()), + name='{}_history'.format(modelname), kwargs={'model': model, 'app': appname,}), + ] diff --git a/versioning/versioning.py b/versioning/versioning.py index 85f727d2..d02a9a4e 100644 --- a/versioning/versioning.py +++ b/versioning/versioning.py @@ -11,6 +11,8 @@ 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 logger = logging.getLogger('tec.pyrigs') @@ -195,78 +197,3 @@ class RIGSVersion(Version): new=self._object_version.object, old=self.parent._object_version.object if self.parent else None ) - - -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): - 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() - context['id'] = self.get_object().pk - - return context - - -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( - [models.Event, models.Venue, models.Person, models.Organisation, models.EventAuthorisation, models.RiskAssessment]) - return versions.order_by("-revision__date_created") - - def get_context_data(self, **kwargs): - context = super(ActivityTable, self).get_context_data(**kwargs) - context['title'] = 'Rigboard' - - return context - -# TODO Defined by the model, rather than with this list -def models_for_feed(): - return [models.Event, models.Venue, models.Person, models.Organisation, models.EventAuthorisation, models.RiskAssessment, models.EventChecklist, - asset_models.Asset, asset_models.Supplier] - - -# Appears on homepage -class ActivityFeed(generic.ListView): - model = RIGSVersion - template_name = "activity_feed_data.html" - paginate_by = 25 - - def get_queryset(self): - versions = RIGSVersion.objects.get_for_multiple_models( - models_for_feed()) - 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 diff --git a/versioning/views.py b/versioning/views.py new file mode 100644 index 00000000..944e27f9 --- /dev/null +++ b/versioning/views.py @@ -0,0 +1,98 @@ +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 != None: + models = filter(lambda item: item in apps.get_app_config(app).get_models(),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(self.kwargs['models']) + 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 + +# Appears on homepage +@method_decorator(never_cache, name='dispatch') # Disable browser based caching +class ActivityFeed(generic.ListView): + model = RIGSVersion + template_name = "activity_feed_data.html" + paginate_by = 25 + + def get_queryset(self): + versions = RIGSVersion.objects.get_for_multiple_models(get_models()) + 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