From 3d2695de498bd6fb12f7ad3b90d79faad9b33d1b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20M=C3=A9nager?= <herve.menager@pasteur.fr>
Date: Tue, 4 Jan 2022 17:53:33 +0100
Subject: [PATCH] add list of contributors in the about page

TODO: contributor detail page
---
 .../ippidb/templates/about-contributors.html  | 26 ++++++
 ippisite/ippidb/templates/about.html          |  3 +
 ippisite/ippidb/urls.py                       |  3 +-
 ippisite/ippidb/views/__init__.py             |  2 +
 ippisite/ippidb/views/about.py                | 83 ++++++++++++++++++-
 ippisite/ippidb/ws.py                         |  4 +-
 6 files changed, 117 insertions(+), 4 deletions(-)
 create mode 100644 ippisite/ippidb/templates/about-contributors.html

diff --git a/ippisite/ippidb/templates/about-contributors.html b/ippisite/ippidb/templates/about-contributors.html
new file mode 100644
index 00000000..54a12cff
--- /dev/null
+++ b/ippisite/ippidb/templates/about-contributors.html
@@ -0,0 +1,26 @@
+{% extends "about.html" %}
+
+{% block title %}inhibitors of Protein-Protein Interaction Database{% endblock %}
+
+{% block pagetitle %}Contributors{% endblock%}
+
+{% block view_content %}
+<div class="row">
+	<table class="table table-striped">
+		<thead>
+		  <tr>
+			<th scope="col" title="Contributor Name">Name</th>
+			<th scope="col" title="Contributor ORCID Link">ORCID</th>
+		  </tr>
+		</thead>
+		<tbody>
+			{% for contributor in object_list %}
+			<tr>
+				<td>{{ contributor.get_contributor_firstname | capfirst }} {{ contributor.get_contributor_lastname | capfirst }}</td>
+				<td><a href="{{ contributor.get_orcid_url }}" target="_blank">{{ contributor.get_orcid }}</a></td>
+			</tr>
+			{% endfor %}
+		</tbody>
+	  </table>
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/ippisite/ippidb/templates/about.html b/ippisite/ippidb/templates/about.html
index 667ed340..67ef120f 100644
--- a/ippisite/ippidb/templates/about.html
+++ b/ippisite/ippidb/templates/about.html
@@ -27,6 +27,9 @@
                 <li>
                     <a href="/about-pca">Chemical space</a>
                 </li>
+                <li>
+                    <a href="/contributors">Contributors</a>
+                </li>
             </ul>
         </div>
     </nav>
