#63 Replacing vote expiration with vote accuarcy

This commit is contained in:
Leonhard Strohmidel 2022-09-20 09:56:23 +02:00
parent d213b51a59
commit 8597e53599
5 changed files with 57 additions and 16 deletions

View File

@ -1,11 +1,13 @@
import os import os
from math import floor import datetime
from math import round, ceil
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
from django.dispatch import receiver from django.dispatch import receiver
from django.db.models.signals import post_delete, pre_save from django.db.models.signals import post_delete, pre_save
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.utils import timezone
from django.conf import settings from django.conf import settings
from lostplaces.models.abstract_models import Submittable, Taggable, Mapable, Expireable from lostplaces.models.abstract_models import Submittable, Taggable, Mapable, Expireable
@ -92,8 +94,6 @@ class Place(Submittable, Taggable, Mapable):
return {'latitude': latitude, 'longitude': longitude} return {'latitude': latitude, 'longitude': longitude}
def calculate_place_level(self): def calculate_place_level(self):
self.remove_expired_votes()
if self.placevotings.count() == 0: if self.placevotings.count() == 0:
self.level = 5 self.level = 5
self.save() self.save()
@ -104,13 +104,19 @@ class Place(Submittable, Taggable, Mapable):
for vote in self.placevotings.all(): for vote in self.placevotings.all():
level += vote.vote level += vote.vote
self.level = floor(level / self.placevotings.count()) self.level = round(level / self.placevotings.count())
self.save() self.save()
def remove_expired_votes(self): def calculate_voting_accuracy(self):
place_age = timezone.now() - self.submitted_when;
accuaries = [];
for vote in self.placevotings.all(): for vote in self.placevotings.all():
if vote.is_expired: vote_age = timezone.now() - vote.created_when;
vote.delete() accuracy = 100 - (100 / (place_age / vote_age))
accuaries.append(accuracy)
return ceil(sum(accuaries) / len(accuaries))
def __str__(self): def __str__(self):
return self.name return self.name

View File

@ -28,12 +28,7 @@
</div> </div>
<div class="LP-Voting__Expiration"> <div class="LP-Voting__Expiration">
<span class="LP-Voting__InfoLabel">Your vote expires on</span> The accuracy of the voting is {{voting.accuracy}}%
<span class="LP-Voting__Date">
<time datetime="{{voting.expires_when|date:'Y-m-d'}}">
{{voting.users_vote.expires_when|date:'d.m.Y'}}
</time>
</span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -23,7 +23,15 @@
{% block maincontent %} {% block maincontent %}
<article class="LP-PlaceDetail"> <article class="LP-PlaceDetail">
<header class="LP-PlaceDetail__Header"> <header class="LP-PlaceDetail__Header">
<h1 class="LP-Headline">{{ place.name }} {% include 'partials/icons/place_favorite.html' %} {% include 'partials/icons/place_visited.html' %}</h1> <h1 class="LP-Headline">
{{ place.name }}
{% include 'partials/icons/place_favorite.html' %}
{% include 'partials/icons/place_visited.html' %}
{% if user.is_superuser %}
<a class="LP-Link" href="{{'/admin/lostplaces/place/'|addstr:place.id }}" target="_blank"><span class="LP-Link__Text">{% translate 'view place in admin panel' %}</span></a>
{% endif %}
</h1>
{% if place.get_hero_image %} {% if place.get_hero_image %}
<div class="LP-PlaceDetail__Image"> <div class="LP-PlaceDetail__Image">
{% include '../partials/image.html' with source_url=place.get_hero_image.filename.hero.url link_url="#image"|addstr:place.get_hero_index_in_queryset %} {% include '../partials/image.html' with source_url=place.get_hero_image.filename.hero.url link_url="#image"|addstr:place.get_hero_index_in_queryset %}

View File

@ -124,3 +124,31 @@ class PlaceTestCase(ModelTestCase):
self.model.__name__ self.model.__name__
) )
) )
def test_level_calculation(self):
place = self.place
explorer = place.submitted_by
PlaceVoting.objects.create(
submitted_by=explorer,
place=place,
vote=5,
expires_when=timezone.now()+self.delta
)
PlaceVoting.objects.create(
submitted_by=explorer,
place=place,
vote=2,
expires_when=timezone.now()+self.delta
)
PlaceVoting.objects.create(
submitted_by=explorer,
place=place,
vote=4,
expires_when=timezone.now()+self.delta
)
self.assertEqual(
4,
place.calculate_place_level()
)

View File

@ -74,7 +74,8 @@ class PlaceDetailView(IsAuthenticatedMixin, IsEligibleToSeePlaceMixin, View):
}, },
'placevoting': { 'placevoting': {
'users_vote': PlaceVoting.objects.filter(place=place, submitted_by=explorer).first(), 'users_vote': PlaceVoting.objects.filter(place=place, submitted_by=explorer).first(),
'all_choices': reversed(PLACE_LEVELS) 'all_choices': reversed(PLACE_LEVELS),
'accuracy': place.calculate_voting_accuracy()
} }
} }
return render(request, 'place/place_detail.html', context) return render(request, 'place/place_detail.html', context)
@ -204,8 +205,11 @@ class PlaceVisitDeleteView(IsAuthenticatedMixin, View):
class PlaceVoteView(IsEligibleToSeePlaceMixin, View): class PlaceVoteView(IsEligibleToSeePlaceMixin, View):
delta = timedelta(weeks=24) delta = timedelta(weeks=24)
def get_place(self):
return get_object_or_404(Place, pk=self.kwargs['place_id'])
def get(self, request, place_id, vote): def get(self, request, place_id, vote):
place = get_object_or_404(Place, id=place_id) place = self.get_place()
explorer = request.user.explorer explorer = request.user.explorer
voting = PlaceVoting.objects.filter( voting = PlaceVoting.objects.filter(