Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 68 additions & 43 deletions website/templates/leaderboard_global.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{% extends "base.html" %}
{% load static %}
{% load string_filters %}
{% block title %}
Global Leaderboard
{% endblock title %}
Expand All @@ -25,11 +26,11 @@ <h1 class="page-header">Global Leaderboard</h1>
</div>
<div class="flex flex-col md:gap-10 px-4 gap-2 md:px-0">
<div class="flex justify-center gap-6 flex-wrap">
<div class=" flex-1 border-2 border-gray-300 pb-3 rounded-b-lg flex-1 min-w-[300px] max-w-[550px]">
<div class="text-center text-3xl font-bold py-4 border-2 border-red-500 rounded-t-lg">Points Leaderboard</div>
<div class=" flex-1 border-2 border-[#e74c3c] pb-3 rounded-lg flex-1 min-w-[300px] max-w-[550px]">
<div class="text-center text-3xl font-bold py-4 border-b-2 border-[#e74c3c] rounded-t-lg">Points Leaderboard</div>
<div class=" list-group w-full p-4">
{% if not leaderboard %}
<p class="text-red-500 text-center font-medium">No data for this month!</p>
<p class="text-[#e74c3c] text-center font-medium">No data for this month!</p>
{% else %}
<div class="flex flex-col gap-2">
{% for leader in leaderboard %}
Expand Down Expand Up @@ -73,90 +74,114 @@ <h1 class="page-header">Global Leaderboard</h1>
{% endif %}
</div>
</div>
<div class=" flex-1 border-2 border-gray-300 pb-3 rounded-b-lg flex-1 min-w-[300px] max-w-[550px]">
<div class=" text-center text-3xl font-bold py-4 border-2 border-red-500 rounded-t-lg">Pull Request Leaderboard</div>
<div class=" flex-1 border-2 border-[#e74c3c] pb-3 rounded-lg flex-1 min-w-[300px] max-w-[550px]">
<div class=" text-center text-3xl font-bold py-4 border-b-2 border-[#e74c3c] rounded-t-lg">
Pull Request Leaderboard
</div>
<div class=" list-group w-full p-4">
{% if pr_leaderboard %}
<div class="flex flex-col gap-2">
{% for leader in pr_leaderboard %}
<div class="flex justify-between items-center">
<div class="flex gap-2 items-center truncate">
{% if leader.user_profile__github_url %}
<img src="https://github.com/{{ leader.user_profile__user__username }}.png"
{% if leader.github_username %}
<img src="https://github.com/{{ leader.github_username }}.png"
class=" size-11 select-none border border-gray-200 rounded-full"
alt="{{ leader.user_profile__user__username }}"
width="50px"
height="50px">
{% else %}
{% elif leader.user_profile__user__email %}
<img src="{% gravatar_url leader.user_profile__user__email 50 %}"
class=" size-11 select-none border border-gray-200 rounded-full"
alt="username"
width="50px"
height="50px">
{% else %}
<img src="{% gravatar_url 'default@example.com' 50 %}"
class=" size-11 select-none border border-gray-200 rounded-full"
alt="username"
width="50px"
height="50px">
{% endif %}
{% if leader.user_profile__user__username %}
<a href="{% url 'profile' slug=leader.user_profile__user__username %}"
class="text-lg transition-all duration-200">{{ leader.user_profile__user__username }}</a>
{% else %}
<span class="text-lg text-gray-500">Unknown User</span>
{% endif %}
{% if leader.user_profile__github_url %}
<a href="{{ leader.user_profile__github_url }}"
target="_blank"
class="ml-2">
<i class="fab fa-github text-xl"></i>
</a>
{% endif %}
<a href="{% url 'profile' slug=leader.user_profile__user__username %}"
class="text-lg transition-all duration-200">{{ leader.user_profile__user__username }}</a>
<a href="{{ leader.user_profile__github_url }}"
target="_blank"
class="ml-2">
<i class="fab fa-github text-xl"></i>
</a>
</div>
<span class="pull-right badge bg-gray-100 flex-shrink-0 rounded-md py-1 px-2 select-none">{{ leader.total_prs }} PRs</span>
</div>
<div class="border-t border-gray-200 my-1"></div>
{% endfor %}
</div>
{% else %}
<p class="text-red-500 text-center font-medium">No pull request data available!</p>
<p class="text-[#e74c3c] text-center font-medium">No pull request data available!</p>
{% endif %}
</div>
</div>
<div class=" flex-1 border-2 border-gray-300 pb-3 rounded-b-lg flex-1 min-w-[300px] max-w-[550px]">
<div class="text-center text-3xl font-bold py-4 border-2 border-red-500 rounded-t-lg">Code Review Leaderboard</div>
<div class=" flex-1 border-2 border-[#e74c3c] pb-3 rounded-lg flex-1 min-w-[300px] max-w-[550px]">
<div class="text-center text-3xl font-bold py-4 border-b-2 border-[#e74c3c] rounded-t-lg">Code Review Leaderboard</div>
<div class="list-group p-4">
{% if code_review_leaderboard %}
<div class="flex flex-col gap-2">
{% for leader in code_review_leaderboard %}
<div class="flex justify-between items-center">
<div class="flex gap-2 items-center truncate">
{% if leader.reviews__reviewer__user__username %}
<img src="https://github.com/{{ leader.reviews__reviewer__user__username }}.png"
{% if leader.github_username %}
<img src="https://github.com/{{ leader.github_username }}.png"
class=" size-11 select-none border border-gray-200 rounded-full"
alt="{{ leader.reviews__reviewer__user__username }}"
alt="{{ leader.reviewer__user__username }}"
width="50px"
height="50px">
{% elif leader.reviewer__user__email %}
<img src="{% gravatar_url leader.reviewer__user__email 50 %}"
class=" size-11 select-none border border-gray-200 rounded-full"
alt="username"
width="50px"
height="50px">
{% else %}
<img src="{% gravatar_url leader.reviews__reviewer__user__email 50 %}"
<img src="{% gravatar_url 'default@example.com' 50 %}"
class=" size-11 select-none border border-gray-200 rounded-full"
alt="username"
width="50px"
height="50px">
{% endif %}
<a href="{% url 'profile' slug=leader.reviews__reviewer__user__username %}"
class="text-lg transition-all duration-200">
{{ leader.reviews__reviewer__user__username }}
</a>
<a href="https://github.com/{{ leader.reviews__reviewer__user__username }}"
target="_blank"
class="ml-2">
<i class="fab fa-github text-xl"></i>
</a>
{% if leader.reviewer__user__username %}
<a href="{% url 'profile' slug=leader.reviewer__user__username %}"
class="text-lg transition-all duration-200">
{{ leader.reviewer__user__username }}
</a>
{% if leader.reviewer__github_url %}
<a href="{{ leader.reviewer__github_url }}" target="_blank" class="ml-2">
<i class="fab fa-github text-xl"></i>
</a>
{% endif %}
{% else %}
<span class="text-lg text-gray-500">Unknown User</span>
{% endif %}
</div>
<span class="pull-right badge bg-gray-100 flex-shrink-0 rounded-md py-1 px-2 select-none">Reviews: {{ leader.total_reviews }}</span>
</div>
<div class="border-t border-gray-200 my-1"></div>
{% endfor %}
</div>
{% else %}
<p class="text-red-500 text-center font-medium">No code review data available!</p>
<p class="text-[#e74c3c] text-center font-medium">No code review data available!</p>
{% endif %}
</div>
</div>
</div>
<div class="flex justify-center gap-6 flex-wrap">
<div class="flex-1 border-2 border-gray-300 pb-3 rounded-b-lg flex-1 min-w-[300px] max-w-[550px]">
<div class="text-center text-3xl font-bold py-4 border-2 border-red-500 rounded-t-lg">Top Visitors</div>
<div class="flex-1 border-2 border-[#e74c3c] pb-3 rounded-lg flex-1 min-w-[300px] max-w-[550px]">
<div class="text-center text-3xl font-bold py-4 border-b-2 border-[#e74c3c] rounded-t-lg">Top Visitors</div>
<div class="list-group w-full p-4">
{% if top_visitors %}
<div class="flex flex-col gap-2">
Expand All @@ -165,13 +190,13 @@ <h1 class="page-header">Global Leaderboard</h1>
<div class="flex gap-2 items-center truncate">
{% if profile.avatar %}
<img src="{{ profile.avatar }}"
class="size-11 select-none border border-gray-200 rounded-full rounded-full"
class="size-11 select-none border border-gray-200 rounded-full"
alt="{{ profile.user.username }}"
width="50px"
height="50px">
{% else %}
<img src="{% gravatar_url profile.user.email 50 %}"
class="size-11 select-none border border-gray-200 rounded-full rounded-full"
class="size-11 select-none border border-gray-200 rounded-full"
alt="{{ profile.user.username }}"
width="50px"
height="50px">
Expand All @@ -188,24 +213,24 @@ <h1 class="page-header">Global Leaderboard</h1>
{% endfor %}
</div>
{% else %}
<p class="text-red-500 text-center font-medium">No visitor data available!</p>
<p class="text-[#e74c3c] text-center font-medium">No visitor data available!</p>
{% endif %}
</div>
</div>
<div class=" flex-1 border-2 border-gray-300 pb-3 rounded-b-lg flex-1 min-w-[300px] max-w-[550px]">
<div class="text-center text-3xl font-bold py-4 border-2 border-red-500 rounded-t-lg">Issue Bounties</div>
<div class=" flex-1 border-2 border-[#e74c3c] pb-3 rounded-lg flex-1 min-w-[300px] max-w-[550px]">
<div class="text-center text-3xl font-bold py-4 border-b-2 border-[#e74c3c] rounded-t-lg">Issue Bounties</div>
<div class=" list-group w-full p-4">
{% if not issue_bounties %}
<p class="text-red-500 text-center font-medium">No issue bounties data available!</p>
<p class="text-[#e74c3c] text-center font-medium">No issue bounties data available!</p>
{% else %}
{% endif %}
</div>
</div>
<div class=" flex-1 border-2 border-gray-300 pb-3 rounded-b-lg flex-1 min-w-[300px] max-w-[550px]">
<div class="text-center text-3xl font-bold py-4 border-2 border-red-500 rounded-t-lg">Bug Bounties</div>
<div class=" flex-1 border-2 border-[#e74c3c] pb-3 rounded-lg flex-1 min-w-[300px] max-w-[550px]">
<div class="text-center text-3xl font-bold py-4 border-b-2 border-[#e74c3c] rounded-t-lg">Bug Bounties</div>
<div class=" list-group w-full p-4">
{% if not bug_bounties %}
<p class="text-red-500 text-center font-medium">No bug bounties data available!</p>
<p class="text-[#e74c3c] text-center font-medium">No bug bounties data available!</p>
{% else %}
{% endif %}
</div>
Expand Down
11 changes: 11 additions & 0 deletions website/templatetags/string_filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django import template

