#63 Replacing vote expiration with vote accuarcy
This commit is contained in:
parent
d213b51a59
commit
8597e53599
@ -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
|
||||||
|
@ -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>
|
||||||
|
@ -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 %}
|
||||||
|
@ -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()
|
||||||
|
)
|
||||||
|
@ -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(
|
||||||
|
Loading…
Reference in New Issue
Block a user