diff --git a/ippisite/ippidb/urls.py b/ippisite/ippidb/urls.py
index 45e15ed1..a75b1025 100644
--- a/ippisite/ippidb/urls.py
+++ b/ippisite/ippidb/urls.py
@@ -44,7 +44,7 @@ class IppiDbStaticSitemap(Sitemap):
 
 sitemaps = {
     "static": IppiDbStaticSitemap,
-    "compounds": views.site.IppiDbCompoundSitemap,
+    "compounds": views.IppiDbCompoundSitemap,
 }
 
 urlpatterns = [
@@ -61,6 +61,7 @@ urlpatterns = [
         name="physicochemistry",
     ),
     re_path(r"^about-pca/$", views.about_pca, name="pca"),
+    re_path(r"^about-contributors/$",  views.ContributorsListView.as_view(), name="contributors"),
     re_path(r"^targetcentric/$", views.PDBView.as_view(), name="cavities"),
     re_path(r"^targetcentric/networks$", views.NetworkView.as_view(), name="networks"),
     re_path(r"^api/", include(ROUTER.urls)),
diff --git a/ippisite/ippidb/views/__init__.py b/ippisite/ippidb/views/__init__.py
index 5010e4e7..7666e858 100644
--- a/ippisite/ippidb/views/__init__.py
+++ b/ippisite/ippidb/views/__init__.py
@@ -32,6 +32,7 @@ from .about import (
     about_pca,
     about_pharmacology,
     about_physicochemistry,
+    ContributorsListView,
 )
 from django.conf import settings
 
@@ -102,6 +103,7 @@ __all__ = [
     about_pca,
     about_pharmacology,
     about_physicochemistry,
+    ContributorsListView,
     PdbViewSet,
     DistanceViewSet,
     PDBView,
diff --git a/ippisite/ippidb/views/about.py b/ippisite/ippidb/views/about.py
index 323bfce6..cc9a875f 100644
--- a/ippisite/ippidb/views/about.py
+++ b/ippisite/ippidb/views/about.py
@@ -2,9 +2,12 @@
 iPPI-DB global statistics views
 """
 
-from django.db.models import F, Count, FloatField
+import re
+from django.contrib.auth import get_user_model
+from django.db.models import F, Count, FloatField, QuerySet
 from django.db.models.functions import Cast, Floor
 from django.shortcuts import render
+from django.views.generic.list import ListView
 import json
 
 
@@ -19,6 +22,8 @@ from ippidb.models import (
     Protein,
 )
 
+from ippidb.ws import get_orcid_user_details
+
 
 def about_general(request):
     compounds_count = Compound.objects.count()
@@ -278,3 +283,79 @@ def about_pca(request):
     except PcaBiplotData.DoesNotExist:
         context = {}
     return render(request, "about-pca.html", context=context)
+
+
+User = get_user_model()
+
+
+def cached_orcid_json(getter_function):
+    def new_function(self):
+        if self.__orcid_json is None:
+            self.__orcid_json = get_orcid_user_details(self.get_orcid())
+        ret = getter_function(self)
+        return ret
+
+    return new_function
+
+
+def get_orcid(self):
+    """
+    Get contributor ORCID from their allauth social account
+    """
+    if self.socialaccount_set.count() > 0:
+        return self.socialaccount_set.all()[0].uid
+    return None
+
+
+def get_orcid_url(self):
+    """
+    Get contributor ORCID fURL from their allauth profile
+    """
+    if self.socialaccount_set.count() > 0:
+        return self.socialaccount_set.all()[0].get_profile_url()
+    return None
+
+
+@cached_orcid_json
+def get_contributor_firstname(self):
+    """
+    Get contributor full name from their ORCID profile
+    """
+    orcid = self.get_orcid()
+    if orcid is not None:
+        data = self.__orcid_json
+        return data['first_name']
+
+
+@cached_orcid_json
+def get_contributor_lastname(self):
+    """
+    Get contributor full name from their ORCID profile
+    """
+    orcid = self.get_orcid()
+    if orcid is not None:
+        data = self.__orcid_json
+        return data['last_name']
+
+
+User.add_to_class("get_orcid", get_orcid)
+User.add_to_class("get_orcid_url", get_orcid_url)
+User.add_to_class("__orcid_json", None)
+User.add_to_class("get_contributor_firstname", get_contributor_firstname)
+User.add_to_class("get_contributor_lastname", get_contributor_lastname)
+
+
+class ContributorsListView(ListView):
+    """
+    Contributors list view
+    """
+
+    model = User
+    template_name = "about-contributors.html"
+
+    def get_queryset(self) -> QuerySet[User]:
+        qs = super().get_queryset()
+        qs = qs.annotate(contributions_count=Count("contribution")).filter(
+            socialaccount__isnull=False, contributions_count__gt=0
+        )
+        return qs
diff --git a/ippisite/ippidb/ws.py b/ippisite/ippidb/ws.py
index 4ec65d1a..9fb52683 100644
--- a/ippisite/ippidb/ws.py
+++ b/ippisite/ippidb/ws.py
@@ -598,6 +598,6 @@ def get_orcid_user_details(orcid: str) -> str:
     )
     data = resp.json()
     return {
-        "first": data["name"]["given-names"]["value"],
-        "last": data["name"]["family-name"]["value"],
+        "first_name": data["name"]["given-names"]["value"],
+        "last_name": data["name"]["family-name"]["value"],
     }
-- 
GitLab