BLT icon indicating copy to clipboard operation
BLT copied to clipboard

move the leaderboard from the gsoc page to the organization detail page have it only show on the owasp organization for now

Open DonnieBLT opened this issue 9 months ago • 3 comments

DonnieBLT avatar Mar 25 '25 17:03 DonnieBLT

/assign

rinkitadhana avatar Mar 25 '25 17:03 rinkitadhana

Hello @rinkitadhana! You've been assigned to OWASP-BLT/BLT issue #4050. You have 24 hours to complete a pull request.

github-actions[bot] avatar Mar 25 '25 17:03 github-actions[bot]

⏰ This issue has been automatically unassigned due to 24 hours of inactivity. The issue is now available for anyone to work on again.

github-actions[bot] avatar Mar 26 '25 18:03 github-actions[bot]

@DonnieBLT Could you please explain a bit more about what you want? Maybe with an example? Also, do you want the leaderboard to be completely removed from the /gsoc page?

rinkitadhana avatar Apr 14 '25 21:04 rinkitadhana

@rinkitadhana it's essentially to move the same logic on to the organization page you could make it work for all organizations now (no need to restrict it to owasp) and yes to remove it from the gsoc page.

DonnieBLT avatar Apr 15 '25 19:04 DonnieBLT

@coderabbitai Could you please clarify the expected behavior for this issue and suggest a rough plan to approach it?

rinkitadhana avatar Apr 17 '25 01:04 rinkitadhana

[!TIP] For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's fetch the issue description
gh issue view 4050 --repo OWASP-BLT/BLT

Length of output: 275


🏁 Script executed:

#!/bin/bash
# Look for files related to GSOC page
echo "Files related to GSOC page:"
rg -l "gsoc" --type-not=binary --type-not=lock

# Look for files related to organization detail page
echo -e "\nFiles related to organization detail page:"
rg -l "organization.*detail" --type-not=binary --type-not=lock

# Look for leaderboard implementations
echo -e "\nFiles related to leaderboard:"
rg -l "leaderboard" --type-not=binary --type-not=lock

Length of output: 499


🏁 Script executed:

#!/bin/bash
# Get an overview of the repository structure
ls -la

# Look for Python files since this appears to be a Django project
echo -e "\nPython files in the repository:"
find . -name "*.py" | grep -v "__pycache__" | sort

Length of output: 22706


🏁 Script executed:

#!/bin/bash
# Look for GSOC related views
echo "GSOC related view files:"
rg -l "gsoc" ./website/views

# Look for organization detail views
echo -e "\nOrganization detail view files:"
rg -l "organization" ./website/views | grep detail

# Look for leaderboard implementations in view files
echo -e "\nLeaderboard implementations in views:"
rg -l "leaderboard" ./website/views

# Look for template files related to GSOC
echo -e "\nTemplate files related to GSOC:"
find ./website -path "*/templates/*.html" -type f -exec grep -l "gsoc" {} \; 2>/dev/null || echo "No GSOC templates found"

# Look for template files related to organization detail
echo -e "\nTemplate files related to organization detail:"
find ./website -path "*/templates/*.html" -type f -exec grep -l "organization.*detail" {} \; 2>/dev/null || echo "No organization detail templates found"

# Look for template files with leaderboard
echo -e "\nTemplate files with leaderboard:"
find ./website -path "*/templates/*.html" -type f -exec grep -l "leaderboard" {} \; 2>/dev/null || echo "No leaderboard templates found"

Length of output: 2837


🏁 Script executed:

#!/bin/bash
# Check the GSOC template
echo "Content of GSOC template:"
cat ./website/templates/gsoc.html

# Check the implementation of the GSOC view in views
echo -e "\nGSOC view implementation:"
rg -A 20 "def gsoc" ./website/views/

# Check the organization detail template
echo -e "\nContent of organization detail template:"
cat ./website/templates/organization/organization_detail.html

# Check the organization view implementation
echo -e "\nOrganization detail view implementation:"
rg -A 20 "def organization_detail" ./website/views/

Length of output: 86109


🏁 Script executed:

