diff --git a/django_lostplaces/lostplaces/models/place.py b/django_lostplaces/lostplaces/models/place.py index 140fb9f..191d849 100644 --- a/django_lostplaces/lostplaces/models/place.py +++ b/django_lostplaces/lostplaces/models/place.py @@ -1,11 +1,13 @@ import os -from math import floor +import datetime +from math import round, ceil from django.db import models from django.urls import reverse from django.dispatch import receiver from django.db.models.signals import post_delete, pre_save from django.utils.translation import gettext as _ +from django.utils import timezone from django.conf import settings from lostplaces.models.abstract_models import Submittable, Taggable, Mapable, Expireable @@ -92,8 +94,6 @@ class Place(Submittable, Taggable, Mapable): return {'latitude': latitude, 'longitude': longitude} def calculate_place_level(self): - self.remove_expired_votes() - if self.placevotings.count() == 0: self.level = 5 self.save() @@ -104,13 +104,19 @@ class Place(Submittable, Taggable, Mapable): for vote in self.placevotings.all(): level += vote.vote - self.level = floor(level / self.placevotings.count()) + self.level = round(level / self.placevotings.count()) 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(): - if vote.is_expired: - vote.delete() + vote_age = timezone.now() - vote.created_when; + accuracy = 100 - (100 / (place_age / vote_age)) + accuaries.append(accuracy) + + return ceil(sum(accuaries) / len(accuaries)) def __str__(self): return self.name diff --git a/django_lostplaces/lostplaces/templates/partials/voting.html b/django_lostplaces/lostplaces/templates/partials/voting.html index 169b8ca..f112756 100644 --- a/django_lostplaces/lostplaces/templates/partials/voting.html +++ b/django_lostplaces/lostplaces/templates/partials/voting.html @@ -28,12 +28,7 @@
- Your vote expires on - - - + The accuracy of the voting is {{voting.accuracy}}%
diff --git a/django_lostplaces/lostplaces/templates/place/place_detail.html b/django_lostplaces/lostplaces/templates/place/place_detail.html index a768ffb..7a0beeb 100644 --- a/django_lostplaces/lostplaces/templates/place/place_detail.html +++ b/django_lostplaces/lostplaces/templates/place/place_detail.html @@ -23,7 +23,15 @@ {% block maincontent %}
-

{{ place.name }} {% include 'partials/icons/place_favorite.html' %} {% include 'partials/icons/place_visited.html' %}

+

+ {{ place.name }} + {% include 'partials/icons/place_favorite.html' %} + {% include 'partials/icons/place_visited.html' %} + + {% if user.is_superuser %} + {% translate 'view place in admin panel' %} + {% endif %} +

{% if place.get_hero_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 %} diff --git a/django_lostplaces/lostplaces/tests/models/test_place_model.py b/django_lostplaces/lostplaces/tests/models/test_place_model.py index baca3ea..98dc949 100644 --- a/django_lostplaces/lostplaces/tests/models/test_place_model.py +++ b/django_lostplaces/lostplaces/tests/models/test_place_model.py @@ -124,3 +124,31 @@ class PlaceTestCase(ModelTestCase): 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() + ) diff --git a/django_lostplaces/lostplaces/views/place_views.py b/django_lostplaces/lostplaces/views/place_views.py index a28a430..a1f83be 100644 --- a/django_lostplaces/lostplaces/views/place_views.py +++ b/django_lostplaces/lostplaces/views/place_views.py @@ -74,7 +74,8 @@ class PlaceDetailView(IsAuthenticatedMixin, IsEligibleToSeePlaceMixin, View): }, 'placevoting': { '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) @@ -204,8 +205,11 @@ class PlaceVisitDeleteView(IsAuthenticatedMixin, View): class PlaceVoteView(IsEligibleToSeePlaceMixin, View): 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): - place = get_object_or_404(Place, id=place_id) + place = self.get_place() explorer = request.user.explorer voting = PlaceVoting.objects.filter(