diff --git a/website/templates/home.html b/website/templates/home.html index f08128ab4..62d881c42 100644 --- a/website/templates/home.html +++ b/website/templates/home.html @@ -77,7 +77,7 @@

Get Involved

class="bg-green-500 text-white font-semibold py-3 px-6 rounded-full"> Join the Community - Explore Projects diff --git a/website/templates/includes/sidenav.html b/website/templates/includes/sidenav.html index 9069401ee..2b97f5bea 100644 --- a/website/templates/includes/sidenav.html +++ b/website/templates/includes/sidenav.html @@ -138,7 +138,7 @@
  • -
    diff --git a/website/templates/projects/repo_detail.html b/website/templates/projects/repo_detail.html index 36c55a5f5..1a3b911c3 100644 --- a/website/templates/projects/repo_detail.html +++ b/website/templates/projects/repo_detail.html @@ -1,7 +1,9 @@ {% extends "base.html" %} {% load humanize %} {% load static %} -{% block title %}{{ repo.name }} - Repo Details{% endblock %} +{% block title %} + {{ repo.name }} - Repo Details +{% endblock title %} {% block content %} {% include "includes/sidenav.html" %} @@ -95,18 +97,26 @@

    {{ repo.name }}

    Standard Repository {% endif %} - {% if repo.tags.all %} -
    - Tags: - {% for tag in repo.tags.all %} - {{ tag.name }} - {% endfor %} +
    + Tags: + {% for tag in repo.tags.all %} + {{ tag.name }} + {% endfor %} +
    +
    - {% endif %} +
    Created {{ repo.created|date:"M d, Y" }}
    -
    Updated {{ repo.last_updated|naturaltime }}
    +
    Updated {{ repo.last_updated|naturaltime }}
    @@ -120,7 +130,7 @@

    {{ repo.name }}

    -

    {{ repo.stars|intcomma }}

    +

    {{ repo.stars|intcomma }}

    @@ -129,7 +139,7 @@

    {{ repo.name }}

    -

    {{ repo.forks|intcomma }}

    +

    {{ repo.forks|intcomma }}

    @@ -141,7 +151,7 @@

    {{ repo.name }}

    -

    {{ repo.watchers|intcomma }}

    +

    {{ repo.watchers|intcomma }}

    @@ -152,7 +162,7 @@

    {{ repo.name }}

    -

    {{ repo.network_count|intcomma }}

    +

    {{ repo.network_count|intcomma }}

    @@ -163,7 +173,7 @@

    {{ repo.name }}

    -

    {{ repo.subscribers_count|intcomma }}

    +

    {{ repo.subscribers_count|intcomma }}

    @@ -174,14 +184,26 @@

    {{ repo.name }}

    -

    - - - - Activity Metrics -

    +
    +

    + + + + Activity Metrics +

    +
    + +
    +
    @@ -202,17 +224,17 @@

    Issues

    Open - {{ repo.open_issues|intcomma }} + {{ repo.open_issues|intcomma }}
    Closed - {{ repo.closed_issues|intcomma }} + {{ repo.closed_issues|intcomma }}
    Total - {{ repo.total_issues|intcomma }} + {{ repo.total_issues|intcomma }}
    @@ -235,7 +257,10 @@

    Pull Requests

    -
    {{ repo.open_pull_requests|intcomma }}
    +
    + {{ repo.open_pull_requests|intcomma }} +
    Open PRs
    @@ -259,7 +284,7 @@

    Commits

    -
    {{ repo.commit_count|intcomma }}
    +
    {{ repo.commit_count|intcomma }}
    Total Commits
    @@ -268,7 +293,8 @@

    Commits

    viewBox="0 0 20 20"> - Last: {{ repo.last_commit_date|date:"M d, Y" }} + Last: + {{ repo.last_commit_date|date:"M d, Y" }}
    @@ -279,14 +305,24 @@

    Commits

    -

    - - - - Community -

    +
    +

    + + + + Community +

    + +
    @@ -357,14 +393,24 @@

    Top Contributors

    -

    - - - - Technical Overview -

    +
    +

    + + + + Technical Overview +

    + +
    @@ -524,4 +570,128 @@

    -{% endblock %} + +{% endblock content %} +{% block after_js %} + +{% endblock after_js %} diff --git a/website/templates/sitemap.html b/website/templates/sitemap.html index 1fd1cf2e7..f7a06af32 100644 --- a/website/templates/sitemap.html +++ b/website/templates/sitemap.html @@ -102,7 +102,7 @@

    Sitemap

  • - Projects + Projects
  • diff --git a/website/views/project.py b/website/views/project.py index e53061582..5bc5b3194 100644 --- a/website/views/project.py +++ b/website/views/project.py @@ -925,3 +925,188 @@ def get_context_data(self, **kwargs): ] return context + + def post(self, request, *args, **kwargs): + def get_issue_count(full_name, query, headers): + search_url = f"https://api.github.com/search/issues?q=repo:{full_name}+{query}" + resp = requests.get(search_url, headers=headers) + if resp.status_code == 200: + return resp.json().get("total_count", 0) + return 0 + + repo = self.get_object() + section = request.POST.get("section") + + if section == "basic": + try: + # Get GitHub API token + github_token = getattr(settings, "GITHUB_TOKEN", None) + if not github_token: + return JsonResponse( + {"status": "error", "message": "GitHub token not configured"}, status=500 + ) + + # Extract owner/repo from GitHub URL + match = re.match(r"https://github.com/([^/]+)/([^/]+)/?", repo.repo_url) + if not match: + return JsonResponse( + {"status": "error", "message": "Invalid repository URL"}, status=400 + ) + + owner, repo_name = match.groups() + api_url = f"https://api.github.com/repos/{owner}/{repo_name}" + + # Make GitHub API request + headers = { + "Authorization": f"token {github_token}", + "Accept": "application/vnd.github.v3+json", + } + response = requests.get(api_url, headers=headers) + + if response.status_code == 200: + data = response.json() + + # Update repo with fresh data + repo.stars = data.get("stargazers_count", 0) + repo.forks = data.get("forks_count", 0) + repo.watchers = data.get("watchers_count", 0) + repo.open_issues = data.get("open_issues_count", 0) + repo.network_count = data.get("network_count", 0) + repo.subscribers_count = data.get("subscribers_count", 0) + repo.last_updated = parse_datetime(data.get("updated_at")) + repo.save() + + return JsonResponse( + { + "status": "success", + "message": "Basic information updated successfully", + "data": { + "stars": repo.stars, + "forks": repo.forks, + "watchers": repo.watchers, + "network_count": repo.network_count, + "subscribers_count": repo.subscribers_count, + "last_updated": naturaltime(repo.last_updated).replace( + "\xa0", " " + ), # Fix unicode space + }, + } + ) + else: + return JsonResponse( + {"status": "error", "message": f"GitHub API error: {response.status_code}"}, + status=response.status_code, + ) + + except Exception as e: + return JsonResponse({"status": "error", "message": str(e)}, status=500) + + elif section == "metrics": + try: + github_token = getattr(settings, "GITHUB_TOKEN", None) + if not github_token: + return JsonResponse( + {"status": "error", "message": "GitHub token not configured"}, status=500 + ) + + match = re.match(r"https://github.com/([^/]+)/([^/]+)/?", repo.repo_url) + if not match: + return JsonResponse( + {"status": "error", "message": "Invalid repository URL"}, status=400 + ) + + # Extract owner and repo from API call + owner, repo_name = match.groups() + api_url = f"https://api.github.com/repos/{owner}/{repo_name}" + headers = { + "Authorization": f"token {github_token}", + "Accept": "application/vnd.github.v3+json", + } + response = requests.get(api_url, headers=headers) + + if response.status_code != 200: + return JsonResponse( + {"status": "error", "message": "Failed to fetch repository data"}, + status=500, + ) + + repo_data = response.json() + full_name = repo_data.get("full_name") + default_branch = repo_data.get("default_branch") + if not full_name: + return JsonResponse( + {"status": "error", "message": "Could not get repository full name"}, + status=500, + ) + + full_name = full_name.replace(" ", "+") + + # get the total commit + url = f"https://api.github.com/repos/{full_name}/commits" + params = {"per_page": 1, "page": 1} + response = requests.get(url, headers=headers, params=params) + if response.status_code == 200: + if "Link" in response.headers: + links = response.headers["Link"] + last_page = 1 + for link in links.split(","): + if 'rel="last"' in link: + last_page = int(link.split("&page=")[1].split(">")[0]) + commit_count = last_page + else: + commits = response.json() + total_commits = len(commits) + commit_count = total_commits + else: + commit_count = 0 + + # Get open issues and PRs + open_issues = get_issue_count(full_name, "type:issue+state:open", headers) + closed_issues = get_issue_count(full_name, "type:issue+state:closed", headers) + open_pull_requests = get_issue_count(full_name, "type:pr+state:open", headers) + total_issues = open_issues + closed_issues + + if ( + repo.open_issues != open_issues + or repo.closed_issues != closed_issues + or repo.total_issues != total_issues + or repo.open_pull_requests != open_pull_requests + or repo.commit_count != commit_count + ): + # Update repository metrics + repo.open_issues = open_issues + repo.closed_issues = closed_issues + repo.total_issues = total_issues + repo.open_pull_requests = open_pull_requests + repo.commit_count = commit_count + + commits_url = f"{api_url}/commits?sha={default_branch}&per_page=1" + commits_response = requests.get(commits_url, headers=headers) + if commits_response.status_code == 200: + commit_data = commits_response.json() + if commit_data: + date_str = commit_data[0]["commit"]["committer"]["date"] + repo.last_commit_date = parse_datetime(date_str) + repo.save() + + return JsonResponse( + { + "status": "success", + "message": "Activity metrics updated successfully", + "data": { + "open_issues": repo.open_issues, + "closed_issues": repo.closed_issues, + "total_issues": repo.total_issues, + "open_pull_requests": repo.open_pull_requests, + "commit_count": repo.commit_count, + "last_commit_date": repo.last_commit_date.strftime("%b %d, %Y") + if repo.last_commit_date + else "", + }, + } + ) + + except Exception as e: + return JsonResponse({"status": "error", "message": str(e)}, status=500) + + return super().post(request, *args, **kwargs)