#!/bin/bash
# Look for the implementation of gsoc view
echo "Looking for gsoc view implementation:"
rg -A 10 'def gsoc\b' ./website/views/

# Look for organization_detail view implementation
echo -e "\nLooking for organization_detail view implementation:"
rg -A 10 'def organization_detail\b' ./website/views/

# Look for any leaderboard related functions in views
echo -e "\nLooking for leaderboard related functions in views:"
rg -A 10 'leaderboard' ./website/views/ | grep "def"

Length of output: 1189


🏁 Script executed:

#!/bin/bash
# First let's find the GSOC view implementation
echo "Looking for view that renders the gsoc template:"
rg -A 5 "render.*gsoc\.html" ./website/views/

# Look for code that populates the projects variable for the GSOC template
echo -e "\nLooking for code that populates projects variable for GSOC template:"
rg -A 10 "projects.*=" ./website/views/

# Check for management commands related to gsoc
echo -e "\nGSOC management commands:"
find ./website/management/commands/ -name "*gsoc*" -type f -exec cat {} \;

# Check organization view implementation
echo -e "\nOrganization detail view implementation:"
rg -B 5 -A 20 "organization_detail" ./website/views/organization.py

Length of output: 40687


@rinkitadhana Based on my analysis of the codebase, I can clarify the requirements and suggest a plan for issue #4050:

Current Implementation

The GSOC page (/gsoc) currently has a leaderboard section titled "Top OWASP GSoC 2025 Contributors and Projects" that shows:

  • Projects with their total PR counts
  • Contributors for each project with their PR counts
  • Visual representation with avatars and links to GitHub

Expected Behavior

  1. Move this leaderboard functionality from the GSOC page to the organization detail page
  2. Make it work for all organizations (not just OWASP)
  3. Remove the leaderboard section from the GSOC page entirely

Implementation Plan

  1. Move Leaderboard Logic

    • Identify the code in website/views/issue.py that populates the GSOC leaderboard data
    • Adapt this logic to work in OrganizationDetailView in website/views/organization.py
    • Modify the code to filter projects and PRs based on the specific organization being viewed
  2. Update Organization Detail Template

    • Add a new section in organization/organization_detail.html for the leaderboard
    • Include similar styling and functionality as the GSOC leaderboard
    • Ensure it works with the adapted view logic
  3. Remove from GSOC Page

    • Remove the leaderboard section from the gsoc.html template
  4. Add Management Commands (if needed)

    • Adapt or create management commands to fetch PR data for all organizations, not just GSOC

This change will enhance the organization detail page by showing project contributions and top contributors in a more visual and interactive way, similar to how it's currently shown on the GSOC page.

coderabbitai[bot] avatar Apr 17 '25 01:04 coderabbitai[bot]

@coderabbitai code this

rinkitadhana avatar Apr 18 '25 17:04 rinkitadhana

[!TIP] For best results, initiate chat on the files or code changes.

A summary of the edits CodeRabbit can apply:

We will update website/views/organization.py to compute and pass leaderboard data (top_projects and top_contributors) for any organization.

We will modify organization_detail.html to make the leaderboard headings dynamic by including the organization's name.

We will remove the Top Contributors Leaderboard section from website/templates/gsoc.html.

We will enhance the organization_detail view in website/views/organization.py to compute and pass projects for the new leaderboard.

We will insert the Top Contributors and Projects leaderboard section into website/templates/organization/organization_detail.html.

We will create a new module website/utils/leaderboard.py to encapsulate the leaderboard data computation for any organization.

We will modify website/views/organization.py to include the organization-specific leaderboard data in its view context.

We will remove the GSOC-specific leaderboard logic from website/views/issue.py.

We will remove the leaderboard section from website/templates/gsoc.html.

A plan of each step that CodeRabbit will take in order to execute the edits for each file (with inline rough draft snippets):

✏️ website/views/organization.py

Add the necessary imports at the top of the file:


from django.db.models import Count
from website.models import PullRequest, Repository

Inside the organization_detail function, just before the return statement, insert the leaderboard computation logic adapted from the GSOC view:


