diff --git a/accounts/tests.py b/accounts/tests.py
index bc6c48e50..93fa97128 100644
--- a/accounts/tests.py
+++ b/accounts/tests.py
@@ -21,32 +21,61 @@ def test_username_is_page_title(self):
response = self.client.get(self.user1_url)
self.assertContains(response, "
user1
", html=True)
- def test_stat_commits(self):
+ def test_stat_commits_no_commits(self):
+ user1_response = self.client.get(self.user1_url)
+ self.assertNotContains(user1_response, "Commits")
+
+ def test_stat_commits_commiter_full_name(self):
+ User.objects.create_user(
+ first_name="James",
+ last_name="Bond",
+ username="007",
+ email="007@mi5.co.uk",
+ password="*****************",
+ )
Revision.objects.create(
- author="user1",
+ author="James Bond <007@mi5.co.uk>",
rev="91c879eda595c12477bbfa6f51115e88b75ddf88",
_time=1731669560,
)
Revision.objects.create(
- author="user1",
+ author="James Bonderson ",
rev="da2432cccae841f0d7629f17a5d79ec47ed7b7cb",
_time=1731669560,
)
+ user1_response = self.client.get(reverse("user_profile", args=["007"]))
+ self.assertContains(
+ user1_response,
+ 'Commits: 1.',
+ html=True,
+ )
+
+ def test_stat_commits_commiter_username(self):
+ User.objects.create_user(
+ first_name="James",
+ last_name="Bond",
+ username="007",
+ email="007@mi5.co.uk",
+ password="*****************",
+ )
Revision.objects.create(
- author="user3",
+ author="007 <007@mi5.co.uk>",
+ rev="91c879eda595c12477bbfa6f51115e88b75ddf88",
+ _time=1731669560,
+ )
+ Revision.objects.create(
+ author="Elizabeth Bennet <300792567+pnp@users.noreply.github.com>",
rev="63dbe30d3363715deaf280214d75b03f6d65a571",
_time=1731669560,
)
-
- user1_response = self.client.get(self.user1_url)
- user2_response = self.client.get(self.user2_url)
+ user1_response = self.client.get(reverse("user_profile", args=["007"]))
self.assertContains(
user1_response,
'Commits: 2.',
+ '?author=007">Commits: 1.',
html=True,
)
- self.assertNotContains(user2_response, "Commits")
def test_stat_tickets(self):
Ticket.objects.create(status="new", reporter="user1")
diff --git a/accounts/views.py b/accounts/views.py
index bbdf888db..81b1303b4 100644
--- a/accounts/views.py
+++ b/accounts/views.py
@@ -40,7 +40,7 @@ def get_user_stats(user):
key = "user_vital_status:%s" % hashlib.md5(username).hexdigest()
info = c.get(key)
if info is None:
- info = trac_stats.get_user_stats(user.username)
+ info = trac_stats.get_user_stats(user)
# Hide any stat with a value = 0 so that we don't accidentally insult
# non-contributors.
for k, v in list(info.items()):
diff --git a/tracdb/stats.py b/tracdb/stats.py
index 2cfa6c1b2..853c17933 100644
--- a/tracdb/stats.py
+++ b/tracdb/stats.py
@@ -6,6 +6,7 @@
from collections import OrderedDict, namedtuple
from django.conf import settings
+from django.db.models import Q
from .models import Revision, Ticket, TicketChange
@@ -34,44 +35,46 @@ def _inner(f):
return _inner
-def get_user_stats(username):
+def get_user_stats(user):
stats = OrderedDict()
for func in sorted(_statfuncs, key=operator.attrgetter("title")):
- stats[func.title] = func(username)
+ stats[func.title] = func(user)
return stats
@stat("Commits")
-def commit_count(username):
- count = Revision.objects.filter(author=username).count()
- # This assumes that the username is their GitHub username, this is very
- # often the case. If this is incorrect, the GitHub will show no commits.
- link = f"https://github.com/django/django/commits/main/?author={username}"
+def commit_count(user):
+ count = Revision.objects.filter(
+ Q(author__istartswith=f"{user.username} <")
+ | Q(author__istartswith=f"{user.get_full_name()} <")
+ ).count()
+ # This assumes that the username is their GitHub username.
+ link = f"https://github.com/django/django/commits/main/?author={user.username}"
return StatData(count=count, link=link)
@stat("Tickets fixed")
-def tickets_fixed(username):
- query = f"owner={username}&resolution=fixed"
+def tickets_fixed(user):
+ query = f"owner={user.username}&resolution=fixed"
count = Ticket.objects.from_querystring(query).count()
link = get_trac_link(query)
return StatData(count=count, link=link)
@stat("Tickets opened")
-def tickets_opened(username):
- query = f"reporter={username}"
+def tickets_opened(user):
+ query = f"reporter={user.username}"
count = Ticket.objects.from_querystring(query).count()
link = get_trac_link(query)
return StatData(count=count, link=link)
@stat("New tickets triaged")
-def new_tickets_reviewed(username):
+def new_tickets_reviewed(user):
# We don't want to de-dup as for tickets_closed: multiple reviews of the
# same ticket should "count" as a review.
qs = TicketChange.objects.filter(
- author=username, field="stage", oldvalue="Unreviewed"
+ author=user.username, field="stage", oldvalue="Unreviewed"
)
qs = qs.exclude(newvalue="Unreviewed")
return StatData(count=qs.count(), link=None)