From e00e33d94e612125086f40b3aa9711ef45f8e8d3 Mon Sep 17 00:00:00 2001
From: dnns01 <git@dnns01.de>
Date: Mon, 30 May 2022 10:58:03 +0200
Subject: [PATCH] Fix issue with randomness

---
 .../migrations/0008_clip_last_played.py       | 18 +++++++++++++
 strolchguru/models.py                         |  1 +
 strolchguru/views.py                          | 26 +++++++++++++++----
 3 files changed, 40 insertions(+), 5 deletions(-)
 create mode 100644 strolchguru/migrations/0008_clip_last_played.py

diff --git a/strolchguru/migrations/0008_clip_last_played.py b/strolchguru/migrations/0008_clip_last_played.py
new file mode 100644
index 0000000..ddc1fc6
--- /dev/null
+++ b/strolchguru/migrations/0008_clip_last_played.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.0.4 on 2022-05-30 06:45
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('strolchguru', '0007_alter_clip_tags'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='clip',
+            name='last_played',
+            field=models.DateTimeField(null=True),
+        ),
+    ]
diff --git a/strolchguru/models.py b/strolchguru/models.py
index 3fd2537..5ee58ce 100644
--- a/strolchguru/models.py
+++ b/strolchguru/models.py
@@ -18,6 +18,7 @@ class Clip(models.Model):
     is_downloaded = models.BooleanField(default=False)
     is_in_loop = models.BooleanField(default=True)
     tags = models.ManyToManyField("Tag", blank=True)
+    last_played = models.DateTimeField(null=True)
 
     @property
     def display_title(self):
diff --git a/strolchguru/views.py b/strolchguru/views.py
index 6861c6d..dc8d13c 100644
--- a/strolchguru/views.py
+++ b/strolchguru/views.py
@@ -1,3 +1,4 @@
+import datetime
 import json
 import random
 import re
@@ -9,6 +10,7 @@ from django.forms import modelformset_factory
 from django.forms.models import model_to_dict
 from django.http import HttpResponse, JsonResponse, Http404, HttpRequest
 from django.shortcuts import render, get_object_or_404, redirect
+from django.db.models.functions import Now
 
 from strolchibot.forms import BaseModelForm
 from strolchibot.models import TwitchUser
@@ -34,19 +36,33 @@ def get_pages(page, num_pages):
         return range(start_page, end_page + 1)
 
 
+def get_clip_in_loop(tag: str = None):
+    # Get all clips, that are allowed to be played in loop. If tag is specified, also filtered by tag
+    clips = Clip.objects.filter(is_published=True, is_downloaded=True, is_in_loop=True).order_by("last_played")
+    if tag:
+        clips = clips.filter(tags__name=tag)
+
+    # Get first half of clips. This will "guarantee", that clips are played more randomly
+    clips = list(clips)
+    clips = clips[:len(clips)//2]
+
+    clip = random.SystemRandom().choice(clips)
+    clip.last_played = Now()
+    clip.save()
+
+    return clip
+
+
 def home(request) -> HttpResponse:
     controls = True if request.GET.get("controls") == "1" else False
-    clips = Clip.objects.filter(is_published=True, is_downloaded=True, is_in_loop=True)
-    clip = random.choice(list(clips))
+    clip = get_clip_in_loop()
     return render(request, 'strolchguru_home.html',
                   context={'clip': clip, 'mode': "random_clips", 'controls': controls})
 
 
 def home_tag(request, tag) -> HttpResponse:
     controls = True if request.GET.get("controls") == "1" else False
-    clips = Clip.objects.filter(is_published=True, is_downloaded=True, tags__name=tag)
-    if clips:
-        clip = random.choice(list(clips))
+    if clip := get_clip_in_loop(tag=tag):
         return render(request, 'strolchguru_home.html',
                       context={'clip': clip, 'mode': "random_clips", 'controls': controls})
     else:
-- 
GitLab