# Leaderboard: top projects by PR count in this organization
org_projects = Repository.objects.filter(organization=organization)
org_projects = org_projects.annotate(pr_count=Count('pullrequest', distinct=True))
leaderboard_projects = org_projects.order_by('-pr_count')[:5]

# Leaderboard: top contributors across those projects
contributors_qs = PullRequest.objects.filter(repository__in=org_projects).values(
    'user__login', 'user__avatar_url'
).annotate(contributions=Count('id')).order_by('-contributions')[:5]
leaderboard_contributors = [
    {
        'username': c['user__login'],
        'avatar_url': c['user__avatar_url'],
        'contributions': c['contributions'],
        'github_url': f"https://github.com/{c['user__login']}"
    }
    for c in contributors_qs
]

context.update({
    'top_projects': leaderboard_projects,
    'top_contributors': leaderboard_contributors,
})

Save the file and restart the Django development server. Visit any organization detail page and verify the leaderboard appears correctly.

✏️ website/templates/organization/organization_detail.html

Replace the static Projects heading at line 455:


<h2 class="text-xl font-semibold text-gray-900">Top {{ organization.name }} Projects</h2>

Replace the static Contributors heading at line 508:


<h2 class="text-xl font-semibold text-gray-900 mb-4">Top {{ organization.name }} Contributors</h2>

Save the changes and reload the organization detail page to confirm the headings now reflect the current organization’s name.

➖ website/templates/gsoc.html

Open website/templates/gsoc.html and delete lines 244 through 306, which encompass the entire Top Contributors Leaderboard block.

✏️ website/views/organization.py

At the top of the file, ensure the following imports appear:

from django.db.models import Count
from .models import Project, PullRequest

Inside the organization_detail function, immediately after retrieving organization, insert:

# Build leaderboard data for this organization
projects = Project.objects.filter(organization=organization)
projects_data = {}
for project in projects:
    prs = PullRequest.objects.filter(repository__project=project)
    total_prs = prs.count()
    contributors_data = prs.values('author__login', 'author__avatar_url')\
                            .annotate(prs=Count('id')).order_by('-prs')[:5]
    projects_data[project.name] = {
        'repo_url': project.repository_url,
        'total_prs': total_prs,
        'contributors': contributors_data
    }

Update the render call to pass projects_data as projects:

return render(request, 'organization/organization_detail.html', {
    'organization': organization,
    'contributors': contributors,
    'projects': projects_data,
})
➕ website/templates/organization/organization_detail.html

After line 49 (the comment <!-- End Existing Contributors Section -->), insert the following block:

<!-- Top Contributors and Projects Leaderboard -->
<div class="bg-white rounded-xl shadow-lg hover:shadow-xl transition-all duration-300 p-8 mb-12 border-l-4 border-red-500">
    <h2 class="text-3xl font-bold text-gray-900 mb-6">Top {{ organization.name }} Contributors and Projects</h2>
    <p class="text-gray-700 mb-4">A glimpse of the top contributors and projects with the most PRs for {{ organization.name }}.</p>
    <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
        {% for project, data in projects.items %}
            <div class="bg-gray-50 rounded-lg p-6">
                <div class="flex justify-between items-center mb-4">
                    <a href="{{ data.repo_url }}" target="_blank" class="text-xl font-semibold text-gray-900">
                        {{ project }} - Total PRs:
                        <span class="text-red-600 font-bold">{{ data.total_prs }}</span>
                    </a>
                </div>
                <div class="space-y-3">
                    {% for contributor in data.contributors %}
                        <div class="flex items-center justify-between p-2 hover:bg-gray-100 rounded">
                            <div class="flex items-center">
                                <img src="{{ contributor.avatar_url }}" alt="{{ contributor.login }}" class="w-8 h-8 rounded-full mr-3" width="32" height="32">
                                <a href="https://github.com/{{ contributor.login }}" target="_blank" class="text-gray-700 hover:text-red-600">{{ contributor.login }}</a>
                            </div>
                            <span class="bg-red-100 text-red-800 text-sm font-medium px-2.5 py-0.5 rounded">
                                {{ contributor.prs }} PR{% if contributor.prs != 1 %}s{% endif %}
                            </span>
                        </div>
                    {% empty %}
                        <p class="text-gray-500 italic">No contributors in this period</p>
                    {% endfor %}
                </div>
            </div>
        {% endfor %}
    </div>
