aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site
diff options
context:
space:
mode:
authorGravatar Leon Sandøy <[email protected]>2020-12-13 15:44:14 +0100
committerGravatar GitHub <[email protected]>2020-12-13 15:44:14 +0100
commit9ae514e76c1899b965323e427ef04e1812a6a5c0 (patch)
tree720ad10140b777c97984f7fae8d554136cdcecb1 /pydis_site
parentFix incorrectly specified environment variable (diff)
parentRemove pointless try/except. (diff)
Merge pull request #435 from python-discord/hotfix/lemon/front-page-project-sanity
Hotfix: Add some sanity to frontpage projects.
Diffstat (limited to 'pydis_site')
-rw-r--r--pydis_site/apps/home/tests/test_repodata_helpers.py8
-rw-r--r--pydis_site/apps/home/views/home.py147
-rw-r--r--pydis_site/templates/home/index.html98
3 files changed, 127 insertions, 126 deletions
diff --git a/pydis_site/apps/home/tests/test_repodata_helpers.py b/pydis_site/apps/home/tests/test_repodata_helpers.py
index 77b1a68d..34bbdcde 100644
--- a/pydis_site/apps/home/tests/test_repodata_helpers.py
+++ b/pydis_site/apps/home/tests/test_repodata_helpers.py
@@ -123,10 +123,4 @@ class TestRepositoryMetadataHelpers(TestCase):
mock_get.return_value.json.return_value = ['garbage']
metadata = self.home_view._get_repo_data()
- self.assertEquals(len(metadata), len(self.home_view.repos))
- for item in metadata:
- with self.subTest(item=item):
- self.assertEqual(item.description, "Not available.")
- self.assertEqual(item.forks, 999)
- self.assertEqual(item.stargazers, 999)
- self.assertEqual(item.language, "Python")
+ self.assertEquals(len(metadata), 0)
diff --git a/pydis_site/apps/home/views/home.py b/pydis_site/apps/home/views/home.py
index c1c2055c..97253a0c 100644
--- a/pydis_site/apps/home/views/home.py
+++ b/pydis_site/apps/home/views/home.py
@@ -1,4 +1,4 @@
-import datetime
+import logging
from typing import Dict, List
import requests
@@ -10,6 +10,8 @@ from django.views import View
from pydis_site.apps.home.models import RepositoryMetadata
+log = logging.getLogger(__name__)
+
class HomeView(View):
"""The main landing page for the website."""
@@ -28,76 +30,88 @@ class HomeView(View):
]
def _get_api_data(self) -> Dict[str, Dict[str, str]]:
- """Call the GitHub API and get information about our repos."""
- repo_dict: Dict[str, dict] = {repo_name: {} for repo_name in self.repos}
+ """
+ Call the GitHub API and get information about our repos.
+
+ If we're unable to get that info for any reason, return an empty dict.
+ """
+ repo_dict = {}
# Fetch the data from the GitHub API
api_data: List[dict] = requests.get(self.github_api).json()
# Process the API data into our dict
for repo in api_data:
- full_name = repo["full_name"]
-
- if full_name in self.repos:
- repo_dict[full_name] = {
- "full_name": repo["full_name"],
- "description": repo["description"],
- "language": repo["language"],
- "forks_count": repo["forks_count"],
- "stargazers_count": repo["stargazers_count"],
- }
+ try:
+ full_name = repo["full_name"]
+
+ if full_name in self.repos:
+ repo_dict[full_name] = {
+ "full_name": repo["full_name"],
+ "description": repo["description"],
+ "language": repo["language"],
+ "forks_count": repo["forks_count"],
+ "stargazers_count": repo["stargazers_count"],
+ }
+ # Something is not right about the API data we got back from GitHub.
+ except (TypeError, ConnectionError, KeyError) as e:
+ log.error(
+ "Unable to parse the GitHub repository metadata from response!",
+ extra={
+ 'api_data': api_data,
+ 'error': e
+ }
+ )
+ continue
return repo_dict
def _get_repo_data(self) -> List[RepositoryMetadata]:
"""Build a list of RepositoryMetadata objects that we can use to populate the front page."""
- # Try to get site data from the cache
- try:
- repo_data = RepositoryMetadata.objects.get(repo_name="python-discord/site")
+ database_repositories = []
- # If the data is stale, we should refresh it.
- if (timezone.now() - repo_data.last_updated).seconds > self.repository_cache_ttl:
+ # First, let's see if we have any metadata cached.
+ cached_data = RepositoryMetadata.objects.all()
- # Try to get new data from the API. If it fails, return the cached data.
- try:
- api_repositories = self._get_api_data()
- except (TypeError, ConnectionError):
- return RepositoryMetadata.objects.all()
- database_repositories = []
-
- # Update or create all RepoData objects in self.repos
- for repo_name, api_data in api_repositories.items():
- try:
- repo_data = RepositoryMetadata.objects.get(repo_name=repo_name)
- repo_data.description = api_data["description"]
- repo_data.language = api_data["language"]
- repo_data.forks = api_data["forks_count"]
- repo_data.stargazers = api_data["stargazers_count"]
- except RepositoryMetadata.DoesNotExist:
- repo_data = RepositoryMetadata(
- repo_name=api_data["full_name"],
- description=api_data["description"],
- forks=api_data["forks_count"],
- stargazers=api_data["stargazers_count"],
- language=api_data["language"],
- )
- repo_data.save()
- database_repositories.append(repo_data)
- return database_repositories
-
- # Otherwise, if the data is fresher than 2 minutes old, we should just return it.
- else:
- return RepositoryMetadata.objects.all()
+ # If we don't, we have to create some!
+ if not cached_data:
- # If this is raised, the database has no repodata at all, we will create them all.
- except RepositoryMetadata.DoesNotExist:
- database_repositories = []
- try:
- # Get new data from API
- api_repositories = self._get_api_data()
+ # Try to get new data from the API. If it fails, we'll return an empty list.
+ # In this case, we simply don't display our projects on the site.
+ api_repositories = self._get_api_data()
+
+ # Create all the repodata records in the database.
+ for api_data in api_repositories.values():
+ repo_data = RepositoryMetadata(
+ repo_name=api_data["full_name"],
+ description=api_data["description"],
+ forks=api_data["forks_count"],
+ stargazers=api_data["stargazers_count"],
+ language=api_data["language"],
+ )
- # Create all the repodata records in the database.
- for api_data in api_repositories.values():
+ repo_data.save()
+ database_repositories.append(repo_data)
+
+ return database_repositories
+
+ # If the data is stale, we should refresh it.
+ if (timezone.now() - cached_data[0].last_updated).seconds > self.repository_cache_ttl:
+ # Try to get new data from the API. If it fails, return the cached data.
+ api_repositories = self._get_api_data()
+
+ if not api_repositories:
+ return RepositoryMetadata.objects.all()
+
+ # Update or create all RepoData objects in self.repos
+ for repo_name, api_data in api_repositories.items():
+ try:
+ repo_data = RepositoryMetadata.objects.get(repo_name=repo_name)
+ repo_data.description = api_data["description"]
+ repo_data.language = api_data["language"]
+ repo_data.forks = api_data["forks_count"]
+ repo_data.stargazers = api_data["stargazers_count"]
+ except RepositoryMetadata.DoesNotExist:
repo_data = RepositoryMetadata(
repo_name=api_data["full_name"],
description=api_data["description"],
@@ -105,23 +119,14 @@ class HomeView(View):
stargazers=api_data["stargazers_count"],
language=api_data["language"],
)
- repo_data.save()
- database_repositories.append(repo_data)
- except TypeError:
- for repo_name in self.repos:
- repo_data = RepositoryMetadata(
- last_updated=timezone.now() - datetime.timedelta(minutes=50),
- repo_name=repo_name,
- description="Not available.",
- forks=999,
- stargazers=999,
- language="Python",
- )
- repo_data.save()
- database_repositories.append(repo_data)
-
+ repo_data.save()
+ database_repositories.append(repo_data)
return database_repositories
+ # Otherwise, if the data is fresher than 2 minutes old, we should just return it.
+ else:
+ return RepositoryMetadata.objects.all()
+
def get(self, request: WSGIRequest) -> HttpResponse:
"""Collect repo data and render the homepage view."""
repo_data = self._get_repo_data()
diff --git a/pydis_site/templates/home/index.html b/pydis_site/templates/home/index.html
index 72a5f67c..a98613a3 100644
--- a/pydis_site/templates/home/index.html
+++ b/pydis_site/templates/home/index.html
@@ -130,57 +130,59 @@
</section>
<!-- Projects -->
- <section id="projects" class="section">
- <div class="container">
- <h1 class="is-size-1">Projects</h1>
-
- <div class="columns is-multiline is-tablet">
-
- {# Generate project data from HomeView.repos #}
- {% for repo in repo_data %}
- <div class="column is-one-third-desktop is-half-tablet">
-
- <a href="https://github.com/{{ repo.repo_name }}">
- <article class="card">
-
- <header class="card-header">
- <span class="card-header-icon">
- <span class="icon"><i class="fab fa-github"></i></span>
- </span>
- <div class="card-header-title">
- {{ repo.repo_name|cut:"python-discord/" }}
- </div>
- </header>
-
- <p class="card-content">
- {{ repo.description }}
- </p>
-
- <footer class="card-footer">
- <div class="card-footer-item">
- <i class="repo-language-dot {{ repo.language | lower }}"></i>
- {{ repo.language }}
- </div>
- <div class="card-footer-item">
- <i class="fas fa-star"></i>
- {{ repo.stargazers }}
- </div>
- <div class="card-footer-item">
- <i class="fas fa-code-branch"></i>
- {{ repo.forks }}
- </div>
- </footer>
-
- </article>
- </a>
+ {% if repo_data %}
+ <section id="projects" class="section">
+ <div class="container">
+ <h1 class="is-size-1">Projects</h1>
+
+ <div class="columns is-multiline is-tablet">
+
+ {# Generate project data from HomeView.repos #}
+ {% for repo in repo_data %}
+ <div class="column is-one-third-desktop is-half-tablet">
+
+ <a href="https://github.com/{{ repo.repo_name }}">
+ <article class="card">
+
+ <header class="card-header">
+ <span class="card-header-icon">
+ <span class="icon"><i class="fab fa-github"></i></span>
+ </span>
+ <div class="card-header-title">
+ {{ repo.repo_name|cut:"python-discord/" }}
+ </div>
+ </header>
+
+ <p class="card-content">
+ {{ repo.description }}
+ </p>
+
+ <footer class="card-footer">
+ <div class="card-footer-item">
+ <i class="repo-language-dot {{ repo.language | lower }}"></i>
+ {{ repo.language }}
+ </div>
+ <div class="card-footer-item">
+ <i class="fas fa-star"></i>
+ {{ repo.stargazers }}
+ </div>
+ <div class="card-footer-item">
+ <i class="fas fa-code-branch"></i>
+ {{ repo.forks }}
+ </div>
+ </footer>
+
+ </article>
+ </a>
- </div>
- {% endfor %}
+ </div>
+ {% endfor %}
- </div>
+ </div>
- </div>
- </section>
+ </div>
+ </section>
+ {% endif %}
<!-- Sponsors -->
<section id="sponsors" class="hero is-light">