register = template.Library()


@register.filter
def split(value, arg):
"""Split a string by the given separator."""
if value:
return value.split(arg)
return []
62 changes: 59 additions & 3 deletions website/views/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,41 @@
logger = logging.getLogger(__name__)


def extract_github_username(github_url):
"""
Extract GitHub username from a GitHub URL for avatar display.

Args:
github_url (str): GitHub URL like 'https://github.com/username' or 'https://github.com/apps/dependabot'

Returns:
str or None: The username part of the URL, or None if invalid/empty
"""
if not github_url or not isinstance(github_url, str):
return None

# Strip trailing slashes and whitespace
github_url = github_url.strip().rstrip("/")

# Validate that this is a GitHub URL
if not github_url.startswith(("https://github.com/", "http://github.com/")):
return None

# Ensure URL contains at least one slash after the domain
if "/" not in github_url:
return None

# Split on "/" and get the last segment
segments = github_url.split("/")
username = segments[-1] if segments else None

# Return username only if it's non-empty and not just domain parts
if username and username not in ["github.com", "www.github.com", ""]:
return username

return None


@receiver(user_signed_up)
def handle_user_signup(request, user, **kwargs):
referral_token = request.session.get("ref")
Expand Down Expand Up @@ -480,9 +515,15 @@ def get_context_data(self, *args, **kwargs):