</div>

Verify indentation matches surrounding HTML, and confirm that the projects variable is available thanks to the updated view.

📄 website/utils/leaderboard.py

Create the directory website/utils if it does not already exist.


In website/utils/leaderboard.py, write the following code:

from django.db.models import Count
from website.models import Project, PullRequest

def get_organization_leaderboard_data(org_slug, top_projects=5, top_contributors=5):
    # Annotate projects with total pull request counts
    projects = (
        Project.objects
        .filter(organization__slug=org_slug)
        .annotate(pr_count=Count('pullrequest'))
        .order_by('-pr_count')[:top_projects]
    )

    leaderboard = []
    for project in projects:
        # Annotate top contributors for each project
        contributors_qs = (
            PullRequest.objects
            .filter(project=project)
            .values('author__login')
            .annotate(pr_count=Count('id'))
            .order_by('-pr_count')[:top_contributors]
        )
        leaderboard.append({
            'project': project,
            'pr_count': project.pr_count,
            'top_contributors': list(contributors_qs),
        })

    return leaderboard
✏️ website/views/organization.py

At the top of the file, add:

from website.utils.leaderboard import get_organization_leaderboard_data

Inside the get method, after setting context['projects'], insert:

# Compute and inject the leaderboard for this organization
leaderboard = get_organization_leaderboard_data(organization.slug)
context['leaderboard'] = leaderboard

Ensure the final render call is:

return render(request, 'organization/organization_detail.html', context)
✏️ website/views/issue.py

Delete or comment out:

# GSOC leaderboard logic
projects = Project.objects.filter(organization__slug='owasp').annotate(pr_count=Count('pullrequest')).order_by('-pr_count')
contributors = PullRequest.objects.filter(project__in=projects).values('author__login').annotate(pr_count=Count('id')).order_by('-pr_count')[:10]
return render(request, 'gsoc.html', {'projects': projects, 'contributors': contributors})

Replace it with:

return render(request, 'gsoc.html', context)
✏️ website/templates/gsoc.html

Delete the block:

<!-- Leaderboard Section -->
<section id="leaderboard">
  <h2>Top OWASP GSoC 2025 Contributors and Projects</h2>
  ... 
</section>

Verify the surrounding HTML remains valid and that the template still renders.

A summary of the context that CodeRabbit is considering across the codebase:

We need to extract the GSOC leaderboard logic so we can reuse it in the OrganizationDetailView for any organization.

We need to find the organization_detail view implementation so we know where to insert the leaderboard data.

We need to pinpoint the exact lines in the organization_detail template where the static headings appear, so we can make them dynamic.

Extract the GSOC view logic to see how the projects context variable is built for the leaderboard.

Locate the organization_detail view to extend it with the leaderboard logic.

Identify the lines in gsoc.html that render the Top Contributors Leaderboard so we can delete them.

Locate the insertion point in organization_detail.html right after the existing Contributors section.

We need to locate the GSOC leaderboard logic in the GSOC view so we can extract it and then remove it from the GSOC page.

We need to find the leaderboard section in the GSOC template so we can remove the HTML block.

We need to identify where to inject the leaderboard in the organization detail view.

  • [ ] ✅ Create PR with these edits

  • [ ] 📋 Get copyable edits

  • [ ] 🔄 Try a different approach

  • [ ] ⏪ Go back to ordinary chat

coderabbitai[bot] avatar Apr 18 '25 17:04 coderabbitai[bot]

@ explain what needs to be done

Krishiv-Mahajan avatar Nov 13 '25 12:11 Krishiv-Mahajan

WIP /assign

mdkaifansari04 avatar Nov 22 '25 13:11 mdkaifansari04

⚠️ This issue is already assigned to @Copilot. Please pick another issue.

github-actions[bot] avatar Nov 22 '25 13:11 github-actions[bot]