Add progress bar with completion level for collections.
--- a/src/iconolab/models.py Mon May 22 16:17:36 2017 +0200
+++ b/src/iconolab/models.py Mon May 22 17:25:40 2017 +0200
@@ -9,7 +9,7 @@
from django.contrib.auth.models import User
from django.contrib.contenttypes.fields import GenericRelation
from django.contrib.contenttypes.models import ContentType
-from django.db import models, transaction
+from django.db import models, transaction, connection
from django.utils.text import slugify
from django_comments_xtd.models import XtdComment
@@ -17,6 +17,14 @@
logger = logging.getLogger(__name__)
+# https://docs.djangoproject.com/fr/1.11/topics/db/sql/#executing-custom-sql-directly
+def dictfetchall(cursor):
+ "Return all rows from a cursor as a dict"
+ columns = [col[0] for col in cursor.description]
+ return [
+ dict(zip(columns, row))
+ for row in cursor.fetchall()
+ ]
class Collection(models.Model):
"""
@@ -42,6 +50,33 @@
height = models.IntegerField(null=True, blank=True)
width = models.IntegerField(null=True, blank=True)
show_image_on_home = models.BooleanField(default=False)
+ completed_percent_calculated = None
+
+ def completed_percent(self):
+
+ if self.completed_percent_calculated is None:
+
+ sql = '''SELECT i.id AS item, COUNT(a.id) AS annotations
+ FROM iconolab_collection c
+ JOIN iconolab_item i ON i.collection_id = c.id
+ JOIN iconolab_image img ON img.item_id = i.id
+ LEFT JOIN iconolab_annotation a ON a.image_id = img.id
+ WHERE c.id = %s
+ GROUP BY c.name, i.id'''
+
+ with connection.cursor() as cursor:
+ cursor.execute(sql, [self.id])
+ results = dictfetchall(cursor)
+ total_items = len(results)
+ items_with_annotation = 0
+
+ for result in results:
+ if result['annotations'] > 0:
+ items_with_annotation += 1
+
+ self.completed_percent_calculated = int(round((items_with_annotation * 100) / total_items))
+
+ return self.completed_percent_calculated
def __str__(self):
return self.name
--- a/src/iconolab/templates/iconolab/collection_home.html Mon May 22 16:17:36 2017 +0200
+++ b/src/iconolab/templates/iconolab/collection_home.html Mon May 22 17:25:40 2017 +0200
@@ -13,6 +13,13 @@
<img src="{{ im.url }}" class="img-responsive">
{% endthumbnail %}
<hr>
+ <div class="progress">
+ <div class="progress-bar progress-bar-info progress-bar-striped" role="progressbar"
+ aria-valuenow="{{ collection.completed_percent }}" aria-valuemin="0" aria-valuemax="100"
+ style="width: {{ collection.completed_percent }}%;">
+ {{ collection.completed_percent }}%
+ </div>
+ </div>
<p>
{{ collection.description | safe }}
</p>
--- a/src/iconolab/templates/iconolab/home.html Mon May 22 16:17:36 2017 +0200
+++ b/src/iconolab/templates/iconolab/home.html Mon May 22 17:25:40 2017 +0200
@@ -30,6 +30,13 @@
</a>
</div>
<h4 class="text-center">{{collection.verbose_name}}</h4>
+ <div class="progress">
+ <div class="progress-bar progress-bar-info progress-bar-striped" role="progressbar"
+ aria-valuenow="{{ collection.completed_percent }}" aria-valuemin="0" aria-valuemax="100"
+ style="width: {{ collection.completed_percent }}%;">
+ {{ collection.completed_percent }}%
+ </div>
+ </div>
<a class="btn btn-default btn-primary btn-block" href="{% url 'collection_home' collection.name %}">
Contribuer
</a>
@@ -148,10 +155,3 @@
{% endif %}
</div>
{% endblock %}
-
-{% block footer_js %}
-<script>
- _v = new Vue(iconolab.CollectionSelector);
- _v.$mount("#homepage-main");
-</script>
-{% endblock %}
--- a/src/iconolab/views/objects.py Mon May 22 16:17:36 2017 +0200
+++ b/src/iconolab/views/objects.py Mon May 22 17:25:40 2017 +0200
@@ -68,6 +68,9 @@
.order_by('-annotation_count')\
.all()[:10]
+ for collection in context['collections_primary']:
+ collection.completed_percent()
+
most_accurate_tags = []
for row in rows:
tag = Tag.objects.get(id=row['tag'])
@@ -212,6 +215,7 @@
return result(request)
context = super(CollectionHomepageView, self).get_context_data(**kwargs)
context['collection_name'] = self.kwargs.get('collection_name', '')
+ collection.completed_percent()
context['collection'] = collection
# get Pagination and navigation query args