From 2692694bfe618337f10a6fd7056046a574813d04 Mon Sep 17 00:00:00 2001
From: Frank Sauerburger <frank@sauerburger.com>
Date: Fri, 8 Jan 2021 17:38:16 +0100
Subject: [PATCH] Add view counters

---
 uhepp_org/uhepp_api/views.py                  |  1 +
 .../migrations/0005_auto_20210108_1625.py     | 23 +++++++++++++++++++
 uhepp_org/uhepp_vault/models.py               | 20 ++++++++++++++++
 .../templates/uhepp_vault/plot_detail.html    |  4 ++++
 uhepp_org/uhepp_vault/views.py                |  6 +++++
 5 files changed, 54 insertions(+)
 create mode 100644 uhepp_org/uhepp_vault/migrations/0005_auto_20210108_1625.py

diff --git a/uhepp_org/uhepp_api/views.py b/uhepp_org/uhepp_api/views.py
index fd2737e..cd22810 100644
--- a/uhepp_org/uhepp_api/views.py
+++ b/uhepp_org/uhepp_api/views.py
@@ -158,6 +158,7 @@ class PlotViewSet(viewsets.ModelViewSet):
         
     def retrieve(self, request, *args, **kwargs):
         instance = self.get_object()
+        instance.increment_api_view_count()
         serializer = self.get_serializer(instance)
         headers = self.get_success_headers(serializer.data)
         return Response(serializer.data, headers=headers)
diff --git a/uhepp_org/uhepp_vault/migrations/0005_auto_20210108_1625.py b/uhepp_org/uhepp_vault/migrations/0005_auto_20210108_1625.py
new file mode 100644
index 0000000..533e8ec
--- /dev/null
+++ b/uhepp_org/uhepp_vault/migrations/0005_auto_20210108_1625.py
@@ -0,0 +1,23 @@
+# Generated by Django 3.1.3 on 2021-01-08 16:25
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('uhepp_vault', '0004_auto_20201201_1955'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='plot',
+            name='api_view_count',
+            field=models.IntegerField(default=0),
+        ),
+        migrations.AddField(
+            model_name='plot',
+            name='ui_view_count',
+            field=models.IntegerField(default=0),
+        ),
+    ]
diff --git a/uhepp_org/uhepp_vault/models.py b/uhepp_org/uhepp_vault/models.py
index 16a32d7..c57d48a 100644
--- a/uhepp_org/uhepp_vault/models.py
+++ b/uhepp_org/uhepp_vault/models.py
@@ -3,6 +3,7 @@ import uuid
 
 from django.conf import settings
 from django.db import models
+from django.db.models import F
 from django.contrib.auth.models import User, Group
 from django.utils.translation import gettext_lazy as _
 
@@ -43,12 +44,31 @@ class Plot(models.Model):
     """Database record of a uhepp compliant plot"""
     uuid = models.UUIDField(primary_key=True, default=uuid.uuid4)
     uhepp = models.JSONField()
+    ui_view_count = models.IntegerField(default=0)
+    api_view_count = models.IntegerField(default=0)
+
     collection = models.ForeignKey(
         Collection,
         on_delete=models.CASCADE,
         related_name='plots'
     )
 
+    def view_count(self):
+        # Plus 1 since increments are not updated
+        return self.api_view_count + self.ui_view_count + 1
+
+    def increment_api_view_count(self):
+        """Increment the view counter without a race condition"""
+        Plot.objects.filter(uuid=self.uuid).update(
+            api_view_count=F('api_view_count') + 1
+        )
+
+    def increment_ui_view_count(self):
+        """Increment the view counter without a race condition"""
+        Plot.objects.filter(uuid=self.uuid).update(
+            ui_view_count=F('ui_view_count') + 1
+        )
+
     def __str__(self):
         try:
             metadata = self.uhepp.get("metadata", {})
diff --git a/uhepp_org/uhepp_vault/templates/uhepp_vault/plot_detail.html b/uhepp_org/uhepp_vault/templates/uhepp_vault/plot_detail.html
index c7f4b70..9d8567f 100644
--- a/uhepp_org/uhepp_vault/templates/uhepp_vault/plot_detail.html
+++ b/uhepp_org/uhepp_vault/templates/uhepp_vault/plot_detail.html
@@ -26,6 +26,9 @@
     </a>
   </span>
   {% endif %}</h1>
+<div class="d-none d-lg-inline text-muted"><i class="fas fa-eye"></i>
+    {{ plot.view_count }} view{{ plot.view_count|pluralize }}
+</div>
 
 <div class="d-flex">
 <span class="d-none d-md-inline">UUID: {{ plot.uuid }}</span>
@@ -109,6 +112,7 @@ uhepp push {{ plot.collection.pk }} local_file.json</pre>
 </div>
 </div>
 
+
 <div id="app-root">
   <div class="d-flex justify-content-center my-5">
     <div class="spinner-border text-primary" role="status">
diff --git a/uhepp_org/uhepp_vault/views.py b/uhepp_org/uhepp_vault/views.py
index 05cdc64..1cce9da 100644
--- a/uhepp_org/uhepp_vault/views.py
+++ b/uhepp_org/uhepp_vault/views.py
@@ -208,6 +208,11 @@ class PlotDetail(generic.DetailView):
             )
         return queryset
 
+    def get_object(self, *args, **kwds):
+        obj = super().get_object(*args, **kwds)
+        obj.increment_ui_view_count()
+        return obj
+
     def get(self, request, *args, **kwargs):
         try:
             return super().get(request, *args, **kwargs)
@@ -240,6 +245,7 @@ def plot_download(request, uuid):
         )
     
     plot = get_object_or_404(queryset, uuid=uuid)
+    plot.increment_ui_view_count()
 
     response =  JsonResponse(plot.uhepp)
     response["Content-Disposition"] = f'attachment; filename="{plot}.json"'
-- 
GitLab