context["leaderboard"] = self.get_leaderboard()[:10] # Limit to 10 entries

# Pull Request Leaderboard
# Pull Request Leaderboard - Only show PRs from tracked repositories
pr_leaderboard = (
GitHubIssue.objects.filter(type="pull_request", is_merged=True)
GitHubIssue.objects.filter(
type="pull_request",
is_merged=True,
repo__isnull=False, # Only include PRs from tracked repositories
)
.exclude(user_profile__isnull=True) # Exclude PRs without user profiles
.select_related("user_profile__user", "repo") # Optimize database queries
.values(
"user_profile__user__username",
"user_profile__user__email",
Expand All @@ -491,18 +532,33 @@ def get_context_data(self, *args, **kwargs):
.annotate(total_prs=Count("id"))
.order_by("-total_prs")[:10]
)
# Extract GitHub username from URL for avatar display
# Note: Processing in a loop is acceptable here since we're limited to top 10 entries
# and URL parsing cannot be done efficiently in the database
for leader in pr_leaderboard:
github_username = extract_github_username(leader.get("user_profile__github_url"))
if github_username:
leader["github_username"] = github_username
context["pr_leaderboard"] = pr_leaderboard

# Reviewed PR Leaderboard - Fixed query to properly count reviews
reviewed_pr_leaderboard = (
GitHubReview.objects.values(
GitHubReview.objects.filter(reviewer__user__isnull=False)
.values(
"reviewer__user__username",
"reviewer__user__email",
"reviewer__github_url",
)
.annotate(total_reviews=Count("id"))
.order_by("-total_reviews")[:10]
)
# Extract GitHub username from URL for avatar display
# Note: Processing in a loop is acceptable here since we're limited to top 10 entries
# and URL parsing cannot be done efficiently in the database
for leader in reviewed_pr_leaderboard:
github_username = extract_github_username(leader.get("reviewer__github_url"))
if github_username:
leader["github_username"] = github_username
context["code_review_leaderboard"] = reviewed_pr_leaderboard

# Top visitors leaderboard
Expand Down
Loading